From 769481704da29c6defbd205c40eb2a7560ff400c Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 27 Oct 2025 19:33:10 +0000 Subject: [PATCH 01/33] [clang][DebugInfo] Make property-auto-synth.m check LLVM IR Check for lack of `setter` and `getter` attributes on `DIObjCProperty` --- clang/test/DebugInfo/ObjC/property-auto-synth.m | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/clang/test/DebugInfo/ObjC/property-auto-synth.m b/clang/test/DebugInfo/ObjC/property-auto-synth.m index 1f489f2f6b637..5e961d424e532 100644 --- a/clang/test/DebugInfo/ObjC/property-auto-synth.m +++ b/clang/test/DebugInfo/ObjC/property-auto-synth.m @@ -1,12 +1,7 @@ -// FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s - -// CHECK: AT_APPLE_property_name -// CHECK-NOT: AT_APPLE_property_getter -// CHECK-NOT: AT_APPLE_property_setter -// CHECK: AT_APPLE_property_attribute -// CHECK: AT_APPLE_property +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s +// CHECK-NOT: setter +// CHECK-NOT: getter @interface I1 @property int p1; From e44dce3cb62013a7d1f573d6e7a1b2fffaaf36d5 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 27 Oct 2025 19:40:32 +0000 Subject: [PATCH 02/33] [clang][DebugInfo][test] Remove redundant Objective-C property test (#165298) We already have the same test (just different variable names) in `property-basic.m`. --- clang/test/DebugInfo/ObjC/property-2.m | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 clang/test/DebugInfo/ObjC/property-2.m diff --git a/clang/test/DebugInfo/ObjC/property-2.m b/clang/test/DebugInfo/ObjC/property-2.m deleted file mode 100644 index f15213131ccc0..0000000000000 --- a/clang/test/DebugInfo/ObjC/property-2.m +++ /dev/null @@ -1,18 +0,0 @@ -// FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited -x objective-c < %s | grep DW_AT_name -@interface Foo { - int i; -} -@property int i; -@end - -@implementation Foo -@synthesize i; -@end - -int bar(Foo *f) { - int i = 1; - f.i = 2; - i = f.i; - return i; -} From 7d14733c12d909e1bdd1499c9557e78565aca4ae Mon Sep 17 00:00:00 2001 From: LU-JOHN Date: Mon, 27 Oct 2025 14:40:56 -0500 Subject: [PATCH 03/33] [AMDGPU] Generate s_absdiff_i32 (#164835) Generate s_absdiff_i32. Tested in absdiff.ll. Also update s_cmp_0.ll to test that s_absdiff_i32 is foldable with a s_cmp_lg_u32 sX, 0. --------- Signed-off-by: John Lu --- llvm/lib/Target/AMDGPU/SOPInstructions.td | 7 +- llvm/test/CodeGen/AMDGPU/absdiff.ll | 104 ++++++++++++++++++++++ llvm/test/CodeGen/AMDGPU/s_cmp_0.ll | 25 ++++-- 3 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/absdiff.ll diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td index 84287b621fe78..1931e0be15152 100644 --- a/llvm/lib/Target/AMDGPU/SOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td @@ -838,9 +838,10 @@ def S_CBRANCH_G_FORK : SOP2_Pseudo < let SubtargetPredicate = isGFX6GFX7GFX8GFX9; } -let Defs = [SCC] in { -def S_ABSDIFF_I32 : SOP2_32 <"s_absdiff_i32">; -} // End Defs = [SCC] +let isCommutable = 1, Defs = [SCC] in +def S_ABSDIFF_I32 : SOP2_32 <"s_absdiff_i32", + [(set i32:$sdst, (UniformUnaryFrag (sub_oneuse i32:$src0, i32:$src1)))] +>; let SubtargetPredicate = isGFX8GFX9 in { def S_RFE_RESTORE_B64 : SOP2_Pseudo < diff --git a/llvm/test/CodeGen/AMDGPU/absdiff.ll b/llvm/test/CodeGen/AMDGPU/absdiff.ll new file mode 100644 index 0000000000000..9cb397fb9d1c6 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/absdiff.ll @@ -0,0 +1,104 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 < %s | FileCheck %s + +define amdgpu_ps i16 @absdiff_i16_false(i16 inreg %arg0, i16 inreg %arg1) { +; CHECK-LABEL: absdiff_i16_false: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_sub_i32 s0, s0, s1 +; CHECK-NEXT: s_sext_i32_i16 s1, s0 +; CHECK-NEXT: s_sub_i32 s0, 0, s0 +; CHECK-NEXT: s_sext_i32_i16 s0, s0 +; CHECK-NEXT: s_max_i32 s0, s1, s0 +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i16 %arg0, %arg1 + %res = call i16 @llvm.abs.i16(i16 %diff, i1 false) ; INT_MIN input returns INT_MIN + ret i16 %res +} + +define amdgpu_ps i16 @absdiff_i16_true(i16 inreg %arg0, i16 inreg %arg1) { +; CHECK-LABEL: absdiff_i16_true: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_sub_i32 s0, s0, s1 +; CHECK-NEXT: s_sext_i32_i16 s1, s0 +; CHECK-NEXT: s_sub_i32 s0, 0, s0 +; CHECK-NEXT: s_sext_i32_i16 s0, s0 +; CHECK-NEXT: s_max_i32 s0, s1, s0 +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i16 %arg0, %arg1 + %res = call i16 @llvm.abs.i16(i16 %diff, i1 true) ; INT_MIN input returns poison + ret i16 %res +} + +define amdgpu_ps i32 @absdiff_i32_false(i32 inreg %arg0, i32 inreg %arg1) { +; CHECK-LABEL: absdiff_i32_false: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_absdiff_i32 s0, s0, s1 +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i32 %arg0, %arg1 + %res = call i32 @llvm.abs.i32(i32 %diff, i1 false) ; INT_MIN input returns INT_MIN + ret i32 %res +} + +define amdgpu_ps i32 @absdiff_i32_true(i32 inreg %arg0, i32 inreg %arg1) { +; CHECK-LABEL: absdiff_i32_true: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_absdiff_i32 s0, s0, s1 +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i32 %arg0, %arg1 + %res = call i32 @llvm.abs.i32(i32 %diff, i1 true) ; INT_MIN input returns poison + ret i32 %res +} + +; Multiple uses of %diff. No benefit for using s_absdiff_i32. +define amdgpu_ps i32 @absdiff_i32_false_multi_use(i32 inreg %arg0, i32 inreg %arg1) { +; CHECK-LABEL: absdiff_i32_false_multi_use: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_sub_i32 s1, s0, s1 +; CHECK-NEXT: s_abs_i32 s0, s1 +; CHECK-NEXT: ;;#ASMSTART +; CHECK-NEXT: ; use s1 +; CHECK-NEXT: ;;#ASMEND +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i32 %arg0, %arg1 + %res = call i32 @llvm.abs.i32(i32 %diff, i1 false) ; INT_MIN input returns INT_MIN + call void asm "; use $0", "s"(i32 %diff) + ret i32 %res +} + +define <2 x i32> @absdiff_2xi32_false(<2 x i32> %arg0, <2 x i32> %arg1) { +; CHECK-LABEL: absdiff_2xi32_false: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_sub_u32_e32 v0, v0, v2 +; CHECK-NEXT: v_sub_u32_e32 v1, v1, v3 +; CHECK-NEXT: v_sub_u32_e32 v2, 0, v0 +; CHECK-NEXT: v_max_i32_e32 v0, v2, v0 +; CHECK-NEXT: v_sub_u32_e32 v2, 0, v1 +; CHECK-NEXT: v_max_i32_e32 v1, v2, v1 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %diff = sub <2 x i32> %arg0, %arg1 + %res = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %diff, i1 false) ; INT_MIN input returns INT_MIN + ret <2 x i32> %res +} + +define <4 x i32> @absdiff_4xi32_false(<4 x i32> %arg0, <4 x i32> %arg1) { +; CHECK-LABEL: absdiff_4xi32_false: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_sub_u32_e32 v0, v0, v4 +; CHECK-NEXT: v_sub_u32_e32 v1, v1, v5 +; CHECK-NEXT: v_sub_u32_e32 v4, 0, v0 +; CHECK-NEXT: v_sub_u32_e32 v2, v2, v6 +; CHECK-NEXT: v_max_i32_e32 v0, v4, v0 +; CHECK-NEXT: v_sub_u32_e32 v4, 0, v1 +; CHECK-NEXT: v_sub_u32_e32 v3, v3, v7 +; CHECK-NEXT: v_max_i32_e32 v1, v4, v1 +; CHECK-NEXT: v_sub_u32_e32 v4, 0, v2 +; CHECK-NEXT: v_max_i32_e32 v2, v4, v2 +; CHECK-NEXT: v_sub_u32_e32 v4, 0, v3 +; CHECK-NEXT: v_max_i32_e32 v3, v4, v3 +; CHECK-NEXT: s_setpc_b64 s[30:31] + %diff = sub <4 x i32> %arg0, %arg1 + %res = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %diff, i1 false) ; INT_MIN input returns INT_MIN + ret <4 x i32> %res +} diff --git a/llvm/test/CodeGen/AMDGPU/s_cmp_0.ll b/llvm/test/CodeGen/AMDGPU/s_cmp_0.ll index dd5f838b4a206..0166d7ac7ddc2 100644 --- a/llvm/test/CodeGen/AMDGPU/s_cmp_0.ll +++ b/llvm/test/CodeGen/AMDGPU/s_cmp_0.ll @@ -110,6 +110,21 @@ define amdgpu_ps i32 @abs32(i32 inreg %val0) { ret i32 %zext } +define amdgpu_ps i32 @absdiff32(i32 inreg %val0, i32 inreg %val1) { +; CHECK-LABEL: absdiff32: +; CHECK: ; %bb.0: +; CHECK-NEXT: s_absdiff_i32 s0, s0, s1 +; CHECK-NEXT: s_cselect_b64 s[0:1], -1, 0 +; CHECK-NEXT: v_cndmask_b32_e64 v0, 0, 1, s[0:1] +; CHECK-NEXT: v_readfirstlane_b32 s0, v0 +; CHECK-NEXT: ; return to shader part epilog + %diff = sub i32 %val0, %val1 + %result = call i32 @llvm.abs.i32(i32 %diff, i1 false) + %cmp = icmp ne i32 %result, 0 + %zext = zext i1 %cmp to i32 + ret i32 %zext +} + define amdgpu_ps i32 @and32(i32 inreg %val0, i32 inreg %val1) { ; CHECK-LABEL: and32: ; CHECK: ; %bb.0: @@ -608,14 +623,14 @@ define amdgpu_ps i32 @si_pc_add_rel_offset_must_not_optimize() { ; CHECK-NEXT: s_add_u32 s0, s0, __unnamed_1@rel32@lo+4 ; CHECK-NEXT: s_addc_u32 s1, s1, __unnamed_1@rel32@hi+12 ; CHECK-NEXT: s_cmp_lg_u64 s[0:1], 0 -; CHECK-NEXT: s_cbranch_scc0 .LBB35_2 +; CHECK-NEXT: s_cbranch_scc0 .LBB36_2 ; CHECK-NEXT: ; %bb.1: ; %endif ; CHECK-NEXT: s_mov_b32 s0, 1 -; CHECK-NEXT: s_branch .LBB35_3 -; CHECK-NEXT: .LBB35_2: ; %if +; CHECK-NEXT: s_branch .LBB36_3 +; CHECK-NEXT: .LBB36_2: ; %if ; CHECK-NEXT: s_mov_b32 s0, 0 -; CHECK-NEXT: s_branch .LBB35_3 -; CHECK-NEXT: .LBB35_3: +; CHECK-NEXT: s_branch .LBB36_3 +; CHECK-NEXT: .LBB36_3: %cmp = icmp ne ptr addrspace(4) @1, null br i1 %cmp, label %endif, label %if From 3d26e6c7172f31f9242e64e1515a20834c673646 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 27 Oct 2025 12:41:05 -0700 Subject: [PATCH 04/33] Revert "[LLDB] Add debug output to test to diagnose bot failure" This reverts commit d8184343755ababad6479d07451f36dd695f75c1. --- lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py b/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py index 3633701833220..3b414ddb78b91 100644 --- a/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py +++ b/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py @@ -21,7 +21,6 @@ def rosetta_debugserver_installed(): import platform version = platform.mac_ver() # Workaround for an undiagnosed problem on green dragon. - print(version) if version[0] and version[0][0] == '15' and version[0][1] == '5': return False return exists("/Library/Apple/usr/libexec/oah/debugserver") From 8c13b75b614fe97c633af1fa72a328b5a1a05044 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 27 Oct 2025 12:42:43 -0700 Subject: [PATCH 05/33] [LLDB] Fix condition in test --- lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py b/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py index 3b414ddb78b91..9050f6a653d50 100644 --- a/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py +++ b/lldb/test/API/macosx/posix_spawn/TestLaunchProcessPosixSpawn.py @@ -21,7 +21,7 @@ def rosetta_debugserver_installed(): import platform version = platform.mac_ver() # Workaround for an undiagnosed problem on green dragon. - if version[0] and version[0][0] == '15' and version[0][1] == '5': + if version[0] == '15.5': return False return exists("/Library/Apple/usr/libexec/oah/debugserver") From 5d9df8f29ab46156d6f6decb43a3b364f88a9587 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 27 Oct 2025 19:43:54 +0000 Subject: [PATCH 06/33] [clang][DebugInfo][test] Convert Objective-C property2.m test to check LLVM IR (#165297) This patch series renames these Objective-C property tests to something more descriptive and adjusts them to check IR. Currently the tests check raw assembly output (not even dwarfdump). Which most likely hid some bugs around property debug-info. --- .../DebugInfo/ObjC/property-explicit-ivar.m | 22 +++++++++++++++++++ clang/test/DebugInfo/ObjC/property2.m | 15 ------------- 2 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 clang/test/DebugInfo/ObjC/property-explicit-ivar.m delete mode 100644 clang/test/DebugInfo/ObjC/property2.m diff --git a/clang/test/DebugInfo/ObjC/property-explicit-ivar.m b/clang/test/DebugInfo/ObjC/property-explicit-ivar.m new file mode 100644 index 0000000000000..5092e23e195f8 --- /dev/null +++ b/clang/test/DebugInfo/ObjC/property-explicit-ivar.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +// CHECK: ![[BASE_PROP:[0-9]+]] = !DIObjCProperty(name: "base" +// CHECK-SAME: attributes: 2316 +// CHECK-SAME: type: ![[P1_TYPE:[0-9]+]] +// +// CHECK: ![[P1_TYPE]] = !DIBasicType(name: "int" +// +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_customIvar" +// CHECK-SAME: extraData: ![[BASE_PROP]] + +@interface C { + int _customIvar; +} +@property int base; +@end + +@implementation C +@synthesize base = _customIvar; +@end + +void foo(C *cptr) {} diff --git a/clang/test/DebugInfo/ObjC/property2.m b/clang/test/DebugInfo/ObjC/property2.m deleted file mode 100644 index 7e0a5e9f954ba..0000000000000 --- a/clang/test/DebugInfo/ObjC/property2.m +++ /dev/null @@ -1,15 +0,0 @@ -// FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s - -// CHECK: AT_APPLE_property_name -@interface C { - int _base; -} -@property int base; -@end - -@implementation C -@synthesize base = _base; -@end - -void foo(C *cptr) {} From d2bcd58aa6d9d49af9129537d837c87bb491d99d Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Mon, 27 Oct 2025 12:43:59 -0700 Subject: [PATCH 07/33] [profdata] Consume reader error if returned early (#163671) --- llvm/tools/llvm-profdata/llvm-profdata.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index a356bcd0773e0..9b853e29592b4 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -778,6 +779,12 @@ loadInput(const WeightedFile &Input, SymbolRemapper *Remapper, // we have more non-fatal errors from InstrProfReader in the future. How // should this interact with different -failure-mode? std::optional> ReaderWarning; + auto ReaderWarningScope = llvm::make_scope_exit([&] { + // If we hit a different error we may still have an error in ReaderWarning. + // Consume it now to avoid an assert + if (ReaderWarning) + consumeError(std::move(ReaderWarning->first)); + }); auto Warn = [&](Error E) { if (ReaderWarning) { consumeError(std::move(E)); From d0a7411cb840d253f58a627cc3957fc7b5263a3d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 27 Oct 2025 19:39:39 +0000 Subject: [PATCH 08/33] [clang][DebugInfo][test] Make Objective-C property5.m test check LLVM IR New name makes it easer to find and checking IR is less likely to hide bugs (and is more consistent with the other Clang debug-info tests). --- .../ObjC/property-explicit-accessors.m | 34 +++++++++++++++++++ clang/test/DebugInfo/ObjC/property5.m | 33 ------------------ 2 files changed, 34 insertions(+), 33 deletions(-) create mode 100644 clang/test/DebugInfo/ObjC/property-explicit-accessors.m delete mode 100644 clang/test/DebugInfo/ObjC/property5.m diff --git a/clang/test/DebugInfo/ObjC/property-explicit-accessors.m b/clang/test/DebugInfo/ObjC/property-explicit-accessors.m new file mode 100644 index 0000000000000..86eade6998afe --- /dev/null +++ b/clang/test/DebugInfo/ObjC/property-explicit-accessors.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +// CHECK: !DIObjCProperty(name: "baseInt" +// CHECK-SAME: setter: "mySetBaseInt:" +// CHECK-SAME: getter: "myGetBaseInt" +// CHECK-SAME: attributes: 2446 +// CHECK-SAME: type: ![[P1_TYPE:[0-9]+]] +// +// CHECK: ![[P1_TYPE]] = !DIBasicType(name: "int" + +@interface BaseClass2 +{ + int _baseInt; +} +- (int) myGetBaseInt; +- (void) mySetBaseInt: (int) in_int; +@property(getter=myGetBaseInt,setter=mySetBaseInt:) int baseInt; +@end + +@implementation BaseClass2 + +- (int) myGetBaseInt +{ + return _baseInt; +} + +- (void) mySetBaseInt: (int) in_int +{ + _baseInt = 2 * in_int; +} +@end + + +void foo(BaseClass2 *ptr) {} diff --git a/clang/test/DebugInfo/ObjC/property5.m b/clang/test/DebugInfo/ObjC/property5.m deleted file mode 100644 index 8b70f1ff20824..0000000000000 --- a/clang/test/DebugInfo/ObjC/property5.m +++ /dev/null @@ -1,33 +0,0 @@ -// FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s - -// CHECK: AT_APPLE_property_name -// CHECK: AT_APPLE_property_getter -// CHECK: AT_APPLE_property_setter -// CHECK: AT_APPLE_property_attribute -// CHECK: AT_APPLE_property - -@interface BaseClass2 -{ - int _baseInt; -} -- (int) myGetBaseInt; -- (void) mySetBaseInt: (int) in_int; -@property(getter=myGetBaseInt,setter=mySetBaseInt:) int baseInt; -@end - -@implementation BaseClass2 - -- (int) myGetBaseInt -{ - return _baseInt; -} - -- (void) mySetBaseInt: (int) in_int -{ - _baseInt = 2 * in_int; -} -@end - - -void foo(BaseClass2 *ptr) {} From 57722ddce172f569f04a50b76ccb2fc524adf8f5 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Mon, 27 Oct 2025 20:07:48 +0000 Subject: [PATCH 09/33] Revert "[lit] Support more ulimit options" This reverts commit 8f1c72dcd3fc4bc871bbcd06bfae76510f3714b0. This is causing builtbot failures. https://lab.llvm.org/buildbot/#/builders/23/builds/15030 https://lab.llvm.org/buildbot/#/builders/190/builds/29834 --- llvm/utils/lit/lit/TestRunner.py | 4 ---- llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py | 4 ---- llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py | 2 -- llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt | 2 -- llvm/utils/lit/tests/shtest-ulimit.py | 4 ---- 5 files changed, 16 deletions(-) diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index a48df097403c7..f88314547bb3f 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -612,10 +612,6 @@ def executeBuiltinUlimit(cmd, shenv): shenv.ulimit["RLIMIT_AS"] = new_limit * 1024 elif cmd.args[1] == "-n": shenv.ulimit["RLIMIT_NOFILE"] = new_limit - elif cmd.args[1] == "-s": - shenv.ulimit["RLIMIT_STACK"] = new_limit * 1024 - elif cmd.args[1] == "-f": - shenv.ulimit["RLIMIT_FSIZE"] = new_limit else: raise InternalShellError( cmd, "'ulimit' does not support option: %s" % cmd.args[1] diff --git a/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py b/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py index a9dc2595497e7..33d2d59ff0dbe 100644 --- a/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py +++ b/llvm/utils/lit/lit/builtin_commands/_launch_with_limit.py @@ -17,10 +17,6 @@ def main(argv): resource.setrlimit(resource.RLIMIT_AS, limit) elif limit_str == "RLIMIT_NOFILE": resource.setrlimit(resource.RLIMIT_NOFILE, limit) - elif limit_str == "RLIMIT_STACK": - resource.setrlimit(resource.RLIMIT_STACK, limit) - elif limit_str == "RLIMIT_FSIZE": - resource.setrlimit(resource.RLIMIT_FSIZE, limit) process_output = subprocess.run(command_args) sys.exit(process_output.returncode) diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py index c732c0429e661..632f954fa8fde 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit/print_limits.py @@ -2,5 +2,3 @@ print("RLIMIT_AS=" + str(resource.getrlimit(resource.RLIMIT_AS)[0])) print("RLIMIT_NOFILE=" + str(resource.getrlimit(resource.RLIMIT_NOFILE)[0])) -print("RLIMIT_STACK=" + str(resource.getrlimit(resource.RLIMIT_STACK)[0])) -print("RLIMIT_FSIZE=" + str(resource.getrlimit(resource.RLIMIT_FSIZE)[0])) diff --git a/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt b/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt index d38dc44fa033d..4edf1c303a092 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt +++ b/llvm/utils/lit/tests/Inputs/shtest-ulimit/ulimit_okay.txt @@ -1,6 +1,4 @@ # RUN: ulimit -n 50 -# RUN: ulimit -s 256 -# RUN: ulimit -f 5 # RUN: %{python} %S/print_limits.py # Fail the test so that we can assert on the output. # RUN: not echo return diff --git a/llvm/utils/lit/tests/shtest-ulimit.py b/llvm/utils/lit/tests/shtest-ulimit.py index ba3de8b1bfced..09cd475b737c1 100644 --- a/llvm/utils/lit/tests/shtest-ulimit.py +++ b/llvm/utils/lit/tests/shtest-ulimit.py @@ -19,11 +19,7 @@ # CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_okay.txt ({{[^)]*}}) # CHECK: ulimit -n 50 -# CHECK: ulimit -s 256 -# CHECK: ulimit -f 5 # CHECK: RLIMIT_NOFILE=50 -# CHECK: RLIMIT_STACK=262144 -# CHECK: RLIMIT_FSIZE=5 # CHECK-LABEL: FAIL: shtest-ulimit :: ulimit_reset.txt ({{[^)]*}}) # CHECK: RLIMIT_NOFILE=[[BASE_NOFILE_LIMIT]] From 1c837ecaa067840b06a97e7e1f13e54bf64e03cf Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Mon, 27 Oct 2025 20:12:39 +0000 Subject: [PATCH 10/33] [Profcheck] Update XFail List 00f5a1e30b1b2a28569c5aa24219518135d107d0 added in some new tests that fail under the profcheck configuration. We have not finished cleaning up SimplifyCFG yet, so disable these tests for now. --- llvm/utils/profcheck-xfail.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt index 151b06573d961..3d07b16cac661 100644 --- a/llvm/utils/profcheck-xfail.txt +++ b/llvm/utils/profcheck-xfail.txt @@ -332,10 +332,10 @@ Instrumentation/MemorySanitizer/AArch64/arm64-vshift.ll Instrumentation/MemorySanitizer/AArch64/module-flags-aarch64.ll Instrumentation/MemorySanitizer/AArch64/neon_vst_float.ll Instrumentation/MemorySanitizer/AArch64/qshrn.ll -Instrumentation/MemorySanitizer/AArch64/sme-aarch64-svcount-mini.ll -Instrumentation/MemorySanitizer/AArch64/sme-aarch64-svcount.ll -Instrumentation/MemorySanitizer/AArch64/sme2-intrinsics-add-mini.ll Instrumentation/MemorySanitizer/AArch64/sme2-intrinsics-add.ll +Instrumentation/MemorySanitizer/AArch64/sme2-intrinsics-add-mini.ll +Instrumentation/MemorySanitizer/AArch64/sme-aarch64-svcount.ll +Instrumentation/MemorySanitizer/AArch64/sme-aarch64-svcount-mini.ll Instrumentation/MemorySanitizer/AArch64/vararg.ll Instrumentation/MemorySanitizer/AArch64/vararg_shadow.ll Instrumentation/MemorySanitizer/abs-vector.ll @@ -1316,6 +1316,8 @@ Transforms/SimpleLoopUnswitch/pr60736.ll Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll Transforms/SimpleLoopUnswitch/trivial-unswitch.ll Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll +Transforms/SimplifyCFG/RISCV/switch-of-powers-of-two.ll +Transforms/SimplifyCFG/X86/switch-of-powers-of-two.ll Transforms/StackProtector/cross-dso-cfi-stack-chk-fail.ll Transforms/StructurizeCFG/AMDGPU/uniform-regions.ll Transforms/StructurizeCFG/hoist-zerocost.ll From 7d1538cd3db3e228459e483ce9cdeb7fa4ae5e00 Mon Sep 17 00:00:00 2001 From: Sterling-Augustine Date: Mon, 27 Oct 2025 14:39:46 -0700 Subject: [PATCH 11/33] Move LIBC_CONF_STRING_UNSAFE_WIDE_READ to top-level libc-configuration (#165046) This options sets a compile option when building sources inside the string directory, and this option affects string_utils.h. But string_utils.h is #included from more places than just the string directory (such as from __support/CPP/string.h), leading to both narrow-reads in those cases, but more seriously, ODR violations when the two different string_length implementations are included int he same program. Having this option at the top level avoids this problem. --- libc/cmake/modules/LLVMLibCCompileOptionRules.cmake | 8 ++++++++ libc/src/string/CMakeLists.txt | 11 ----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index 4c36ed8620f40..4e9a9b66a63a7 100644 --- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -81,6 +81,14 @@ function(_get_compile_options_from_config output_var) list(APPEND config_options "-DLIBC_QSORT_IMPL=${LIBC_CONF_QSORT_IMPL}") endif() + if(LIBC_CONF_STRING_UNSAFE_WIDE_READ) + list(APPEND config_options "-DLIBC_COPT_STRING_UNSAFE_WIDE_READ") + endif() + + if(LIBC_CONF_MEMSET_X86_USE_SOFTWARE_PREFETCHING) + list(APPEND config_options "-DLIBC_COPT_MEMSET_X86_USE_SOFTWARE_PREFETCHING") + endif() + if(LIBC_TYPES_TIME_T_IS_32_BIT AND LLVM_LIBC_FULL_BUILD) list(APPEND config_options "-DLIBC_TYPES_TIME_T_IS_32_BIT") endif() diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 83c956429be24..a640e1d2cc774 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -1,15 +1,5 @@ add_subdirectory(memory_utils) -if(LIBC_CONF_STRING_UNSAFE_WIDE_READ) - list(APPEND string_config_options "-DLIBC_COPT_STRING_UNSAFE_WIDE_READ") -endif() -if(LIBC_CONF_MEMSET_X86_USE_SOFTWARE_PREFETCHING) - list(APPEND string_config_options "-DLIBC_COPT_MEMSET_X86_USE_SOFTWARE_PREFETCHING") -endif() -if(string_config_options) - list(PREPEND string_config_options "COMPILE_OPTIONS") -endif() - add_header_library( string_utils HDRS @@ -24,7 +14,6 @@ add_header_library( libc.src.__support.common libc.src.__support.macros.attributes libc.src.string.memory_utils.inline_memcpy - ${string_config_options} ) add_header_library( From 585da50d7d651ae3fcdd1368204ecc7d8250db24 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 27 Oct 2025 17:43:57 -0400 Subject: [PATCH 12/33] [third-party] Add a snapshot of Boost.Math 1.89 standalone (#141508) This PR adds the code of Boost.Math as of version 1.89 into the third-party directory, as discussed in a recent RFC [1]. The goal is for this code to be used as a back-end for the C++17 Math Special Functions. As explained in third-paty/README.md, this code is cleared for usage inside libc++ for the Math Special functions, however the LLVM Foundation should be consulted before using this code anywhere else in the LLVM project, due to the fact that it is under the Boost Software License (as opposed to the usual LLVM license). See the RFC [1] for more details. [1]: https://discourse.llvm.org/t/rfc-libc-taking-a-dependency-on-boost-math-for-the-c-17-math-special-functions --- third-party/README.md | 11 + third-party/boost-math/.codecov.yml | 26 + third-party/boost-math/.drone.star | 75 + third-party/boost-math/.gitattributes | 96 + third-party/boost-math/.gitignore | 30 + third-party/boost-math/.travis.yml | 795 +++ third-party/boost-math/CMakeLists.txt | 61 + third-party/boost-math/LICENSE | 23 + third-party/boost-math/README.md | 180 + third-party/boost-math/build.jam | 48 + .../boost-math/include/boost/cstdfloat.hpp | 58 + .../math/bindings/detail/big_digamma.hpp | 297 ++ .../math/bindings/detail/big_lanczos.hpp | 777 +++ .../include/boost/math/bindings/mpfr.hpp | 974 ++++ .../include/boost/math/bindings/mpreal.hpp | 921 ++++ .../include/boost/math/bindings/rr.hpp | 876 ++++ .../include/boost/math/ccmath/abs.hpp | 89 + .../include/boost/math/ccmath/ccmath.hpp | 45 + .../include/boost/math/ccmath/ceil.hpp | 78 + .../include/boost/math/ccmath/copysign.hpp | 81 + .../boost/math/ccmath/detail/config.hpp | 52 + .../include/boost/math/ccmath/detail/swap.hpp | 21 + .../include/boost/math/ccmath/div.hpp | 86 + .../include/boost/math/ccmath/fabs.hpp | 41 + .../include/boost/math/ccmath/fdim.hpp | 93 + .../include/boost/math/ccmath/floor.hpp | 131 + .../include/boost/math/ccmath/fma.hpp | 130 + .../include/boost/math/ccmath/fmax.hpp | 89 + .../include/boost/math/ccmath/fmin.hpp | 89 + .../include/boost/math/ccmath/fmod.hpp | 114 + .../include/boost/math/ccmath/fpclassify.hpp | 48 + .../include/boost/math/ccmath/frexp.hpp | 101 + .../include/boost/math/ccmath/hypot.hpp | 116 + .../include/boost/math/ccmath/ilogb.hpp | 60 + .../include/boost/math/ccmath/isfinite.hpp | 53 + .../include/boost/math/ccmath/isgreater.hpp | 42 + .../boost/math/ccmath/isgreaterequal.hpp | 42 + .../include/boost/math/ccmath/isinf.hpp | 61 + .../include/boost/math/ccmath/isless.hpp | 42 + .../include/boost/math/ccmath/islessequal.hpp | 42 + .../include/boost/math/ccmath/isnan.hpp | 42 + .../include/boost/math/ccmath/isnormal.hpp | 47 + .../include/boost/math/ccmath/isunordered.hpp | 35 + .../include/boost/math/ccmath/ldexp.hpp | 81 + .../include/boost/math/ccmath/logb.hpp | 86 + .../include/boost/math/ccmath/modf.hpp | 79 + .../include/boost/math/ccmath/next.hpp | 458 ++ .../include/boost/math/ccmath/remainder.hpp | 106 + .../include/boost/math/ccmath/round.hpp | 179 + .../include/boost/math/ccmath/scalbln.hpp | 60 + .../include/boost/math/ccmath/scalbn.hpp | 81 + .../include/boost/math/ccmath/signbit.hpp | 219 + .../include/boost/math/ccmath/sqrt.hpp | 80 + .../include/boost/math/ccmath/trunc.hpp | 70 + .../include/boost/math/common_factor.hpp | 23 + .../include/boost/math/common_factor_ct.hpp | 34 + .../include/boost/math/common_factor_rt.hpp | 30 + .../boost-math/include/boost/math/complex.hpp | 32 + .../include/boost/math/complex/acos.hpp | 245 + .../include/boost/math/complex/acosh.hpp | 34 + .../include/boost/math/complex/asin.hpp | 252 + .../include/boost/math/complex/asinh.hpp | 32 + .../include/boost/math/complex/atan.hpp | 36 + .../include/boost/math/complex/atanh.hpp | 214 + .../include/boost/math/complex/details.hpp | 68 + .../include/boost/math/complex/fabs.hpp | 23 + .../boost/math/concepts/distributions.hpp | 497 ++ .../boost/math/concepts/real_concept.hpp | 400 ++ .../boost/math/concepts/real_type_concept.hpp | 119 + .../boost/math/concepts/std_real_concept.hpp | 427 ++ .../math/constants/calculate_constants.hpp | 1109 ++++ .../boost/math/constants/constants.hpp | 361 ++ .../include/boost/math/constants/info.hpp | 169 + .../boost/math/cstdfloat/cstdfloat_cmath.hpp | 1012 ++++ .../math/cstdfloat/cstdfloat_complex.hpp | 38 + .../math/cstdfloat/cstdfloat_complex_std.hpp | 813 +++ .../math/cstdfloat/cstdfloat_iostream.hpp | 822 +++ .../boost/math/cstdfloat/cstdfloat_limits.hpp | 87 + .../boost/math/cstdfloat/cstdfloat_types.hpp | 441 ++ .../boost/math/differentiation/autodiff.hpp | 2061 ++++++++ .../math/differentiation/autodiff_cpp11.hpp | 387 ++ .../differentiation/finite_difference.hpp | 266 + .../differentiation/lanczos_smoothing.hpp | 591 +++ .../include/boost/math/distributions.hpp | 58 + .../boost/math/distributions/arcsine.hpp | 548 ++ .../boost/math/distributions/bernoulli.hpp | 349 ++ .../include/boost/math/distributions/beta.hpp | 584 +++ .../boost/math/distributions/binomial.hpp | 729 +++ .../boost/math/distributions/cauchy.hpp | 379 ++ .../boost/math/distributions/chi_squared.hpp | 347 ++ .../boost/math/distributions/complement.hpp | 198 + .../detail/common_error_handling.hpp | 228 + .../detail/derived_accessors.hpp | 190 + .../distributions/detail/generic_mode.hpp | 145 + .../distributions/detail/generic_quantile.hpp | 100 + .../detail/hypergeometric_cdf.hpp | 101 + .../detail/hypergeometric_pdf.hpp | 490 ++ .../detail/hypergeometric_quantile.hpp | 245 + .../detail/inv_discrete_quantile.hpp | 583 +++ ...rical_cumulative_distribution_function.hpp | 73 + .../boost/math/distributions/exponential.hpp | 352 ++ .../math/distributions/extreme_value.hpp | 392 ++ .../math/distributions/find_location.hpp | 140 + .../boost/math/distributions/find_scale.hpp | 200 + .../boost/math/distributions/fisher_f.hpp | 393 ++ .../include/boost/math/distributions/fwd.hpp | 171 + .../boost/math/distributions/gamma.hpp | 396 ++ .../boost/math/distributions/geometric.hpp | 571 ++ .../boost/math/distributions/holtsmark.hpp | 2518 +++++++++ .../math/distributions/hyperexponential.hpp | 641 +++ .../math/distributions/hypergeometric.hpp | 311 ++ .../distributions/inverse_chi_squared.hpp | 398 ++ .../math/distributions/inverse_gamma.hpp | 504 ++ .../math/distributions/inverse_gaussian.hpp | 555 ++ .../math/distributions/kolmogorov_smirnov.hpp | 511 ++ .../boost/math/distributions/landau.hpp | 4642 +++++++++++++++++ .../boost/math/distributions/laplace.hpp | 494 ++ .../boost/math/distributions/logistic.hpp | 397 ++ .../boost/math/distributions/lognormal.hpp | 361 ++ .../boost/math/distributions/mapairy.hpp | 4220 +++++++++++++++ .../math/distributions/negative_binomial.hpp | 609 +++ .../math/distributions/non_central_beta.hpp | 977 ++++ .../distributions/non_central_chi_squared.hpp | 998 ++++ .../math/distributions/non_central_f.hpp | 419 ++ .../math/distributions/non_central_t.hpp | 1325 +++++ .../boost/math/distributions/normal.hpp | 368 ++ .../boost/math/distributions/pareto.hpp | 508 ++ .../boost/math/distributions/poisson.hpp | 563 ++ .../boost/math/distributions/rayleigh.hpp | 381 ++ .../boost/math/distributions/saspoint5.hpp | 2796 ++++++++++ .../boost/math/distributions/skew_normal.hpp | 760 +++ .../boost/math/distributions/students_t.hpp | 512 ++ .../boost/math/distributions/triangular.hpp | 548 ++ .../boost/math/distributions/uniform.hpp | 398 ++ .../boost/math/distributions/weibull.hpp | 487 ++ .../include/boost/math/filters/daubechies.hpp | 99 + .../interpolators/barycentric_rational.hpp | 99 + .../math/interpolators/bezier_polynomial.hpp | 60 + .../math/interpolators/bilinear_uniform.hpp | 54 + .../interpolators/cardinal_cubic_b_spline.hpp | 87 + .../cardinal_quadratic_b_spline.hpp | 57 + .../cardinal_quintic_b_spline.hpp | 62 + .../interpolators/cardinal_trigonometric.hpp | 58 + .../boost/math/interpolators/catmull_rom.hpp | 310 ++ .../math/interpolators/cubic_b_spline.hpp | 90 + .../math/interpolators/cubic_hermite.hpp | 141 + .../detail/barycentric_rational_detail.hpp | 214 + .../detail/bezier_polynomial_detail.hpp | 167 + .../detail/bilinear_uniform_detail.hpp | 137 + .../detail/cardinal_cubic_b_spline_detail.hpp | 331 ++ .../cardinal_quadratic_b_spline_detail.hpp | 208 + .../cardinal_quintic_b_spline_detail.hpp | 240 + .../detail/cardinal_trigonometric_detail.hpp | 684 +++ .../detail/cubic_b_spline_detail.hpp | 330 ++ .../detail/cubic_hermite_detail.hpp | 438 ++ .../detail/quintic_hermite_detail.hpp | 585 +++ .../detail/septic_hermite_detail.hpp | 652 +++ .../vector_barycentric_rational_detail.hpp | 195 + .../detail/whittaker_shannon_detail.hpp | 128 + .../boost/math/interpolators/makima.hpp | 178 + .../boost/math/interpolators/pchip.hpp | 131 + .../math/interpolators/quintic_hermite.hpp | 142 + .../math/interpolators/septic_hermite.hpp | 146 + .../vector_barycentric_rational.hpp | 82 + .../math/interpolators/whittaker_shannon.hpp | 47 + .../include/boost/math/octonion.hpp | 4250 +++++++++++++++ .../boost/math/optimization/cma_es.hpp | 392 ++ .../boost/math/optimization/detail/common.hpp | 200 + .../optimization/differential_evolution.hpp | 236 + .../include/boost/math/optimization/jso.hpp | 465 ++ .../boost/math/optimization/random_search.hpp | 145 + .../boost/math/policies/error_handling.hpp | 1058 ++++ .../include/boost/math/policies/policy.hpp | 1009 ++++ .../quadrature/detail/exp_sinh_detail.hpp | 2002 +++++++ .../detail/ooura_fourier_integrals_detail.hpp | 676 +++ .../quadrature/detail/sinh_sinh_detail.hpp | 1353 +++++ .../quadrature/detail/tanh_sinh_detail.hpp | 879 ++++ .../boost/math/quadrature/exp_sinh.hpp | 180 + .../include/boost/math/quadrature/gauss.hpp | 904 ++++ .../boost/math/quadrature/gauss_kronrod.hpp | 1317 +++++ .../math/quadrature/naive_monte_carlo.hpp | 468 ++ .../quadrature/ooura_fourier_integrals.hpp | 68 + .../boost/math/quadrature/sinh_sinh.hpp | 72 + .../boost/math/quadrature/tanh_sinh.hpp | 289 + .../boost/math/quadrature/trapezoidal.hpp | 125 + .../math/quadrature/wavelet_transforms.hpp | 47 + .../include/boost/math/quaternion.hpp | 1190 +++++ .../include/boost/math/special_functions.hpp | 86 + .../boost/math/special_functions/acosh.hpp | 102 + .../boost/math/special_functions/airy.hpp | 475 ++ .../boost/math/special_functions/asinh.hpp | 110 + .../boost/math/special_functions/atanh.hpp | 116 + .../math/special_functions/bernoulli.hpp | 149 + .../boost/math/special_functions/bessel.hpp | 795 +++ .../special_functions/bessel_iterators.hpp | 187 + .../math/special_functions/bessel_prime.hpp | 343 ++ .../boost/math/special_functions/beta.hpp | 1849 +++++++ .../boost/math/special_functions/binomial.hpp | 87 + .../special_functions/cardinal_b_spline.hpp | 218 + .../boost/math/special_functions/cbrt.hpp | 215 + .../math/special_functions/chebyshev.hpp | 314 ++ .../special_functions/chebyshev_transform.hpp | 237 + .../boost/math/special_functions/cos_pi.hpp | 128 + .../special_functions/daubechies_scaling.hpp | 491 ++ .../special_functions/daubechies_wavelet.hpp | 266 + .../detail/airy_ai_bi_zero.hpp | 222 + .../detail/bernoulli_details.hpp | 629 +++ .../detail/bessel_derivatives_linear.hpp | 107 + .../special_functions/detail/bessel_i0.hpp | 550 ++ .../special_functions/detail/bessel_i1.hpp | 556 ++ .../special_functions/detail/bessel_ik.hpp | 447 ++ .../special_functions/detail/bessel_j0.hpp | 192 + .../special_functions/detail/bessel_j1.hpp | 179 + .../special_functions/detail/bessel_jn.hpp | 127 + .../special_functions/detail/bessel_jy.hpp | 600 +++ .../detail/bessel_jy_asym.hpp | 230 + .../detail/bessel_jy_derivatives_asym.hpp | 141 + .../detail/bessel_jy_derivatives_series.hpp | 219 + .../detail/bessel_jy_series.hpp | 267 + .../detail/bessel_jy_zero.hpp | 643 +++ .../special_functions/detail/bessel_k0.hpp | 485 ++ .../special_functions/detail/bessel_k1.hpp | 526 ++ .../special_functions/detail/bessel_kn.hpp | 91 + .../special_functions/detail/bessel_y0.hpp | 205 + .../special_functions/detail/bessel_y1.hpp | 183 + .../special_functions/detail/bessel_yn.hpp | 113 + .../daubechies_scaling_integer_grid.hpp | 244 + .../math/special_functions/detail/erf_inv.hpp | 559 ++ .../special_functions/detail/fp_traits.hpp | 580 ++ .../special_functions/detail/gamma_inva.hpp | 241 + .../detail/hypergeometric_0F1_bessel.hpp | 46 + ...ergeometric_1F1_addition_theorems_on_z.hpp | 293 ++ .../detail/hypergeometric_1F1_bessel.hpp | 768 +++ .../detail/hypergeometric_1F1_by_ratios.hpp | 678 +++ .../detail/hypergeometric_1F1_cf.hpp | 50 + .../detail/hypergeometric_1F1_large_a.hpp | 35 + .../detail/hypergeometric_1F1_large_abz.hpp | 492 ++ .../hypergeometric_1F1_negative_b_regions.hpp | 521 ++ .../detail/hypergeometric_1F1_recurrence.hpp | 522 ++ .../hypergeometric_1F1_scaled_series.hpp | 60 + ...metric_1F1_small_a_negative_b_by_ratio.hpp | 70 + .../detail/hypergeometric_asym.hpp | 179 + .../detail/hypergeometric_cf.hpp | 228 + .../hypergeometric_pFq_checked_series.hpp | 671 +++ .../detail/hypergeometric_pade.hpp | 131 + .../detail/hypergeometric_rational.hpp | 167 + .../hypergeometric_separated_series.hpp | 50 + .../detail/hypergeometric_series.hpp | 434 ++ .../special_functions/detail/ibeta_inv_ab.hpp | 331 ++ .../detail/ibeta_inverse.hpp | 1122 ++++ .../math/special_functions/detail/iconv.hpp | 43 + .../detail/igamma_inverse.hpp | 587 +++ .../special_functions/detail/igamma_large.hpp | 823 +++ .../detail/lambert_w_lookup_table.ipp | 134 + .../special_functions/detail/lanczos_sse2.hpp | 238 + .../special_functions/detail/lgamma_small.hpp | 569 ++ .../special_functions/detail/polygamma.hpp | 538 ++ .../special_functions/detail/round_fwd.hpp | 87 + .../detail/t_distribution_inv.hpp | 567 ++ .../detail/unchecked_bernoulli.hpp | 1305 +++++ .../detail/unchecked_factorial.hpp | 1727 ++++++ .../boost/math/special_functions/digamma.hpp | 631 +++ .../boost/math/special_functions/ellint_1.hpp | 815 +++ .../boost/math/special_functions/ellint_2.hpp | 756 +++ .../boost/math/special_functions/ellint_3.hpp | 374 ++ .../boost/math/special_functions/ellint_d.hpp | 183 + .../math/special_functions/ellint_rc.hpp | 112 + .../math/special_functions/ellint_rd.hpp | 207 + .../math/special_functions/ellint_rf.hpp | 169 + .../math/special_functions/ellint_rg.hpp | 130 + .../math/special_functions/ellint_rj.hpp | 299 ++ .../boost/math/special_functions/erf.hpp | 1322 +++++ .../boost/math/special_functions/expint.hpp | 1614 ++++++ .../boost/math/special_functions/expm1.hpp | 416 ++ .../math/special_functions/factorials.hpp | 276 + .../math/special_functions/fibonacci.hpp | 92 + .../fourier_transform_daubechies.hpp | 248 + .../math/special_functions/fpclassify.hpp | 797 +++ .../boost/math/special_functions/gamma.hpp | 2502 +++++++++ .../math/special_functions/gegenbauer.hpp | 84 + .../boost/math/special_functions/hankel.hpp | 186 + .../boost/math/special_functions/hermite.hpp | 79 + .../math/special_functions/heuman_lambda.hpp | 97 + .../special_functions/hypergeometric_0F1.hpp | 116 + .../special_functions/hypergeometric_1F0.hpp | 69 + .../special_functions/hypergeometric_1F1.hpp | 822 +++ .../special_functions/hypergeometric_2F0.hpp | 163 + .../special_functions/hypergeometric_pFq.hpp | 195 + .../boost/math/special_functions/hypot.hpp | 82 + .../boost/math/special_functions/jacobi.hpp | 69 + .../special_functions/jacobi_elliptic.hpp | 319 ++ .../math/special_functions/jacobi_theta.hpp | 802 +++ .../math/special_functions/jacobi_zeta.hpp | 83 + .../boost/math/special_functions/laguerre.hpp | 139 + .../math/special_functions/lambert_w.hpp | 2171 ++++++++ .../boost/math/special_functions/lanczos.hpp | 2760 ++++++++++ .../boost/math/special_functions/legendre.hpp | 380 ++ .../special_functions/legendre_stieltjes.hpp | 234 + .../boost/math/special_functions/log1p.hpp | 417 ++ .../math/special_functions/logaddexp.hpp | 41 + .../math/special_functions/logsumexp.hpp | 60 + .../boost/math/special_functions/math_fwd.hpp | 1901 +++++++ .../boost/math/special_functions/modf.hpp | 74 + .../boost/math/special_functions/next.hpp | 886 ++++ .../nonfinite_num_facets.hpp | 588 +++ .../boost/math/special_functions/owens_t.hpp | 1067 ++++ .../math/special_functions/polygamma.hpp | 83 + .../boost/math/special_functions/pow.hpp | 144 + .../boost/math/special_functions/powm1.hpp | 101 + .../boost/math/special_functions/prime.hpp | 2433 +++++++++ .../special_functions/relative_difference.hpp | 134 + .../boost/math/special_functions/round.hpp | 353 ++ .../boost/math/special_functions/rsqrt.hpp | 52 + .../boost/math/special_functions/sign.hpp | 241 + .../boost/math/special_functions/sin_pi.hpp | 136 + .../boost/math/special_functions/sinc.hpp | 123 + .../boost/math/special_functions/sinhc.hpp | 142 + .../special_functions/spherical_harmonic.hpp | 205 + .../boost/math/special_functions/sqrt1pm1.hpp | 49 + .../boost/math/special_functions/trigamma.hpp | 448 ++ .../boost/math/special_functions/trunc.hpp | 385 ++ .../boost/math/special_functions/ulp.hpp | 102 + .../boost/math/special_functions/zeta.hpp | 1081 ++++ .../math/statistics/anderson_darling.hpp | 112 + .../math/statistics/bivariate_statistics.hpp | 470 ++ .../statistics/chatterjee_correlation.hpp | 159 + .../boost/math/statistics/detail/rank.hpp | 140 + .../math/statistics/detail/single_pass.hpp | 401 ++ .../math/statistics/linear_regression.hpp | 133 + .../boost/math/statistics/ljung_box.hpp | 70 + .../boost/math/statistics/runs_test.hpp | 121 + .../math/statistics/signal_statistics.hpp | 350 ++ .../include/boost/math/statistics/t_test.hpp | 275 + .../math/statistics/univariate_statistics.hpp | 1184 +++++ .../include/boost/math/statistics/z_test.hpp | 161 + .../include/boost/math/tools/agm.hpp | 47 + .../include/boost/math/tools/array.hpp | 41 + .../include/boost/math/tools/assert.hpp | 49 + .../include/boost/math/tools/atomic.hpp | 50 + .../include/boost/math/tools/big_constant.hpp | 110 + .../boost/math/tools/bivariate_statistics.hpp | 96 + .../tools/centered_continued_fraction.hpp | 173 + .../boost/math/tools/cohen_acceleration.hpp | 51 + .../include/boost/math/tools/color_maps.hpp | 1943 +++++++ .../include/boost/math/tools/complex.hpp | 115 + .../include/boost/math/tools/concepts.hpp | 24 + .../boost/math/tools/condition_numbers.hpp | 144 + .../include/boost/math/tools/config.hpp | 856 +++ .../boost/math/tools/convert_from_string.hpp | 85 + .../include/boost/math/tools/cstdint.hpp | 107 + .../include/boost/math/tools/cubic_roots.hpp | 176 + .../include/boost/math/tools/cxx03_warn.hpp | 95 + .../math/tools/detail/is_const_iterable.hpp | 38 + .../tools/detail/polynomial_horner1_10.hpp | 84 + .../tools/detail/polynomial_horner1_11.hpp | 90 + .../tools/detail/polynomial_horner1_12.hpp | 96 + .../tools/detail/polynomial_horner1_13.hpp | 102 + .../tools/detail/polynomial_horner1_14.hpp | 108 + .../tools/detail/polynomial_horner1_15.hpp | 114 + .../tools/detail/polynomial_horner1_16.hpp | 120 + .../tools/detail/polynomial_horner1_17.hpp | 126 + .../tools/detail/polynomial_horner1_18.hpp | 132 + .../tools/detail/polynomial_horner1_19.hpp | 138 + .../tools/detail/polynomial_horner1_2.hpp | 36 + .../tools/detail/polynomial_horner1_20.hpp | 144 + .../tools/detail/polynomial_horner1_3.hpp | 42 + .../tools/detail/polynomial_horner1_4.hpp | 48 + .../tools/detail/polynomial_horner1_5.hpp | 54 + .../tools/detail/polynomial_horner1_6.hpp | 60 + .../tools/detail/polynomial_horner1_7.hpp | 66 + .../tools/detail/polynomial_horner1_8.hpp | 72 + .../tools/detail/polynomial_horner1_9.hpp | 78 + .../tools/detail/polynomial_horner2_10.hpp | 90 + .../tools/detail/polynomial_horner2_11.hpp | 97 + .../tools/detail/polynomial_horner2_12.hpp | 104 + .../tools/detail/polynomial_horner2_13.hpp | 111 + .../tools/detail/polynomial_horner2_14.hpp | 118 + .../tools/detail/polynomial_horner2_15.hpp | 125 + .../tools/detail/polynomial_horner2_16.hpp | 132 + .../tools/detail/polynomial_horner2_17.hpp | 139 + .../tools/detail/polynomial_horner2_18.hpp | 146 + .../tools/detail/polynomial_horner2_19.hpp | 153 + .../tools/detail/polynomial_horner2_2.hpp | 48 + .../tools/detail/polynomial_horner2_20.hpp | 160 + .../tools/detail/polynomial_horner2_3.hpp | 48 + .../tools/detail/polynomial_horner2_4.hpp | 48 + .../tools/detail/polynomial_horner2_5.hpp | 55 + .../tools/detail/polynomial_horner2_6.hpp | 62 + .../tools/detail/polynomial_horner2_7.hpp | 69 + .../tools/detail/polynomial_horner2_8.hpp | 76 + .../tools/detail/polynomial_horner2_9.hpp | 83 + .../tools/detail/polynomial_horner3_10.hpp | 156 + .../tools/detail/polynomial_horner3_11.hpp | 181 + .../tools/detail/polynomial_horner3_12.hpp | 208 + .../tools/detail/polynomial_horner3_13.hpp | 237 + .../tools/detail/polynomial_horner3_14.hpp | 268 + .../tools/detail/polynomial_horner3_15.hpp | 301 ++ .../tools/detail/polynomial_horner3_16.hpp | 336 ++ .../tools/detail/polynomial_horner3_17.hpp | 373 ++ .../tools/detail/polynomial_horner3_18.hpp | 412 ++ .../tools/detail/polynomial_horner3_19.hpp | 453 ++ .../tools/detail/polynomial_horner3_2.hpp | 48 + .../tools/detail/polynomial_horner3_20.hpp | 496 ++ .../tools/detail/polynomial_horner3_3.hpp | 48 + .../tools/detail/polynomial_horner3_4.hpp | 48 + .../tools/detail/polynomial_horner3_5.hpp | 61 + .../tools/detail/polynomial_horner3_6.hpp | 76 + .../tools/detail/polynomial_horner3_7.hpp | 93 + .../tools/detail/polynomial_horner3_8.hpp | 112 + .../tools/detail/polynomial_horner3_9.hpp | 133 + .../math/tools/detail/rational_horner1_10.hpp | 138 + .../math/tools/detail/rational_horner1_11.hpp | 150 + .../math/tools/detail/rational_horner1_12.hpp | 162 + .../math/tools/detail/rational_horner1_13.hpp | 174 + .../math/tools/detail/rational_horner1_14.hpp | 186 + .../math/tools/detail/rational_horner1_15.hpp | 198 + .../math/tools/detail/rational_horner1_16.hpp | 210 + .../math/tools/detail/rational_horner1_17.hpp | 222 + .../math/tools/detail/rational_horner1_18.hpp | 234 + .../math/tools/detail/rational_horner1_19.hpp | 246 + .../math/tools/detail/rational_horner1_2.hpp | 42 + .../math/tools/detail/rational_horner1_20.hpp | 258 + .../math/tools/detail/rational_horner1_3.hpp | 54 + .../math/tools/detail/rational_horner1_4.hpp | 66 + .../math/tools/detail/rational_horner1_5.hpp | 78 + .../math/tools/detail/rational_horner1_6.hpp | 90 + .../math/tools/detail/rational_horner1_7.hpp | 102 + .../math/tools/detail/rational_horner1_8.hpp | 114 + .../math/tools/detail/rational_horner1_9.hpp | 126 + .../math/tools/detail/rational_horner2_10.hpp | 144 + .../math/tools/detail/rational_horner2_11.hpp | 160 + .../math/tools/detail/rational_horner2_12.hpp | 176 + .../math/tools/detail/rational_horner2_13.hpp | 192 + .../math/tools/detail/rational_horner2_14.hpp | 208 + .../math/tools/detail/rational_horner2_15.hpp | 224 + .../math/tools/detail/rational_horner2_16.hpp | 240 + .../math/tools/detail/rational_horner2_17.hpp | 256 + .../math/tools/detail/rational_horner2_18.hpp | 272 + .../math/tools/detail/rational_horner2_19.hpp | 288 + .../math/tools/detail/rational_horner2_2.hpp | 48 + .../math/tools/detail/rational_horner2_20.hpp | 304 ++ .../math/tools/detail/rational_horner2_3.hpp | 48 + .../math/tools/detail/rational_horner2_4.hpp | 48 + .../math/tools/detail/rational_horner2_5.hpp | 64 + .../math/tools/detail/rational_horner2_6.hpp | 80 + .../math/tools/detail/rational_horner2_7.hpp | 96 + .../math/tools/detail/rational_horner2_8.hpp | 112 + .../math/tools/detail/rational_horner2_9.hpp | 128 + .../math/tools/detail/rational_horner3_10.hpp | 396 ++ .../math/tools/detail/rational_horner3_11.hpp | 482 ++ .../math/tools/detail/rational_horner3_12.hpp | 576 ++ .../math/tools/detail/rational_horner3_13.hpp | 678 +++ .../math/tools/detail/rational_horner3_14.hpp | 788 +++ .../math/tools/detail/rational_horner3_15.hpp | 906 ++++ .../math/tools/detail/rational_horner3_16.hpp | 1032 ++++ .../math/tools/detail/rational_horner3_17.hpp | 1166 +++++ .../math/tools/detail/rational_horner3_18.hpp | 1308 +++++ .../math/tools/detail/rational_horner3_19.hpp | 1458 ++++++ .../math/tools/detail/rational_horner3_2.hpp | 48 + .../math/tools/detail/rational_horner3_20.hpp | 1616 ++++++ .../math/tools/detail/rational_horner3_3.hpp | 48 + .../math/tools/detail/rational_horner3_4.hpp | 48 + .../math/tools/detail/rational_horner3_5.hpp | 86 + .../math/tools/detail/rational_horner3_6.hpp | 132 + .../math/tools/detail/rational_horner3_7.hpp | 186 + .../math/tools/detail/rational_horner3_8.hpp | 248 + .../math/tools/detail/rational_horner3_9.hpp | 318 ++ .../boost/math/tools/engel_expansion.hpp | 124 + .../include/boost/math/tools/estrin.hpp | 72 + .../include/boost/math/tools/fraction.hpp | 354 ++ .../boost/math/tools/header_deprecated.hpp | 27 + .../math/tools/is_constant_evaluated.hpp | 51 + .../include/boost/math/tools/is_detected.hpp | 56 + .../boost/math/tools/is_standalone.hpp | 18 + .../boost/math/tools/luroth_expansion.hpp | 147 + .../include/boost/math/tools/minima.hpp | 164 + .../include/boost/math/tools/mp.hpp | 423 ++ .../include/boost/math/tools/norms.hpp | 638 +++ .../include/boost/math/tools/nothrow.hpp | 27 + .../boost/math/tools/numeric_limits.hpp | 888 ++++ .../math/tools/numerical_differentiation.hpp | 12 + .../include/boost/math/tools/polynomial.hpp | 862 +++ .../boost/math/tools/polynomial_gcd.hpp | 268 + .../include/boost/math/tools/precision.hpp | 418 ++ .../include/boost/math/tools/promotion.hpp | 135 + .../boost/math/tools/quartic_roots.hpp | 157 + .../boost/math/tools/random_vector.hpp | 101 + .../include/boost/math/tools/rational.hpp | 346 ++ .../include/boost/math/tools/real_cast.hpp | 31 + .../include/boost/math/tools/recurrence.hpp | 330 ++ .../include/boost/math/tools/roots.hpp | 1062 ++++ .../include/boost/math/tools/series.hpp | 221 + .../boost/math/tools/signal_statistics.hpp | 353 ++ .../math/tools/simple_continued_fraction.hpp | 177 + .../include/boost/math/tools/stats.hpp | 87 + .../include/boost/math/tools/test_value.hpp | 143 + .../boost/math/tools/throw_exception.hpp | 43 + .../boost/math/tools/toms748_solve.hpp | 636 +++ .../include/boost/math/tools/traits.hpp | 140 + .../include/boost/math/tools/tuple.hpp | 88 + .../include/boost/math/tools/type_traits.hpp | 494 ++ .../include/boost/math/tools/ulps_plot.hpp | 598 +++ .../math/tools/univariate_statistics.hpp | 437 ++ .../include/boost/math/tools/user.hpp | 105 + .../include/boost/math/tools/utility.hpp | 69 + .../include/boost/math/tools/workaround.hpp | 42 + .../boost-math/include/boost/math/tr1.hpp | 1121 ++++ .../include/boost/math/tr1_c_macros.ipp | 810 +++ .../boost-math/include/boost/math_fwd.hpp | 42 + .../boost/math/constants/generate.hpp | 76 + .../boost/math/tools/iteration_logger.hpp | 77 + .../boost/math/tools/remez.hpp | 667 +++ .../boost/math/tools/solve.hpp | 80 + .../include_private/boost/math/tools/test.hpp | 319 ++ .../boost/math/tools/test_data.hpp | 967 ++++ third-party/boost-math/index.html | 14 + third-party/update_boost_math.sh | 29 + 517 files changed, 184283 insertions(+) create mode 100644 third-party/README.md create mode 100644 third-party/boost-math/.codecov.yml create mode 100644 third-party/boost-math/.drone.star create mode 100644 third-party/boost-math/.gitattributes create mode 100644 third-party/boost-math/.gitignore create mode 100644 third-party/boost-math/.travis.yml create mode 100644 third-party/boost-math/CMakeLists.txt create mode 100644 third-party/boost-math/LICENSE create mode 100644 third-party/boost-math/README.md create mode 100644 third-party/boost-math/build.jam create mode 100644 third-party/boost-math/include/boost/cstdfloat.hpp create mode 100644 third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp create mode 100644 third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp create mode 100644 third-party/boost-math/include/boost/math/bindings/mpfr.hpp create mode 100644 third-party/boost-math/include/boost/math/bindings/mpreal.hpp create mode 100644 third-party/boost-math/include/boost/math/bindings/rr.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/abs.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/ccmath.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/ceil.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/copysign.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/detail/config.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/div.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fabs.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fdim.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/floor.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fma.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fmax.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fmin.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fmod.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/frexp.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/hypot.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/ilogb.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isfinite.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isgreater.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isinf.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isless.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/islessequal.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isnan.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isnormal.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/isunordered.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/ldexp.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/logb.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/modf.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/next.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/remainder.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/round.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/scalbln.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/scalbn.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/signbit.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/sqrt.hpp create mode 100644 third-party/boost-math/include/boost/math/ccmath/trunc.hpp create mode 100644 third-party/boost-math/include/boost/math/common_factor.hpp create mode 100644 third-party/boost-math/include/boost/math/common_factor_ct.hpp create mode 100644 third-party/boost-math/include/boost/math/common_factor_rt.hpp create mode 100644 third-party/boost-math/include/boost/math/complex.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/acos.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/acosh.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/asin.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/asinh.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/atan.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/atanh.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/details.hpp create mode 100644 third-party/boost-math/include/boost/math/complex/fabs.hpp create mode 100644 third-party/boost-math/include/boost/math/concepts/distributions.hpp create mode 100644 third-party/boost-math/include/boost/math/concepts/real_concept.hpp create mode 100644 third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp create mode 100644 third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp create mode 100644 third-party/boost-math/include/boost/math/constants/calculate_constants.hpp create mode 100644 third-party/boost-math/include/boost/math/constants/constants.hpp create mode 100644 third-party/boost-math/include/boost/math/constants/info.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp create mode 100644 third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp create mode 100644 third-party/boost-math/include/boost/math/differentiation/autodiff.hpp create mode 100644 third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp create mode 100644 third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp create mode 100644 third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/arcsine.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/bernoulli.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/beta.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/binomial.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/cauchy.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/chi_squared.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/complement.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/exponential.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/extreme_value.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/find_location.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/find_scale.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/fisher_f.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/fwd.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/gamma.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/geometric.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/holtsmark.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/hyperexponential.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/hypergeometric.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/inverse_chi_squared.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/inverse_gamma.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/inverse_gaussian.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/kolmogorov_smirnov.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/landau.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/laplace.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/logistic.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/lognormal.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/mapairy.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/negative_binomial.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/non_central_beta.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/non_central_chi_squared.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/non_central_f.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/non_central_t.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/normal.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/pareto.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/poisson.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/rayleigh.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/saspoint5.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/skew_normal.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/students_t.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/triangular.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/uniform.hpp create mode 100644 third-party/boost-math/include/boost/math/distributions/weibull.hpp create mode 100644 third-party/boost-math/include/boost/math/filters/daubechies.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/barycentric_rational.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/bezier_polynomial.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/bilinear_uniform.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cardinal_cubic_b_spline.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cardinal_quadratic_b_spline.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cardinal_quintic_b_spline.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cardinal_trigonometric.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/catmull_rom.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cubic_b_spline.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/cubic_hermite.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/barycentric_rational_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/bezier_polynomial_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/bilinear_uniform_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cubic_b_spline_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/cubic_hermite_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/quintic_hermite_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/septic_hermite_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/detail/whittaker_shannon_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/makima.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/pchip.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/quintic_hermite.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/septic_hermite.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/vector_barycentric_rational.hpp create mode 100644 third-party/boost-math/include/boost/math/interpolators/whittaker_shannon.hpp create mode 100644 third-party/boost-math/include/boost/math/octonion.hpp create mode 100644 third-party/boost-math/include/boost/math/optimization/cma_es.hpp create mode 100644 third-party/boost-math/include/boost/math/optimization/detail/common.hpp create mode 100644 third-party/boost-math/include/boost/math/optimization/differential_evolution.hpp create mode 100644 third-party/boost-math/include/boost/math/optimization/jso.hpp create mode 100644 third-party/boost-math/include/boost/math/optimization/random_search.hpp create mode 100644 third-party/boost-math/include/boost/math/policies/error_handling.hpp create mode 100644 third-party/boost-math/include/boost/math/policies/policy.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/detail/exp_sinh_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/detail/sinh_sinh_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/detail/tanh_sinh_detail.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/exp_sinh.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/gauss.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/gauss_kronrod.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/naive_monte_carlo.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/ooura_fourier_integrals.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/sinh_sinh.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/tanh_sinh.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/trapezoidal.hpp create mode 100644 third-party/boost-math/include/boost/math/quadrature/wavelet_transforms.hpp create mode 100644 third-party/boost-math/include/boost/math/quaternion.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/acosh.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/airy.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/asinh.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/atanh.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/bernoulli.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/bessel.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/bessel_iterators.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/bessel_prime.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/beta.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/binomial.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/cardinal_b_spline.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/cbrt.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/chebyshev.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/chebyshev_transform.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/cos_pi.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/daubechies_scaling.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/daubechies_wavelet.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/airy_ai_bi_zero.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bernoulli_details.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_derivatives_linear.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_i0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_i1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_ik.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_j0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_j1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jn.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_asym.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_zero.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_k0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_k1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_kn.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_y0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_y1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/bessel_yn.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/erf_inv.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/fp_traits.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/gamma_inva.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_asym.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_cf.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pade.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_rational.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_separated_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_series.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inv_ab.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inverse.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/iconv.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/igamma_inverse.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/igamma_large.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/lambert_w_lookup_table.ipp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/lanczos_sse2.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/lgamma_small.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/polygamma.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/round_fwd.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/t_distribution_inv.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/unchecked_bernoulli.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/detail/unchecked_factorial.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/digamma.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_2.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_3.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_d.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_rc.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_rd.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_rf.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_rg.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ellint_rj.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/erf.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/expint.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/expm1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/factorials.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/fibonacci.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/fourier_transform_daubechies.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/fpclassify.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/gamma.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/gegenbauer.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hankel.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hermite.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/heuman_lambda.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypergeometric_0F1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypergeometric_2F0.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypergeometric_pFq.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/hypot.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/jacobi.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/jacobi_elliptic.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/jacobi_theta.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/jacobi_zeta.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/laguerre.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/lambert_w.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/lanczos.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/legendre.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/legendre_stieltjes.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/log1p.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/logaddexp.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/logsumexp.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/math_fwd.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/modf.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/next.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/nonfinite_num_facets.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/owens_t.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/polygamma.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/pow.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/powm1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/prime.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/relative_difference.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/round.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/rsqrt.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/sign.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/sin_pi.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/sinc.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/sinhc.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/spherical_harmonic.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/sqrt1pm1.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/trigamma.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/trunc.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/ulp.hpp create mode 100644 third-party/boost-math/include/boost/math/special_functions/zeta.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/anderson_darling.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/bivariate_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/chatterjee_correlation.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/detail/rank.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/detail/single_pass.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/linear_regression.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/ljung_box.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/runs_test.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/signal_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/t_test.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/univariate_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/statistics/z_test.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/agm.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/array.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/assert.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/atomic.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/big_constant.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/bivariate_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/centered_continued_fraction.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/cohen_acceleration.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/color_maps.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/complex.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/concepts.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/condition_numbers.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/config.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/convert_from_string.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/cstdint.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/cubic_roots.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/cxx03_warn.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/is_const_iterable.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner1_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner2_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_10.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_11.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_12.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_13.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_14.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_15.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_16.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_17.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_18.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_19.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_2.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_20.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_3.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_4.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_5.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_6.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_7.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_8.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/detail/rational_horner3_9.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/engel_expansion.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/estrin.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/fraction.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/header_deprecated.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/is_constant_evaluated.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/is_detected.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/is_standalone.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/luroth_expansion.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/minima.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/mp.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/norms.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/nothrow.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/numeric_limits.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/numerical_differentiation.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/polynomial.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/polynomial_gcd.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/precision.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/promotion.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/quartic_roots.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/random_vector.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/rational.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/real_cast.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/recurrence.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/roots.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/series.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/signal_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/simple_continued_fraction.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/stats.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/test_value.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/throw_exception.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/toms748_solve.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/traits.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/tuple.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/type_traits.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/ulps_plot.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/univariate_statistics.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/user.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/utility.hpp create mode 100644 third-party/boost-math/include/boost/math/tools/workaround.hpp create mode 100644 third-party/boost-math/include/boost/math/tr1.hpp create mode 100644 third-party/boost-math/include/boost/math/tr1_c_macros.ipp create mode 100644 third-party/boost-math/include/boost/math_fwd.hpp create mode 100644 third-party/boost-math/include_private/boost/math/constants/generate.hpp create mode 100644 third-party/boost-math/include_private/boost/math/tools/iteration_logger.hpp create mode 100644 third-party/boost-math/include_private/boost/math/tools/remez.hpp create mode 100644 third-party/boost-math/include_private/boost/math/tools/solve.hpp create mode 100644 third-party/boost-math/include_private/boost/math/tools/test.hpp create mode 100644 third-party/boost-math/include_private/boost/math/tools/test_data.hpp create mode 100644 third-party/boost-math/index.html create mode 100755 third-party/update_boost_math.sh diff --git a/third-party/README.md b/third-party/README.md new file mode 100644 index 0000000000000..e9c51f20c4392 --- /dev/null +++ b/third-party/README.md @@ -0,0 +1,11 @@ +# Third-party LLVM dependencies + +This directory contains third-party dependencies used in various components of LLVM. +Integrating a new third-party dependency generally requires it to be licensed under +the Apache-with-LLVM-exception license. For integrating code under other licenses, +please follow the process explained in the [LLVM Developer Policy](https://llvm.org/docs/DeveloperPolicy.html#copyright-license-and-patents). + +In particular, due to its non-LLVM license, the Boost.Math third-party dependency +can exclusively be used within the libc++ compiled library as discussed in [this RFC](https://discourse.llvm.org/t/rfc-libc-taking-a-dependency-on-boost-math-for-the-c-17-math-special-functions). +Do not use it in other parts of LLVM without prior discussion with the LLVM Board +(and update this documentation). diff --git a/third-party/boost-math/.codecov.yml b/third-party/boost-math/.codecov.yml new file mode 100644 index 0000000000000..751f83ac9668d --- /dev/null +++ b/third-party/boost-math/.codecov.yml @@ -0,0 +1,26 @@ +# Copyright 2019 - 2021 Alexander Grund +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) +# +# Sample codecov configuration file. Edit as required + +codecov: + max_report_age: off + require_ci_to_pass: yes + notify: + # Increase this if you have multiple coverage collection jobs + after_n_builds: 1 + wait_for_ci: yes + +# Change how pull request comments look +comment: + layout: "reach,diff,flags,files,footer" + +# Ignore specific files or folders. Glob patterns are supported. +# See https://docs.codecov.com/docs/ignoring-paths +ignore: + - extra/**/* + - reporting/**/* + - example/**/* + - include_private/**/* + - tools/**/* diff --git a/third-party/boost-math/.drone.star b/third-party/boost-math/.drone.star new file mode 100644 index 0000000000000..bc51cc7e0e853 --- /dev/null +++ b/third-party/boost-math/.drone.star @@ -0,0 +1,75 @@ +# Use, modification, and distribution are +# subject to the Boost Software License, Version 1.0. (See accompanying +# file LICENSE.txt) +# +# Copyright Rene Rivera 2020. +# Copyright John Maddock 2021. + +# For Drone CI we use the Starlark scripting language to reduce duplication. +# As the yaml syntax for Drone CI is rather limited. +# +# +globalenv={} +linuxglobalimage="cppalliance/droneubuntu1604:1" +windowsglobalimage="cppalliance/dronevs2019" + +def main(ctx): + + things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests", "concepts" ] + gcc13_things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests", "concepts", "new_floats" ] + sanitizer_test = [ "special_fun", "distribution_tests", "misc", "interpolators", "quadrature", "float128_tests" ] + gnu_5_stds = [ "gnu++14", "c++14" ] + gnu_6_stds = [ "gnu++14", "c++14", "gnu++17", "c++17" ] + clang_6_stds = [ "c++14", "c++17" ] + gnu_9_stds = [ "gnu++14", "c++14", "gnu++17", "c++17", "gnu++2a", "c++2a" ] + clang_10_stds = [ "c++14", "c++17", "c++2a" ] + gnu_non_native = [ "gnu++17" ] + gcc13_stds = [ "c++23" ] + + result = [] + + for suite in sanitizer_test: + # + # Sanitizers: + # + result.append(linux_cxx("Ubuntu Clang-18 C++20 ASAN" + " " + suite, "clang++-18", packages="clang-18", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-18', 'CXXSTD': 'gnu++20', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=address -fsanitize=address -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu Clang-18 C++20 USAN" + " " + suite, "clang++-18", packages="clang-18", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-18', 'CXXSTD': 'gnu++20', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=undefined -fsanitize=undefined -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu Clang-18 C++20 TSAN" + " " + suite, "clang++-18", packages="clang-18", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-18', 'CXXSTD': 'gnu++20', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=thread -fsanitize=thread -DBOOST_CI_SANITIZER_BUILD' }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu Clang-18 C++20 ISAN" + " " + suite, "clang++-18", packages="clang-18", privileged=True, buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-18', 'CXXSTD': 'gnu++20', 'TEST_SUITE': suite, 'OPTIONS': '-fsanitize=integer -fsanitize=integer' }, globalenv=globalenv)) + + for suite in things_to_test: + for cxx in gnu_5_stds: + result.append(linux_cxx("Ubuntu g++-5 " + cxx + " " + suite, "g++-5", packages="g++-5", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_6_stds: + result.append(linux_cxx("Ubuntu g++-6 " + cxx + " " + suite, "g++-6", packages="g++-6", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-7 " + cxx + " " + suite, "g++-7", packages="g++-7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-8 " + cxx + " " + suite, "g++-8", packages="g++-8", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-9 " + cxx + " " + suite, "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in clang_6_stds: + result.append(linux_cxx("Ubuntu clang++-6 " + cxx + " " + suite, "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-7 " + cxx + " " + suite, "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-8 " + cxx + " " + suite, "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-9 " + cxx + " " + suite, "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_9_stds: + result.append(linux_cxx("Ubuntu g++-10 " + cxx + " " + suite, "g++-10", packages="g++-10", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-11 " + cxx + " " + suite, "g++-11", packages="g++-11", buildtype="boost", image="cppalliance/droneubuntu2004:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-11', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-12 " + cxx + " " + suite, "g++-12", packages="g++-12", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-12', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-14 " + cxx + " " + suite, "clang++-14", packages="clang-14", llvm_os="jammy", llvm_ver="14", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-14', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu clang++-15 " + cxx + " " + suite, "clang++-15", packages="clang-15", llvm_os="jammy", llvm_ver="15", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-15', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in clang_10_stds: + result.append(linux_cxx("Ubuntu clang++-10 " + cxx + " " + suite, "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(linux_cxx("Ubuntu g++ s390s " + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="s390x", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(linux_cxx("Ubuntu g++ ARM64" + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="arm64", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + for cxx in gnu_non_native: + result.append(osx_cxx("M1 Clang " + cxx + " " + suite, "clang++", buildscript="drone", buildtype="boost", xcode_version="14.1", environment={'TOOLSET': 'clang', 'CXXSTD': cxx, 'TEST_SUITE': suite, 'DEFINE': 'BOOST_MATH_NO_REAL_CONCEPT_TESTS,BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS,BOOST_MATH_MULTI_ARCH_CI_RUN', }, globalenv=globalenv)) + for suite in gcc13_things_to_test: + for cxx in gcc13_stds: + result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + result.append(linux_cxx("Ubuntu g++-14 " + cxx + " " + suite, "g++-14", packages="g++-14", buildtype="boost", image="cppalliance/droneubuntu2404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-14', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv)) + + return result + +# from https://github.com/boostorg/boost-ci +load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/third-party/boost-math/.gitattributes b/third-party/boost-math/.gitattributes new file mode 100644 index 0000000000000..3e84d7c704432 --- /dev/null +++ b/third-party/boost-math/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/third-party/boost-math/.gitignore b/third-party/boost-math/.gitignore new file mode 100644 index 0000000000000..6435addffdc9b --- /dev/null +++ b/third-party/boost-math/.gitignore @@ -0,0 +1,30 @@ +/doc/inspect.htm +/**/*.log +reporting/*/third_party +reporting/*/html +inspect.html +/example/float128_examples.cpp +test/cuda +*.DS_Store +/**/*.dSYM/ +**/.temps/* +build/* +.vscode/* +*.svg +tools/bin/** +.idea/* + +# CMake Related Options +*.a +*.o +cmake_install.cmake +CMakeCache.txt +Makefile +**/CMakeFiles/** +**CTestTestfile.cmake +DartConfiguration.tcl +cmake-build-debug/* +.cmake/* +build.ninja +.ninja* +a.out diff --git a/third-party/boost-math/.travis.yml b/third-party/boost-math/.travis.yml new file mode 100644 index 0000000000000..f53ea490746db --- /dev/null +++ b/third-party/boost-math/.travis.yml @@ -0,0 +1,795 @@ +# Copyright 2016, 2017 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +language: cpp + +sudo: false + +python: "2.7" + +os: + - linux + - osx + +branches: + only: + - master + - develop + +env: + matrix: + - BOGUS_JOB=true + +matrix: + + exclude: + - env: BOGUS_JOB=true + + include: + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=gnu++14 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=gnu++14 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=gnu++14 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=gnu++14 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z TEST_SUITE=../tools + addons: + apt: + packages: + - g++-6 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=misc + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-5 + - libgmp-dev + - libmpfr-dev + - libfftw3-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=misc + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=c++14 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-8 + - libgmp-dev + - libmpfr-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=misc + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++03 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-8 + - libgmp-dev + - libmpfr-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=special_fun + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=quadrature + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=float128_tests + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=../example//examples + addons: + apt: + packages: + - g++-8 + sources: + - ubuntu-toolchain-r-test + + - os: linux + dist: trusty + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=gnu++17 TEST_SUITE=../tools + addons: + apt: + packages: + - g++-8 + - libgmp-dev + - libmpfr-dev + sources: + - ubuntu-toolchain-r-test + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=special_fun + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=distribution_tests + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=misc + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=quadrature + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=../example//examples + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=c++11 TEST_SUITE=../tools + addons: + apt: + packages: + - clang-6.0 + - libgmp-dev + - libmpfr-dev + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=special_fun + osx_image: xcode11 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=distribution_tests + osx_image: xcode11 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=misc + osx_image: xcode11 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=quadrature + osx_image: xcode11 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=float128_tests + osx_image: xcode11 + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 TEST_SUITE=../example//examples + osx_image: xcode11 + + +install: + - cd .. + - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + - cd boost-root + - git submodule update --init tools/build + - git submodule update --init tools/boost_install + - git submodule update --init libs/headers + - git submodule update --init libs/config + - git submodule update --init libs/format + - git submodule update --init libs/numeric + - git submodule update --init libs/type_traits + - git submodule update --init libs/timer + - git submodule update --init tools/boostdep + - cp -r $TRAVIS_BUILD_DIR/* libs/math + - python tools/boostdep/depinst/depinst.py math + - ./bootstrap.sh + - ./b2 headers + +script: + - |- + echo "using $TOOLSET : : $COMPILER : -std=$CXXSTD ;" > ~/user-config.jam + - (cd libs/config/test && ../../../b2 config_info_travis_install toolset=$TOOLSET && ./config_info_travis) + - (cd libs/math/test && travis_wait 60 ../../../b2 -j3 toolset=$TOOLSET $TEST_SUITE define=CI_SUPPRESS_KNOWN_ISSUES define=SLOW_COMPILER) + +notifications: + email: + on_success: always diff --git a/third-party/boost-math/CMakeLists.txt b/third-party/boost-math/CMakeLists.txt new file mode 100644 index 0000000000000..a1f6011d95e55 --- /dev/null +++ b/third-party/boost-math/CMakeLists.txt @@ -0,0 +1,61 @@ +# Copyright 2020 Peter Dimov +# Copyright 2021 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.16) + +project(boost_math VERSION 1.89.0 LANGUAGES CXX) + +add_library(boost_math INTERFACE) + +add_library(Boost::math ALIAS boost_math) + +target_include_directories(boost_math INTERFACE include) +if(NOT CMAKE_VERSION VERSION_LESS "3.19") + file(GLOB_RECURSE headers include/*.hpp) + target_sources(boost_math PRIVATE ${headers}) +endif() + +include(CMakeDependentOption) + +cmake_dependent_option(BOOST_MATH_STANDALONE "Use Boost.Math in standalone mode" ON "NOT BOOST_SUPERPROJECT_VERSION" OFF) + +message(STATUS "Boost.Math: standalone mode ${BOOST_MATH_STANDALONE}") + +if(BOOST_MATH_STANDALONE) + + target_compile_definitions(boost_math INTERFACE BOOST_MATH_STANDALONE=1) + +else() + + target_link_libraries(boost_math + INTERFACE + Boost::assert + Boost::concept_check + Boost::config + Boost::core + Boost::integer + Boost::lexical_cast + Boost::predef + Boost::random + Boost::static_assert + Boost::throw_exception + ) + +endif() + +if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + + add_subdirectory(test) + +# Only enable tests when we're the root project +elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + + include(CTest) + add_subdirectory(test) + + include(GNUInstallDirs) + install(DIRECTORY "include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +endif() diff --git a/third-party/boost-math/LICENSE b/third-party/boost-math/LICENSE new file mode 100644 index 0000000000000..36b7cd93cdfba --- /dev/null +++ b/third-party/boost-math/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third-party/boost-math/README.md b/third-party/boost-math/README.md new file mode 100644 index 0000000000000..39b0bddd63201 --- /dev/null +++ b/third-party/boost-math/README.md @@ -0,0 +1,180 @@ +Boost Math Library +============================ + +>ANNOUNCEMENT: This library requires a compliant C++14 compiler. + + +| | Master | Develop | +|------------------|----------|-------------| +| Drone | [![Build Status](https://drone.cpp.al/api/badges/boostorg/math/status.svg?ref=refs/heads/master)](https://drone.cpp.al/boostorg/math) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/math/status.svg)](https://drone.cpp.al/boostorg/math) | +| Github Actions | [![Build Status](https://github.com/boostorg/math/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/math/actions?query=branch%3Amaster) | [![Build Status](https://github.com/boostorg/math/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/math/actions?query=branch%3Adevelop) | +| Codecov | [![codecov](https://codecov.io/gh/boostorg/math/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/math/branch/master) | [![codecov](https://codecov.io/gh/boostorg/math/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/math/branch/develop) | + + +The Math library provides numerous advanced mathematical functions +implemented in modern C++. The library strives to deliver the utmost +in numerical and syntactical correctness while still +maintaining high-performance. + +All code is header-only, facilitating easy client setup +and use throughout the entire diverse collection of functions. + +The library is divided into several interconnected parts: + +### Floating Point Utilities + +Utility functions for dealing with floating point arithmetic, includes functions for floating point classification (fpclassify, isnan, isinf etc), sign manipulation, rounding, comparison, and computing the distance between floating point numbers. + +### Specific Width Floating Point Types + +A set of `typedef`s similar to those provided by C++20's `` but in `namespace boost`. + +### Mathematical Constants + +A wide range of constants ranging from fractions to various multiples of $\pi$, Euler's constant, etc. + +These are of course usable from template code, or as non-templates with a simplified interface if that is more appropriate. + +### Statistical Distributions + +Provides a reasonably comprehensive set of statistical distributions, upon which higher level statistical tests can be built. + +The initial focus is on the central univariate distributions. Both continuous (like normal & Fisher) and discrete (like binomial & Poisson) distributions are provided. + +A comprehensive tutorial is provided, along with a series of worked examples illustrating how the library is used to conduct statistical tests. + +### Special Functions + +Provides a wide range of high quality special functions; initially these were concentrated +on functions used in statistical applications along with those in the Technical Report +on C++ Library Extensions. + +The function families currently implemented are the gamma, beta and error functions +along with the incomplete gamma and beta functions (four variants of each) +and all the possible inverses of these, plus the digamma, various factorial +functions, Bessel functions, elliptic integrals, hypergeometrics, sinus cardinals +(along with their hyperbolic variants), inverse hyperbolic functions, +Legrendre/Laguerre/Hermite/Chebyshev polynomials +and various special power and logarithmic functions. + +All the implementations are fully generic and support the use of arbitrary "real-number" types, +including those in [Boost.Multiprecision](https://github.com/boostorg/multiprecision). +Most functions are, however, optimized for use with types with known significand (or mantissa) sizes: +typically built-in `float`, `double` or `long double`. + +These functions also provide the basis of support for the TR1 special functions, +many of which became standardized in [C++17](https://en.cppreference.com/w/cpp/numeric/special_functions). + +### Root Finding + +A comprehensive set of root-finding algorithms over the real line, both with derivatives and derivative free. + +### Optimization + +Minimization of cost functions via Brent's method and differential evolution. + +### Polynomials and Rational Functions + +Tools for manipulating polynomials and for efficient evaluation of rationals or polynomials. + +### Interpolation + +Function interpolation via barycentric rational interpolation, +compactly supported quadratic, cubic, and quintic B-splines, +the Chebyshev transform, trigonometric polynomials, Makima, +pchip, cubic Hermite splines, and bilinear interpolation. + +### Numerical Integration and Differentiation + +A reasonably comprehensive set of routines for integration +(trapezoidal, Gauss-Legendre, Gauss-Kronrod, Gauss-Chebyshev, double-exponential, and Monte-Carlo) +and differentiation (Chebyshev transform, finite difference, the complex step derivative, +and forward-mode automatic differentiation). + +The integration routines are usable for functions returning complex results - and hence can be used for computation of contour integrals. + +### Quaternions and Octonions + +Quaternion and Octonion are class templates similar to std::complex. + +The full documentation is available on [boost.org](http://www.boost.org/doc/libs/release/libs/math). + +### Standalone Mode + +Defining `BOOST_MATH_STANDALONE` allows Boost.Math to be used without any Boost dependencies. +Some functionality is reduced in this mode. A static_assert message will alert you +if a particular feature has been disabled by standalone mode. Standalone mode is not designed to +be used with the rest of boost, and may result in compiler errors. + +## Supported Compilers + +The following compilers are tested with the CI system, and are known to work. +Currently a compiler that is fully compliant with C++14 is required to use Boost.Math. + +* g++ 5 or later +* clang++ 5 or later +* Visual Studio 2015 (14.0) or later + +## Support, bugs and feature requests + +Bugs and feature requests can be reported through the [GitHub issue tracker](https://github.com/boostorg/math/issues) +(see [open issues](https://github.com/boostorg/math/issues) and +[closed issues](https://github.com/boostorg/math/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed)). + +You can submit your changes through a [pull request](https://github.com/boostorg/math/pulls). + +There is no mailing-list specific to Boost Math, although you can use the general-purpose Boost [mailing-list](http://lists.boost.org/mailman/listinfo.cgi/boost-users) using the tag [math]. + + +## Development + +Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)): + + $ git clone https://github.com/boostorg/boost + $ cd boost + $ git submodule update --init + +The Boost Math Library is located in `libs/math/`. + +### Running tests + +First, make sure you are in `libs/math/test`. +You can either run all the tests listed in `Jamfile.v2` or run a single test: + + test$ ../../../b2 <- run all tests + test$ ../../../b2 static_assert_test <- single test + test$ # A more advanced syntax, demoing various options for building the tests: + test$ ../../../b2 -a -j2 -q --reconfigure toolset=clang cxxflags="--std=c++14 -fsanitize=address -fsanitize=undefined" linkflags="-fsanitize=undefined -fsanitize=address" + +### Continuous Integration + +The default action for a PR or commit to a PR is for CI to run the full complement of tests. The following can be appended to the end of a commit message to modify behavior: + + * [ci skip] to skip all tests + * [linux] to test using GCC Versions 5-12 and Clang Versions 5-14 on Ubuntu LTS versions 18.04-22.04. + * [apple] to test Apple Clang on the latest version of MacOS. + * [windows] to test MSVC-14.0, MSVC-14.2, MSVC-14.3, CYGWIN, and mingw on the latest version of Windows. + * [standalone] to run standalone mode compile tests + + +### Building documentation + +Full instructions can be found [here](https://svn.boost.org/trac10/wiki/BoostDocs/GettingStarted), but to reiterate slightly: + +```bash +libs/math/doc$ brew install docbook-xsl # on mac +libs/math/doc$ touch ~/user-config.jam +libs/math/doc$ # now edit so that: +libs/math/doc$ cat ~/user-config.jam +using darwin ; + +using xsltproc ; + +using boostbook + : /usr/local/opt/docbook-xsl/docbook-xsl + ; + +using doxygen ; +using quickbook ; +libs/math/doc$ ../../../b2 +``` diff --git a/third-party/boost-math/build.jam b/third-party/boost-math/build.jam new file mode 100644 index 0000000000000..fb244e511db5e --- /dev/null +++ b/third-party/boost-math/build.jam @@ -0,0 +1,48 @@ +# Copyright René Ferdinand Rivera Morell 2023-2024 +# 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) + +require-b2 5.2 ; + +constant boost_dependencies : + /boost/assert//boost_assert + /boost/concept_check//boost_concept_check + /boost/config//boost_config + /boost/core//boost_core + /boost/integer//boost_integer + /boost/lexical_cast//boost_lexical_cast + /boost/predef//boost_predef + /boost/random//boost_random + /boost/static_assert//boost_static_assert + /boost/throw_exception//boost_throw_exception ; + +project /boost/math + : common-requirements + include + ; + +explicit + [ alias boost_math : : : : $(boost_dependencies) ] + [ alias boost_math_c99 : build//boost_math_c99 ] + [ alias boost_math_c99f : build//boost_math_c99f ] + [ alias boost_math_c99l : build//boost_math_c99l ] + [ alias boost_math_tr1 : build//boost_math_tr1 ] + [ alias boost_math_tr1f : build//boost_math_tr1f ] + [ alias boost_math_tr1l : build//boost_math_tr1l ] + [ alias all : + boost_math + boost_math_c99 boost_math_c99f boost_math_c99l + boost_math_tr1 boost_math_tr1f boost_math_tr1l + example test ] + [ alias testing : : : : + test + include_private ] + ; + +call-if : boost-library math + : install boost_math + boost_math_c99 boost_math_c99f boost_math_c99l + boost_math_tr1 boost_math_tr1f boost_math_tr1l + ; + diff --git a/third-party/boost-math/include/boost/cstdfloat.hpp b/third-party/boost-math/include/boost/cstdfloat.hpp new file mode 100644 index 0000000000000..2814bb08bbe54 --- /dev/null +++ b/third-party/boost-math/include/boost/cstdfloat.hpp @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// implements floating-point typedefs having +// specified widths, as described in N3626 (proposed for C++14). +// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf + +#ifndef BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ + #define BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ + + // Include the floating-point type definitions. + #include + + // Support a specialization of std::numeric_limits<> for the wrapped quadmath library (if available). + #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) + #include + #endif + + // Support functions for the wrapped quadmath library (if available). + #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #include + #endif + + // Support I/O stream operations for the wrapped quadmath library (if available). + #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + #include + #endif + + // Support a specialization of std::complex<> for the wrapped quadmath library (if available). + #if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_COMPLEX) + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined. + #endif + #include + #endif + + + // Undefine BOOST_NO_FLOAT128_T because this constant is not meant for public use. + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) + #undef BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T + #endif + +#endif // BOOST_MATH_CSTDFLOAT_2014_01_09_HPP_ diff --git a/third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp b/third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp new file mode 100644 index 0000000000000..099484faad3e8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp @@ -0,0 +1,297 @@ +// (C) Copyright John Maddock 2006-8. +// 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) + +#ifndef BOOST_MATH_NTL_DIGAMMA +#define BOOST_MATH_NTL_DIGAMMA + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T big_digamma_helper(T x) +{ + static const T P[61] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6660133691143982067148122682345055274952e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6365271516829242456324234577164675383137e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2991038873096202943405966144203628966976e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9211116495503170498076013367421231351115e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2090792764676090716286400360584443891749e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3730037777359591428226035156377978092809e79), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5446396536956682043376492370432031543834e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6692523966335177847425047827449069256345e77), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7062543624100864681625612653756619116848e76), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6499914905966283735005256964443226879158e75), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5280364564853225211197557708655426736091e74), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3823205608981176913075543599005095206953e73), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2486733714214237704739129972671154532415e72), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1462562139602039577983434547171318011675e71), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7821169065036815012381267259559910324285e69), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3820552182348155468636157988764435365078e68), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1711618296983598244658239925535632505062e67), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7056661618357643731419080738521475204245e65), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2685246896473614017356264531791459936036e64), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9455168125599643085283071944864977592391e62), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3087541626972538362237309145177486236219e61), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9367928873352980208052601301625005737407e59), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2645306130689794942883818547314327466007e58), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6961815141171454309161007351079576190079e56), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1709637824471794552313802669803885946843e55), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3921553258481531526663112728778759311158e53), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.8409006354449988687714450897575728228696e51), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1686755204461325935742097669030363344927e50), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3166653542877070999007425197729038754254e48), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5566029092358215049069560272835654229637e46), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9161766287916328133080586672953875116242e44), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1412317772330871298317974693514430627922000), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 20387991986727877473732570146112459874790), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 275557928713904105182512535678580359839.3), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3485719851040516559072031256589598330.723), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 41247046743564028399938106707656877.40859), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 456274078125709314602601667471879.0147312), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4714450683242899367025707077155.310613012), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 45453933537925041680009544258.75073849996), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 408437900487067278846361972.302331241052), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3415719344386166273085838.705771571751035), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 26541502879185876562320.93134691487351145), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 191261415065918713661.1571433274648417668), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1275349770108718421.645275944284937551702), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 7849171120971773.318910987434906905704272), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 44455946386549.80866460312682983576538056), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 230920362395.3198137186361608905136598046), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1095700096.240863858624279930600654130254), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4727085.467506050153744334085516289728134), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 18440.75118859447173303252421991479005424), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 64.62515887799460295677071749181651317052), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.201851568864688406206528472883512147547), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.0005565091674187978029138500039504078098143), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1338097668312907986354698683493366559613e-5), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.276308225077464312820179030238305271638e-8), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4801582970473168520375942100071070575043e-11), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6829184144212920949740376186058541800175e-14), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7634080076358511276617829524639455399182e-17), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6290035083727140966418512608156646142409e-20), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.339652245667538733044036638506893821352e-23), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9017518064256388530773585529891677854909e-27) + }; + static const T Q[61] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1386831185456898357379390197203894063459e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6467076379487574703291056110838151259438e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1394967823848615838336194279565285465161e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1872927317344192945218570366455046340458e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1772461045338946243584650759986310355937e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1267294892200258648315971144069595555118e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7157764838362416821508872117623058626589e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.329447266909948668265277828268378274513e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1264376077317689779509250183194342571207e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4118230304191980787640446056583623228873e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1154393529762694616405952270558316515261e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.281655612889423906125295485693696744275e79), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6037483524928743102724159846414025482077e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1145927995397835468123576831800276999614e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1938624296151985600348534009382865995154e77), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.293980925856227626211879961219188406675e76), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4015574518216966910319562902099567437832e75), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4961475457509727343545565970423431880907e74), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5565482348278933960215521991000378896338e73), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5686112924615820754631098622770303094938e72), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5305988545844796293285410303747469932856e71), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4533363413802585060568537458067343491358e70), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3553932059473516064068322757331575565718e69), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2561198565218704414618802902533972354203e68), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1699519313292900324098102065697454295572e67), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1039830160862334505389615281373574959236e66), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5873082967977428281000961954715372504986e64), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3065255179030575882202133042549783442446e63), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1479494813481364701208655943688307245459e62), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6608150467921598615495180659808895663164e60), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2732535313770902021791888953487787496976e59), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1046402297662493314531194338414508049069e58), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3711375077192882936085049147920021549622e56), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1219154482883895482637944309702972234576e55), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3708359374149458741391374452286837880162e53), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1044095509971707189716913168889769471468e52), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.271951506225063286130946773813524945052e50), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6548016291215163843464133978454065823866e48), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1456062447610542135403751730809295219344e47), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2986690175077969760978388356833006028929e45), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 5643149706574013350061247429006443326844000), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 98047545414467090421964387960743688053480), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1563378767746846395507385099301468978550), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 22823360528584500077862274918382796495), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 304215527004115213046601295970388750), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3690289075895685793844344966820325), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 40584512015702371433911456606050), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 402834190897282802772754873905), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3589522158493606918146495750), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 28530557707503483723634725), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 200714561335055753000730), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1237953783437761888641), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 6614698701445762950), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 30155495647727505), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 114953256021450), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 356398020013), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 863113950), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1531345), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1770), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1) + }; + static const T PD[60] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6365271516829242456324234577164675383137e81), + 2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2991038873096202943405966144203628966976e81), + 3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9211116495503170498076013367421231351115e80), + 4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2090792764676090716286400360584443891749e80), + 5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3730037777359591428226035156377978092809e79), + 6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5446396536956682043376492370432031543834e78), + 7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6692523966335177847425047827449069256345e77), + 8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7062543624100864681625612653756619116848e76), + 9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6499914905966283735005256964443226879158e75), + 10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5280364564853225211197557708655426736091e74), + 11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3823205608981176913075543599005095206953e73), + 12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2486733714214237704739129972671154532415e72), + 13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1462562139602039577983434547171318011675e71), + 14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7821169065036815012381267259559910324285e69), + 15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3820552182348155468636157988764435365078e68), + 16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1711618296983598244658239925535632505062e67), + 17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7056661618357643731419080738521475204245e65), + 18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2685246896473614017356264531791459936036e64), + 19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9455168125599643085283071944864977592391e62), + 20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3087541626972538362237309145177486236219e61), + 21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9367928873352980208052601301625005737407e59), + 22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2645306130689794942883818547314327466007e58), + 23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6961815141171454309161007351079576190079e56), + 24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1709637824471794552313802669803885946843e55), + 25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3921553258481531526663112728778759311158e53), + 26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.8409006354449988687714450897575728228696e51), + 27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1686755204461325935742097669030363344927e50), + 28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3166653542877070999007425197729038754254e48), + 29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5566029092358215049069560272835654229637e46), + 30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9161766287916328133080586672953875116242e44), + 31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1412317772330871298317974693514430627922000), + 32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 20387991986727877473732570146112459874790), + 33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 275557928713904105182512535678580359839.3), + 34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3485719851040516559072031256589598330.723), + 35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 41247046743564028399938106707656877.40859), + 36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 456274078125709314602601667471879.0147312), + 37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4714450683242899367025707077155.310613012), + 38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 45453933537925041680009544258.75073849996), + 39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 408437900487067278846361972.302331241052), + 40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3415719344386166273085838.705771571751035), + 41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 26541502879185876562320.93134691487351145), + 42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 191261415065918713661.1571433274648417668), + 43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1275349770108718421.645275944284937551702), + 44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 7849171120971773.318910987434906905704272), + 45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 44455946386549.80866460312682983576538056), + 46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 230920362395.3198137186361608905136598046), + 47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1095700096.240863858624279930600654130254), + 48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4727085.467506050153744334085516289728134), + 49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 18440.75118859447173303252421991479005424), + 50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 64.62515887799460295677071749181651317052), + 51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.201851568864688406206528472883512147547), + 52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.0005565091674187978029138500039504078098143), + 53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1338097668312907986354698683493366559613e-5), + 54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.276308225077464312820179030238305271638e-8), + 55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4801582970473168520375942100071070575043e-11), + 56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6829184144212920949740376186058541800175e-14), + 57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7634080076358511276617829524639455399182e-17), + 58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6290035083727140966418512608156646142409e-20), + 59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.339652245667538733044036638506893821352e-23), + 60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9017518064256388530773585529891677854909e-27) + }; + static const T QD[60] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1386831185456898357379390197203894063459e81), + 2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6467076379487574703291056110838151259438e81), + 3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1394967823848615838336194279565285465161e82), + 4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1872927317344192945218570366455046340458e82), + 5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1772461045338946243584650759986310355937e82), + 6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1267294892200258648315971144069595555118e82), + 7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7157764838362416821508872117623058626589e81), + 8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.329447266909948668265277828268378274513e81), + 9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1264376077317689779509250183194342571207e81), + 10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4118230304191980787640446056583623228873e80), + 11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1154393529762694616405952270558316515261e80), + 12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.281655612889423906125295485693696744275e79), + 13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6037483524928743102724159846414025482077e78), + 14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1145927995397835468123576831800276999614e78), + 15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1938624296151985600348534009382865995154e77), + 16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.293980925856227626211879961219188406675e76), + 17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4015574518216966910319562902099567437832e75), + 18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4961475457509727343545565970423431880907e74), + 19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5565482348278933960215521991000378896338e73), + 20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5686112924615820754631098622770303094938e72), + 21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5305988545844796293285410303747469932856e71), + 22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4533363413802585060568537458067343491358e70), + 23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3553932059473516064068322757331575565718e69), + 24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2561198565218704414618802902533972354203e68), + 25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1699519313292900324098102065697454295572e67), + 26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1039830160862334505389615281373574959236e66), + 27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5873082967977428281000961954715372504986e64), + 28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3065255179030575882202133042549783442446e63), + 29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1479494813481364701208655943688307245459e62), + 30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6608150467921598615495180659808895663164e60), + 31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2732535313770902021791888953487787496976e59), + 32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1046402297662493314531194338414508049069e58), + 33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3711375077192882936085049147920021549622e56), + 34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1219154482883895482637944309702972234576e55), + 35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3708359374149458741391374452286837880162e53), + 36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1044095509971707189716913168889769471468e52), + 37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.271951506225063286130946773813524945052e50), + 38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6548016291215163843464133978454065823866e48), + 39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1456062447610542135403751730809295219344e47), + 40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2986690175077969760978388356833006028929e45), + 41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 5643149706574013350061247429006443326844000), + 42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 98047545414467090421964387960743688053480), + 43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1563378767746846395507385099301468978550), + 44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 22823360528584500077862274918382796495), + 45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 304215527004115213046601295970388750), + 46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3690289075895685793844344966820325), + 47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 40584512015702371433911456606050), + 48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 402834190897282802772754873905), + 49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3589522158493606918146495750), + 50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 28530557707503483723634725), + 51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 200714561335055753000730), + 52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1237953783437761888641), + 53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 6614698701445762950), + 54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 30155495647727505), + 55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 114953256021450), + 56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 356398020013), + 57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 863113950), + 58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1531345), + 59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1770), + 60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1) + }; + static const double g = 63.192152; + + T zgh = x + g - 0.5; + + T result = (x - 0.5) / zgh; + result += log(zgh); + result += tools::evaluate_polynomial(PD, x) / tools::evaluate_polynomial(P, x); + result -= tools::evaluate_polynomial(QD, x) / tools::evaluate_polynomial(Q, x); + result -= 1; + + return result; +} + +template +T big_digamma(T x) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + return big_digamma_helper(static_cast(1-x)) + constants::pi() / tan(constants::pi() * (1-x)); + } + return big_digamma_helper(x); +} + +}}} + +#endif // include guard diff --git a/third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp b/third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp new file mode 100644 index 0000000000000..525706ec5f676 --- /dev/null +++ b/third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp @@ -0,0 +1,777 @@ +// (C) Copyright John Maddock 2006-8. +// 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) + +#ifndef BOOST_BIG_LANCZOS_HPP +#define BOOST_BIG_LANCZOS_HPP + +#include + +namespace boost{ namespace math{ namespace lanczos{ + +// +// Lanczos Coefficients for N=13 G=13.144565 +// Max experimental error (with arbitrary precision arithmetic) 9.2213e-23 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +typedef lanczos13 lanczos13UDT; + +// +// Lanczos Coefficients for N=22 G=22.61891 +// Max experimental error (with arbitrary precision arithmetic) 2.9524e-38 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos22UDT : public std::integral_constant +{ + // + // Produces slightly better than 128-bit long-double precision when + // evaluated at higher precision: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 46198410803245094237463011094.12173081986)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 43735859291852324413622037436.321513777)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 19716607234435171720534556386.97481377748)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5629401471315018442177955161.245623932129)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1142024910634417138386281569.245580222392)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 175048529315951173131586747.695329230778)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 21044290245653709191654675.41581372963167)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2033001410561031998451380.335553678782601)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 160394318862140953773928.8736211601848891)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10444944438396359705707.48957290388740896)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 565075825801617290121.1466393747967538948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 25475874292116227538.99448534450411942597)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 957135055846602154.6720835535232270205725)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 29874506304047462.23662392445173880821515)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 769651310384737.2749087590725764959689181)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 16193289100889.15989633624378404096011797)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 273781151680.6807433264462376754578933261)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3630485900.32917021712188739762161583295)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 36374352.05577334277856865691538582936484)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 258945.7742115532455441786924971194951043)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1167.501919472435718934219997431551246996)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2.50662827463100050241576528481104525333)) + }; + static const T denom[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 6939996264376682180.277485395074954356211)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 6570067992110214451.87201438870245659384)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2961859037444440551.986724631496417064121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 845657339772791245.3541226499766163431651)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 171556737035449095.2475716923888737881837)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 26296059072490867.7822441885603400926007)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3161305619652108.433798300149816829198706)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 305400596026022.4774396904484542582526472)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 24094681058862.55120507202622377623528108)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1569055604375.919477574824168939428328839)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 84886558909.02047889339710230696942513159)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3827024985.166751989686050643579753162298)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 143782298.9273215199098728674282885500522)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 4487794.24541641841336786238909171265944)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 115618.2025760830513505888216285273541959)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432.580773108508276957461757328744780439)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 41.12782532742893597168530008461874360191)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.5453771709477689805460179187388702295792)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.005464211062612080347167337964166505282809)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.388992321263586767037090706042788910953e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.1753839324538447655939518484052327068859e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.3765495513732730583386223384116545391759e-9)) + }; + static const T denom[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[21] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8.318998691953337183034781139546384476554)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -63.15415991415959158214140353299240638675)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 217.3108224383632868591462242669081540163)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -448.5134281386108366899784093610397354889)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 619.2903759363285456927248474593012711346)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -604.1630177420625418522025080080444177046)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 428.8166750424646119935047118287362193314)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -224.6988753721310913866347429589434550302)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 87.32181627555510833499451817622786940961)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -25.07866854821128965662498003029199058098)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5.264398125689025351448861011657789005392)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.792518936256495243383586076579921559914)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.08317448364744713773350272460937904691566)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.005845345166274053157781068150827567998882)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0002599412126352082483326238522490030412391)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6748102079670763884917431338234783496303e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.908824383434109002762325095643458603605e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.5299325929309389890892469299969669579725e-9)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.994306085859549890267983602248532869362e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3499893692975262747371544905820891835298e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7260746353663365145454867069182884694961e-20)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[21] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 75.39272007105208086018421070699575462226)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -572.3481967049935412452681346759966390319)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1969.426202741555335078065370698955484358)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -4064.74968778032030891520063865996757519)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5612.452614138013929794736248384309574814)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -5475.357667500026172903620177988213902339)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3886.243614216111328329547926490398103492)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -2036.382026072125407192448069428134470564)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 791.3727954936062108045551843636692287652)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -227.2808432388436552794021219198885223122)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 47.70974355562144229897637024320739257284)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -7.182373807798293545187073539819697141572)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7537866989631514559601547530490976100468)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.05297470142240154822658739758236594717787)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.00235577330936380542539812701472320434133)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6115613067659273118098229498679502138802e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.8236417010170941915758315020695551724181e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.4802628430993048190311242611330072198089e-8)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.9011113376981524418952720279739624707342e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3171854152689711198382455703658589996796e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.6580207998808093935798753964580596673177e-19)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 22.61890999999999962710717227309942245483; } +}; +// +// Lanczos Coefficients for N=31 G=32.08067 +// Max experimental error (with arbitrary precision arithmetic) 0.162e-52 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at May 9 2006 +// +struct lanczos31UDT +{ + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2579646553333513328235723061836959833277e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2444796504337453845497419271639377138264e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1119885499016017172212179730662673475329e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3301983829072723658949204487793889113715e45)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7041171040503851585152895336505379417066e44)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1156687509001223855125097826246939403504e44)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1522559363393940883866575697565974893306000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 164914363507650839510801418717701057005700)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14978522943127593263654178827041568394060)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1156707153701375383907746879648168666774)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 76739431129980851159755403434593664173.2)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4407916278928188620282281495575981079.306)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 220487883931812802092792125175269667.3004)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9644828280794966468052381443992828.433924)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 369996467042247229310044531282837.6549068)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12468380890717344610932904378961.13494291)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 369289245210898235894444657859.0529720075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9607992460262594951559461829.34885209022)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 219225935074853412540086410.981421315799)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4374309943598658046326340.720767382079549)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 76008779092264509404014.10530947173485581)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1143503533822162444712.335663112617754987)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14779233719977576920.37884890049671578409)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 162409028440678302.9992838032166348069916)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1496561553388385.733407609544964535634135)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11347624460661.81008311053190661436107043)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 68944915931.32004991941950530448472223832)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 322701221.6391432296123937035480931903651)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1092364.213992634267819050120261755371294)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2380.151399852411512711176940867823024864)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.506628274631000502415765284811045253007)), + }; + static const T denom[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)), + }; + return boost::math::tools::evaluate_rational(num, denom, z, 31); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 30137154810677525966583148469478.52374216)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 28561746428637727032849890123131.36314653)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13083250730789213354063781611435.74046294)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3857598154697777600846539129354.783647)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 822596651552555685068015316144.0952185852)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 135131964033213842052904200372.039133532)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17787555889683709693655685146.19771358863)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1926639793777927562221423874.149673297196)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 174989113988888477076973808.6991839697774)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13513425905835560387095425.01158383184045)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 896521313378762433091075.1446749283094845)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 51496223433749515758124.71524415105430686)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2575886794780078381228.37205955912263407)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 112677328855422964200.4155776009524490958)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4322545967487943330.625233358130724324796)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 145663957202380774.0362027607207590519723)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4314283729473470.686566233465428332496534)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 112246988185485.8877916434026906290603878)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2561143864972.040563435178307062626388193)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 51103611767.9626550674442537989885239605)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 887985348.0369447209508500133077232094491)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13359172.3954672607019822025834072685839)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 172660.8841147568768783928167105965064459)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1897.370795407433013556725714874693719617)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17.48383210090980598861217644749573257178)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1325705316732132940835251054350153028901)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0008054605783673449641889260501816356090452)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.377001130700104515644336869896819162464e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1276172868883867038813825443204454996531e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2780651912081116274907381023821492811093e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2928410648650955854121639682890739211234e-13)), + }; + static const T denom[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)), + }; + return boost::math::tools::evaluate_rational(num, denom, z, 31); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[30] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11.80038544942943603508206880307972596807)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -130.6355975335626214564236363322099481079)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 676.2177719145993049893392276809256538927)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2174.724497783850503069990936574060452057)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4869.877180638131076410069103742986502022)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8065.744271864238179992762265472478229172)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 10245.03825618572106228191509520638651539)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -10212.83902362683215459850403668669647192)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8110.289185383288952562767679576754140336)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -5179.310892558291062401828964000776095156)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2673.987492589052370230989109591011091273)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1118.342574651205183051884250033505609141)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 378.5812742511620662650096436471920295596)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -103.3725999812126067084828735543906768961)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 22.62913974335996321848099677797888917792)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -3.936414819950859548507275533569588041446)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5376818198843817355682124535902641644854)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0567827903603478957483409124122554243201)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.004545544993648879420352693271088478106482)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0002689795568951033950042375135970897959935)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1139493459006846530734617710847103572122e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.3316581197839213921885210451302820192794e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.6285613334898374028443777562554713906213e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7222145115734409070310317999856424167091e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.4562976983547274766890241815002584238219e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1380593023819058919640038942493212141072e-14)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1629663871586410129307496385264268190679e-17)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.5429994291916548849493889660077076739993e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2922682842441892106795386303084661338957e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.8456967065309046044689041041336866118459e-31)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[30] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 147.9979641587472136175636384176549713358)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1638.404318611773924210055619836375434296)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8480.981744216135641122944743711911653273)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -27274.93942104458448200467097634494071176)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 61076.98019918759324489193232276937262854)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -101158.8762737154296509560513952101409264)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 128491.1252383947174824913796141607174379)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -128087.2892038336581928787480535905496026)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 101717.5492545853663296795562084430123258)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -64957.8330410311808907869707511362206858)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 33536.59139229792478811870738772305570317)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -14026.01847115365926835980820243003785821)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4748.087094096186515212209389240715050212)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1296.477510211815971152205100242259733245)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 283.8099337545793198947620951499958085157)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -49.36969067101255103452092297769364837753)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6.743492833270653628580811118017061581404)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7121578704864048548351804794951487823626)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0570092738016915476694118877057948681298)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.003373485297696102660302960722607722438643)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0001429128843527532859999752593761934089751)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.41595867130858508233493767243236888636e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7883284669307241040059778207492255409785e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.905786322462384670803148223703187214379e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5722790216999820323272452464661250331451e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1731510870832349779315841757234562309727e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2043890314358438601429048378015983874378e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.6810185176079344204740000170500311171065e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3665567641131713928114853776588342403919e-24)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1060655106553177007425710511436497259484e-29)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 32.08066999999999779902282170951366424561; } +}; + +// +// Lanczos Coefficients for N=61 G=63.192152 +// Max experimental error (with 1000-bit precision arithmetic) 3.740e-113 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 12 2006 +// +struct lanczos61UDT +{ + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[61] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659584)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13349415823254323512107320481.3495396037261649201426994438803767191136434970492309775123879)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -300542621510568204264185787475.230003734889859348050696493467253861933279360152095861484548)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3273919938390136737194044982676.40271056035622723775417608127544182097346526115858803376474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -22989594065095806099337396006399.5874206181563663855129141706748733174902067950115092492439)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 116970582893952893160414263796102.542775878583510989850142808618916073286745084692189044738)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -459561969036479455224850813196807.283291532483532558959779434457349912822256480548436066098)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1450959909778264914956547227964788.89797179379520834974601372820249784303794436366366810477)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -3782846865486775046285288437885921.41537699732805465141128848354901016102326190612528503251)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8305043213936355459145388670886540.09976337905520168067329932809302445437208115570138102767)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -15580988484396722546934484726970745.4927787160273626078250810989811865283255762028143642311)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 25262722284076250779006793435537600.0822901485517345545978818780090308947301031347345640449)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -35714428027687018805443603728757116.5304655170478705341887572982734901197345415291580897698)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 44334726194692443174715432419157343.2294160783772787096321009453791271387235388689346602833)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -48599573547617297831555162417695106.187829304963846482633791012658974681648157963911491985)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 47258466493366798944386359199482189.0753349196625125615316002614813737880755896979754845101)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -40913448215392412059728312039233342.142914753896559359297977982314043378636755884088383226)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 31626312914486892948769164616982902.7262756989418188077611392594232674722318027323102462687)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -21878079174441332123064991795834438.4699982361692990285700077902601657354101259411789722708)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13567268503974326527361474986354265.3136632133935430378937191911532112778452274286122946396)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -7551494211746723529747611556474669.62996644923557605747803028485900789337467673523741066527)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3775516572689476384052312341432597.70584966904950490541958869730702790312581801585742038997)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1696271471453637244930364711513292.79902955514107737992185368006225264329876265486853482449)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 684857608019352767999083000986166.20765273693720041519286231015176745354062413008561259139)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -248397566275708464679881624417990.410438107634139924805871051723444048539177890346227250473)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80880368999557992138783568858556.1512378233079327986518410244522800950609595592170022878937)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -23618197945394013802495450485616.9025005749893350650829964098117490779655546610665927669729)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6176884636893816103087134481332.06708966653493024119556843727320635285468825056891248447124)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1444348683723439589948246285262.64080678953468490544615312565485170860503207005915261691108)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 301342031656979076702313946827.961658905182634508217626783081241074250132289461989777865387)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -55959656587719766738301589651.3940625826610668990368881615587469329021742236397809951765678)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9223339169004064297247180402.36227016155682738556103138196079389248843082157924368301293963)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1344882881571942601385730283.42710150182526891377514071881534880944872423492272147871101373)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 172841913316760599352601139.54409257740173055624405575900164401527761357324625574736896079)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -19496120443876233531343952.3802212016691702737346568192063937387825469602063310488794471653)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1920907372583710284097959.44121420322495784420169085871802458519363819782779653621724219067)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -164429314798240461613359.399597503536657962383155875723527581699785846599051112719962464604)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12154026644351189572525.1452249886865981747374191977801688548318519692423556934568426042152)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -770443988366210815096.519382051977221101156336663806705367929328924137169970381042234329058)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 41558909851418707920.4696085656889424895313728719601503526476333404973280596225722152966128)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1890879946549708819.24562220042687554209318172044783707920086716716717574156283898330017796)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 71844996557297623.9583461685535340440524052492427928388171299145330229958643439878608673403)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2253785109518255.55600197759875781765803818232939130127735487613049577235879610065545755637)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 57616883849355.997562563968344493719962252675875692642406455612671495250543228005045106721)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1182495730353.08218118278997948852215670614084013289033222774171548915344541249351599628436)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 19148649358.6196967288062261380599423925174178776792840639099120170800869284300966978300613)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -239779605.891370259668403359614360511661030470269478602533200704639655585967442891496784613)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2267583.00284368310957842936892685032434505866445291643236133553754152047677944820353796872)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -15749.490806784673108773558070497383604733010677027764233749920147549999361110299643477893)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 77.7059495149052727171505425584459982871343274332635726864135949842508025564999785370162956)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.261619987273930331397625130282851629108569607193781378836014468617185550622160348688297247)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000572252321659691600529444769356185993188551770817110673186068921175991328434642504616377475)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.765167220661540041663007112207436426423746402583423562585653954743978584117929356523307954e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.579179571056209077507916813937971472839851499147582627425979879366849876944438724610663401e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.224804733043915149719206760378355636826808754704148660354494460792713189958510735070096991e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.392711975389579343321746945135488409914483448652884894759297584020979857734289645857714768e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.258603588346412049542768766878162221817684639789901440429511261589010049357907537684380983e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.499992460848751668441190360024540741752242879565548017176883304716370989218399797418478685e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.196211614533318174187346267877390498735734213905206562766348625767919122511096089367364025e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.874722648949676363732094858062907290148733370978226751462386623191111439121706262759209573e-37)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.163907874717737848669759890242660846846105433791283903651924563157080252845636658802930428e-44)), + }; + T result = d[0]; + for(unsigned k = 1; k < sizeof(d)/sizeof(d[0]); ++k) + { + result += d[k]/(z+(k-1)); + } + return result; + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[61] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.901751806425638853077358552989167785490911341809902155556127108480303870921448984935411583e-27)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4.80241125306810017699523302110401965428995345115391817406006361151407344955277298373661032)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -108.119283021710869401330097315436214587270846871451487282117128515476478251641970487922552)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1177.78262074811362219818923738088833932279000985161077740440010901595132448469513438139561)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8270.43570321334374279057432173814835581983913167617217749736484999327758232081395983082867)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 42079.807161997077661752306902088979258826568702655699995911391774839958572703348502730394)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -165326.003834443330215001219988296482004968548294447320869281647211603153902436231468280089)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 521978.361504895300685499370463597042533432134369277742485307843747923127933979566742421213)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1360867.51629992863544553419296636395576666570468519805449755596254912681418267100657262281)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2987713.73338656161102517003716335104823650191612448011720936412226357385029800040631754755)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -5605212.64915921452169919008770165304171481697939254152852673009005154549681704553438450709)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9088186.58332916818449459635132673652700922052988327069535513580836143146727832380184335474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -12848155.5543636394746355365819800465364996596310467415907815393346205151090486190421959769)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 15949281.2867656960575878805158849857756293807220033618942867694361569866468996967761600898)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -17483546.9948295433308250581770557182576171673272450149400973735206019559576269174369907171)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17001087.8599749419660906448951424280111036786456594738278573653160553115681287326064596964)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -14718487.0643665950346574802384331125115747311674609017568623694516187494204567579595827859)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11377468.7255609717716845971105161298889777425898291183866813269222281486121330837791392732)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -7870571.64253038587947746661946939286858490057774448573157856145556080330153403858747655263)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4880783.08440908743641723492059912671377140680710345996273343885045364205895751515063844239)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2716626.7992639625103140035635916455652302249897918893040695025407382316653674141983775542)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1358230.46602865696544327299659410214201327791319846880787515156343361311278133805428800255)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -610228.440751458395860905749312275043435828322076830117123636938979942213530882048883969802)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 246375.416501158654327780901087115642493055617468601787093268312234390446439555559050129729)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -89360.2599028475206119333931211015869139511677735549267100272095432140508089207221096740632)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 29096.4637987498328341260960356772198979319790332957125131055960448759586930781530063775634)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8496.57401431514433694413130585404918350686834939156759654375188338156288564260152505382438)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2222.11523574301594407443285016240908726891841242444092960094015874546135316534057865883047)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -519.599993280949289705514822058693289933461756514489674453254304308040888101533569480646682)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 108.406868361306987817730701109400305482972790224573776407166683184990131682003417239181112)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -20.1313142142558596796857948064047373605439974799116521459977609253211918146595346493447238)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3.31806787671783168020012913552384112429614503798293169239082032849759155847394955909684383)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.483817477111537877685595212919784447924875428848331771524426361483392903320495411973587861)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0621793463102927384924303843912913542297042029136293808338022462765755471002366206711862637)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00701366932085103924241526535768453911099671087892444015581511551813219720807206445462785293)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000691040514756294308758606917671220770856269030526647010461217455799229645004351524024364997)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.591529398871361458428147660822525365922497109038495896497692806150033516658042357799869656e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.437237367535177689875119370170434437030440227275583289093139147244747901678407875809020739e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.277164853397051135996651958345647824709602266382721185838782221179129726200661453504250697e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.149506899012035980148891401548317536032574502641368034781671941165064546410613201579653674e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.68023824066463262779882895193964639544061678698791279217407325790147925675797085217462974e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.258460163734186329938721529982859244969655253624066115559707985878606277800329299821882688e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.810792256024669306744649981276512583535251727474303382740940985102669076169168931092026491e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.207274966207031327521921078048021807442500113231320959236850963529304158700096495799022922e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.425399199286327802950259994834798737777721414442095221716122926637623478450472871269742436e-15)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.688866766744198529064607574117697940084548375790020728788313274612845280173338912495478431e-17)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.862599751805643281578607291655858333628582704771553874199104377131082877406179933909898885e-19)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.815756005678735657200275584442908437977926312650210429668619446123450972547018343768177988e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.566583084099007858124915716926967268295318152203932871370429534546567151650626184750291695e-23)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.279544761599725082805446124351997692260093135930731230328454667675190245860598623539891708e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941169851584987983984201821679114408126982142904386301937192011680047611188837432096199601e-28)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.205866011331040736302780507155525142187875191518455173304638008169488993406425201915370746e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.27526655245712584371295491216289353976964567057707464008951584303679019796521332324352501e-33)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208358067979444305082929004102609366169534624348056112144990933897581971394396210379638792e-36)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.808728107661779323263133007119729988596844663194254976820030366188579170595441991680169012e-40)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.141276924383478964519776436955079978012672985961918248012931336621229652792338950573694356e-43)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.930318449287651389310440021745842417218125582685428432576258687100661462527604238849332053e-48)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.179870748819321661641184169834635133045197146966203370650788171790610563029431722308057539e-52)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.705865243912790337263229413370018392321238639017433365017168104310561824133229343750737083e-58)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3146787805734405996448268100558028857930560442377698646099945108125281507396722995748398e-64)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.589653534231618730406843260601322236697428143603814281282790370329151249078338470962782338e-72)), + }; + T result = d[0]; + for(unsigned k = 1; k < sizeof(d)/sizeof(d[0]); ++k) + { + result += d[k]/(z+(k-1)); + } + return result; + } + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[60] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 23.2463658527729692390378860713647146932236940604550445351214987229819352880524561852919518)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -523.358012551815715084547614110229469295755088686612838322817729744722233637819564673967396)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 5701.12892340421080714956066268650092612647620400476183901625272640935853188559347587495571)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -40033.5506451901904954336453419007623117537868026994808919201793803506999271787018654246699)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 203689.884259074923009439144410340256983393397995558814367995938668111650624499963153485034)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -800270.648969745331278757692597096167418585957703057412758177038340791380011708874081291202)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2526668.23380061659863999395867315313385499515711742092815402701950519696944982260718031476)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -6587362.57559198722630391278043503867973853468105110382293763174847657538179665571836023631)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14462211.3454541602975917764900442754186801975533106565506542322063393991552960595701762805)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -27132375.1879227404375395522940895789625516798992585980380939378508607160857820002128106898)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 43991923.8735251977856804364757478459275087361742168436524951824945035673768875988985478116)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -62192284.0030124679010201921841372967696262036115679150017649233887633598058364494608060812)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 77203473.0770033513405070667417251568915937590689150831268228886281254637715669678358204991)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -84630180.2217173903516348977915150565994784278120192219937728967986198118628659866582594874)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 82294807.2253549409847505891112074804416229757832871133388349982640444405470371147991706317)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -71245738.2484649177928765605893043553453557808557887270209768163561363857395639001251515788)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 55073334.3180266913441333534260714059077572215147571872597651029894142803987981342430068594)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -38097984.1648990787690036742690550656061009857688125101191167768314179751258568264424911474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 23625729.5032184580395130592017474282828236643586203914515183078852982915252442161768527976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -13149998.4348054726172055622442157883429575511528431835657668083088902165366619827169829685)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6574597.77221556423683199818131482663205682902023554728024972161230111356285973623550338976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2953848.1483469149918109110050192571921018042012905892107136410603990336401921230407043408)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1192595.29584357246380113611351829515963605337523874715861849584306265512819543347806085356)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -432553.812019608638388918135375154289816441900572658692369491476137741687213006403648722272)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 140843.215385933866391177743292449477205328233960902455943995092958295858485718885800427129)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -41128.186992679630058614841985110676526199977321524879849001760603476646382839182691529968)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 10756.2849191854701631989789887757784944313743544315113894758328432005767448056040879337769)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2515.15559672041299884426826962296210458052543246529646213159169885444118227871246315458787)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 524.750087004805200600237632074908875763734578390662349666321453103782638818305404274166951)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -97.4468596421732493988298219295878130651986131393383646674144877163795143930682205035917965)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 16.0613108128210806736384551896802799172445298357754547684100294231532127326987175444453058)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2.34194813526540240672426202485306862230641838409943369059203455578340880900483887447559874)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300982934748016059399829007219431333744032924923669397318820178988611410275964499475465815)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.033950095985367909789000959795708551814461844488183964432565731809399824963680858993718525)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.00334502394288921146242772614150438404658527112198421937945605441697314216921393987758378122)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.000286333429067523984607730553301991502191011265745476190940771685897687956262049750683013485)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.211647426149364947402896718485536530479491688838087899435991994237067890628274492042231115e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.134163345121302758109675190598169832775248626443483098532368562186356128620805552609175683e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.723697303042715085329782938306424498336642078597508935450663080894255773653328980495047891e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.329273487343139063533251321553223583999676337945788660475231347828772272134656322947906888e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.12510922551028971731767784013117088894558604838820475961392154031378891971216135267744134e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.392468958215589939603666430583400537413757786057185505426804034745840192914621891690369903e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100332717101049934370760667782927946803279422001380028508200697081188326364078428184546051e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.205917088291197705194762747639836655808855850989058813560983717575008725393428497910009756e-14)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.333450178247893143608439314203175490705783992567107481617660357577257627854979230819461489e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.417546693906616047110563550428133589051498362676394888715581845170969319500638944065594319e-18)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.394871691642184410859178529844325390739857256666676534513661579365702353214518478078730801e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.274258012587811199757875927548699264063511843669070634471054184977334027224611843434000922e-22)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.135315354265459854889496635967343027244391821142592599244505313738163473730636430399785048e-24)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.455579032003288910408487905303223613382276173706542364543918076752861628464036586507967767e-27)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.99650703862462739161520123768147312466695159780582506041370833824093136783202694548427718e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1332444609228706921659395801935919548447859029572115502899861345555006827214220195650058e-32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100856999148765307000182397631280249632761913433008379786888200467467364474581430670889392e-35)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.39146979455613683472384690509165395074425354524713697428673406058157887065953366609738731e-39)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.683859606707931248105140296850112494069265272540298100341919970496564103098283709868586478e-43)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.450326344248604222735147147805963966503893913752040066400766411031387063854141246972061792e-47)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.870675378039492904184581895322153006461319724931909799151743284769901586333730037761678891e-52)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.341678395249272265744518787745356400350877656459401143889000625280131819505857966769964401e-57)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.152322191370871666358069530949353871960316638394428595988162174042653299702098929238880862e-63)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.285425405297633795767452984791738825078111150078605004958179057245980222485147999495352632e-71)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[60] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 557.56438192770795764344217888434355281097193198928944200046501607026919782564033547346298)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -12552.748616427645475141433405567201788681683808077269330800392600825597799119572762385222)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 136741.650054039199076788077149441364242294724343897779563222338447737802381279007988884806)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -960205.223613240309942047656967301131022760634321049075674684679438471862998829007639437133)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4885504.47588736223774859617054275229642041717942140469884121916073195308537421162982679289)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -19194501.738192166918904824982935279260356575935661514109550613809352009246483412530545583)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 60602169.8633537742937457094837494059849674261357199218329545854990149896822944801504450843)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -157997975.522506767297528502540724511908584668874487506510120462561270100749019845014382885)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 346876323.86092543685419723290495817330608574729543216092477261152247521712190505658568876)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -650770365.471136883718747607976242475416651908858429752332176373467422603953536408709972919)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1055146856.05909309330903130910708372830487315684258450293308627289334336871273080305128138)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1491682726.25614447429071368736790697283307005456720192465860871846879804207692411263924608)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1851726287.94866167094858600116562210167031458934987154557042242638980748286188183300900268)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2029855953.68334371445800569238095379629407314338521720558391277508374519526853827142679839)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1973842002.53354868177824629525448788555435194808657489238517523691040148611221295436287925)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1708829941.98209573247426625323314413060108441455314880934710595647408841619484540679859098)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1320934627.12433688699625456833930317624783222321555050330381730035733198249283009357314954)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -913780636.858542526294419197161614811332299249415125108737474024007693329922089123296358727)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 566663423.929632170286007468016419798879660054391183200464733820209439185545886930103546787)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -315402880.436816230388857961460509181823167373029384218959199936902955049832392362044305869)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 157691811.550465734461741500275930418786875005567018699867961482249002625886064187146134966)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -70848085.5705405970640618473551954585013808128304384354476488268600720054598122945113512731)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 28604413.4050137708444142264980840059788755325900041515286382001704951527733220637586013815)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -10374808.7067303054787164054055989420809074792801592763124972441820101840292558840131568633)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3378126.32016207486657791623723515804931231041318964254116390764473281291389374196880720069)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -986460.090390653140964189383080344920103075349535669020623874668558777188889544398718979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 257989.631187387317948158483575125380011593209850756066176921901006833159795100137743395985)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -60326.0391159227288325790327830741260824763549807922845004854215660451399733578621565837087)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12586.1375399649496159880821645216260841794563919652590583420570326276086323953958907053394)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2337.26417330316922535871922886167444795452055677161063205953141105726549966801856628447293)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 385.230745012608736644117458716226876976056390433401632749144285378123105481506733917763829)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -56.1716559403731491675970177460841997333796694857076749852739159067307309470690838101179615)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7.21907953468550196348585224042498727840087634483369357697580053424523903859773769748599575)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.814293485887386870805786409956942772883474224091975496298369877683530509729332902182019049)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0802304419995150047616460464220884371214157889148846405799324851793571580868840034085001373)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00686771095380619535195996193943858680694970000948742557733102777115482017857981277171196115)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000507636621977556438232617777542864427109623356049335590894564220687567763620803789858345916)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.32179095465362720747836116655088181481893063531138957363431280817392443948706754917605911e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.173578890579848508947329833426585354230744194615295570820295052665075101971588563893718407e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.789762880006288893888161070734302768702358633525134582027140158619195373770299678322596835e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300074637200885066788470310738617992259402710843493097610337134266720909870967550606601658e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941337297619721713151110244242536308266701344868601679868536153775533330272973088246835359e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.24064815013182536657310186836079333949814111498828401548170442715552017773994482539471456e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.493892399304811910466345686492277504628763169549384435563232052965821874553923373100791477e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.799780678476644196901221989475355609743387528732994566453160178199295104357319723742820593e-15)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.100148627870893347527249092785257443532967736956154251497569191947184705954310833302770086e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.947100256812658897084619699699028861352615460106539259289295071616221848196411749449858071e-19)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.657808193528898116367845405906343884364280888644748907819280236995018351085371701094007759e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.324554050057463845012469010247790763753999056976705084126950591088538742509983426730851614e-23)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.10927068902162908990029309141242256163212535730975970310918370355165185052827948996110107e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.239012340507870646690121104637467232366271566488184795459093215303237974655782634371712486e-28)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.31958700972990573259359660326375143524864710953063781494908314884519046349402409667329667e-31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.241905641292988284384362036555782113275737930713192053073501265726048089991747342247551645e-34)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.93894080230619233745797029179332447129464915420290457418429337322820997038069119047864035e-38)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.164023814025085488413251990798690797467351995518990067783355251949198292596815470576539877e-41)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.108010831192689925518484618970761942019888832176355541674171850211917230280206410356465451e-45)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208831600642796805563854019033577205240227465154130766898180386564934443551840379116390645e-50)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.819516067465171848863933747691434138146789031214932473898084756489529673230665363014007306e-56)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.365344970579318347488211604761724311582675708113250505307342682118101409913523622073678179e-62)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.684593199208628857931267904308244537968349564351534581234005234847904343404822808648361291e-70)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 63.19215200000000010049916454590857028961181640625; } +}; + +}}} // namespaces + +#endif + + diff --git a/third-party/boost-math/include/boost/math/bindings/mpfr.hpp b/third-party/boost-math/include/boost/math/bindings/mpfr.hpp new file mode 100644 index 0000000000000..711daded77bb0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/bindings/mpfr.hpp @@ -0,0 +1,974 @@ +// Copyright John Maddock 2008. +// 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) +// +// Wrapper that works with mpfr_class defined in gmpfrxx.h +// See http://math.berkeley.edu/~wilken/code/gmpfrxx/ +// Also requires the gmp and mpfr libraries. +// + +#ifndef BOOST_MATH_MPLFR_BINDINGS_HPP +#define BOOST_MATH_MPLFR_BINDINGS_HPP + +#include + +#ifdef _MSC_VER +// +// We get a lot of warnings from the gmp, mpfr and gmpfrxx headers, +// disable them here, so we only see warnings from *our* code: +// +#pragma warning(push) +#pragma warning(disable: 4127 4800 4512) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +inline mpfr_class fabs(const mpfr_class& v) +{ + return abs(v); +} +template +inline mpfr_class fabs(const __gmp_expr& v) +{ + return abs(static_cast(v)); +} + +inline mpfr_class pow(const mpfr_class& b, const mpfr_class& e) +{ + mpfr_class result; + mpfr_pow(result.__get_mp(), b.__get_mp(), e.__get_mp(), GMP_RNDN); + return result; +} +/* +template +inline mpfr_class pow(const __gmp_expr& b, const __gmp_expr& e) +{ + return pow(static_cast(b), static_cast(e)); +} +*/ +inline mpfr_class ldexp(const mpfr_class& v, int e) +{ + //int e = mpfr_get_exp(*v.__get_mp()); + mpfr_class result(v); + mpfr_set_exp(result.__get_mp(), e); + return result; +} +template +inline mpfr_class ldexp(const __gmp_expr& v, int e) +{ + return ldexp(static_cast(v), e); +} + +inline mpfr_class frexp(const mpfr_class& v, int* expon) +{ + int e = mpfr_get_exp(v.__get_mp()); + mpfr_class result(v); + mpfr_set_exp(result.__get_mp(), 0); + *expon = e; + return result; +} +template +inline mpfr_class frexp(const __gmp_expr& v, int* expon) +{ + return frexp(static_cast(v), expon); +} + +inline mpfr_class fmod(const mpfr_class& v1, const mpfr_class& v2) +{ + mpfr_class n; + if(v1 < 0) + n = ceil(v1 / v2); + else + n = floor(v1 / v2); + return v1 - n * v2; +} +template +inline mpfr_class fmod(const __gmp_expr& v1, const __gmp_expr& v2) +{ + return fmod(static_cast(v1), static_cast(v2)); +} + +template +inline mpfr_class modf(const mpfr_class& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - boost::math::tools::real_cast(*ipart); +} +template +inline mpfr_class modf(const __gmp_expr& v, long long* ipart, const Policy& pol) +{ + return modf(static_cast(v), ipart, pol); +} + +template +inline int iround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline int iround(__gmp_expr const& x, const Policy& pol) +{ + return iround(static_cast(x), pol); +} + +template +inline long lround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline long lround(__gmp_expr const& x, const Policy& pol) +{ + return lround(static_cast(x), pol); +} + +template +inline long long llround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline long long llround(__gmp_expr const& x, const Policy& pol) +{ + return llround(static_cast(x), pol); +} + +template +inline int itrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline int itrunc(__gmp_expr const& x, const Policy& pol) +{ + return itrunc(static_cast(x), pol); +} + +template +inline long ltrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline long ltrunc(__gmp_expr const& x, const Policy& pol) +{ + return ltrunc(static_cast(x), pol); +} + +template +inline long long lltrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline long long lltrunc(__gmp_expr const& x, const Policy& pol) +{ + return lltrunc(static_cast(x), pol); +} + +namespace boost{ + +#ifdef BOOST_MATH_USE_FLOAT128 + template<> struct std::is_convertible : public std::integral_constant{}; +#endif + template<> struct std::is_convertible : public std::integral_constant{}; + +namespace math{ + +#if defined(__GNUC__) && (__GNUC__ < 4) + using ::iround; + using ::lround; + using ::llround; + using ::itrunc; + using ::ltrunc; + using ::lltrunc; + using ::modf; +#endif + +namespace lanczos{ + +struct mpfr_lanczos +{ + static mpfr_class lanczos_sum(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static mpfr_class lanczos_sum_expG_scaled(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static mpfr_class lanczos_sum_near_1(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static mpfr_class lanczos_sum_near_2(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static mpfr_class g() + { + unsigned long p = mpfr_class::get_dprec(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef mpfr_lanczos type; +}; + +} // namespace lanczos + +namespace constants{ + +template +struct construction_traits; + +template +struct construction_traits +{ + typedef std::integral_constant type; +}; + +} + +namespace tools +{ + +template +struct promote_arg<__gmp_expr > +{ // If T is integral type, then promote to double. + typedef mpfr_class type; +}; + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) noexcept +{ + return mpfr_class::get_dprec(); +} + +namespace detail{ + +template +void convert_to_long_result(mpfr_class const& r, Integer& result) +{ + result = 0; + I last_result(0); + mpfr_class t(r); + double term; + do + { + term = real_cast(t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline mpfr_class real_cast(long long t) +{ + mpfr_class result; + int expon = 0; + int sign = 1; + if(t < 0) + { + sign = -1; + t = -t; + } + while(t) + { + result += ldexp(static_cast(t & 0xffffL), expon); + expon += 32; + t >>= 32; + } + return result * sign; +} +template <> +inline unsigned real_cast(mpfr_class t) +{ + return t.get_ui(); +} +template <> +inline int real_cast(mpfr_class t) +{ + return t.get_si(); +} +template <> +inline double real_cast(mpfr_class t) +{ + return t.get_d(); +} +template <> +inline float real_cast(mpfr_class t) +{ + return static_cast(t.get_d()); +} +template <> +inline long real_cast(mpfr_class t) +{ + long result; + detail::convert_to_long_result(t, result); + return result; +} +template <> +inline long long real_cast(mpfr_class t) +{ + long long result; + detail::convert_to_long_result(t, result); + return result; +} + +template <> +inline mpfr_class max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val; + if(!has_init) + { + val = 0.5; + mpfr_set_exp(val.__get_mp(), mpfr_get_emax()); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val; + if(!has_init) + { + val = 0.5; + mpfr_set_exp(val.__get_mp(), mpfr_get_emin()); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + return ldexp(mpfr_class(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +namespace policies{ + +template +struct evaluation<__gmp_expr, Policy> +{ + typedef mpfr_class type; +}; + +} + +template +inline mpfr_class skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr skewness can not be calculated in standalone mode"); + #endif + + return static_cast("1.1395470994046486574927930193898461120875997958366"); +} + +template +inline mpfr_class skewness(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr skewness can not be calculated in standalone mode"); + #endif + + return static_cast("0.63111065781893713819189935154422777984404221106391"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 2 * root_pi() * pi_minus_three() / pow23_four_minus_pi(); +} + +template +inline mpfr_class kurtosis(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr kurtosis can not be calculated in standalone mode"); + #endif + + return static_cast("3.2450893006876380628486604106197544154170667057995"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 3 - (6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} + +template +inline mpfr_class kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + //using namespace boost::math::constants; + // Computed using NTL at 150 bit, about 50 decimal digits. + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr excess kurtosis can not be calculated in standalone mode"); + #endif + + return static_cast("0.2450893006876380628486604106197544154170667057995"); + // return -(6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} // kurtosis + +namespace detail{ + +// +// Version of Digamma accurate to ~100 decimal digits. +// +template +mpfr_class digamma_imp(mpfr_class x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // empfr_classor handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + mpfr_class result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + mpfr_class remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} +// +// Specialisations of this function provides the initial +// starting guess for Halley iteration: +// +template +inline mpfr_class erf_inv_imp(const mpfr_class& p, const mpfr_class& q, const Policy&, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + mpfr_class result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute empfr_classor compared to |Y|. + // + // double: Max empfr_classor found: 2.001849e-18 + // long double: Max empfr_classor found: 1.017064e-20 + // Maximum Deviation Found (actual empfr_classor term at infinite precision) 8.030e-21 + // + static const float Y = 0.0891314744949340820313f; + static const mpfr_class P[] = { + -0.000508781949658280665617, + -0.00836874819741736770379, + 0.0334806625409744615033, + -0.0126926147662974029034, + -0.0365637971411762664006, + 0.0219878681111168899165, + 0.00822687874676915743155, + -0.00538772965071242932965 + }; + static const mpfr_class Q[] = { + 1, + -0.970005043303290640362, + -1.56574558234175846809, + 1.56221558398423026363, + 0.662328840472002992063, + -0.71228902341542847553, + -0.0527396382340099713954, + 0.0795283687341571680018, + -0.00233393759374190016776, + 0.000886216390456424707504 + }; + mpfr_class g = p * (p + 10); + mpfr_class r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute empfr_classor compared to Y. + // + // double : Max empfr_classor found: 7.403372e-17 + // long double : Max empfr_classor found: 6.084616e-20 + // Maximum Deviation Found (empfr_classor term) 4.811e-20 + // + static const float Y = 2.249481201171875f; + static const mpfr_class P[] = { + -0.202433508355938759655, + 0.105264680699391713268, + 8.37050328343119927838, + 17.6447298408374015486, + -18.8510648058714251895, + -44.6382324441786960818, + 17.445385985570866523, + 21.1294655448340526258, + -3.67192254707729348546 + }; + static const mpfr_class Q[] = { + 1, + 6.24264124854247537712, + 3.9713437953343869095, + -28.6608180499800029974, + -20.1432634680485188801, + 48.5609213108739935468, + 10.8268667355460159008, + -22.6436933413139721736, + 1.72114765761200282724 + }; + mpfr_class g = sqrt(-2 * log(q)); + mpfr_class xs = q - 0.25; + mpfr_class r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute empfr_classor compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + mpfr_class x = sqrt(-log(q)); + if(x < 3) + { + // Max empfr_classor found: 1.089051e-20 + static const float Y = 0.807220458984375f; + static const mpfr_class P[] = { + -0.131102781679951906451, + -0.163794047193317060787, + 0.117030156341995252019, + 0.387079738972604337464, + 0.337785538912035898924, + 0.142869534408157156766, + 0.0290157910005329060432, + 0.00214558995388805277169, + -0.679465575181126350155e-6, + 0.285225331782217055858e-7, + -0.681149956853776992068e-9 + }; + static const mpfr_class Q[] = { + 1, + 3.46625407242567245975, + 5.38168345707006855425, + 4.77846592945843778382, + 2.59301921623620271374, + 0.848854343457902036425, + 0.152264338295331783612, + 0.01105924229346489121 + }; + mpfr_class xs = x - 1.125; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // Max empfr_classor found: 8.389174e-21 + static const float Y = 0.93995571136474609375f; + static const mpfr_class P[] = { + -0.0350353787183177984712, + -0.00222426529213447927281, + 0.0185573306514231072324, + 0.00950804701325919603619, + 0.00187123492819559223345, + 0.000157544617424960554631, + 0.460469890584317994083e-5, + -0.230404776911882601748e-9, + 0.266339227425782031962e-11 + }; + static const mpfr_class Q[] = { + 1, + 1.3653349817554063097, + 0.762059164553623404043, + 0.220091105764131249824, + 0.0341589143670947727934, + 0.00263861676657015992959, + 0.764675292302794483503e-4 + }; + mpfr_class xs = x - 3; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // Max empfr_classor found: 1.481312e-19 + static const float Y = 0.98362827301025390625f; + static const mpfr_class P[] = { + -0.0167431005076633737133, + -0.00112951438745580278863, + 0.00105628862152492910091, + 0.000209386317487588078668, + 0.149624783758342370182e-4, + 0.449696789927706453732e-6, + 0.462596163522878599135e-8, + -0.281128735628831791805e-13, + 0.99055709973310326855e-16 + }; + static const mpfr_class Q[] = { + 1, + 0.591429344886417493481, + 0.138151865749083321638, + 0.0160746087093676504695, + 0.000964011807005165528527, + 0.275335474764726041141e-4, + 0.282243172016108031869e-6 + }; + mpfr_class xs = x - 6; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // Max empfr_classor found: 5.697761e-20 + static const float Y = 0.99714565277099609375f; + static const mpfr_class P[] = { + -0.0024978212791898131227, + -0.779190719229053954292e-5, + 0.254723037413027451751e-4, + 0.162397777342510920873e-5, + 0.396341011304801168516e-7, + 0.411632831190944208473e-9, + 0.145596286718675035587e-11, + -0.116765012397184275695e-17 + }; + static const mpfr_class Q[] = { + 1, + 0.207123112214422517181, + 0.0169410838120975906478, + 0.000690538265622684595676, + 0.145007359818232637924e-4, + 0.144437756628144157666e-6, + 0.509761276599778486139e-9 + }; + mpfr_class xs = x - 18; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // Max empfr_classor found: 1.279746e-20 + static const float Y = 0.99941349029541015625f; + static const mpfr_class P[] = { + -0.000539042911019078575891, + -0.28398759004727721098e-6, + 0.899465114892291446442e-6, + 0.229345859265920864296e-7, + 0.225561444863500149219e-9, + 0.947846627503022684216e-12, + 0.135880130108924861008e-14, + -0.348890393399948882918e-21 + }; + static const mpfr_class Q[] = { + 1, + 0.0845746234001899436914, + 0.00282092984726264681981, + 0.468292921940894236786e-4, + 0.399968812193862100054e-6, + 0.161809290887904476097e-8, + 0.231558608310259605225e-11 + }; + mpfr_class xs = x - 44; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +inline mpfr_class bessel_i0(mpfr_class x) +{ + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(x) == 0, "mpfr bessel_i0 can not be calculated in standalone mode"); + #endif + + static const mpfr_class P1[] = { + static_cast("-2.2335582639474375249e+15"), + static_cast("-5.5050369673018427753e+14"), + static_cast("-3.2940087627407749166e+13"), + static_cast("-8.4925101247114157499e+11"), + static_cast("-1.1912746104985237192e+10"), + static_cast("-1.0313066708737980747e+08"), + static_cast("-5.9545626019847898221e+05"), + static_cast("-2.4125195876041896775e+03"), + static_cast("-7.0935347449210549190e+00"), + static_cast("-1.5453977791786851041e-02"), + static_cast("-2.5172644670688975051e-05"), + static_cast("-3.0517226450451067446e-08"), + static_cast("-2.6843448573468483278e-11"), + static_cast("-1.5982226675653184646e-14"), + static_cast("-5.2487866627945699800e-18"), + }; + static const mpfr_class Q1[] = { + static_cast("-2.2335582639474375245e+15"), + static_cast("7.8858692566751002988e+12"), + static_cast("-1.2207067397808979846e+10"), + static_cast("1.0377081058062166144e+07"), + static_cast("-4.8527560179962773045e+03"), + static_cast("1.0"), + }; + static const mpfr_class P2[] = { + static_cast("-2.2210262233306573296e-04"), + static_cast("1.3067392038106924055e-02"), + static_cast("-4.4700805721174453923e-01"), + static_cast("5.5674518371240761397e+00"), + static_cast("-2.3517945679239481621e+01"), + static_cast("3.1611322818701131207e+01"), + static_cast("-9.6090021968656180000e+00"), + }; + static const mpfr_class Q2[] = { + static_cast("-5.5194330231005480228e-04"), + static_cast("3.2547697594819615062e-02"), + static_cast("-1.1151759188741312645e+00"), + static_cast("1.3982595353892851542e+01"), + static_cast("-6.0228002066743340583e+01"), + static_cast("8.5539563258012929600e+01"), + static_cast("-3.1446690275135491500e+01"), + static_cast("1.0"), + }; + mpfr_class value, factor, r; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (x < 0) + { + x = -x; // even function + } + if (x == 0) + { + return static_cast(1); + } + if (x <= 15) // x in (0, 15] + { + mpfr_class y = x * x; + value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + } + else // x in (15, \infty) + { + mpfr_class y = 1 / x - mpfr_class(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(x) / sqrt(x); + value = factor * r; + } + + return value; +} + +inline mpfr_class bessel_i1(mpfr_class x) +{ + static const mpfr_class P1[] = { + static_cast("-1.4577180278143463643e+15"), + static_cast("-1.7732037840791591320e+14"), + static_cast("-6.9876779648010090070e+12"), + static_cast("-1.3357437682275493024e+11"), + static_cast("-1.4828267606612366099e+09"), + static_cast("-1.0588550724769347106e+07"), + static_cast("-5.1894091982308017540e+04"), + static_cast("-1.8225946631657315931e+02"), + static_cast("-4.7207090827310162436e-01"), + static_cast("-9.1746443287817501309e-04"), + static_cast("-1.3466829827635152875e-06"), + static_cast("-1.4831904935994647675e-09"), + static_cast("-1.1928788903603238754e-12"), + static_cast("-6.5245515583151902910e-16"), + static_cast("-1.9705291802535139930e-19"), + }; + static const mpfr_class Q1[] = { + static_cast("-2.9154360556286927285e+15"), + static_cast("9.7887501377547640438e+12"), + static_cast("-1.4386907088588283434e+10"), + static_cast("1.1594225856856884006e+07"), + static_cast("-5.1326864679904189920e+03"), + static_cast("1.0"), + }; + static const mpfr_class P2[] = { + static_cast("1.4582087408985668208e-05"), + static_cast("-8.9359825138577646443e-04"), + static_cast("2.9204895411257790122e-02"), + static_cast("-3.4198728018058047439e-01"), + static_cast("1.3960118277609544334e+00"), + static_cast("-1.9746376087200685843e+00"), + static_cast("8.5591872901933459000e-01"), + static_cast("-6.0437159056137599999e-02"), + }; + static const mpfr_class Q2[] = { + static_cast("3.7510433111922824643e-05"), + static_cast("-2.2835624489492512649e-03"), + static_cast("7.4212010813186530069e-02"), + static_cast("-8.5017476463217924408e-01"), + static_cast("3.2593714889036996297e+00"), + static_cast("-3.8806586721556593450e+00"), + static_cast("1.0"), + }; + mpfr_class value, factor, r, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 15) // w in (0, 15] + { + mpfr_class y = x * x; + r = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + factor = w; + value = factor * r; + } + else // w in (15, \infty) + { + mpfr_class y = 1 / w - mpfr_class(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(w) / sqrt(w); + value = factor * r; + } + + if (x < 0) + { + value *= -value; // odd function + } + return value; +} + +} // namespace detail + +} + +template<> struct std::is_convertible : public std::false_type{}; + +} + +#endif // BOOST_MATH_MPLFR_BINDINGS_HPP + diff --git a/third-party/boost-math/include/boost/math/bindings/mpreal.hpp b/third-party/boost-math/include/boost/math/bindings/mpreal.hpp new file mode 100644 index 0000000000000..3271550110093 --- /dev/null +++ b/third-party/boost-math/include/boost/math/bindings/mpreal.hpp @@ -0,0 +1,921 @@ +// Copyright John Maddock 2008. +// 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) +// +// Wrapper that works with mpfr::mpreal defined in gmpfrxx.h +// See http://math.berkeley.edu/~wilken/code/gmpfrxx/ +// Also requires the gmp and mpfr libraries. +// + +#ifndef BOOST_MATH_MPREAL_BINDINGS_HPP +#define BOOST_MATH_MPREAL_BINDINGS_HPP + +#include + +#ifdef _MSC_VER +// +// We get a lot of warnings from the gmp, mpfr and gmpfrxx headers, +// disable them here, so we only see warnings from *our* code: +// +#pragma warning(push) +#pragma warning(disable: 4127 4800 4512) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace mpfr{ + +template +inline mpreal operator + (const mpreal& r, const T& t){ return r + mpreal(t); } +template +inline mpreal operator - (const mpreal& r, const T& t){ return r - mpreal(t); } +template +inline mpreal operator * (const mpreal& r, const T& t){ return r * mpreal(t); } +template +inline mpreal operator / (const mpreal& r, const T& t){ return r / mpreal(t); } + +template +inline mpreal operator + (const T& t, const mpreal& r){ return mpreal(t) + r; } +template +inline mpreal operator - (const T& t, const mpreal& r){ return mpreal(t) - r; } +template +inline mpreal operator * (const T& t, const mpreal& r){ return mpreal(t) * r; } +template +inline mpreal operator / (const T& t, const mpreal& r){ return mpreal(t) / r; } + +template +inline bool operator == (const mpreal& r, const T& t){ return r == mpreal(t); } +template +inline bool operator != (const mpreal& r, const T& t){ return r != mpreal(t); } +template +inline bool operator <= (const mpreal& r, const T& t){ return r <= mpreal(t); } +template +inline bool operator >= (const mpreal& r, const T& t){ return r >= mpreal(t); } +template +inline bool operator < (const mpreal& r, const T& t){ return r < mpreal(t); } +template +inline bool operator > (const mpreal& r, const T& t){ return r > mpreal(t); } + +template +inline bool operator == (const T& t, const mpreal& r){ return mpreal(t) == r; } +template +inline bool operator != (const T& t, const mpreal& r){ return mpreal(t) != r; } +template +inline bool operator <= (const T& t, const mpreal& r){ return mpreal(t) <= r; } +template +inline bool operator >= (const T& t, const mpreal& r){ return mpreal(t) >= r; } +template +inline bool operator < (const T& t, const mpreal& r){ return mpreal(t) < r; } +template +inline bool operator > (const T& t, const mpreal& r){ return mpreal(t) > r; } + +/* +inline mpfr::mpreal fabs(const mpfr::mpreal& v) +{ + return abs(v); +} +inline mpfr::mpreal pow(const mpfr::mpreal& b, const mpfr::mpreal e) +{ + mpfr::mpreal result; + mpfr_pow(result.__get_mp(), b.__get_mp(), e.__get_mp(), GMP_RNDN); + return result; +} +*/ +inline mpfr::mpreal ldexp(const mpfr::mpreal& v, int e) +{ + return mpfr::ldexp(v, static_cast(e)); +} + +inline mpfr::mpreal frexp(const mpfr::mpreal& v, int* expon) +{ + mp_exp_t e; + mpfr::mpreal r = mpfr::frexp(v, &e); + *expon = e; + return r; +} + +#if (MPFR_VERSION < MPFR_VERSION_NUM(2,4,0)) +mpfr::mpreal fmod(const mpfr::mpreal& v1, const mpfr::mpreal& v2) +{ + mpfr::mpreal n; + if(v1 < 0) + n = ceil(v1 / v2); + else + n = floor(v1 / v2); + return v1 - n * v2; +} +#endif + +template +inline mpfr::mpreal modf(const mpfr::mpreal& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - boost::math::tools::real_cast(*ipart); +} +template +inline int iround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline long lround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline long long llround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline int itrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +template +inline long ltrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +template +inline long long lltrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +} + +namespace boost{ namespace math{ + +#if defined(__GNUC__) && (__GNUC__ < 4) + using ::iround; + using ::lround; + using ::llround; + using ::itrunc; + using ::ltrunc; + using ::lltrunc; + using ::modf; +#endif + +namespace lanczos{ + +struct mpreal_lanczos +{ + static mpfr::mpreal lanczos_sum(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static mpfr::mpreal lanczos_sum_expG_scaled(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static mpfr::mpreal lanczos_sum_near_1(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static mpfr::mpreal lanczos_sum_near_2(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static mpfr::mpreal g() + { + unsigned long p = mpfr::mpreal::get_default_prec(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef mpreal_lanczos type; +}; + +} // namespace lanczos + +namespace tools +{ + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + return mpfr::mpreal::get_default_prec(); +} + +namespace detail{ + +template(t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline mpfr::mpreal real_cast(long long t) +{ + mpfr::mpreal result; + int expon = 0; + int sign = 1; + if(t < 0) + { + sign = -1; + t = -t; + } + while(t) + { + result += ldexp(static_cast(t & 0xffffL), expon); + expon += 32; + t >>= 32; + } + return result * sign; +} +/* +template <> +inline unsigned real_cast(mpfr::mpreal t) +{ + return t.get_ui(); +} +template <> +inline int real_cast(mpfr::mpreal t) +{ + return t.get_si(); +} +template <> +inline double real_cast(mpfr::mpreal t) +{ + return t.get_d(); +} +template <> +inline float real_cast(mpfr::mpreal t) +{ + return static_cast(t.get_d()); +} +template <> +inline long real_cast(mpfr::mpreal t) +{ + long result; + detail::convert_to_long_result(t, result); + return result; +} +*/ +template <> +inline long long real_cast(mpfr::mpreal t) +{ + long long result; + detail::convert_to_long_result(t, result); + return result; +} + +template <> +inline mpfr::mpreal max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val(0.5); + if(!has_init) + { + val = ldexp(val, mpfr_get_emax()); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val(0.5); + if(!has_init) + { + val = ldexp(val, mpfr_get_emin()); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + return ldexp(mpfr::mpreal(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +template +inline mpfr::mpreal skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal skewness can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("1.1395470994046486574927930193898461120875997958366"); +} + +template +inline mpfr::mpreal skewness(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal skewness can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("0.63111065781893713819189935154422777984404221106391"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 2 * root_pi() * pi_minus_three() / pow23_four_minus_pi(); +} + +template +inline mpfr::mpreal kurtosis(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal kurtosis can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("3.2450893006876380628486604106197544154170667057995"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 3 - (6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} + +template +inline mpfr::mpreal kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + //using namespace boost::math::constants; + // Computed using NTL at 150 bit, about 50 decimal digits. + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal excess kurtosis can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("0.2450893006876380628486604106197544154170667057995"); + // return -(6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} // kurtosis + +namespace detail{ + +// +// Version of Digamma accurate to ~100 decimal digits. +// +template +mpfr::mpreal digamma_imp(mpfr::mpreal x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // empfr_classor handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + mpfr::mpreal result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + mpfr::mpreal remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} +// +// Specialisations of this function provides the initial +// starting guess for Halley iteration: +// +template +mpfr::mpreal erf_inv_imp(const mpfr::mpreal& p, const mpfr::mpreal& q, const Policy&, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + mpfr::mpreal result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute empfr_classor compared to |Y|. + // + // double: Max empfr_classor found: 2.001849e-18 + // long double: Max empfr_classor found: 1.017064e-20 + // Maximum Deviation Found (actual empfr_classor term at infinite precision) 8.030e-21 + // + static const float Y = 0.0891314744949340820313f; + static const mpfr::mpreal P[] = { + -0.000508781949658280665617, + -0.00836874819741736770379, + 0.0334806625409744615033, + -0.0126926147662974029034, + -0.0365637971411762664006, + 0.0219878681111168899165, + 0.00822687874676915743155, + -0.00538772965071242932965 + }; + static const mpfr::mpreal Q[] = { + 1, + -0.970005043303290640362, + -1.56574558234175846809, + 1.56221558398423026363, + 0.662328840472002992063, + -0.71228902341542847553, + -0.0527396382340099713954, + 0.0795283687341571680018, + -0.00233393759374190016776, + 0.000886216390456424707504 + }; + mpfr::mpreal g = p * (p + 10); + mpfr::mpreal r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute empfr_classor compared to Y. + // + // double : Max empfr_classor found: 7.403372e-17 + // long double : Max empfr_classor found: 6.084616e-20 + // Maximum Deviation Found (empfr_classor term) 4.811e-20 + // + static const float Y = 2.249481201171875f; + static const mpfr::mpreal P[] = { + -0.202433508355938759655, + 0.105264680699391713268, + 8.37050328343119927838, + 17.6447298408374015486, + -18.8510648058714251895, + -44.6382324441786960818, + 17.445385985570866523, + 21.1294655448340526258, + -3.67192254707729348546 + }; + static const mpfr::mpreal Q[] = { + 1, + 6.24264124854247537712, + 3.9713437953343869095, + -28.6608180499800029974, + -20.1432634680485188801, + 48.5609213108739935468, + 10.8268667355460159008, + -22.6436933413139721736, + 1.72114765761200282724 + }; + mpfr::mpreal g = sqrt(-2 * log(q)); + mpfr::mpreal xs = q - 0.25; + mpfr::mpreal r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute empfr_classor compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + mpfr::mpreal x = sqrt(-log(q)); + if(x < 3) + { + // Max empfr_classor found: 1.089051e-20 + static const float Y = 0.807220458984375f; + static const mpfr::mpreal P[] = { + -0.131102781679951906451, + -0.163794047193317060787, + 0.117030156341995252019, + 0.387079738972604337464, + 0.337785538912035898924, + 0.142869534408157156766, + 0.0290157910005329060432, + 0.00214558995388805277169, + -0.679465575181126350155e-6, + 0.285225331782217055858e-7, + -0.681149956853776992068e-9 + }; + static const mpfr::mpreal Q[] = { + 1, + 3.46625407242567245975, + 5.38168345707006855425, + 4.77846592945843778382, + 2.59301921623620271374, + 0.848854343457902036425, + 0.152264338295331783612, + 0.01105924229346489121 + }; + mpfr::mpreal xs = x - 1.125; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // Max empfr_classor found: 8.389174e-21 + static const float Y = 0.93995571136474609375f; + static const mpfr::mpreal P[] = { + -0.0350353787183177984712, + -0.00222426529213447927281, + 0.0185573306514231072324, + 0.00950804701325919603619, + 0.00187123492819559223345, + 0.000157544617424960554631, + 0.460469890584317994083e-5, + -0.230404776911882601748e-9, + 0.266339227425782031962e-11 + }; + static const mpfr::mpreal Q[] = { + 1, + 1.3653349817554063097, + 0.762059164553623404043, + 0.220091105764131249824, + 0.0341589143670947727934, + 0.00263861676657015992959, + 0.764675292302794483503e-4 + }; + mpfr::mpreal xs = x - 3; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // Max empfr_classor found: 1.481312e-19 + static const float Y = 0.98362827301025390625f; + static const mpfr::mpreal P[] = { + -0.0167431005076633737133, + -0.00112951438745580278863, + 0.00105628862152492910091, + 0.000209386317487588078668, + 0.149624783758342370182e-4, + 0.449696789927706453732e-6, + 0.462596163522878599135e-8, + -0.281128735628831791805e-13, + 0.99055709973310326855e-16 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.591429344886417493481, + 0.138151865749083321638, + 0.0160746087093676504695, + 0.000964011807005165528527, + 0.275335474764726041141e-4, + 0.282243172016108031869e-6 + }; + mpfr::mpreal xs = x - 6; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // Max empfr_classor found: 5.697761e-20 + static const float Y = 0.99714565277099609375f; + static const mpfr::mpreal P[] = { + -0.0024978212791898131227, + -0.779190719229053954292e-5, + 0.254723037413027451751e-4, + 0.162397777342510920873e-5, + 0.396341011304801168516e-7, + 0.411632831190944208473e-9, + 0.145596286718675035587e-11, + -0.116765012397184275695e-17 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.207123112214422517181, + 0.0169410838120975906478, + 0.000690538265622684595676, + 0.145007359818232637924e-4, + 0.144437756628144157666e-6, + 0.509761276599778486139e-9 + }; + mpfr::mpreal xs = x - 18; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // Max empfr_classor found: 1.279746e-20 + static const float Y = 0.99941349029541015625f; + static const mpfr::mpreal P[] = { + -0.000539042911019078575891, + -0.28398759004727721098e-6, + 0.899465114892291446442e-6, + 0.229345859265920864296e-7, + 0.225561444863500149219e-9, + 0.947846627503022684216e-12, + 0.135880130108924861008e-14, + -0.348890393399948882918e-21 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.0845746234001899436914, + 0.00282092984726264681981, + 0.468292921940894236786e-4, + 0.399968812193862100054e-6, + 0.161809290887904476097e-8, + 0.231558608310259605225e-11 + }; + mpfr::mpreal xs = x - 44; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +inline mpfr::mpreal bessel_i0(mpfr::mpreal x) +{ + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(x) == 0, "mpreal bessel_i0 can not be calculated in standalone mode"); + #endif + + static const mpfr::mpreal P1[] = { + boost::lexical_cast("-2.2335582639474375249e+15"), + boost::lexical_cast("-5.5050369673018427753e+14"), + boost::lexical_cast("-3.2940087627407749166e+13"), + boost::lexical_cast("-8.4925101247114157499e+11"), + boost::lexical_cast("-1.1912746104985237192e+10"), + boost::lexical_cast("-1.0313066708737980747e+08"), + boost::lexical_cast("-5.9545626019847898221e+05"), + boost::lexical_cast("-2.4125195876041896775e+03"), + boost::lexical_cast("-7.0935347449210549190e+00"), + boost::lexical_cast("-1.5453977791786851041e-02"), + boost::lexical_cast("-2.5172644670688975051e-05"), + boost::lexical_cast("-3.0517226450451067446e-08"), + boost::lexical_cast("-2.6843448573468483278e-11"), + boost::lexical_cast("-1.5982226675653184646e-14"), + boost::lexical_cast("-5.2487866627945699800e-18"), + }; + static const mpfr::mpreal Q1[] = { + boost::lexical_cast("-2.2335582639474375245e+15"), + boost::lexical_cast("7.8858692566751002988e+12"), + boost::lexical_cast("-1.2207067397808979846e+10"), + boost::lexical_cast("1.0377081058062166144e+07"), + boost::lexical_cast("-4.8527560179962773045e+03"), + boost::lexical_cast("1.0"), + }; + static const mpfr::mpreal P2[] = { + boost::lexical_cast("-2.2210262233306573296e-04"), + boost::lexical_cast("1.3067392038106924055e-02"), + boost::lexical_cast("-4.4700805721174453923e-01"), + boost::lexical_cast("5.5674518371240761397e+00"), + boost::lexical_cast("-2.3517945679239481621e+01"), + boost::lexical_cast("3.1611322818701131207e+01"), + boost::lexical_cast("-9.6090021968656180000e+00"), + }; + static const mpfr::mpreal Q2[] = { + boost::lexical_cast("-5.5194330231005480228e-04"), + boost::lexical_cast("3.2547697594819615062e-02"), + boost::lexical_cast("-1.1151759188741312645e+00"), + boost::lexical_cast("1.3982595353892851542e+01"), + boost::lexical_cast("-6.0228002066743340583e+01"), + boost::lexical_cast("8.5539563258012929600e+01"), + boost::lexical_cast("-3.1446690275135491500e+01"), + boost::lexical_cast("1.0"), + }; + mpfr::mpreal value, factor, r; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (x < 0) + { + x = -x; // even function + } + if (x == 0) + { + return static_cast(1); + } + if (x <= 15) // x in (0, 15] + { + mpfr::mpreal y = x * x; + value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + } + else // x in (15, \infty) + { + mpfr::mpreal y = 1 / x - mpfr::mpreal(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(x) / sqrt(x); + value = factor * r; + } + + return value; +} + +inline mpfr::mpreal bessel_i1(mpfr::mpreal x) +{ + static const mpfr::mpreal P1[] = { + static_cast("-1.4577180278143463643e+15"), + static_cast("-1.7732037840791591320e+14"), + static_cast("-6.9876779648010090070e+12"), + static_cast("-1.3357437682275493024e+11"), + static_cast("-1.4828267606612366099e+09"), + static_cast("-1.0588550724769347106e+07"), + static_cast("-5.1894091982308017540e+04"), + static_cast("-1.8225946631657315931e+02"), + static_cast("-4.7207090827310162436e-01"), + static_cast("-9.1746443287817501309e-04"), + static_cast("-1.3466829827635152875e-06"), + static_cast("-1.4831904935994647675e-09"), + static_cast("-1.1928788903603238754e-12"), + static_cast("-6.5245515583151902910e-16"), + static_cast("-1.9705291802535139930e-19"), + }; + static const mpfr::mpreal Q1[] = { + static_cast("-2.9154360556286927285e+15"), + static_cast("9.7887501377547640438e+12"), + static_cast("-1.4386907088588283434e+10"), + static_cast("1.1594225856856884006e+07"), + static_cast("-5.1326864679904189920e+03"), + static_cast("1.0"), + }; + static const mpfr::mpreal P2[] = { + static_cast("1.4582087408985668208e-05"), + static_cast("-8.9359825138577646443e-04"), + static_cast("2.9204895411257790122e-02"), + static_cast("-3.4198728018058047439e-01"), + static_cast("1.3960118277609544334e+00"), + static_cast("-1.9746376087200685843e+00"), + static_cast("8.5591872901933459000e-01"), + static_cast("-6.0437159056137599999e-02"), + }; + static const mpfr::mpreal Q2[] = { + static_cast("3.7510433111922824643e-05"), + static_cast("-2.2835624489492512649e-03"), + static_cast("7.4212010813186530069e-02"), + static_cast("-8.5017476463217924408e-01"), + static_cast("3.2593714889036996297e+00"), + static_cast("-3.8806586721556593450e+00"), + static_cast("1.0"), + }; + mpfr::mpreal value, factor, r, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 15) // w in (0, 15] + { + mpfr::mpreal y = x * x; + r = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + factor = w; + value = factor * r; + } + else // w in (15, \infty) + { + mpfr::mpreal y = 1 / w - mpfr::mpreal(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(w) / sqrt(w); + value = factor * r; + } + + if (x < 0) + { + value *= -value; // odd function + } + return value; +} + +} // namespace detail +} // namespace math + +} + +#endif // BOOST_MATH_MPLFR_BINDINGS_HPP + diff --git a/third-party/boost-math/include/boost/math/bindings/rr.hpp b/third-party/boost-math/include/boost/math/bindings/rr.hpp new file mode 100644 index 0000000000000..6cd73b838faae --- /dev/null +++ b/third-party/boost-math/include/boost/math/bindings/rr.hpp @@ -0,0 +1,876 @@ +// Copyright John Maddock 2007. +// 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) + +#ifndef BOOST_MATH_NTL_RR_HPP +#define BOOST_MATH_NTL_RR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace ntl +{ + +class RR; + +RR ldexp(RR r, int exp); +RR frexp(RR r, int* exp); + +class RR +{ +public: + // Constructors: + RR() {} + RR(const ::NTL::RR& c) : m_value(c){} + RR(char c) + { + m_value = c; + } + RR(wchar_t c) + { + m_value = c; + } + RR(unsigned char c) + { + m_value = c; + } + RR(signed char c) + { + m_value = c; + } + RR(unsigned short c) + { + m_value = c; + } + RR(short c) + { + m_value = c; + } + RR(unsigned int c) + { + assign_large_int(c); + } + RR(int c) + { + assign_large_int(c); + } + RR(unsigned long c) + { + assign_large_int(c); + } + RR(long c) + { + assign_large_int(c); + } + RR(unsigned long long c) + { + assign_large_int(c); + } + RR(long long c) + { + assign_large_int(c); + } + RR(float c) + { + m_value = c; + } + RR(double c) + { + m_value = c; + } + RR(long double c) + { + assign_large_real(c); + } + + // Assignment: + RR& operator=(char c) { m_value = c; return *this; } + RR& operator=(unsigned char c) { m_value = c; return *this; } + RR& operator=(signed char c) { m_value = c; return *this; } + RR& operator=(wchar_t c) { m_value = c; return *this; } + RR& operator=(short c) { m_value = c; return *this; } + RR& operator=(unsigned short c) { m_value = c; return *this; } + RR& operator=(int c) { assign_large_int(c); return *this; } + RR& operator=(unsigned int c) { assign_large_int(c); return *this; } + RR& operator=(long c) { assign_large_int(c); return *this; } + RR& operator=(unsigned long c) { assign_large_int(c); return *this; } + RR& operator=(long long c) { assign_large_int(c); return *this; } + RR& operator=(unsigned long long c) { assign_large_int(c); return *this; } + RR& operator=(float c) { m_value = c; return *this; } + RR& operator=(double c) { m_value = c; return *this; } + RR& operator=(long double c) { assign_large_real(c); return *this; } + + // Access: + NTL::RR& value(){ return m_value; } + NTL::RR const& value()const{ return m_value; } + + // Member arithmetic: + RR& operator+=(const RR& other) + { m_value += other.value(); return *this; } + RR& operator-=(const RR& other) + { m_value -= other.value(); return *this; } + RR& operator*=(const RR& other) + { m_value *= other.value(); return *this; } + RR& operator/=(const RR& other) + { m_value /= other.value(); return *this; } + RR operator-()const + { return -m_value; } + RR const& operator+()const + { return *this; } + + // RR compatibility: + const ::NTL::ZZ& mantissa() const + { return m_value.mantissa(); } + long exponent() const + { return m_value.exponent(); } + + static void SetPrecision(long p) + { ::NTL::RR::SetPrecision(p); } + + static long precision() + { return ::NTL::RR::precision(); } + + static void SetOutputPrecision(long p) + { ::NTL::RR::SetOutputPrecision(p); } + static long OutputPrecision() + { return ::NTL::RR::OutputPrecision(); } + + +private: + ::NTL::RR m_value; + + template + void assign_large_real(const V& a) + { + using std::frexp; + using std::ldexp; + using std::floor; + if (a == 0) { + clear(m_value); + return; + } + + if (a == 1) { + NTL::set(m_value); + return; + } + + if (!(boost::math::isfinite)(a)) + { + throw std::overflow_error("Cannot construct an instance of NTL::RR with an infinite value."); + } + + int e; + long double f, term; + ::NTL::RR t; + clear(m_value); + + f = frexp(a, &e); + + while(f) + { + // extract 30 bits from f: + f = ldexp(f, 30); + term = floor(f); + e -= 30; + conv(t.x, (int)term); + t.e = e; + m_value += t; + f -= term; + } + } + + template + void assign_large_int(V a) + { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4146) +#endif + clear(m_value); + int exp = 0; + NTL::RR t; + bool neg = a < V(0) ? true : false; + if(neg) + a = -a; + while(a) + { + t = static_cast(a & 0xffff); + m_value += ldexp(RR(t), exp).value(); + a >>= 16; + exp += 16; + } + if(neg) + m_value = -m_value; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } +}; + +// Non-member arithmetic: +inline RR operator+(const RR& a, const RR& b) +{ + RR result(a); + result += b; + return result; +} +inline RR operator-(const RR& a, const RR& b) +{ + RR result(a); + result -= b; + return result; +} +inline RR operator*(const RR& a, const RR& b) +{ + RR result(a); + result *= b; + return result; +} +inline RR operator/(const RR& a, const RR& b) +{ + RR result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const RR& a, const RR& b) +{ return a.value() == b.value() ? true : false; } +inline bool operator != (const RR& a, const RR& b) +{ return a.value() != b.value() ? true : false;} +inline bool operator < (const RR& a, const RR& b) +{ return a.value() < b.value() ? true : false; } +inline bool operator <= (const RR& a, const RR& b) +{ return a.value() <= b.value() ? true : false; } +inline bool operator > (const RR& a, const RR& b) +{ return a.value() > b.value() ? true : false; } +inline bool operator >= (const RR& a, const RR& b) +{ return a.value() >= b.value() ? true : false; } + +#if 0 +// Non-member mixed compare: +template +inline bool operator == (const T& a, const RR& b) +{ + return a == b.value(); +} +template +inline bool operator != (const T& a, const RR& b) +{ + return a != b.value(); +} +template +inline bool operator < (const T& a, const RR& b) +{ + return a < b.value(); +} +template +inline bool operator > (const T& a, const RR& b) +{ + return a > b.value(); +} +template +inline bool operator <= (const T& a, const RR& b) +{ + return a <= b.value(); +} +template +inline bool operator >= (const T& a, const RR& b) +{ + return a >= b.value(); +} +#endif // Non-member mixed compare: + +// Non-member functions: +/* +inline RR acos(RR a) +{ return ::NTL::acos(a.value()); } +*/ +inline RR cos(RR a) +{ return ::NTL::cos(a.value()); } +/* +inline RR asin(RR a) +{ return ::NTL::asin(a.value()); } +inline RR atan(RR a) +{ return ::NTL::atan(a.value()); } +inline RR atan2(RR a, RR b) +{ return ::NTL::atan2(a.value(), b.value()); } +*/ +inline RR ceil(RR a) +{ return ::NTL::ceil(a.value()); } +/* +inline RR fmod(RR a, RR b) +{ return ::NTL::fmod(a.value(), b.value()); } +inline RR cosh(RR a) +{ return ::NTL::cosh(a.value()); } +*/ +inline RR exp(RR a) +{ return ::NTL::exp(a.value()); } +inline RR fabs(RR a) +{ return ::NTL::fabs(a.value()); } +inline RR abs(RR a) +{ return ::NTL::abs(a.value()); } +inline RR floor(RR a) +{ return ::NTL::floor(a.value()); } +/* +inline RR modf(RR a, RR* ipart) +{ + ::NTL::RR ip; + RR result = modf(a.value(), &ip); + *ipart = ip; + return result; +} +inline RR frexp(RR a, int* expon) +{ return ::NTL::frexp(a.value(), expon); } +inline RR ldexp(RR a, int expon) +{ return ::NTL::ldexp(a.value(), expon); } +*/ +inline RR log(RR a) +{ return ::NTL::log(a.value()); } +inline RR log10(RR a) +{ return ::NTL::log10(a.value()); } +/* +inline RR tan(RR a) +{ return ::NTL::tan(a.value()); } +*/ +inline RR pow(RR a, RR b) +{ return ::NTL::pow(a.value(), b.value()); } +inline RR pow(RR a, int b) +{ return ::NTL::power(a.value(), b); } +inline RR sin(RR a) +{ return ::NTL::sin(a.value()); } +/* +inline RR sinh(RR a) +{ return ::NTL::sinh(a.value()); } +*/ +inline RR sqrt(RR a) +{ return ::NTL::sqrt(a.value()); } +/* +inline RR tanh(RR a) +{ return ::NTL::tanh(a.value()); } +*/ + inline RR pow(const RR& r, long l) + { + return ::NTL::power(r.value(), l); + } + inline RR tan(const RR& a) + { + return sin(a)/cos(a); + } + inline RR frexp(RR r, int* exp) + { + *exp = r.value().e; + r.value().e = 0; + while(r >= 1) + { + *exp += 1; + r.value().e -= 1; + } + while(r < 0.5) + { + *exp -= 1; + r.value().e += 1; + } + BOOST_MATH_ASSERT(r < 1); + BOOST_MATH_ASSERT(r >= 0.5); + return r; + } + inline RR ldexp(RR r, int exp) + { + r.value().e += exp; + return r; + } + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const RR& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, RR& a) +{ + ::NTL::RR v; + is >> v; + a = v; + return is; +} + +} // namespace ntl + +namespace lanczos{ + +struct ntl_lanczos +{ + static ntl::RR lanczos_sum(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static ntl::RR lanczos_sum_expG_scaled(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static ntl::RR lanczos_sum_near_1(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static ntl::RR lanczos_sum_near_2(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static ntl::RR g() + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef ntl_lanczos type; +}; + +} // namespace lanczos + +namespace tools +{ + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + return ::NTL::RR::precision(); +} + +template <> +inline float real_cast(boost::math::ntl::RR t) +{ + double r; + conv(r, t.value()); + return static_cast(r); +} +template <> +inline double real_cast(boost::math::ntl::RR t) +{ + double r; + conv(r, t.value()); + return r; +} + +namespace detail{ + +template +void convert_to_long_result(NTL::RR const& r, Integer& result) +{ + result = 0; + I last_result(0); + NTL::RR t(r); + double term; + do + { + conv(term, t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline long double real_cast(boost::math::ntl::RR t) +{ + long double result(0); + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline boost::math::ntl::RR real_cast(boost::math::ntl::RR t) +{ + return t; +} +template <> +inline unsigned real_cast(boost::math::ntl::RR t) +{ + unsigned result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline int real_cast(boost::math::ntl::RR t) +{ + int result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline long real_cast(boost::math::ntl::RR t) +{ + long result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline long long real_cast(boost::math::ntl::RR t) +{ + long long result; + detail::convert_to_long_result(t.value(), result); + return result; +} + +template <> +inline boost::math::ntl::RR max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = NTL_OVFBND-20; + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = -NTL_OVFBND+20; + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = NTL_OVFBND-20; + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = -NTL_OVFBND+20; + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + return ldexp(boost::math::ntl::RR(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +// +// The number of digits precision in RR can vary with each call +// so we need to recalculate these with each call: +// +namespace constants{ + +template<> inline boost::math::ntl::RR pi(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + NTL::RR result; + ComputePi(result); + return result; +} +template<> inline boost::math::ntl::RR e(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + NTL::RR result; + result = 1; + return exp(result); +} + +} // namespace constants + +namespace ntl{ + // + // These are some fairly brain-dead versions of the math + // functions that NTL fails to provide. + // + + + // + // Inverse trig functions: + // + struct asin_root + { + asin_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR f0 = sin(p); + RR f1 = cos(p); + RR f2 = -f0; + f0 -= t; + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR asin(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + asin_root(z), + RR(std::asin(r)), + RR(-boost::math::constants::pi()/2), + RR(boost::math::constants::pi()/2), + NTL::RR::precision()); + } + + struct acos_root + { + acos_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR f0 = cos(p); + RR f1 = -sin(p); + RR f2 = -f0; + f0 -= t; + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR acos(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + acos_root(z), + RR(std::acos(r)), + RR(-boost::math::constants::pi()/2), + RR(boost::math::constants::pi()/2), + NTL::RR::precision()); + } + + struct atan_root + { + atan_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR c = cos(p); + RR ta = tan(p); + RR f0 = ta - t; + RR f1 = 1 / (c * c); + RR f2 = 2 * ta / (c * c); + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR atan(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + atan_root(z), + RR(std::atan(r)), + -boost::math::constants::pi()/2, + boost::math::constants::pi()/2, + NTL::RR::precision()); + } + + inline RR atan2(RR y, RR x) + { + if(x > 0) + return atan(y / x); + if(x < 0) + { + return y < 0 ? atan(y / x) - boost::math::constants::pi() : atan(y / x) + boost::math::constants::pi(); + } + return y < 0 ? -boost::math::constants::half_pi() : boost::math::constants::half_pi() ; + } + + inline RR sinh(RR z) + { + return (expm1(z.value()) - expm1(-z.value())) / 2; + } + + inline RR cosh(RR z) + { + return (exp(z) + exp(-z)) / 2; + } + + inline RR tanh(RR z) + { + return sinh(z) / cosh(z); + } + + inline RR fmod(RR x, RR y) + { + // This is a really crummy version of fmod, we rely on lots + // of digits to get us out of trouble... + RR factor = floor(x/y); + return x - factor * y; + } + + template + inline int iround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline long lround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline long long llround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline int itrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + + template + inline long ltrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + + template + inline long long lltrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + +} // namespace ntl + +namespace detail{ + +template +ntl::RR digamma_imp(ntl::RR x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + ntl::RR result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + ntl::RR remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} + +} // namespace detail + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_REAL_CONCEPT_HPP + + diff --git a/third-party/boost-math/include/boost/math/ccmath/abs.hpp b/third-party/boost-math/include/boost/math/ccmath/abs.hpp new file mode 100644 index 0000000000000..db59502ab62dd --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/abs.hpp @@ -0,0 +1,89 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constepxr implementation of abs (see c.math.abs secion 26.8.2 of the ISO standard) + +#ifndef BOOST_MATH_CCMATH_ABS +#define BOOST_MATH_CCMATH_ABS + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T abs_impl(T x) noexcept +{ + if ((boost::math::ccmath::isnan)(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (x == static_cast(-0)) + { + return static_cast(0); + } + + if constexpr (std::is_integral_v) + { + BOOST_MATH_ASSERT(x != (std::numeric_limits::min)()); + } + + return x >= 0 ? x : -x; +} + +} // Namespace detail + +template , bool> = true> +constexpr T abs(T x) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return detail::abs_impl(x); + } + else + { + using std::abs; + return abs(x); + } +} + +// If abs() is called with an argument of type X for which is_unsigned_v is true and if X +// cannot be converted to int by integral promotion (7.3.7), the program is ill-formed. +template , bool> = true> +constexpr T abs(T x) noexcept +{ + if constexpr (std::is_convertible_v) + { + return detail::abs_impl(static_cast(x)); + } + else + { + static_assert(sizeof(T) == 0, "Taking the absolute value of an unsigned value not convertible to int is UB."); + return T(0); // Unreachable, but suppresses warnings + } +} + +constexpr long int labs(long int j) noexcept +{ + return boost::math::ccmath::abs(j); +} + +constexpr long long int llabs(long long int j) noexcept +{ + return boost::math::ccmath::abs(j); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ABS diff --git a/third-party/boost-math/include/boost/math/ccmath/ccmath.hpp b/third-party/boost-math/include/boost/math/ccmath/ccmath.hpp new file mode 100644 index 0000000000000..f075eac96899c --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/ccmath.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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) +// + +#ifndef BOOST_MATH_CCMATH_HPP +#define BOOST_MATH_CCMATH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_MATH_CCMATH_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/ceil.hpp b/third-party/boost-math/include/boost/math/ccmath/ceil.hpp new file mode 100644 index 0000000000000..bc264a0be0c3d --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/ceil.hpp @@ -0,0 +1,78 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_CEIL_HPP +#define BOOST_MATH_CCMATH_CEIL_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T ceil_impl(T arg) noexcept +{ + T result = boost::math::ccmath::floor(arg); + + if(result == arg) + { + return result; + } + else + { + return result + 1; + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real ceil(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::ceil_impl(arg); + } + else + { + using std::ceil; + return ceil(arg); + } +} + +template , bool> = true> +inline constexpr double ceil(Z arg) noexcept +{ + return boost::math::ccmath::ceil(static_cast(arg)); +} + +inline constexpr float ceilf(float arg) noexcept +{ + return boost::math::ccmath::ceil(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double ceill(long double arg) noexcept +{ + return boost::math::ccmath::ceil(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_CEIL_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/copysign.hpp b/third-party/boost-math/include/boost/math/ccmath/copysign.hpp new file mode 100644 index 0000000000000..e117e57faa23c --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/copysign.hpp @@ -0,0 +1,81 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_COPYSIGN_HPP +#define BOOST_MATH_CCMATH_COPYSIGN_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T copysign_impl(const T mag, const T sgn) noexcept +{ + if (boost::math::ccmath::signbit(sgn)) + { + return -boost::math::ccmath::abs(mag); + } + else + { + return boost::math::ccmath::abs(mag); + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real copysign(Real mag, Real sgn) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(mag)) + { + return boost::math::ccmath::detail::copysign_impl(mag, sgn); + } + else + { + using std::copysign; + return copysign(mag, sgn); + } +} + +template +constexpr auto copysign(T1 mag, T2 sgn) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(mag)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::copysign(static_cast(mag), static_cast(sgn)); + } + else + { + using std::copysign; + return copysign(mag, sgn); + } +} + +constexpr float copysignf(float mag, float sgn) noexcept +{ + return boost::math::ccmath::copysign(mag, sgn); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double copysignl(long double mag, long double sgn) noexcept +{ + return boost::math::ccmath::copysign(mag, sgn); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_COPYSIGN_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/detail/config.hpp b/third-party/boost-math/include/boost/math/ccmath/detail/config.hpp new file mode 100644 index 0000000000000..097d69a16bd3d --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/detail/config.hpp @@ -0,0 +1,52 @@ +// (C) Copyright John Maddock 2023. +// 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) +// +// Core configuration for ccmath functions, basically will they work or not? + +#ifndef BOOST_MATH_CCMATH_DETAIL_CONFIG +#define BOOST_MATH_CCMATH_DETAIL_CONFIG + +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE + +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +# define BOOST_MATH_NO_CCMATH +#endif + +#else // BOOST_MATH_STANDALONE + +#if defined(_MSC_VER) + +#if defined(_MSVC_LANG) && (_MSVC_LANG < 201703) +# define BOOST_MATH_NO_CCMATH +#endif + +#else // _MSC_VER + +#if (__cplusplus < 201703) +# define BOOST_MATH_NO_CCMATH +#endif + +#endif + +#endif + +#ifndef _MSC_VER +// +// Don't check here for msvc as they didn't get std lib configuration macros at the same time as C++17 +// +#if (defined(__cpp_lib_bool_constant) && __cpp_lib_bool_constant < 201505L) && !defined(BOOST_MATH_NO_CCMATH) +# define BOOST_MATH_NO_CCMATH +#endif +#endif + + +#endif diff --git a/third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp b/third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp new file mode 100644 index 0000000000000..ccca9601ceee0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp @@ -0,0 +1,21 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_DETAIL_SWAP_HPP +#define BOOST_MATH_CCMATH_DETAIL_SWAP_HPP + +namespace boost::math::ccmath::detail { + +template +inline constexpr void swap(T& x, T& y) noexcept +{ + T temp = x; + x = y; + y = temp; +} + +} + +#endif // BOOST_MATH_CCMATH_DETAIL_SWAP_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/div.hpp b/third-party/boost-math/include/boost/math/ccmath/div.hpp new file mode 100644 index 0000000000000..613a22f3f524a --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/div.hpp @@ -0,0 +1,86 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_DIV_HPP +#define BOOST_MATH_CCMATH_DIV_HPP + +#include +#include +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr ReturnType div_impl(const Z x, const Z y) noexcept +{ + // std::div_t/ldiv_t/lldiv_t/imaxdiv_t can be defined as either { Z quot; Z rem; }; or { Z rem; Z quot; }; + // so don't use braced initialization to guarantee compatibility + ReturnType ans {0, 0}; + + ans.quot = x / y; + ans.rem = x % y; + + return ans; +} + +} // Namespace detail + +// Used for types other than built-ins (e.g. boost multiprecision) +template +struct div_t +{ + Z quot; + Z rem; +}; + +template +inline constexpr auto div(Z x, Z y) noexcept +{ + if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else + { + return detail::div_impl>(x, y); + } +} + +inline constexpr std::ldiv_t ldiv(long x, long y) noexcept +{ + return detail::div_impl(x, y); +} + +inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept +{ + return detail::div_impl(x, y); +} + +inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept +{ + return detail::div_impl(x, y); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_DIV_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fabs.hpp b/third-party/boost-math/include/boost/math/ccmath/fabs.hpp new file mode 100644 index 0000000000000..02191db3d1a4a --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fabs.hpp @@ -0,0 +1,41 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constepxr implementation of fabs (see c.math.abs secion 26.8.2 of the ISO standard) + +#ifndef BOOST_MATH_CCMATH_FABS +#define BOOST_MATH_CCMATH_FABS + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr auto fabs(T x) noexcept +{ + return boost::math::ccmath::abs(x); +} + +inline constexpr float fabsf(float x) noexcept +{ + return boost::math::ccmath::abs(x); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double fabsl(long double x) noexcept +{ + return boost::math::ccmath::abs(x); +} +#endif + +} + +#endif // BOOST_MATH_CCMATH_FABS diff --git a/third-party/boost-math/include/boost/math/ccmath/fdim.hpp b/third-party/boost-math/include/boost/math/ccmath/fdim.hpp new file mode 100644 index 0000000000000..d6b4e25cec2e0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fdim.hpp @@ -0,0 +1,93 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_FDIM_HPP +#define BOOST_MATH_CCMATH_FDIM_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fdim_impl(const T x, const T y) noexcept +{ + if (x <= y) + { + return 0; + } + else if ((y < 0) && (x > (std::numeric_limits::max)() + y)) + { + return std::numeric_limits::infinity(); + } + else + { + return x - y; + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fdim(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::fdim_impl(x, y); + } + else + { + using std::fdim; + return fdim(x, y); + } +} + +template +constexpr auto fdim(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::fdim(promoted_type(x), promoted_type(y)); + } + else + { + using std::fdim; + return fdim(x, y); + } +} + +constexpr float fdimf(float x, float y) noexcept +{ + return boost::math::ccmath::fdim(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fdiml(long double x, long double y) noexcept +{ + return boost::math::ccmath::fdim(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FDIM_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/floor.hpp b/third-party/boost-math/include/boost/math/ccmath/floor.hpp new file mode 100644 index 0000000000000..5afed7d0ca23d --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/floor.hpp @@ -0,0 +1,131 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_FLOOR_HPP +#define BOOST_MATH_CCMATH_FLOOR_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T floor_pos_impl(T arg) noexcept +{ + constexpr auto max_comp_val = T(1) / std::numeric_limits::epsilon(); + + if (arg >= max_comp_val) + { + return arg; + } + + T result = 1; + + if(result <= arg) + { + while(result < arg) + { + result *= 2; + } + while(result > arg) + { + --result; + } + + return result; + } + else + { + return T(0); + } +} + +template +inline constexpr T floor_neg_impl(T arg) noexcept +{ + T result = -1; + + if(result > arg) + { + while(result > arg) + { + result *= 2; + } + while(result < arg) + { + ++result; + } + if(result != arg) + { + --result; + } + } + + return result; +} + +template +inline constexpr T floor_impl(T arg) noexcept +{ + if(arg > 0) + { + return floor_pos_impl(arg); + } + else + { + return floor_neg_impl(arg); + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real floor(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::floor_impl(arg); + } + else + { + using std::floor; + return floor(arg); + } +} + +template , bool> = true> +inline constexpr double floor(Z arg) noexcept +{ + return boost::math::ccmath::floor(static_cast(arg)); +} + +inline constexpr float floorf(float arg) noexcept +{ + return boost::math::ccmath::floor(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double floorl(long double arg) noexcept +{ + return boost::math::ccmath::floor(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_FLOOR_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fma.hpp b/third-party/boost-math/include/boost/math/ccmath/fma.hpp new file mode 100644 index 0000000000000..c4d16c8ae5e65 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fma.hpp @@ -0,0 +1,130 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_FMA_HPP +#define BOOST_MATH_CCMATH_FMA_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fma_imp(const T x, const T y, const T z) noexcept +{ + #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) + if constexpr (std::is_same_v) + { + return __builtin_fmaf(x, y, z); + } + else if constexpr (std::is_same_v) + { + return __builtin_fma(x, y, z); + } + else if constexpr (std::is_same_v) + { + return __builtin_fmal(x, y, z); + } + #endif + + // If we can't use compiler intrinsics hope that -fma flag optimizes this call to fma instruction + return (x * y) + z; +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fma(Real x, Real y, Real z) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (x == 0 && boost::math::ccmath::isinf(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (y == 0 && boost::math::ccmath::isinf(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(z)) + { + return std::numeric_limits::quiet_NaN(); + } + + return boost::math::ccmath::detail::fma_imp(x, y, z); + } + else + { + using std::fma; + return fma(x, y, z); + } +} + +template +constexpr auto fma(T1 x, T2 y, T3 z) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T3p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>>>; + #else + >>>; + #endif + + return boost::math::ccmath::fma(promoted_type(x), promoted_type(y), promoted_type(z)); + } + else + { + using std::fma; + return fma(x, y, z); + } +} + +constexpr float fmaf(float x, float y, float z) noexcept +{ + return boost::math::ccmath::fma(x, y, z); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fmal(long double x, long double y, long double z) noexcept +{ + return boost::math::ccmath::fma(x, y, z); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMA_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fmax.hpp b/third-party/boost-math/include/boost/math/ccmath/fmax.hpp new file mode 100644 index 0000000000000..8a0d17d03ea8b --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fmax.hpp @@ -0,0 +1,89 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_FMAX_HPP +#define BOOST_MATH_CCMATH_FMAX_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fmax_impl(const T x, const T y) noexcept +{ + if (x > y) + { + return x; + } + else + { + return y; + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fmax(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x)) + { + return y; + } + else if (boost::math::ccmath::isnan(y)) + { + return x; + } + + return boost::math::ccmath::detail::fmax_impl(x, y); + } + else + { + using std::fmax; + return fmax(x, y); + } +} + +template +constexpr auto fmax(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::fmax(static_cast(x), static_cast(y)); + } + else + { + using std::fmax; + return fmax(x, y); + } +} + +constexpr float fmaxf(float x, float y) noexcept +{ + return boost::math::ccmath::fmax(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fmaxl(long double x, long double y) noexcept +{ + return boost::math::ccmath::fmax(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMAX_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fmin.hpp b/third-party/boost-math/include/boost/math/ccmath/fmin.hpp new file mode 100644 index 0000000000000..29885b69c8ac1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fmin.hpp @@ -0,0 +1,89 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_FMIN_HPP +#define BOOST_MATH_CCMATH_FMIN_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fmin_impl(const T x, const T y) noexcept +{ + if (x < y) + { + return x; + } + else + { + return y; + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fmin(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x)) + { + return y; + } + else if (boost::math::ccmath::isnan(y)) + { + return x; + } + + return boost::math::ccmath::detail::fmin_impl(x, y); + } + else + { + using std::fmin; + return fmin(x, y); + } +} + +template +constexpr auto fmin(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::fmin(static_cast(x), static_cast(y)); + } + else + { + using std::fmin; + return fmin(x, y); + } +} + +constexpr float fminf(float x, float y) noexcept +{ + return boost::math::ccmath::fmin(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fminl(long double x, long double y) noexcept +{ + return boost::math::ccmath::fmin(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMIN_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fmod.hpp b/third-party/boost-math/include/boost/math/ccmath/fmod.hpp new file mode 100644 index 0000000000000..ba61cc95a2c72 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fmod.hpp @@ -0,0 +1,114 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_FMOD_HPP +#define BOOST_MATH_CCMATH_FMOD_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fmod_impl(T x, T y) +{ + if (x == y) + { + return static_cast(0); + } + else + { + while (x >= y) + { + x -= y; + } + + return static_cast(x); + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fmod(Real x, Real y) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::abs(x) == static_cast(0) && y != static_cast(0)) + { + return x; + } + else if (boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::abs(y) == static_cast(0) && !boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isinf(y) && boost::math::ccmath::isfinite(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::fmod_impl(x, y); + } + else + { + using std::fmod; + return fmod(x, y); + } +} + +template +constexpr auto fmod(T1 x, T2 y) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::fmod(promoted_type(x), promoted_type(y)); + } + else + { + using std::fmod; + return fmod(x, y); + } +} + +constexpr float fmodf(float x, float y) +{ + return boost::math::ccmath::fmod(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fmodl(long double x, long double y) +{ + return boost::math::ccmath::fmod(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_FMOD_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp b/third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp new file mode 100644 index 0000000000000..ce0728a277870 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp @@ -0,0 +1,48 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_FPCLASSIFY +#define BOOST_MATH_CCMATH_FPCLASSIFY + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template , bool> = true> +inline constexpr int fpclassify BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return (boost::math::ccmath::isnan)(x) ? FP_NAN : + (boost::math::ccmath::isinf)(x) ? FP_INFINITE : + boost::math::ccmath::abs(x) == T(0) ? FP_ZERO : + boost::math::ccmath::abs(x) > 0 && boost::math::ccmath::abs(x) < (std::numeric_limits::min)() ? FP_SUBNORMAL : FP_NORMAL; + } + else + { + using boost::math::fpclassify; + return (fpclassify)(x); + } +} + +template , bool> = true> +inline constexpr int fpclassify(Z x) +{ + return boost::math::ccmath::fpclassify(static_cast(x)); +} + +} + +#endif // BOOST_MATH_CCMATH_FPCLASSIFY diff --git a/third-party/boost-math/include/boost/math/ccmath/frexp.hpp b/third-party/boost-math/include/boost/math/ccmath/frexp.hpp new file mode 100644 index 0000000000000..6c200cb6411db --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/frexp.hpp @@ -0,0 +1,101 @@ +// (C) Copyright Christopher Kormanyos 1999 - 2021. +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_FREXP_HPP +#define BOOST_MATH_CCMATH_FREXP_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail +{ + +template +inline constexpr Real frexp_zero_impl(Real arg, int* exp) +{ + *exp = 0; + return arg; +} + +template +inline constexpr Real frexp_impl(Real arg, int* exp) +{ + const bool negative_arg = (arg < Real(0)); + + Real f = negative_arg ? -arg : arg; + int e2 = 0; + constexpr Real two_pow_32 = Real(4294967296); + + while (f >= two_pow_32) + { + f = f / two_pow_32; + e2 += 32; + } + + while(f >= Real(1)) + { + f = f / Real(2); + ++e2; + } + + if(exp != nullptr) + { + *exp = e2; + } + + return !negative_arg ? f : -f; +} + +} // namespace detail + +template , bool> = true> +inline constexpr Real frexp(Real arg, int* exp) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return arg == Real(0) ? detail::frexp_zero_impl(arg, exp) : + arg == Real(-0) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::isinf(arg) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::isnan(arg) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::detail::frexp_impl(arg, exp); + } + else + { + using std::frexp; + return frexp(arg, exp); + } +} + +template , bool> = true> +inline constexpr double frexp(Z arg, int* exp) +{ + return boost::math::ccmath::frexp(static_cast(arg), exp); +} + +inline constexpr float frexpf(float arg, int* exp) +{ + return boost::math::ccmath::frexp(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double frexpl(long double arg, int* exp) +{ + return boost::math::ccmath::frexp(arg, exp); +} +#endif + +} + +#endif // BOOST_MATH_CCMATH_FREXP_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/hypot.hpp b/third-party/boost-math/include/boost/math/ccmath/hypot.hpp new file mode 100644 index 0000000000000..34dd5ab2c0a86 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/hypot.hpp @@ -0,0 +1,116 @@ +// (C) Copyright John Maddock 2005-2021. +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_HYPOT_HPP +#define BOOST_MATH_CCMATH_HYPOT_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T hypot_impl(T x, T y) noexcept +{ + x = boost::math::ccmath::abs(x); + y = boost::math::ccmath::abs(y); + + if (y > x) + { + boost::math::ccmath::detail::swap(x, y); + } + + if(x * std::numeric_limits::epsilon() >= y) + { + return x; + } + + T rat = y / x; + return x * boost::math::ccmath::sqrt(1 + rat * rat); +} + +} // Namespace detail + +template , bool> = true> +constexpr Real hypot(Real x, Real y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::abs(x) == static_cast(0)) + { + return boost::math::ccmath::abs(y); + } + else if (boost::math::ccmath::abs(y) == static_cast(0)) + { + return boost::math::ccmath::abs(x); + } + // Return +inf even if the other argument is NaN + else if (boost::math::ccmath::isinf(x) || boost::math::ccmath::isinf(y)) + { + return std::numeric_limits::infinity(); + } + else if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::hypot_impl(x, y); + } + else + { + using std::hypot; + return hypot(x, y); + } +} + +template +constexpr auto hypot(T1 x, T2 y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::hypot(static_cast(x), static_cast(y)); + } + else + { + using std::hypot; + return hypot(x, y); + } +} + +constexpr float hypotf(float x, float y) noexcept +{ + return boost::math::ccmath::hypot(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double hypotl(long double x, long double y) noexcept +{ + return boost::math::ccmath::hypot(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_HYPOT_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/ilogb.hpp b/third-party/boost-math/include/boost/math/ccmath/ilogb.hpp new file mode 100644 index 0000000000000..6ec6fca9aac44 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/ilogb.hpp @@ -0,0 +1,60 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_ILOGB_HPP +#define BOOST_MATH_CCMATH_ILOGB_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +// If arg is not zero, infinite, or NaN, the value returned is exactly equivalent to static_cast(std::logb(arg)) +template , bool> = true> +inline constexpr int ilogb(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? FP_ILOGB0 : + boost::math::ccmath::isinf(arg) ? INT_MAX : + boost::math::ccmath::isnan(arg) ? FP_ILOGBNAN : + static_cast(boost::math::ccmath::logb(arg)); + } + else + { + using std::ilogb; + return ilogb(arg); + } +} + +template , bool> = true> +inline constexpr int ilogb(Z arg) noexcept +{ + return boost::math::ccmath::ilogb(static_cast(arg)); +} + +inline constexpr int ilogbf(float arg) noexcept +{ + return boost::math::ccmath::ilogb(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr int ilogbl(long double arg) noexcept +{ + return boost::math::ccmath::ilogb(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ILOGB_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/isfinite.hpp b/third-party/boost-math/include/boost/math/ccmath/isfinite.hpp new file mode 100644 index 0000000000000..328742ccad700 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isfinite.hpp @@ -0,0 +1,53 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISFINITE +#define BOOST_MATH_CCMATH_ISFINITE + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isfinite(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // bool isfinite (IntegralType arg) is a set of overloads accepting the arg argument of any integral type + // equivalent to casting the integral argument arg to double (e.g. static_cast(arg)) + if constexpr (std::is_integral_v) + { + return !boost::math::ccmath::isinf(static_cast(x)) && !boost::math::ccmath::isnan(static_cast(x)); + } + else + { + return !boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(x); + } + } + else + { + using std::isfinite; + + if constexpr (!std::is_integral_v) + { + return isfinite(x); + } + else + { + return isfinite(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISFINITE diff --git a/third-party/boost-math/include/boost/math/ccmath/isgreater.hpp b/third-party/boost-math/include/boost/math/ccmath/isgreater.hpp new file mode 100644 index 0000000000000..7b29f9bffee17 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isgreater.hpp @@ -0,0 +1,42 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISGREATER_HPP +#define BOOST_MATH_CCMATH_ISGREATER_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isgreater(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x > y; + } + } + else + { + using std::isgreater; + return isgreater(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISGREATER_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp b/third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp new file mode 100644 index 0000000000000..d6586a95d82f9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp @@ -0,0 +1,42 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISGREATEREQUAL_HPP +#define BOOST_MATH_CCMATH_ISGREATEREQUAL_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isgreaterequal(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x >= y; + } + } + else + { + using std::isgreaterequal; + return isgreaterequal(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISGREATEREQUAL_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/isinf.hpp b/third-party/boost-math/include/boost/math/ccmath/isinf.hpp new file mode 100644 index 0000000000000..f1b0e7c726bb1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isinf.hpp @@ -0,0 +1,61 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISINF +#define BOOST_MATH_CCMATH_ISINF + +#include +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +namespace boost::math::ccmath { + +template +constexpr bool isinf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if constexpr (std::numeric_limits::is_signed) + { +#if defined(__clang_major__) && __clang_major__ >= 6 +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wtautological-constant-compare" +# if defined(__has_warning) +# if __has_warning("-Wnan-infinity-disabled") +# pragma clang diagnostic ignored "-Wnan-infinity-disabled" +# endif +# endif +#endif + return x == std::numeric_limits::infinity() || -x == std::numeric_limits::infinity(); +#if defined(__clang_major__) && __clang_major__ >= 6 +#pragma clang diagnostic pop +#endif + } + else + { + return x == std::numeric_limits::infinity(); + } + } + else + { + using boost::math::isinf; + + if constexpr (!std::is_integral_v) + { + return (isinf)(x); + } + else + { + return (isinf)(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISINF diff --git a/third-party/boost-math/include/boost/math/ccmath/isless.hpp b/third-party/boost-math/include/boost/math/ccmath/isless.hpp new file mode 100644 index 0000000000000..bf923e6f807b8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isless.hpp @@ -0,0 +1,42 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISLESS_HPP +#define BOOST_MATH_CCMATH_ISLESS_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isless(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x < y; + } + } + else + { + using std::isless; + return isless(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISLESS_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/islessequal.hpp b/third-party/boost-math/include/boost/math/ccmath/islessequal.hpp new file mode 100644 index 0000000000000..075d4cad674ef --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/islessequal.hpp @@ -0,0 +1,42 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISLESSEQUAL_HPP +#define BOOST_MATH_CCMATH_ISLESSEQUAL_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool islessequal(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x <= y; + } + } + else + { + using std::islessequal; + return islessequal(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISLESSEQUAL_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/isnan.hpp b/third-party/boost-math/include/boost/math/ccmath/isnan.hpp new file mode 100644 index 0000000000000..753f2079b2a64 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isnan.hpp @@ -0,0 +1,42 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISNAN +#define BOOST_MATH_CCMATH_ISNAN + +#include +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +namespace boost::math::ccmath { + +template +inline constexpr bool isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return x != x; + } + else + { + using boost::math::isnan; + + if constexpr (!std::is_integral_v) + { + return (isnan)(x); + } + else + { + return (isnan)(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISNAN diff --git a/third-party/boost-math/include/boost/math/ccmath/isnormal.hpp b/third-party/boost-math/include/boost/math/ccmath/isnormal.hpp new file mode 100644 index 0000000000000..cf5a4d1536778 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isnormal.hpp @@ -0,0 +1,47 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_ISNORMAL_HPP +#define BOOST_MATH_ISNORMAL_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isnormal(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return x == T(0) ? false : + boost::math::ccmath::isinf(x) ? false : + boost::math::ccmath::isnan(x) ? false : + boost::math::ccmath::abs(x) < (std::numeric_limits::min)() ? false : true; + } + else + { + using std::isnormal; + + if constexpr (!std::is_integral_v) + { + return isnormal(x); + } + else + { + return isnormal(static_cast(x)); + } + } +} +} + +#endif // BOOST_MATH_ISNORMAL_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/isunordered.hpp b/third-party/boost-math/include/boost/math/ccmath/isunordered.hpp new file mode 100644 index 0000000000000..9d55db0d38bee --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/isunordered.hpp @@ -0,0 +1,35 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_ISUNORDERED_HPP +#define BOOST_MATH_CCMATH_ISUNORDERED_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isunordered(const T x, const T y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y); + } + else + { + using std::isunordered; + return isunordered(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISUNORDERED_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/ldexp.hpp b/third-party/boost-math/include/boost/math/ccmath/ldexp.hpp new file mode 100644 index 0000000000000..3e2cd3610fee4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/ldexp.hpp @@ -0,0 +1,81 @@ +// (C) Copyright Matt Borland 2021. +// (C) Copyright John Maddock 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_LDEXP_HPP +#define BOOST_MATH_CCMATH_LDEXP_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real ldexp_impl(Real arg, int exp) noexcept +{ + while(exp > 0) + { + arg *= 2; + --exp; + } + while(exp < 0) + { + arg /= 2; + ++exp; + } + + return arg; +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real ldexp(Real arg, int exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + (boost::math::ccmath::isinf)(arg) ? arg : + (boost::math::ccmath::isnan)(arg) ? arg : + boost::math::ccmath::detail::ldexp_impl(arg, exp); + } + else + { + using std::ldexp; + return ldexp(arg, exp); + } +} + +template , bool> = true> +inline constexpr double ldexp(Z arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(static_cast(arg), exp); +} + +inline constexpr float ldexpf(float arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double ldexpl(long double arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_LDEXP_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/logb.hpp b/third-party/boost-math/include/boost/math/ccmath/logb.hpp new file mode 100644 index 0000000000000..9a0c4a1c022a8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/logb.hpp @@ -0,0 +1,86 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_LOGB_HPP +#define BOOST_MATH_CCMATH_LOGB_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// The value of the exponent returned by std::logb is always 1 less than the exponent returned by +// std::frexp because of the different normalization requirements: for the exponent e returned by std::logb, +// |arg*r^-e| is between 1 and r (typically between 1 and 2), but for the exponent e returned by std::frexp, +// |arg*2^-e| is between 0.5 and 1. +template +constexpr T logb_impl(T arg) noexcept +{ + int exp = 0; + boost::math::ccmath::frexp(arg, &exp); + + return static_cast(exp - 1); +} + +} // Namespace detail + +template , bool> = true> +constexpr Real logb(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + if (boost::math::ccmath::abs(arg) == Real(0)) + { + return -std::numeric_limits::infinity(); + } + else if (boost::math::ccmath::isinf(arg)) + { + return std::numeric_limits::infinity(); + } + else if (boost::math::ccmath::isnan(arg)) + { + return arg; + } + + return boost::math::ccmath::detail::logb_impl(arg); + } + else + { + using std::logb; + return logb(arg); + } +} + +template , bool> = true> +constexpr double logb(Z arg) noexcept +{ + return boost::math::ccmath::logb(static_cast(arg)); +} + +constexpr float logbf(float arg) noexcept +{ + return boost::math::ccmath::logb(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double logbl(long double arg) noexcept +{ + return boost::math::ccmath::logb(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_LOGB_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/modf.hpp b/third-party/boost-math/include/boost/math/ccmath/modf.hpp new file mode 100644 index 0000000000000..87b6a4b5081d9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/modf.hpp @@ -0,0 +1,79 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_MODF_HPP +#define BOOST_MATH_CCMATH_MODF_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real modf_error_impl(Real x, Real* iptr) +{ + *iptr = x; + return boost::math::ccmath::abs(x) == Real(0) ? x : + x > Real(0) ? Real(0) : -Real(0); +} + +template +inline constexpr Real modf_nan_impl(Real x, Real* iptr) +{ + *iptr = x; + return x; +} + +template +inline constexpr Real modf_impl(Real x, Real* iptr) +{ + *iptr = boost::math::ccmath::trunc(x); + return (x - *iptr); +} + +} // Namespace detail + +template +inline constexpr Real modf(Real x, Real* iptr) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::abs(x) == Real(0) ? detail::modf_error_impl(x, iptr) : + boost::math::ccmath::isinf(x) ? detail::modf_error_impl(x, iptr) : + boost::math::ccmath::isnan(x) ? detail::modf_nan_impl(x, iptr) : + boost::math::ccmath::detail::modf_impl(x, iptr); + } + else + { + using std::modf; + return modf(x, iptr); + } +} + +inline constexpr float modff(float x, float* iptr) +{ + return boost::math::ccmath::modf(x, iptr); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double modfl(long double x, long double* iptr) +{ + return boost::math::ccmath::modf(x, iptr); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_MODF_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/next.hpp b/third-party/boost-math/include/boost/math/ccmath/next.hpp new file mode 100644 index 0000000000000..f03fe5cfa8a9e --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/next.hpp @@ -0,0 +1,458 @@ +// (C) Copyright John Maddock 2008 - 2022. +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_NEXT_HPP +#define BOOST_MATH_CCMATH_NEXT_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// Forward Declarations +template > +constexpr result_type float_prior(const T& val); + +template > +constexpr result_type float_next(const T& val); + +template +struct has_hidden_guard_digits; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +#ifdef BOOST_HAS_FLOAT128 +template <> +struct has_hidden_guard_digits<__float128> : public std::false_type {}; +#endif + +template +struct has_hidden_guard_digits_10 : public std::false_type {}; +template +struct has_hidden_guard_digits_10 : public std::integral_constant::digits10 != std::numeric_limits::max_digits10)> {}; + +template +struct has_hidden_guard_digits + : public has_hidden_guard_digits_10::is_specialized + && (std::numeric_limits::radix == 10) > +{}; + +template +constexpr T normalize_value(const T& val, const std::false_type&) { return val; } +template +constexpr T normalize_value(const T& val, const std::true_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + std::intmax_t shift = static_cast(std::numeric_limits::digits) - static_cast(boost::math::ccmath::ilogb(val)) - 1; + T result = boost::math::ccmath::scalbn(val, shift); + result = boost::math::ccmath::round(result); + return boost::math::ccmath::scalbn(result, -shift); +} + +template +constexpr T get_smallest_value(const std::true_type&) +{ + // + // numeric_limits lies about denorms being present - particularly + // when this can be turned on or off at runtime, as is the case + // when using the SSE2 registers in DAZ or FTZ mode. + // + constexpr T m = std::numeric_limits::denorm_min(); + return ((tools::min_value() / 2) == 0) ? tools::min_value() : m; +} + +template +constexpr T get_smallest_value(const std::false_type&) +{ + return tools::min_value(); +} + +template +constexpr T get_smallest_value() +{ + return get_smallest_value(std::integral_constant::is_specialized>()); +} + +template +constexpr T calc_min_shifted(const std::true_type&) +{ + return boost::math::ccmath::ldexp(tools::min_value(), tools::digits() + 1); +} + +template +constexpr T calc_min_shifted(const std::false_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + return boost::math::ccmath::scalbn(tools::min_value(), std::numeric_limits::digits + 1); +} + +template +constexpr T get_min_shift_value() +{ + const T val = calc_min_shifted(std::integral_constant::is_specialized || std::numeric_limits::radix == 2>()); + return val; +} + +template > +struct exponent_type +{ + using type = int; +}; + +template +struct exponent_type +{ + using type = typename T::backend_type::exponent_type; +}; + +template > +using exponent_type_t = typename exponent_type::type; + +template +constexpr T float_next_imp(const T& val, const std::true_type&) +{ + using exponent_type = exponent_type_t; + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::ldexp(boost::math::ccmath::detail::float_next(static_cast(boost::math::ccmath::ldexp(val, 2 * tools::digits()))), -2 * tools::digits()); + } + + if (-0.5f == boost::math::ccmath::frexp(val, &expon)) + { + --expon; // reduce exponent when val is a power of two, and negative. + } + T diff = boost::math::ccmath::ldexp(static_cast(1), expon - tools::digits()); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + return val + diff; +} + +// +// Special version for some base other than 2: +// +template +constexpr T float_next_imp(const T& val, const std::false_type&) +{ + using exponent_type = exponent_type_t; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::scalbn(boost::math::ccmath::detail::float_next(static_cast(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits::digits))), -2 * std::numeric_limits::digits); + } + + expon = 1 + boost::math::ccmath::ilogb(val); + if(-1 == boost::math::ccmath::scalbn(val, -expon) * std::numeric_limits::radix) + { + --expon; // reduce exponent when val is a power of base, and negative. + } + + T diff = boost::math::ccmath::scalbn(static_cast(1), expon - std::numeric_limits::digits); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + + return val + diff; +} + +template +constexpr result_type float_next(const T& val) +{ + return detail::float_next_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>()); +} + +template +constexpr T float_prior_imp(const T& val, const std::true_type&) +{ + using exponent_type = exponent_type_t; + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return -detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::ldexp(boost::math::ccmath::detail::float_prior(static_cast(boost::math::ccmath::ldexp(val, 2 * tools::digits()))), -2 * tools::digits()); + } + + if(T remain = boost::math::ccmath::frexp(val, &expon); remain == 0.5f) + { + --expon; // when val is a power of two we must reduce the exponent + } + + T diff = boost::math::ccmath::ldexp(static_cast(1), expon - tools::digits()); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + + return val - diff; +} + +// +// Special version for bases other than 2: +// +template +constexpr T float_prior_imp(const T& val, const std::false_type&) +{ + using exponent_type = exponent_type_t; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return -detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::scalbn(boost::math::ccmath::detail::float_prior(static_cast(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits::digits))), -2 * std::numeric_limits::digits); + } + + expon = 1 + boost::math::ccmath::ilogb(val); + + if (T remain = boost::math::ccmath::scalbn(val, -expon); remain * std::numeric_limits::radix == 1) + { + --expon; // when val is a power of two we must reduce the exponent + } + + T diff = boost::math::ccmath::scalbn(static_cast(1), expon - std::numeric_limits::digits); + if (diff == 0) + { + diff = detail::get_smallest_value(); + } + return val - diff; +} // float_prior_imp + +template +constexpr result_type float_prior(const T& val) +{ + return detail::float_prior_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>()); +} + +} // namespace detail + +template > +constexpr result_type nextafter(const T& val, const U& direction) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(val)) + { + if (boost::math::ccmath::isnan(val)) + { + return val; + } + else if (boost::math::ccmath::isnan(direction)) + { + return direction; + } + else if (val < direction) + { + return boost::math::ccmath::detail::float_next(val); + } + else if (val == direction) + { + // IEC 60559 recommends that from is returned whenever from == to. These functions return to instead, + // which makes the behavior around zero consistent: std::nextafter(-0.0, +0.0) returns +0.0 and + // std::nextafter(+0.0, -0.0) returns -0.0. + return direction; + } + + return boost::math::ccmath::detail::float_prior(val); + } + else + { + using std::nextafter; + return nextafter(static_cast(val), static_cast(direction)); + } +} + +constexpr float nextafterf(float val, float direction) +{ + return boost::math::ccmath::nextafter(val, direction); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + +constexpr long double nextafterl(long double val, long double direction) +{ + return boost::math::ccmath::nextafter(val, direction); +} + +template , typename return_type = std::conditional_t, double, T>> +constexpr return_type nexttoward(T val, long double direction) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(val)) + { + return static_cast(boost::math::ccmath::nextafter(static_cast(val), direction)); + } + else + { + using std::nexttoward; + return nexttoward(val, direction); + } +} + +constexpr float nexttowardf(float val, long double direction) +{ + return boost::math::ccmath::nexttoward(val, direction); +} + +constexpr long double nexttowardl(long double val, long double direction) +{ + return boost::math::ccmath::nexttoward(val, direction); +} + +#endif + +} // Namespaces + +#endif // BOOST_MATH_SPECIAL_NEXT_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/remainder.hpp b/third-party/boost-math/include/boost/math/ccmath/remainder.hpp new file mode 100644 index 0000000000000..b57420b87910d --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/remainder.hpp @@ -0,0 +1,106 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_REMAINDER_HPP +#define BOOST_MATH_CCMATH_REMAINDER_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T remainder_impl(const T x, const T y) +{ + T n = 0; + + if (T fractional_part = boost::math::ccmath::modf((x / y), &n); fractional_part > static_cast(1.0/2)) + { + ++n; + } + else if (fractional_part < static_cast(-1.0/2)) + { + --n; + } + + return x - n*y; +} + +} // Namespace detail + +template , bool> = true> +constexpr Real remainder(Real x, Real y) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::abs(y) == static_cast(0) && !boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::remainder_impl(x, y); + } + else + { + using std::remainder; + return remainder(x, y); + } +} + +template +constexpr auto remainder(T1 x, T2 y) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::remainder(promoted_type(x), promoted_type(y)); + } + else + { + using std::remainder; + return remainder(x, y); + } +} + +constexpr float remainderf(float x, float y) +{ + return boost::math::ccmath::remainder(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double remainderl(long double x, long double y) +{ + return boost::math::ccmath::remainder(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_REMAINDER_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/round.hpp b/third-party/boost-math/include/boost/math/ccmath/round.hpp new file mode 100644 index 0000000000000..334919e5260b2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/round.hpp @@ -0,0 +1,179 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_ROUND_HPP +#define BOOST_MATH_CCMATH_ROUND_HPP + +#include +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// Computes the nearest integer value to arg (in floating-point format), +// rounding halfway cases away from zero, regardless of the current rounding mode. +template +inline constexpr T round_impl(T arg) noexcept +{ + T iptr = 0; + const T x = boost::math::ccmath::modf(arg, &iptr); + constexpr T half = T(1)/2; + + if(x >= half && iptr > 0) + { + return iptr + 1; + } + else if(boost::math::ccmath::abs(x) >= half && iptr < 0) + { + return iptr - 1; + } + else + { + return iptr; + } +} + +template +inline constexpr ReturnType int_round_impl(T arg) +{ + const T rounded_arg = round_impl(arg); + + if(rounded_arg > static_cast((std::numeric_limits::max)())) + { + if constexpr (std::is_same_v) + { + throw std::domain_error("Rounded value cannot be represented by a long long type without overflow"); + } + else + { + throw std::domain_error("Rounded value cannot be represented by a long type without overflow"); + } + } + else + { + return static_cast(rounded_arg); + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real round(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::round_impl(arg); + } + else + { + using std::round; + return round(arg); + } +} + +template , bool> = true> +inline constexpr double round(Z arg) noexcept +{ + return boost::math::ccmath::round(static_cast(arg)); +} + +inline constexpr float roundf(float arg) noexcept +{ + return boost::math::ccmath::round(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double roundl(long double arg) noexcept +{ + return boost::math::ccmath::round(arg); +} +#endif + +template , bool> = true> +inline constexpr long lround(Real arg) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? 0l : + boost::math::ccmath::isinf(arg) ? 0l : + boost::math::ccmath::isnan(arg) ? 0l : + boost::math::ccmath::detail::int_round_impl(arg); + } + else + { + using std::lround; + return lround(arg); + } +} + +template , bool> = true> +inline constexpr long lround(Z arg) +{ + return boost::math::ccmath::lround(static_cast(arg)); +} + +inline constexpr long lroundf(float arg) +{ + return boost::math::ccmath::lround(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long lroundl(long double arg) +{ + return boost::math::ccmath::lround(arg); +} +#endif + +template , bool> = true> +inline constexpr long long llround(Real arg) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? 0ll : + boost::math::ccmath::isinf(arg) ? 0ll : + boost::math::ccmath::isnan(arg) ? 0ll : + boost::math::ccmath::detail::int_round_impl(arg); + } + else + { + using std::llround; + return llround(arg); + } +} + +template , bool> = true> +inline constexpr long llround(Z arg) +{ + return boost::math::ccmath::llround(static_cast(arg)); +} + +inline constexpr long long llroundf(float arg) +{ + return boost::math::ccmath::llround(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long long llroundl(long double arg) +{ + return boost::math::ccmath::llround(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ROUND_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/scalbln.hpp b/third-party/boost-math/include/boost/math/ccmath/scalbln.hpp new file mode 100644 index 0000000000000..2321f14c891bf --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/scalbln.hpp @@ -0,0 +1,60 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_SCALBLN_HPP +#define BOOST_MATH_CCMATH_SCALBLN_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template , bool> = true> +inline constexpr Real scalbln(Real arg, long exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::scalbn_impl(arg, exp); + } + else + { + using std::scalbln; + return scalbln(arg, exp); + } +} + +template , bool> = true> +inline constexpr double scalbln(Z arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(static_cast(arg), exp); +} + +inline constexpr float scalblnf(float arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double scalblnl(long double arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SCALBLN_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/scalbn.hpp b/third-party/boost-math/include/boost/math/ccmath/scalbn.hpp new file mode 100644 index 0000000000000..20268225259f1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/scalbn.hpp @@ -0,0 +1,81 @@ +// (C) Copyright Matt Borland 2021. +// (C) Copyright John Maddock 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_SCALBN_HPP +#define BOOST_MATH_CCMATH_SCALBN_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real scalbn_impl(Real arg, Z exp) noexcept +{ + while(exp > 0) + { + arg *= FLT_RADIX; + --exp; + } + while(exp < 0) + { + arg /= FLT_RADIX; + ++exp; + } + + return arg; +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real scalbn(Real arg, int exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::scalbn_impl(arg, exp); + } + else + { + using std::scalbn; + return scalbn(arg, exp); + } +} + +template , bool> = true> +inline constexpr double scalbn(Z arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(static_cast(arg), exp); +} + +inline constexpr float scalbnf(float arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double scalbnl(long double arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SCALBN_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/signbit.hpp b/third-party/boost-math/include/boost/math/ccmath/signbit.hpp new file mode 100644 index 0000000000000..bb12a5b618f7e --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/signbit.hpp @@ -0,0 +1,219 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_CCMATH_SIGNBIT_HPP +#define BOOST_MATH_CCMATH_SIGNBIT_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include + +#ifdef __has_include +# if __has_include() +# include +# if __cpp_lib_bit_cast >= 201806L +# define BOOST_MATH_BIT_CAST(T, x) std::bit_cast(x) +# endif +# elif defined(__has_builtin) +# if __has_builtin(__builtin_bit_cast) +# define BOOST_MATH_BIT_CAST(T, x) __builtin_bit_cast(T, x) +# endif +# endif +#endif + +/* +The following error is given using Apple Clang version 13.1.6, and Clang 13, and 14 on Ubuntu 22.04.01 +TODO: Remove the following undef when Apple Clang supports + +ccmath_signbit_test.cpp:32:19: error: static_assert expression is not an integral constant expression + static_assert(boost::math::ccmath::signbit(T(-1)) == true); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../../../boost/math/ccmath/signbit.hpp:62:24: note: constexpr bit_cast involving bit-field is not yet supported + const auto u = BOOST_MATH_BIT_CAST(float_bits, arg); + ^ +../../../boost/math/ccmath/signbit.hpp:20:37: note: expanded from macro 'BOOST_MATH_BIT_CAST' +# define BOOST_MATH_BIT_CAST(T, x) __builtin_bit_cast(T, x) + ^ +*/ + +#if defined(__clang__) && defined(BOOST_MATH_BIT_CAST) +# undef BOOST_MATH_BIT_CAST +#endif + +namespace boost::math::ccmath { + +namespace detail { + +#ifdef BOOST_MATH_BIT_CAST + +struct IEEEf2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa : 23; + std::uint32_t exponent : 8; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 8; + std::uint32_t mantissa : 23; +#endif +}; + +struct IEEEd2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 20; + std::uint32_t exponent : 11; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 11; + std::uint32_t mantissa_h : 20; + std::uint32_t mantissa_l : 32; +#endif +}; + +// 80 bit long double +#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 32; + std::uint32_t exponent : 15; + std::uint32_t sign : 1; + std::uint32_t pad : 32; +#else // Big endian + std::uint32_t pad : 32; + std::uint32_t sign : 1; + std::uint32_t exponent : 15; + std::uint32_t mantissa_h : 32; + std::uint32_t mantissa_l : 32; +#endif +}; + +// 128 bit long double +#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint64_t mantissa_l : 64; + std::uint64_t mantissa_h : 48; + std::uint32_t exponent : 15; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 15; + std::uint64_t mantissa_h : 48; + std::uint64_t mantissa_l : 64; +#endif +}; + +// 64 bit long double (double == long double on ARM) +#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 20; + std::uint32_t exponent : 11; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 11; + std::uint32_t mantissa_h : 20; + std::uint32_t mantissa_l : 32; +#endif +}; + +#else // Unsupported long double representation +# define BOOST_MATH_UNSUPPORTED_LONG_DOUBLE +#endif + +template +constexpr bool signbit_impl(T arg) +{ + if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEf2bits, arg); + return u.sign; + } + else if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEd2bits, arg); + return u.sign; + } + #ifndef BOOST_MATH_UNSUPPORTED_LONG_DOUBLE + else if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEl2bits, arg); + return u.sign; + } + #endif + else + { + BOOST_MATH_ASSERT_MSG(!boost::math::ccmath::isnan(arg), "NAN is not supported with this type or platform"); + BOOST_MATH_ASSERT_MSG(boost::math::ccmath::abs(arg) != 0, "Signed 0 is not support with this type or platform"); + + return arg < static_cast(0); + } +} + +#else + +// Typical implementations of signbit involve type punning via union and manipulating +// overflow (see libc++ or musl). Neither of these are allowed in constexpr contexts +// (technically type punning via union in general is UB in c++ but well defined in C) +// therefore we static assert these cases. + +template +constexpr bool signbit_impl(T arg) +{ + BOOST_MATH_ASSERT_MSG(!boost::math::ccmath::isnan(arg), "NAN is not supported without __builtin_bit_cast or std::bit_cast"); + BOOST_MATH_ASSERT_MSG(boost::math::ccmath::abs(arg) != 0, "Signed 0 is not support without __builtin_bit_cast or std::bit_cast"); + + return arg < static_cast(0); +} + +#endif + +} + +// Return value: true if arg is negative, false if arg is 0, NAN, or positive +template , bool> = true> +constexpr bool signbit(Real arg) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::detail::signbit_impl(arg); + } + else + { + using std::signbit; + return signbit(arg); + } +} + +template , bool> = true> +constexpr bool signbit(Z arg) +{ + return boost::math::ccmath::signbit(static_cast(arg)); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SIGNBIT_HPP diff --git a/third-party/boost-math/include/boost/math/ccmath/sqrt.hpp b/third-party/boost-math/include/boost/math/ccmath/sqrt.hpp new file mode 100644 index 0000000000000..36396107003d9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/sqrt.hpp @@ -0,0 +1,80 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constexpr implementation of sqrt function + +#ifndef BOOST_MATH_CCMATH_SQRT +#define BOOST_MATH_CCMATH_SQRT + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr Real sqrt_impl_2(Real x, Real s, Real s2) +{ + return !(s < s2) ? s2 : sqrt_impl_2(x, (x / s + s) / 2, s); +} + +template +constexpr Real sqrt_impl_1(Real x, Real s) +{ + return sqrt_impl_2(x, (x / s + s) / 2, s); +} + +template +constexpr Real sqrt_impl(Real x) +{ + return sqrt_impl_1(x, x > 1 ? x : Real(1)); +} + +} // namespace detail + +template , bool> = true> +constexpr Real sqrt(Real x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || + (boost::math::ccmath::isinf(x) && x > 0) || + boost::math::ccmath::abs(x) == Real(0)) + { + return x; + } + // Domain error is implementation defined so return NAN + else if (boost::math::ccmath::isinf(x) && x < 0) + { + return std::numeric_limits::quiet_NaN(); + } + + return detail::sqrt_impl(x); + } + else + { + using std::sqrt; + return sqrt(x); + } +} + +template , bool> = true> +constexpr double sqrt(Z x) +{ + return detail::sqrt_impl(static_cast(x)); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SQRT diff --git a/third-party/boost-math/include/boost/math/ccmath/trunc.hpp b/third-party/boost-math/include/boost/math/ccmath/trunc.hpp new file mode 100644 index 0000000000000..7d30fd8b4cbf0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/ccmath/trunc.hpp @@ -0,0 +1,70 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_CCMATH_TRUNC_HPP +#define BOOST_MATH_CCMATH_TRUNC_HPP + +#include + +#ifdef BOOST_MATH_NO_CCMATH +#error "The header can only be used in C++17 and later." +#endif + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T trunc_impl(T arg) noexcept +{ + return (arg > 0) ? boost::math::ccmath::floor(arg) : boost::math::ccmath::ceil(arg); +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real trunc(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::trunc_impl(arg); + } + else + { + using std::trunc; + return trunc(arg); + } +} + +template , bool> = true> +inline constexpr double trunc(Z arg) noexcept +{ + return boost::math::ccmath::trunc(static_cast(arg)); +} + +inline constexpr float truncf(float arg) noexcept +{ + return boost::math::ccmath::trunc(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double truncl(long double arg) noexcept +{ + return boost::math::ccmath::trunc(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_TRUNC_HPP diff --git a/third-party/boost-math/include/boost/math/common_factor.hpp b/third-party/boost-math/include/boost/math/common_factor.hpp new file mode 100644 index 0000000000000..71a28ae539050 --- /dev/null +++ b/third-party/boost-math/include/boost/math/common_factor.hpp @@ -0,0 +1,23 @@ +// Boost common_factor.hpp header file -------------------------------------// + +// (C) Copyright Daryle Walker 2001-2002. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_HPP +#define BOOST_MATH_COMMON_FACTOR_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_HPP diff --git a/third-party/boost-math/include/boost/math/common_factor_ct.hpp b/third-party/boost-math/include/boost/math/common_factor_ct.hpp new file mode 100644 index 0000000000000..145d16fdd9bd9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/common_factor_ct.hpp @@ -0,0 +1,34 @@ +// Boost common_factor_ct.hpp header file ----------------------------------// + +// (C) Copyright John Maddock 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP +#define BOOST_MATH_COMMON_FACTOR_CT_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost +{ +namespace math +{ + + using boost::integer::static_gcd; + using boost::integer::static_lcm; + using boost::integer::static_gcd_type; + +} // namespace math +} // namespace boost +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_CT_HPP diff --git a/third-party/boost-math/include/boost/math/common_factor_rt.hpp b/third-party/boost-math/include/boost/math/common_factor_rt.hpp new file mode 100644 index 0000000000000..6cc425437b693 --- /dev/null +++ b/third-party/boost-math/include/boost/math/common_factor_rt.hpp @@ -0,0 +1,30 @@ +// (C) Copyright John Maddock 2017. + +// 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) + +#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP +#define BOOST_MATH_COMMON_FACTOR_RT_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost { + namespace math { + using boost::integer::gcd; + using boost::integer::lcm; + using boost::integer::gcd_range; + using boost::integer::lcm_range; + using boost::integer::gcd_evaluator; + using boost::integer::lcm_evaluator; + } +} +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP diff --git a/third-party/boost-math/include/boost/math/complex.hpp b/third-party/boost-math/include/boost/math/complex.hpp new file mode 100644 index 0000000000000..8d9145edf7f5c --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex.hpp @@ -0,0 +1,32 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_INCLUDED +#define BOOST_MATH_COMPLEX_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ACOS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATAN_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_FABS_INCLUDED +# include +#endif + + +#endif // BOOST_MATH_COMPLEX_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/acos.hpp b/third-party/boost-math/include/boost/math/complex/acos.hpp new file mode 100644 index 0000000000000..91df777414221 --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/acos.hpp @@ -0,0 +1,245 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ACOS_INCLUDED +#define BOOST_MATH_COMPLEX_ACOS_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] std::complex acos(const std::complex& z) +{ + // + // This implementation is a transcription of the pseudo-code in: + // + // "Implementing the Complex Arcsine and Arccosine Functions using Exception Handling." + // T E Hull, Thomas F Fairgrieve and Ping Tak Peter Tang. + // ACM Transactions on Mathematical Software, Vol 23, No 3, Sept 1997. + // + + // + // These static constants should really be in a maths constants library, + // note that we have tweaked a_crossover as per: https://svn.boost.org/trac/boost/ticket/7290 + // + static const T one = static_cast(1); + //static const T two = static_cast(2); + static const T half = static_cast(0.5L); + static const T a_crossover = static_cast(10); + static const T b_crossover = static_cast(0.6417L); + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + // + // Get real and imaginary parts, discard the signs as we can + // figure out the sign of the result later: + // + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + + T real, imag; // these hold our result + + // + // Handle special cases specified by the C99 standard, + // many of these special cases aren't really needed here, + // but doing it this way prevents overflow/underflow arithmetic + // in the main body of the logic, which may trip up some machines: + // + if((boost::math::isinf)(x)) + { + if((boost::math::isinf)(y)) + { + real = quarter_pi; + imag = std::numeric_limits::infinity(); + } + else if((boost::math::isnan)(y)) + { + return std::complex(y, -std::numeric_limits::infinity()); + } + else + { + // y is not infinity or nan: + real = 0; + imag = std::numeric_limits::infinity(); + } + } + else if((boost::math::isnan)(x)) + { + if((boost::math::isinf)(y)) + return std::complex(x, ((boost::math::signbit)(z.imag())) ? std::numeric_limits::infinity() : -std::numeric_limits::infinity()); + return std::complex(x, x); + } + else if((boost::math::isinf)(y)) + { + real = half_pi; + imag = std::numeric_limits::infinity(); + } + else if((boost::math::isnan)(y)) + { + return std::complex((x == 0) ? half_pi : y, y); + } + else + { + // + // What follows is the regular Hull et al code, + // begin with the special case for real numbers: + // + if((y == 0) && (x <= one)) + return std::complex((x == 0) ? half_pi : std::acos(z.real()), (boost::math::changesign)(z.imag())); + // + // Figure out if our input is within the "safe area" identified by Hull et al. + // This would be more efficient with portable floating point exception handling; + // fortunately the quantities M and u identified by Hull et al (figure 3), + // match with the max and min methods of numeric_limits. + // + T safe_max = detail::safe_max(static_cast(8)); + T safe_min = detail::safe_min(static_cast(4)); + + T xp1 = one + x; + T xm1 = x - one; + + if((x < safe_max) && (x > safe_min) && (y < safe_max) && (y > safe_min)) + { + T yy = y * y; + T r = std::sqrt(xp1*xp1 + yy); + T s = std::sqrt(xm1*xm1 + yy); + T a = half * (r + s); + T b = x / a; + + if(b <= b_crossover) + { + real = std::acos(b); + } + else + { + T apx = a + x; + if(x <= one) + { + real = std::atan(std::sqrt(half * apx * (yy /(r + xp1) + (s-xm1)))/x); + } + else + { + real = std::atan((y * std::sqrt(half * (apx/(r + xp1) + apx/(s+xm1))))/x); + } + } + + if(a <= a_crossover) + { + T am1; + if(x < one) + { + am1 = half * (yy/(r + xp1) + yy/(s - xm1)); + } + else + { + am1 = half * (yy/(r + xp1) + (s + xm1)); + } + imag = boost::math::log1p(am1 + std::sqrt(am1 * (a + one))); + } + else + { + imag = std::log(a + std::sqrt(a*a - one)); + } + } + else + { + // + // This is the Hull et al exception handling code from Fig 6 of their paper: + // + if(y <= (std::numeric_limits::epsilon() * std::fabs(xm1))) + { + if(x < one) + { + real = std::acos(x); + imag = y / std::sqrt(xp1*(one-x)); + } + else + { + // This deviates from Hull et al's paper as per https://svn.boost.org/trac/boost/ticket/7290 + if(((std::numeric_limits::max)() / xp1) > xm1) + { + // xp1 * xm1 won't overflow: + real = y / std::sqrt(xm1*xp1); + imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1)); + } + else + { + real = y / x; + imag = log_two + std::log(x); + } + } + } + else if(y <= safe_min) + { + // There is an assumption in Hull et al's analysis that + // if we get here then x == 1. This is true for all "good" + // machines where : + // + // E^2 > 8*sqrt(u); with: + // + // E = std::numeric_limits::epsilon() + // u = (std::numeric_limits::min)() + // + // Hull et al provide alternative code for "bad" machines + // but we have no way to test that here, so for now just assert + // on the assumption: + // + BOOST_MATH_ASSERT(x == 1); + real = std::sqrt(y); + imag = std::sqrt(y); + } + else if(std::numeric_limits::epsilon() * y - one >= x) + { + real = half_pi; + imag = log_two + std::log(y); + } + else if(x > one) + { + real = std::atan(y/x); + T xoy = x/y; + imag = log_two + std::log(y) + half * boost::math::log1p(xoy*xoy); + } + else + { + real = half_pi; + T a = std::sqrt(one + y*y); + imag = half * boost::math::log1p(static_cast(2)*y*(y+a)); + } + } + } + + // + // Finish off by working out the sign of the result: + // + if((boost::math::signbit)(z.real())) + real = s_pi - real; + if(!(boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ACOS_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/acosh.hpp b/third-party/boost-math/include/boost/math/complex/acosh.hpp new file mode 100644 index 0000000000000..c5b52826e521c --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/acosh.hpp @@ -0,0 +1,34 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED +#define BOOST_MATH_COMPLEX_ACOSH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] inline std::complex acosh(const std::complex& z) +{ + // + // We use the relation acosh(z) = +-i acos(z) + // Choosing the sign of multiplier to give real(acosh(z)) >= 0 + // as well as compatibility with C99. + // + std::complex result = boost::math::acos(z); + if(!(boost::math::isnan)(result.imag()) && signbit(result.imag())) + return detail::mult_i(result); + return detail::mult_minus_i(result); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ACOSH_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/asin.hpp b/third-party/boost-math/include/boost/math/complex/asin.hpp new file mode 100644 index 0000000000000..d1fbc2f1646fb --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/asin.hpp @@ -0,0 +1,252 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED +#define BOOST_MATH_COMPLEX_ASIN_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] inline std::complex asin(const std::complex& z) +{ + // + // This implementation is a transcription of the pseudo-code in: + // + // "Implementing the complex Arcsine and Arccosine Functions using Exception Handling." + // T E Hull, Thomas F Fairgrieve and Ping Tak Peter Tang. + // ACM Transactions on Mathematical Software, Vol 23, No 3, Sept 1997. + // + + // + // These static constants should really be in a maths constants library, + // note that we have tweaked the value of a_crossover as per https://svn.boost.org/trac/boost/ticket/7290: + // + static const T one = static_cast(1); + //static const T two = static_cast(2); + static const T half = static_cast(0.5L); + static const T a_crossover = static_cast(10); + static const T b_crossover = static_cast(0.6417L); + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + // + // Get real and imaginary parts, discard the signs as we can + // figure out the sign of the result later: + // + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + T real, imag; // our results + + // + // Begin by handling the special cases for infinities and nan's + // specified in C99, most of this is handled by the regular logic + // below, but handling it as a special case prevents overflow/underflow + // arithmetic which may trip up some machines: + // + if((boost::math::isnan)(x)) + { + if((boost::math::isnan)(y)) + return std::complex(x, x); + if((boost::math::isinf)(y)) + { + real = x; + imag = std::numeric_limits::infinity(); + } + else + return std::complex(x, x); + } + else if((boost::math::isnan)(y)) + { + if(x == 0) + { + real = 0; + imag = y; + } + else if((boost::math::isinf)(x)) + { + real = y; + imag = std::numeric_limits::infinity(); + } + else + return std::complex(y, y); + } + else if((boost::math::isinf)(x)) + { + if((boost::math::isinf)(y)) + { + real = quarter_pi; + imag = std::numeric_limits::infinity(); + } + else + { + real = half_pi; + imag = std::numeric_limits::infinity(); + } + } + else if((boost::math::isinf)(y)) + { + real = 0; + imag = std::numeric_limits::infinity(); + } + else + { + // + // special case for real numbers: + // + if((y == 0) && (x <= one)) + return std::complex(std::asin(z.real()), z.imag()); + // + // Figure out if our input is within the "safe area" identified by Hull et al. + // This would be more efficient with portable floating point exception handling; + // fortunately the quantities M and u identified by Hull et al (figure 3), + // match with the max and min methods of numeric_limits. + // + T safe_max = detail::safe_max(static_cast(8)); + T safe_min = detail::safe_min(static_cast(4)); + + T xp1 = one + x; + T xm1 = x - one; + + if((x < safe_max) && (x > safe_min) && (y < safe_max) && (y > safe_min)) + { + T yy = y * y; + T r = std::sqrt(xp1*xp1 + yy); + T s = std::sqrt(xm1*xm1 + yy); + T a = half * (r + s); + T b = x / a; + + if(b <= b_crossover) + { + real = std::asin(b); + } + else + { + T apx = a + x; + if(x <= one) + { + real = std::atan(x/std::sqrt(half * apx * (yy /(r + xp1) + (s-xm1)))); + } + else + { + real = std::atan(x/(y * std::sqrt(half * (apx/(r + xp1) + apx/(s+xm1))))); + } + } + + if(a <= a_crossover) + { + T am1; + if(x < one) + { + am1 = half * (yy/(r + xp1) + yy/(s - xm1)); + } + else + { + am1 = half * (yy/(r + xp1) + (s + xm1)); + } + imag = boost::math::log1p(am1 + std::sqrt(am1 * (a + one))); + } + else + { + imag = std::log(a + std::sqrt(a*a - one)); + } + } + else + { + // + // This is the Hull et al exception handling code from Fig 3 of their paper: + // + if(y <= (std::numeric_limits::epsilon() * std::fabs(xm1))) + { + if(x < one) + { + real = std::asin(x); + imag = y / std::sqrt(-xp1*xm1); + } + else + { + real = half_pi; + if(((std::numeric_limits::max)() / xp1) > xm1) + { + // xp1 * xm1 won't overflow: + imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1)); + } + else + { + imag = log_two + std::log(x); + } + } + } + else if(y <= safe_min) + { + // There is an assumption in Hull et al's analysis that + // if we get here then x == 1. This is true for all "good" + // machines where : + // + // E^2 > 8*sqrt(u); with: + // + // E = std::numeric_limits::epsilon() + // u = (std::numeric_limits::min)() + // + // Hull et al provide alternative code for "bad" machines + // but we have no way to test that here, so for now just assert + // on the assumption: + // + BOOST_MATH_ASSERT(x == 1); + real = half_pi - std::sqrt(y); + imag = std::sqrt(y); + } + else if(std::numeric_limits::epsilon() * y - one >= x) + { + real = x/y; // This can underflow! + imag = log_two + std::log(y); + } + else if(x > one) + { + real = std::atan(x/y); + T xoy = x/y; + imag = log_two + std::log(y) + half * boost::math::log1p(xoy*xoy); + } + else + { + T a = std::sqrt(one + y*y); + real = x/a; // This can underflow! + imag = half * boost::math::log1p(static_cast(2)*y*(y+a)); + } + } + } + + // + // Finish off by working out the sign of the result: + // + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ASIN_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/asinh.hpp b/third-party/boost-math/include/boost/math/complex/asinh.hpp new file mode 100644 index 0000000000000..1c9a42eb07e18 --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/asinh.hpp @@ -0,0 +1,32 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED +#define BOOST_MATH_COMPLEX_ASINH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] inline std::complex asinh(const std::complex& x) +{ + // + // We use asinh(z) = i asin(-i z); + // Note that C99 defines this the other way around (which is + // to say asin is specified in terms of asinh), this is consistent + // with C99 though: + // + return ::boost::math::detail::mult_i(::boost::math::asin(::boost::math::detail::mult_minus_i(x))); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ASINH_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/atan.hpp b/third-party/boost-math/include/boost/math/complex/atan.hpp new file mode 100644 index 0000000000000..a11ea41ee5a92 --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/atan.hpp @@ -0,0 +1,36 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ATAN_INCLUDED +#define BOOST_MATH_COMPLEX_ATAN_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] std::complex atan(const std::complex& x) +{ + // + // We're using the C99 definition here; atan(z) = -i atanh(iz): + // + if(x.real() == 0) + { + if(x.imag() == 1) + return std::complex(0, std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : static_cast(HUGE_VAL)); + if(x.imag() == -1) + return std::complex(0, std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -static_cast(HUGE_VAL)); + } + return ::boost::math::detail::mult_minus_i(::boost::math::atanh(::boost::math::detail::mult_i(x))); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ATAN_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/atanh.hpp b/third-party/boost-math/include/boost/math/complex/atanh.hpp new file mode 100644 index 0000000000000..5b7dc90108168 --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/atanh.hpp @@ -0,0 +1,214 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +#define BOOST_MATH_COMPLEX_ATANH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +[[deprecated("Replaced by C++11")]] std::complex atanh(const std::complex& z) +{ + // + // References: + // + // Eric W. Weisstein. "Inverse Hyperbolic Tangent." + // From MathWorld--A Wolfram Web Resource. + // http://mathworld.wolfram.com/InverseHyperbolicTangent.html + // + // Also: The Wolfram Functions Site, + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/ + // + // Also "Abramowitz and Stegun. Handbook of Mathematical Functions." + // at : http://jove.prohosting.com/~skripty/toc.htm + // + // See also: https://svn.boost.org/trac/boost/ticket/7291 + // + + static const T pi = boost::math::constants::pi(); + static const T half_pi = pi / 2; + static const T one = static_cast(1.0L); + static const T two = static_cast(2.0L); + static const T four = static_cast(4.0L); + static const T zero = static_cast(0); + static const T log_two = boost::math::constants::ln_two(); + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + + T real, imag; // our results + + T safe_upper = detail::safe_max(two); + T safe_lower = detail::safe_min(static_cast(2)); + + // + // Begin by handling the special cases specified in C99: + // + if((boost::math::isnan)(x)) + { + if((boost::math::isnan)(y)) + return std::complex(x, x); + else if((boost::math::isinf)(y)) + return std::complex(0, ((boost::math::signbit)(z.imag()) ? -half_pi : half_pi)); + else + return std::complex(x, x); + } + else if((boost::math::isnan)(y)) + { + if(x == 0) + return std::complex(x, y); + if((boost::math::isinf)(x)) + return std::complex(0, y); + else + return std::complex(y, y); + } + else if((x > safe_lower) && (x < safe_upper) && (y > safe_lower) && (y < safe_upper)) + { + + T yy = y*y; + T mxm1 = one - x; + /// + // The real part is given by: + // + // real(atanh(z)) == log1p(4*x / ((x-1)*(x-1) + y^2)) + // + real = boost::math::log1p(four * x / (mxm1*mxm1 + yy)); + real /= four; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + + imag = std::atan2((y * two), (mxm1*(one+x) - yy)); + imag /= two; + if(z.imag() < 0) + imag = (boost::math::changesign)(imag); + } + else + { + // + // This section handles exception cases that would normally cause + // underflow or overflow in the main formulas. + // + // Begin by working out the real part, we need to approximate + // real = boost::math::log1p(4x / ((x-1)^2 + y^2)) + // without either overflow or underflow in the squared terms. + // + T mxm1 = one - x; + if(x >= safe_upper) + { + // x-1 = x to machine precision: + if((boost::math::isinf)(x) || (boost::math::isinf)(y)) + { + real = 0; + } + else if(y >= safe_upper) + { + // Big x and y: divide through by x*y: + real = boost::math::log1p((four/y) / (x/y + y/x)); + } + else if(y > one) + { + // Big x: divide through by x: + real = boost::math::log1p(four / (x + y*y/x)); + } + else + { + // Big x small y, as above but neglect y^2/x: + real = boost::math::log1p(four/x); + } + } + else if(y >= safe_upper) + { + if(x > one) + { + // Big y, medium x, divide through by y: + real = boost::math::log1p((four*x/y) / (y + mxm1*mxm1/y)); + } + else + { + // Small or medium x, large y: + real = four*x/y/y; + } + } + else if (x != one) + { + // y is small, calculate divisor carefully: + T div = mxm1*mxm1; + if(y > safe_lower) + div += y*y; + real = boost::math::log1p(four*x/div); + } + else + real = boost::math::changesign(two * (std::log(y) - log_two)); + + real /= four; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + + // + // Now handle imaginary part, this is much easier, + // if x or y are large, then the formula: + // atan2(2y, (1-x)*(1+x) - y^2) + // evaluates to +-(PI - theta) where theta is negligible compared to PI. + // + if((x >= safe_upper) || (y >= safe_upper)) + { + imag = pi; + } + else if(x <= safe_lower) + { + // + // If both x and y are small then atan(2y), + // otherwise just x^2 is negligible in the divisor: + // + if(y <= safe_lower) + imag = std::atan2(two*y, one); + else + { + if((y == zero) && (x == zero)) + imag = 0; + else + imag = std::atan2(two*y, one - y*y); + } + } + else + { + // + // y^2 is negligible: + // + if((y == zero) && (x == one)) + imag = 0; + else + imag = std::atan2(two*y, mxm1*(one+x)); + } + imag /= two; + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + } + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ATANH_INCLUDED diff --git a/third-party/boost-math/include/boost/math/complex/details.hpp b/third-party/boost-math/include/boost/math/complex/details.hpp new file mode 100644 index 0000000000000..0a3d35347da4b --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/details.hpp @@ -0,0 +1,68 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +#define BOOST_MATH_COMPLEX_DETAILS_INCLUDED +// +// This header contains all the support code that is common to the +// inverse trig complex functions, it also contains all the includes +// that we need to implement all these functions. +// + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline T mult_minus_one(const T& t) +{ + return (boost::math::isnan)(t) ? t : (boost::math::changesign)(t); +} + +template +inline std::complex mult_i(const std::complex& t) +{ + return std::complex(mult_minus_one(t.imag()), t.real()); +} + +template +inline std::complex mult_minus_i(const std::complex& t) +{ + return std::complex(t.imag(), mult_minus_one(t.real())); +} + +template +inline T safe_max(T t) +{ + return std::sqrt((std::numeric_limits::max)()) / t; +} +inline long double safe_max(long double t) +{ + // long double sqrt often returns infinity due to + // insufficient internal precision: + return std::sqrt((std::numeric_limits::max)()) / t; +} + +template +inline T safe_min(T t) +{ + return std::sqrt((std::numeric_limits::min)()) * t; +} +inline long double safe_min(long double t) +{ + // long double sqrt often returns zero due to + // insufficient internal precision: + return std::sqrt((std::numeric_limits::min)()) * t; +} + +} } } // namespaces + +#endif // BOOST_MATH_COMPLEX_DETAILS_INCLUDED + diff --git a/third-party/boost-math/include/boost/math/complex/fabs.hpp b/third-party/boost-math/include/boost/math/complex/fabs.hpp new file mode 100644 index 0000000000000..5eb8b3bd80b59 --- /dev/null +++ b/third-party/boost-math/include/boost/math/complex/fabs.hpp @@ -0,0 +1,23 @@ +// (C) Copyright John Maddock 2005. +// 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) + +#ifndef BOOST_MATH_COMPLEX_FABS_INCLUDED +#define BOOST_MATH_COMPLEX_FABS_INCLUDED + +#ifndef BOOST_MATH_HYPOT_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +inline T fabs(const std::complex& z) +{ + return ::boost::math::hypot(z.real(), z.imag()); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_FABS_INCLUDED diff --git a/third-party/boost-math/include/boost/math/concepts/distributions.hpp b/third-party/boost-math/include/boost/math/concepts/distributions.hpp new file mode 100644 index 0000000000000..7f9af2dd5a89b --- /dev/null +++ b/third-party/boost-math/include/boost/math/concepts/distributions.hpp @@ -0,0 +1,497 @@ +// Copyright John Maddock 2006. +// 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) + +// distributions.hpp provides definitions of the concept of a distribution +// and non-member accessor functions that must be implemented by all distributions. +// This is used to verify that +// all the features of a distributions have been fully implemented. + +#ifndef BOOST_MATH_DISTRIBUTION_CONCEPT_HPP +#define BOOST_MATH_DISTRIBUTION_CONCEPT_HPP + +#ifndef BOOST_MATH_STANDALONE + +#include +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4100) +#pragma warning(disable: 4510) +#pragma warning(disable: 4610) +#pragma warning(disable: 4189) // local variable is initialized but not referenced. +#endif +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include + +namespace boost{ +namespace math{ + +namespace concepts +{ +// Begin by defining a concept archetype +// for a distribution class: +// +template +class distribution_archetype +{ +public: + typedef RealType value_type; + + distribution_archetype(const distribution_archetype&); // Copy constructible. + distribution_archetype& operator=(const distribution_archetype&); // Assignable. + + // There is no default constructor, + // but we need a way to instantiate the archetype: + static distribution_archetype& get_object() + { + // will never get called: + return *reinterpret_cast(nullptr); + } +}; // template class distribution_archetype + +// Non-member accessor functions: +// (This list defines the functions that must be implemented by all distributions). + +template +RealType pdf(const distribution_archetype& dist, const RealType& x); + +template +RealType cdf(const distribution_archetype& dist, const RealType& x); + +template +RealType quantile(const distribution_archetype& dist, const RealType& p); + +template +RealType cdf(const complemented2_type, RealType>& c); + +template +RealType quantile(const complemented2_type, RealType>& c); + +template +RealType mean(const distribution_archetype& dist); + +template +RealType standard_deviation(const distribution_archetype& dist); + +template +RealType variance(const distribution_archetype& dist); + +template +RealType hazard(const distribution_archetype& dist); + +template +RealType chf(const distribution_archetype& dist); +// http://en.wikipedia.org/wiki/Characteristic_function_%28probability_theory%29 + +template +RealType coefficient_of_variation(const distribution_archetype& dist); + +template +RealType mode(const distribution_archetype& dist); + +template +RealType skewness(const distribution_archetype& dist); + +template +RealType kurtosis_excess(const distribution_archetype& dist); + +template +RealType kurtosis(const distribution_archetype& dist); + +template +RealType median(const distribution_archetype& dist); + +template +std::pair range(const distribution_archetype& dist); + +template +std::pair support(const distribution_archetype& dist); + +// +// Next comes the concept checks for verifying that a class +// fulfils the requirements of a Distribution: +// +template +struct DistributionConcept +{ + typedef typename Distribution::value_type value_type; + + void constraints() + { + function_requires >(); + function_requires >(); + + const Distribution& dist = DistributionConcept::get_object(); + + value_type x = 0; + // The result values are ignored in all these checks. + value_type v = cdf(dist, x); + v = cdf(complement(dist, x)); + suppress_unused_variable_warning(v); + v = pdf(dist, x); + suppress_unused_variable_warning(v); + v = quantile(dist, x); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, x)); + suppress_unused_variable_warning(v); + v = mean(dist); + suppress_unused_variable_warning(v); + v = mode(dist); + suppress_unused_variable_warning(v); + v = standard_deviation(dist); + suppress_unused_variable_warning(v); + v = variance(dist); + suppress_unused_variable_warning(v); + v = hazard(dist, x); + suppress_unused_variable_warning(v); + v = chf(dist, x); + suppress_unused_variable_warning(v); + v = coefficient_of_variation(dist); + suppress_unused_variable_warning(v); + v = skewness(dist); + suppress_unused_variable_warning(v); + v = kurtosis(dist); + suppress_unused_variable_warning(v); + v = kurtosis_excess(dist); + suppress_unused_variable_warning(v); + v = median(dist); + suppress_unused_variable_warning(v); + std::pair pv; + pv = range(dist); + suppress_unused_variable_warning(pv); + pv = support(dist); + suppress_unused_variable_warning(pv); + + float f = 1; + v = cdf(dist, f); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, f)); + suppress_unused_variable_warning(v); + v = pdf(dist, f); + suppress_unused_variable_warning(v); + v = quantile(dist, f); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, f)); + suppress_unused_variable_warning(v); + v = hazard(dist, f); + suppress_unused_variable_warning(v); + v = chf(dist, f); + suppress_unused_variable_warning(v); + double d = 1; + v = cdf(dist, d); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, d)); + suppress_unused_variable_warning(v); + v = pdf(dist, d); + suppress_unused_variable_warning(v); + v = quantile(dist, d); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, d)); + suppress_unused_variable_warning(v); + v = hazard(dist, d); + suppress_unused_variable_warning(v); + v = chf(dist, d); + suppress_unused_variable_warning(v); +#ifndef TEST_MPFR + long double ld = 1; + v = cdf(dist, ld); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, ld)); + suppress_unused_variable_warning(v); + v = pdf(dist, ld); + suppress_unused_variable_warning(v); + v = quantile(dist, ld); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, ld)); + suppress_unused_variable_warning(v); + v = hazard(dist, ld); + suppress_unused_variable_warning(v); + v = chf(dist, ld); + suppress_unused_variable_warning(v); +#endif + int i = 1; + v = cdf(dist, i); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, i)); + suppress_unused_variable_warning(v); + v = pdf(dist, i); + suppress_unused_variable_warning(v); + v = quantile(dist, i); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, i)); + suppress_unused_variable_warning(v); + v = hazard(dist, i); + suppress_unused_variable_warning(v); + v = chf(dist, i); + suppress_unused_variable_warning(v); + unsigned long li = 1; + v = cdf(dist, li); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, li)); + suppress_unused_variable_warning(v); + v = pdf(dist, li); + suppress_unused_variable_warning(v); + v = quantile(dist, li); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, li)); + suppress_unused_variable_warning(v); + v = hazard(dist, li); + suppress_unused_variable_warning(v); + v = chf(dist, li); + suppress_unused_variable_warning(v); + test_extra_members(dist); + } + template + static void test_extra_members(const D&) + {} + template + static void test_extra_members(const boost::math::bernoulli_distribution& d) + { + value_type r = d.success_fraction(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::beta_distribution& d) + { + value_type r1 = d.alpha(); + value_type r2 = d.beta(); + r1 = boost::math::beta_distribution::find_alpha(r1, r2); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_beta(r1, r2); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_alpha(r1, r2, r1); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_beta(r1, r2, r1); + suppress_unused_variable_warning(r1); + } + template + static void test_extra_members(const boost::math::binomial_distribution& d) + { + value_type r = d.success_fraction(); + r = d.trials(); + r = Distribution::find_lower_bound_on_p(r, r, r); + r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); + r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); + r = Distribution::find_upper_bound_on_p(r, r, r); + r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); + r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); + r = Distribution::find_minimum_number_of_trials(r, r, r); + r = Distribution::find_maximum_number_of_trials(r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::cauchy_distribution& d) + { + value_type r = d.location(); + r = d.scale(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::chi_squared_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = Distribution::find_degrees_of_freedom(r, r, r, r); + r = Distribution::find_degrees_of_freedom(r, r, r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::exponential_distribution& d) + { + value_type r = d.lambda(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::extreme_value_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::fisher_f_distribution& d) + { + value_type r = d.degrees_of_freedom1(); + r = d.degrees_of_freedom2(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::gamma_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::inverse_chi_squared_distribution& d) + { + value_type r = d.scale(); + r = d.degrees_of_freedom(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::inverse_gamma_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::hypergeometric_distribution& d) + { + std::uint64_t u = d.defective(); + u = d.sample_count(); + u = d.total(); + suppress_unused_variable_warning(u); + } + template + static void test_extra_members(const boost::math::laplace_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::logistic_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::lognormal_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::negative_binomial_distribution& d) + { + value_type r = d.success_fraction(); + r = d.successes(); + r = Distribution::find_lower_bound_on_p(r, r, r); + r = Distribution::find_upper_bound_on_p(r, r, r); + r = Distribution::find_minimum_number_of_trials(r, r, r); + r = Distribution::find_maximum_number_of_trials(r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::non_central_beta_distribution& d) + { + value_type r1 = d.alpha(); + value_type r2 = d.beta(); + r1 = d.non_centrality(); + (void)r1; // warning suppression + (void)r2; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_chi_squared_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.non_centrality(); + r = Distribution::find_degrees_of_freedom(r, r, r); + r = Distribution::find_degrees_of_freedom(boost::math::complement(r, r, r)); + r = Distribution::find_non_centrality(r, r, r); + r = Distribution::find_non_centrality(boost::math::complement(r, r, r)); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_f_distribution& d) + { + value_type r = d.degrees_of_freedom1(); + r = d.degrees_of_freedom2(); + r = d.non_centrality(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_t_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.non_centrality(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::normal_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + r = d.mean(); + r = d.standard_deviation(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::pareto_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::poisson_distribution& d) + { + value_type r = d.mean(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::rayleigh_distribution& d) + { + value_type r = d.sigma(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::students_t_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.find_degrees_of_freedom(r, r, r, r); + r = d.find_degrees_of_freedom(r, r, r, r, r); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::triangular_distribution& d) + { + value_type r = d.lower(); + r = d.mode(); + r = d.upper(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::weibull_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::uniform_distribution& d) + { + value_type r = d.lower(); + r = d.upper(); + (void)r; // warning suppression + } +private: + static Distribution* pd; + static Distribution& get_object() + { + // In reality this will never get called: + return *pd; + } +}; // struct DistributionConcept + +template +Distribution* DistributionConcept::pd = 0; + +} // namespace concepts +} // namespace math +} // namespace boost + +#else +#error This header can not be used in standalone mode. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_DISTRIBUTION_CONCEPT_HPP + diff --git a/third-party/boost-math/include/boost/math/concepts/real_concept.hpp b/third-party/boost-math/include/boost/math/concepts/real_concept.hpp new file mode 100644 index 0000000000000..565d58e421078 --- /dev/null +++ b/third-party/boost-math/include/boost/math/concepts/real_concept.hpp @@ -0,0 +1,400 @@ +// Copyright John Maddock 2006. +// 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) + +// Test real concept. + +// real_concept is an archetype for User defined Real types. + +// This file defines the features, constructors, operators, functions... +// that are essential to use mathematical and statistical functions. +// The template typename "RealType" is used where this type +// (as well as the normal built-in types, float, double & long double) +// can be used. +// That this is the minimum set is confirmed by use as a type +// in tests of all functions & distributions, for example: +// test_spots(0.F); & test_spots(0.); for float and double, but also +// test_spots(boost::math::concepts::real_concept(0.)); +// NTL quad_float type is an example of a type meeting the requirements, +// but note minor additions are needed - see ntl.diff and documentation +// "Using With NTL - a High-Precision Floating-Point Library". + +#ifndef BOOST_MATH_REAL_CONCEPT_HPP +#define BOOST_MATH_REAL_CONCEPT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__SGI_STL_PORT) +# include +#endif +#include +#include +#include +#include +#include + +#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__) +# include +#endif + +#if defined __has_include +# if __cplusplus > 202002L || _MSVC_LANG > 202002L +# if __has_include () +# include +# endif +# endif +#endif + +namespace boost{ namespace math{ + +namespace concepts +{ + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + typedef double real_concept_base_type; +#else + typedef long double real_concept_base_type; +#endif + +class real_concept +{ +public: + // Constructors: + real_concept() : m_value(0){} + real_concept(char c) : m_value(c){} + real_concept(wchar_t c) : m_value(c){} + real_concept(unsigned char c) : m_value(c){} + real_concept(signed char c) : m_value(c){} + real_concept(unsigned short c) : m_value(c){} + real_concept(short c) : m_value(c){} + real_concept(unsigned int c) : m_value(c){} + real_concept(int c) : m_value(c){} + real_concept(unsigned long c) : m_value(c){} + real_concept(long c) : m_value(c){} + real_concept(unsigned long long c) : m_value(static_cast(c)){} + real_concept(long long c) : m_value(static_cast(c)){} + real_concept(float c) : m_value(c){} + real_concept(double c) : m_value(c){} + real_concept(long double c) : m_value(c){} +#ifdef BOOST_MATH_USE_FLOAT128 + real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){} +#endif +#ifdef __STDCPP_FLOAT32_T__ + real_concept(std::float32_t c) : m_value(static_cast(c)){} +#endif +#ifdef __STDCPP_FLOAT64_T__ + real_concept(std::float64_t c) : m_value(static_cast(c)){} +#endif + + // Assignment: + real_concept& operator=(char c) { m_value = c; return *this; } + real_concept& operator=(unsigned char c) { m_value = c; return *this; } + real_concept& operator=(signed char c) { m_value = c; return *this; } + real_concept& operator=(wchar_t c) { m_value = c; return *this; } + real_concept& operator=(short c) { m_value = c; return *this; } + real_concept& operator=(unsigned short c) { m_value = c; return *this; } + real_concept& operator=(int c) { m_value = c; return *this; } + real_concept& operator=(unsigned int c) { m_value = c; return *this; } + real_concept& operator=(long c) { m_value = c; return *this; } + real_concept& operator=(unsigned long c) { m_value = c; return *this; } + real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } + real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + real_concept& operator=(float c) { m_value = c; return *this; } + real_concept& operator=(double c) { m_value = c; return *this; } + real_concept& operator=(long double c) { m_value = c; return *this; } + #ifdef __STDCPP_FLOAT32_T__ + real_concept& operator=(std::float32_t c) { m_value = c; return *this; } + #endif + #ifdef __STDCPP_FLOAT64_T__ + real_concept& operator=(std::float64_t c) { m_value = c; return *this; } + #endif + + // Access: + real_concept_base_type value()const{ return m_value; } + + // Member arithmetic: + real_concept& operator+=(const real_concept& other) + { m_value += other.value(); return *this; } + real_concept& operator-=(const real_concept& other) + { m_value -= other.value(); return *this; } + real_concept& operator*=(const real_concept& other) + { m_value *= other.value(); return *this; } + real_concept& operator/=(const real_concept& other) + { m_value /= other.value(); return *this; } + real_concept operator-()const + { return -m_value; } + real_concept const& operator+()const + { return *this; } + real_concept& operator++() + { ++m_value; return *this; } + real_concept& operator--() + { --m_value; return *this; } + +private: + real_concept_base_type m_value; +}; + +// Non-member arithmetic: +inline real_concept operator+(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result += b; + return result; +} +inline real_concept operator-(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result -= b; + return result; +} +inline real_concept operator*(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result *= b; + return result; +} +inline real_concept operator/(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const real_concept& a, const real_concept& b) +{ return a.value() == b.value(); } +inline bool operator != (const real_concept& a, const real_concept& b) +{ return a.value() != b.value();} +inline bool operator < (const real_concept& a, const real_concept& b) +{ return a.value() < b.value(); } +inline bool operator <= (const real_concept& a, const real_concept& b) +{ return a.value() <= b.value(); } +inline bool operator > (const real_concept& a, const real_concept& b) +{ return a.value() > b.value(); } +inline bool operator >= (const real_concept& a, const real_concept& b) +{ return a.value() >= b.value(); } + +// Non-member functions: +inline real_concept acos(real_concept a) +{ return std::acos(a.value()); } +inline real_concept cos(real_concept a) +{ return std::cos(a.value()); } +inline real_concept asin(real_concept a) +{ return std::asin(a.value()); } +inline real_concept atan(real_concept a) +{ return std::atan(a.value()); } +inline real_concept atan2(real_concept a, real_concept b) +{ return std::atan2(a.value(), b.value()); } +inline real_concept ceil(real_concept a) +{ return std::ceil(a.value()); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +// I've seen std::fmod(long double) crash on some platforms +// so use fmodl instead: +#ifdef _WIN32_WCE +// +// Ugly workaround for macro fmodl: +// +inline long double call_fmodl(long double a, long double b) +{ return fmodl(a, b); } +inline real_concept fmod(real_concept a, real_concept b) +{ return call_fmodl(a.value(), b.value()); } +#else +inline real_concept fmod(real_concept a, real_concept b) +{ return fmodl(a.value(), b.value()); } +#endif +#endif +inline real_concept cosh(real_concept a) +{ return std::cosh(a.value()); } +inline real_concept exp(real_concept a) +{ return std::exp(a.value()); } +inline real_concept fabs(real_concept a) +{ return std::fabs(a.value()); } +inline real_concept abs(real_concept a) +{ return std::abs(a.value()); } +inline real_concept floor(real_concept a) +{ return std::floor(a.value()); } +inline real_concept modf(real_concept a, real_concept* ipart) +{ +#ifdef __MINGW32__ + real_concept_base_type ip; + real_concept_base_type result = boost::math::modf(a.value(), &ip); + *ipart = ip; + return result; +#else + real_concept_base_type ip; + real_concept_base_type result = std::modf(a.value(), &ip); + *ipart = ip; + return result; +#endif +} +inline real_concept frexp(real_concept a, int* expon) +{ return std::frexp(a.value(), expon); } +inline real_concept ldexp(real_concept a, int expon) +{ return std::ldexp(a.value(), expon); } +inline real_concept log(real_concept a) +{ return std::log(a.value()); } +inline real_concept log10(real_concept a) +{ return std::log10(a.value()); } +inline real_concept tan(real_concept a) +{ return std::tan(a.value()); } +inline real_concept pow(real_concept a, real_concept b) +{ return std::pow(a.value(), b.value()); } +#if !defined(__SUNPRO_CC) +inline real_concept pow(real_concept a, int b) +{ return std::pow(a.value(), b); } +#else +inline real_concept pow(real_concept a, int b) +{ return std::pow(a.value(), static_cast(b)); } +#endif +inline real_concept sin(real_concept a) +{ return std::sin(a.value()); } +inline real_concept sinh(real_concept a) +{ return std::sinh(a.value()); } +inline real_concept sqrt(real_concept a) +{ return std::sqrt(a.value()); } +inline real_concept tanh(real_concept a) +{ return std::tanh(a.value()); } + +// +// C++11 ism's +// Note that these must not actually call the std:: versions as that precludes using this +// header to test in C++03 mode, call the Boost versions instead: +// +inline boost::math::concepts::real_concept asinh(boost::math::concepts::real_concept a) +{ + return boost::math::asinh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} +inline boost::math::concepts::real_concept acosh(boost::math::concepts::real_concept a) +{ + return boost::math::acosh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} +inline boost::math::concepts::real_concept atanh(boost::math::concepts::real_concept a) +{ + return boost::math::atanh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} + +// +// Conversion and truncation routines: +// +template +inline int iround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::iround(v.value(), pol); } +inline int iround(const concepts::real_concept& v) +{ return boost::math::iround(v.value(), policies::policy<>()); } +template +inline long lround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::lround(v.value(), pol); } +inline long lround(const concepts::real_concept& v) +{ return boost::math::lround(v.value(), policies::policy<>()); } + +template +inline long long llround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::llround(v.value(), pol); } +inline long long llround(const concepts::real_concept& v) +{ return boost::math::llround(v.value(), policies::policy<>()); } + +template +inline int itrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::itrunc(v.value(), pol); } +inline int itrunc(const concepts::real_concept& v) +{ return boost::math::itrunc(v.value(), policies::policy<>()); } +template +inline long ltrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::ltrunc(v.value(), pol); } +inline long ltrunc(const concepts::real_concept& v) +{ return boost::math::ltrunc(v.value(), policies::policy<>()); } + +template +inline long long lltrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::lltrunc(v.value(), pol); } +inline long long lltrunc(const concepts::real_concept& v) +{ return boost::math::lltrunc(v.value(), policies::policy<>()); } + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const real_concept& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, real_concept& a) +{ + real_concept_base_type v; + is >> v; + a = v; + return is; +} + +} // namespace concepts + +namespace tools +{ + +template <> +inline concepts::real_concept make_big_value(boost::math::tools::largest_float val, const char* , std::false_type const&, std::false_type const&) +{ + return val; // Can't use lexical_cast here, sometimes it fails.... +} + +template <> +inline concepts::real_concept max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return max_value(); +} + +template <> +inline concepts::real_concept min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return min_value(); +} + +template <> +inline concepts::real_concept log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return log_max_value(); +} + +template <> +inline concepts::real_concept log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return log_min_value(); +} + +template <> +inline concepts::real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ +#ifdef __SUNPRO_CC + return std::numeric_limits::epsilon(); +#else + return tools::epsilon(); +#endif +} + +template <> +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) noexcept +{ + // Assume number of significand bits is same as real_concept_base_type, + // unless std::numeric_limits::is_specialized to provide digits. + return tools::digits(); + // Note that if numeric_limits real concept is NOT specialized to provide digits10 + // (or max_digits10) then the default precision of 6 decimal digits will be used + // by Boost test (giving misleading error messages like + // "difference between {9.79796} and {9.79796} exceeds 5.42101e-19%" + // and by Boost lexical cast and serialization causing loss of accuracy. +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_REAL_CONCEPT_HPP + + diff --git a/third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp b/third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp new file mode 100644 index 0000000000000..2d7fe58d3d596 --- /dev/null +++ b/third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp @@ -0,0 +1,119 @@ +// Copyright John Maddock 2007-8. +// 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) + +#ifndef BOOST_MATH_REAL_TYPE_CONCEPT_HPP +#define BOOST_MATH_REAL_TYPE_CONCEPT_HPP + +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4100) +#pragma warning(disable: 4510) +#pragma warning(disable: 4610) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include + + +namespace boost{ namespace math{ namespace concepts{ + +template +struct RealTypeConcept +{ + template + void check_binary_ops(Other o) const + { + RealType r(o); + r = o; + r -= o; + r += o; + r *= o; + r /= o; + r = r - o; + r = o - r; + r = r + o; + r = o + r; + r = o * r; + r = r * o; + r = r / o; + r = o / r; + bool b; + b = r == o; + suppress_unused_variable_warning(b); + b = o == r; + suppress_unused_variable_warning(b); + b = r != o; + suppress_unused_variable_warning(b); + b = o != r; + suppress_unused_variable_warning(b); + b = r <= o; + suppress_unused_variable_warning(b); + b = o <= r; + suppress_unused_variable_warning(b); + b = r >= o; + suppress_unused_variable_warning(b); + b = o >= r; + suppress_unused_variable_warning(b); + b = r < o; + suppress_unused_variable_warning(b); + b = o < r; + suppress_unused_variable_warning(b); + b = r > o; + suppress_unused_variable_warning(b); + b = o > r; + suppress_unused_variable_warning(b); + } + + void constraints() + { + BOOST_MATH_STD_USING + + RealType r; + check_binary_ops(r); + check_binary_ops(0.5f); + check_binary_ops(0.5); + //check_binary_ops(0.5L); + check_binary_ops(1); + //check_binary_ops(1u); + check_binary_ops(1L); + //check_binary_ops(1uL); + check_binary_ops(1LL); + RealType r2 = +r; + r2 = -r; + + r2 = fabs(r); + r2 = abs(r); + r2 = ceil(r); + r2 = floor(r); + r2 = exp(r); + r2 = pow(r, r2); + r2 = sqrt(r); + r2 = log(r); + r2 = cos(r); + r2 = sin(r); + r2 = tan(r); + r2 = asin(r); + r2 = acos(r); + r2 = atan(r); + int i {}; + r2 = ldexp(r, i); + r2 = frexp(r, &i); + i = boost::math::tools::digits(); + r2 = boost::math::tools::max_value(); + r2 = boost::math::tools::min_value(); + r2 = boost::math::tools::log_max_value(); + r2 = boost::math::tools::log_min_value(); + r2 = boost::math::tools::epsilon(); + } +}; // struct DistributionConcept + + +}}} // namespaces + +#endif + diff --git a/third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp b/third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp new file mode 100644 index 0000000000000..43f562efe1d0e --- /dev/null +++ b/third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp @@ -0,0 +1,427 @@ +// Copyright John Maddock 2006. +// 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) + +// std_real_concept is an archetype for built-in Real types. + +// The main purpose in providing this type is to verify +// that std lib functions are found via a using declaration +// bringing those functions into the current scope, and not +// just because they happen to be in global scope. +// +// If ::pow is found rather than std::pow say, then the code +// will silently compile, but truncation of long doubles to +// double will cause a significant loss of precision. +// A template instantiated with std_real_concept will *only* +// compile if it std::whatever is in scope. + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STD_REAL_CONCEPT_HPP +#define BOOST_MATH_STD_REAL_CONCEPT_HPP + +namespace boost{ namespace math{ + +namespace concepts +{ + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + typedef double std_real_concept_base_type; +#else + typedef long double std_real_concept_base_type; +#endif + +class std_real_concept +{ +public: + // Constructors: + std_real_concept() : m_value(0){} + std_real_concept(char c) : m_value(c){} +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + std_real_concept(wchar_t c) : m_value(c){} +#endif + std_real_concept(unsigned char c) : m_value(c){} + std_real_concept(signed char c) : m_value(c){} + std_real_concept(unsigned short c) : m_value(c){} + std_real_concept(short c) : m_value(c){} + std_real_concept(unsigned int c) : m_value(c){} + std_real_concept(int c) : m_value(c){} + std_real_concept(unsigned long c) : m_value(c){} + std_real_concept(long c) : m_value(c){} +#if defined(__DECCXX) || defined(__SUNPRO_CC) + std_real_concept(unsigned long long c) : m_value(static_cast(c)){} + std_real_concept(long long c) : m_value(static_cast(c)){} +#endif + std_real_concept(unsigned long long c) : m_value(static_cast(c)){} + std_real_concept(long long c) : m_value(static_cast(c)){} + std_real_concept(float c) : m_value(c){} + std_real_concept(double c) : m_value(c){} + std_real_concept(long double c) : m_value(c){} +#ifdef BOOST_MATH_USE_FLOAT128 + std_real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){} +#endif + + // Assignment: + std_real_concept& operator=(char c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned char c) { m_value = c; return *this; } + std_real_concept& operator=(signed char c) { m_value = c; return *this; } +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + std_real_concept& operator=(wchar_t c) { m_value = c; return *this; } +#endif + std_real_concept& operator=(short c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned short c) { m_value = c; return *this; } + std_real_concept& operator=(int c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned int c) { m_value = c; return *this; } + std_real_concept& operator=(long c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned long c) { m_value = c; return *this; } +#if defined(__DECCXX) || defined(__SUNPRO_CC) + std_real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + std_real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } +#endif + std_real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } + std_real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + + std_real_concept& operator=(float c) { m_value = c; return *this; } + std_real_concept& operator=(double c) { m_value = c; return *this; } + std_real_concept& operator=(long double c) { m_value = c; return *this; } +#ifdef BOOST_MATH_USE_FLOAT128 + std_real_concept& operator=(BOOST_MATH_FLOAT128_TYPE c) { m_value = c; return *this; } +#endif + + // Access: + std_real_concept_base_type value()const{ return m_value; } + + // Member arithmetic: + std_real_concept& operator+=(const std_real_concept& other) + { m_value += other.value(); return *this; } + std_real_concept& operator-=(const std_real_concept& other) + { m_value -= other.value(); return *this; } + std_real_concept& operator*=(const std_real_concept& other) + { m_value *= other.value(); return *this; } + std_real_concept& operator/=(const std_real_concept& other) + { m_value /= other.value(); return *this; } + std_real_concept operator-()const + { return -m_value; } + std_real_concept const& operator+()const + { return *this; } + +private: + std_real_concept_base_type m_value; +}; + +// Non-member arithmetic: +inline std_real_concept operator+(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result += b; + return result; +} +inline std_real_concept operator-(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result -= b; + return result; +} +inline std_real_concept operator*(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result *= b; + return result; +} +inline std_real_concept operator/(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const std_real_concept& a, const std_real_concept& b) +{ return a.value() == b.value(); } +inline bool operator != (const std_real_concept& a, const std_real_concept& b) +{ return a.value() != b.value();} +inline bool operator < (const std_real_concept& a, const std_real_concept& b) +{ return a.value() < b.value(); } +inline bool operator <= (const std_real_concept& a, const std_real_concept& b) +{ return a.value() <= b.value(); } +inline bool operator > (const std_real_concept& a, const std_real_concept& b) +{ return a.value() > b.value(); } +inline bool operator >= (const std_real_concept& a, const std_real_concept& b) +{ return a.value() >= b.value(); } + +} // namespace concepts +} // namespace math +} // namespace boost + +namespace std{ + +// Non-member functions: +inline boost::math::concepts::std_real_concept acos(boost::math::concepts::std_real_concept a) +{ return std::acos(a.value()); } +inline boost::math::concepts::std_real_concept cos(boost::math::concepts::std_real_concept a) +{ return std::cos(a.value()); } +inline boost::math::concepts::std_real_concept asin(boost::math::concepts::std_real_concept a) +{ return std::asin(a.value()); } +inline boost::math::concepts::std_real_concept atan(boost::math::concepts::std_real_concept a) +{ return std::atan(a.value()); } +inline boost::math::concepts::std_real_concept atan2(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::atan2(a.value(), b.value()); } +inline boost::math::concepts::std_real_concept ceil(boost::math::concepts::std_real_concept a) +{ return std::ceil(a.value()); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return fmodl(a.value(), b.value()); } +#else +inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::fmod(a.value(), b.value()); } +#endif +inline boost::math::concepts::std_real_concept cosh(boost::math::concepts::std_real_concept a) +{ return std::cosh(a.value()); } +inline boost::math::concepts::std_real_concept exp(boost::math::concepts::std_real_concept a) +{ return std::exp(a.value()); } +inline boost::math::concepts::std_real_concept fabs(boost::math::concepts::std_real_concept a) +{ return std::fabs(a.value()); } +inline boost::math::concepts::std_real_concept abs(boost::math::concepts::std_real_concept a) +{ return std::abs(a.value()); } +inline boost::math::concepts::std_real_concept floor(boost::math::concepts::std_real_concept a) +{ return std::floor(a.value()); } +inline boost::math::concepts::std_real_concept modf(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept* ipart) +{ + boost::math::concepts::std_real_concept_base_type ip; + boost::math::concepts::std_real_concept_base_type result = std::modf(a.value(), &ip); + *ipart = ip; + return result; +} +inline boost::math::concepts::std_real_concept frexp(boost::math::concepts::std_real_concept a, int* expon) +{ return std::frexp(a.value(), expon); } +inline boost::math::concepts::std_real_concept ldexp(boost::math::concepts::std_real_concept a, int expon) +{ return std::ldexp(a.value(), expon); } +inline boost::math::concepts::std_real_concept log(boost::math::concepts::std_real_concept a) +{ return std::log(a.value()); } +inline boost::math::concepts::std_real_concept log10(boost::math::concepts::std_real_concept a) +{ return std::log10(a.value()); } +inline boost::math::concepts::std_real_concept tan(boost::math::concepts::std_real_concept a) +{ return std::tan(a.value()); } +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::pow(a.value(), b.value()); } +#if !defined(__SUNPRO_CC) +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b) +{ return std::pow(a.value(), b); } +#else +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b) +{ return std::pow(a.value(), static_cast(b)); } +#endif +inline boost::math::concepts::std_real_concept sin(boost::math::concepts::std_real_concept a) +{ return std::sin(a.value()); } +inline boost::math::concepts::std_real_concept sinh(boost::math::concepts::std_real_concept a) +{ return std::sinh(a.value()); } +inline boost::math::concepts::std_real_concept sqrt(boost::math::concepts::std_real_concept a) +{ return std::sqrt(a.value()); } +inline boost::math::concepts::std_real_concept tanh(boost::math::concepts::std_real_concept a) +{ return std::tanh(a.value()); } +inline boost::math::concepts::std_real_concept (nextafter)(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return (boost::math::nextafter)(a, b); } +// +// C++11 ism's +// Now that we only support C++11 and later, we can allow use of these: +// +inline boost::math::concepts::std_real_concept asinh(boost::math::concepts::std_real_concept a) +{ return std::asinh(a.value()); } +inline boost::math::concepts::std_real_concept acosh(boost::math::concepts::std_real_concept a) +{ return std::acosh(a.value()); } +inline boost::math::concepts::std_real_concept atanh(boost::math::concepts::std_real_concept a) +{ return std::atanh(a.value()); } +inline bool (isfinite)(boost::math::concepts::std_real_concept a) +{ + return (boost::math::isfinite)(a.value()); +} +inline boost::math::concepts::std_real_concept log2(boost::math::concepts::std_real_concept a) +{ return std::log2(a.value()); } +inline int ilogb(boost::math::concepts::std_real_concept a) +{ return std::ilogb(a.value()); } + + +} // namespace std + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace concepts{ + +// +// Conversion and truncation routines: +// +template +inline int iround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::iround(v.value(), pol); +} +inline int iround(const concepts::std_real_concept& v) +{ + return boost::math::iround(v.value(), policies::policy<>()); +} + +template +inline long lround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::lround(v.value(), pol); +} +inline long lround(const concepts::std_real_concept& v) +{ + return boost::math::lround(v.value(), policies::policy<>()); +} + +template +inline long long llround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::llround(v.value(), pol); +} +inline long long llround(const concepts::std_real_concept& v) +{ + return boost::math::llround(v.value(), policies::policy<>()); +} + +template +inline int itrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::itrunc(v.value(), pol); +} +inline int itrunc(const concepts::std_real_concept& v) +{ + return boost::math::itrunc(v.value(), policies::policy<>()); +} + +template +inline long ltrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::ltrunc(v.value(), pol); +} +inline long ltrunc(const concepts::std_real_concept& v) +{ + return boost::math::ltrunc(v.value(), policies::policy<>()); +} + +template +inline long long lltrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::lltrunc(v.value(), pol); +} +inline long long lltrunc(const concepts::std_real_concept& v) +{ + return boost::math::lltrunc(v.value(), policies::policy<>()); +} + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const std_real_concept& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, std_real_concept& a) +{ +#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__) || defined(_LIBCPP_VERSION) + std::string s; + std_real_concept_base_type d; + is >> s; + std::sscanf(s.c_str(), "%Lf", &d); + a = d; + return is; +#else + std_real_concept_base_type v; + is >> v; + a = v; + return is; +#endif +} + +} // namespace concepts +}} + +#include + +namespace boost{ namespace math{ +namespace tools +{ + +template <> +inline concepts::std_real_concept make_big_value(boost::math::tools::largest_float val, const char*, std::false_type const&, std::false_type const&) +{ + return val; // Can't use lexical_cast here, sometimes it fails.... +} + +template <> +inline concepts::std_real_concept max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return max_value(); +} + +template <> +inline concepts::std_real_concept min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return min_value(); +} + +template <> +inline concepts::std_real_concept log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return log_max_value(); +} + +template <> +inline concepts::std_real_concept log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return log_min_value(); +} + +template <> +inline concepts::std_real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return tools::epsilon(); +} + +template <> +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) noexcept +{ // Assume number of significand bits is same as std_real_concept_base_type, + // unless std::numeric_limits::is_specialized to provide digits. + return digits(); +} + +template <> +inline double real_cast(concepts::std_real_concept r) +{ + return static_cast(r.value()); +} + + +} // namespace tools + +#if defined(_MSC_VER) && (_MSC_VER <= 1310) +using concepts::itrunc; +using concepts::ltrunc; +using concepts::lltrunc; +using concepts::iround; +using concepts::lround; +using concepts::llround; +#endif + +} // namespace math +} // namespace boost + +// +// These must go at the end, as they include stuff that won't compile until +// after std_real_concept has been defined: +// +#include +#include +#include + +#endif // BOOST_MATH_STD_REAL_CONCEPT_HPP diff --git a/third-party/boost-math/include/boost/math/constants/calculate_constants.hpp b/third-party/boost-math/include/boost/math/constants/calculate_constants.hpp new file mode 100644 index 0000000000000..3db74c3b66b7a --- /dev/null +++ b/third-party/boost-math/include/boost/math/constants/calculate_constants.hpp @@ -0,0 +1,1109 @@ +// Copyright John Maddock 2010, 2012. +// Copyright Paul A. Bristow 2011, 2012. + +// 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) + +#ifndef BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED +#define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED +#include + +namespace boost{ namespace math{ namespace constants{ namespace detail{ + +template +template +inline T constant_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + + return ldexp(acos(T(0)), 1); + + /* + // Although this code works well, it's usually more accurate to just call acos + // and access the number types own representation of PI which is usually calculated + // at slightly higher precision... + + T result; + T a = 1; + T b; + T A(a); + T B = 0.5f; + T D = 0.25f; + + T lim; + lim = boost::math::tools::epsilon(); + + unsigned k = 1; + + do + { + result = A + B; + result = ldexp(result, -2); + b = sqrt(B); + a += b; + a = ldexp(a, -1); + A = a * a; + B = A - result; + B = ldexp(B, 1); + result = A - B; + bool neg = boost::math::sign(result) < 0; + if(neg) + result = -result; + if(result <= lim) + break; + if(neg) + result = -result; + result = ldexp(result, k - 1); + D -= result; + ++k; + lim = ldexp(lim, 1); + } + while(true); + + result = B / D; + return result; + */ +} + +template +template +inline T constant_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 * pi > >(); +} + +template // 2 / pi +template +inline T constant_two_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 / pi > >(); +} + +template // sqrt(2/pi) +template +inline T constant_root_two_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt((2 / pi > >())); +} + +template +template +inline T constant_one_div_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / two_pi > >(); +} + +template +template +inline T constant_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(pi > >()); +} + +template +template +inline T constant_root_half_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(pi > >() / 2); +} + +template +template +inline T constant_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(two_pi > >()); +} + +template +template +inline T constant_log_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(root_two_pi > >()); +} + +template +template +inline T constant_root_ln_four::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(log(static_cast(4))); +} + +template +template +inline T constant_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // + // Although we can clearly calculate this from first principles, this hooks into + // T's own notion of e, which hopefully will more accurate than one calculated to + // a few epsilon: + // + BOOST_MATH_STD_USING + return exp(static_cast(1)); +} + +template +template +inline T constant_half::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / static_cast(2); +} + +template +template +inline T constant_euler::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + // + // This is the method described in: + // "Some New Algorithms for High-Precision Computation of Euler's Constant" + // Richard P Brent and Edwin M McMillan. + // Mathematics of Computation, Volume 34, Number 149, Jan 1980, pages 305-312. + // See equation 17 with p = 2. + // + T n = 3 + (M ? (std::min)(M, tools::digits()) : tools::digits()) / 4; + T lim = M ? ldexp(T(1), 1 - (std::min)(M, tools::digits())) : tools::epsilon(); + T lnn = log(n); + T term = 1; + T N = -lnn; + T D = 1; + T Hk = 0; + T one = 1; + + for(unsigned k = 1;; ++k) + { + term *= n * n; + term /= k * k; + Hk += one / k; + N += term * (Hk - lnn); + D += term; + + if(term < D * lim) + break; + } + return N / D; +} + +template +template +inline T constant_euler_sqr::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return euler > >() + * euler > >(); +} + +template +template +inline T constant_one_div_euler::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) + / euler > >(); +} + + +template +template +inline T constant_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(2)); +} + + +template +template +inline T constant_root_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(3)); +} + +template +template +inline T constant_half_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(2)) / 2; +} + +template +template +inline T constant_ln_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // + // Although there are good ways to calculate this from scratch, this hooks into + // T's own notion of log(2) which will hopefully be accurate to the full precision + // of T: + // + BOOST_MATH_STD_USING + return log(static_cast(2)); +} + +template +template +inline T constant_ln_ten::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(static_cast(10)); +} + +template +template +inline T constant_ln_ln_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(log(static_cast(2))); +} + +template +template +inline T constant_third::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / static_cast(3); +} + +template +template +inline T constant_twothirds::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(2) / static_cast(3); +} + +template +template +inline T constant_two_thirds::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(2) / static_cast(3); +} + +template +template +inline T constant_three_quarters::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(3) / static_cast(4); +} + +template +template +inline T constant_sixth::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / static_cast(6); +} + +// Pi and related constants. +template +template +inline T constant_pi_minus_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return pi > >() - static_cast(3); +} + +template +template +inline T constant_four_minus_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(4) - pi > >(); +} + +template +template +inline T constant_exp_minus_half::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return exp(static_cast(-0.5)); +} + +template +template +inline T constant_exp_minus_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return exp(static_cast(-1.)); +} + +template +template +inline T constant_one_div_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_two > >(); +} + +template +template +inline T constant_one_div_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_pi > >(); +} + +template +template +inline T constant_one_div_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_two_pi > >(); +} + +template +template +inline T constant_root_one_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(1) / pi > >()); +} + +template +template +inline T constant_four_thirds_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(4) / static_cast(3); +} + +template +template +inline T constant_half_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(2); +} + +template +template +inline T constant_third_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(3); +} + +template +template +inline T constant_sixth_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(6); +} + +template +template +inline T constant_two_thirds_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(2) / static_cast(3); +} + +template +template +inline T constant_three_quarters_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(3) / static_cast(4); +} + +template +template +inline T constant_pi_pow_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(pi > >(), e > >()); // +} + +template +template +inline T constant_pi_sqr::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() ; // +} + +template +template +inline T constant_pi_sqr_div_six::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() + / static_cast(6); // +} + +template +template +inline T constant_pi_cubed::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() + * pi > >() + ; // +} + +template +template +inline T constant_cbrt_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(pi > >(), static_cast(1)/ static_cast(3)); +} + +template +template +inline T constant_one_div_cbrt_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) + / pow(pi > >(), static_cast(1)/ static_cast(3)); +} + +// Euler's e + +template +template +inline T constant_e_pow_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(e > >(), pi > >()); // +} + +template +template +inline T constant_root_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(e > >()); +} + +template +template +inline T constant_log10_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log10(e > >()); +} + +template +template +inline T constant_one_div_log10_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / + log10(e > >()); +} + +// Trigonometric + +template +template +inline T constant_degree::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + / static_cast(180) + ; // +} + +template +template +inline T constant_radian::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(180) + / pi > >() + ; // +} + +template +template +inline T constant_sin_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sin(static_cast(1)) ; // +} + +template +template +inline T constant_cos_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return cos(static_cast(1)) ; // +} + +template +template +inline T constant_sinh_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sinh(static_cast(1)) ; // +} + +template +template +inline T constant_cosh_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return cosh(static_cast(1)) ; // +} + +template +template +inline T constant_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return (static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ; // +} + +template +template +inline T constant_ln_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log((static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ); +} + +template +template +inline T constant_one_div_ln_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / + log((static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ); +} + +// Zeta + +template +template +inline T constant_zeta_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + + return pi > >() + * pi > >() + /static_cast(6); +} + +template +template +inline T constant_zeta_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // http://mathworld.wolfram.com/AperysConstant.html + // http://en.wikipedia.org/wiki/Mathematical_constant + + // http://oeis.org/A002117/constant + //T zeta3("1.20205690315959428539973816151144999076" + // "4986292340498881792271555341838205786313" + // "09018645587360933525814619915"); + + //"1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915" A002117 + // 1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915780, +00); + //"1.2020569031595942 double + // http://www.spaennare.se/SSPROG/ssnum.pdf // section 11, Algorithm for Apery's constant zeta(3). + // Programs to Calculate some Mathematical Constants to Large Precision, Document Version 1.50 + + // by Stefan Spannare September 19, 2007 + // zeta(3) = 1/64 * sum + BOOST_MATH_STD_USING + T n_fact=static_cast(1); // build n! for n = 0. + T sum = static_cast(77); // Start with n = 0 case. + // for n = 0, (77/1) /64 = 1.203125 + //double lim = std::numeric_limits::epsilon(); + T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits())) : tools::epsilon(); + for(unsigned int n = 1; n < 40; ++n) + { // three to five decimal digits per term, so 40 should be plenty for 100 decimal digits. + //cout << "n = " << n << endl; + n_fact *= n; // n! + T n_fact_p10 = n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact; // (n!)^10 + T num = ((205 * n * n) + (250 * n) + 77) * n_fact_p10; // 205n^2 + 250n + 77 + // int nn = (2 * n + 1); + // T d = factorial(nn); // inline factorial. + T d = 1; + for(unsigned int i = 1; i <= (n+n + 1); ++i) // (2n + 1) + { + d *= i; + } + T den = d * d * d * d * d; // [(2n+1)!]^5 + //cout << "den = " << den << endl; + T term = num/den; + if (n % 2 != 0) + { //term *= -1; + sum -= term; + } + else + { + sum += term; + } + //cout << "term = " << term << endl; + //cout << "sum/64 = " << sum/64 << endl; + if(abs(term) < lim) + { + break; + } + } + return sum / 64; +} + +template +template +inline T constant_catalan::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // http://oeis.org/A006752/constant + //T c("0.915965594177219015054603514932384110774" + //"149374281672134266498119621763019776254769479356512926115106248574"); + + // 9.159655941772190150546035149323841107, 74149374281672134266498119621763019776254769479356512926115106248574422619, -01); + + // This is equation (entry) 31 from + // http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm + // See also http://www.mpfr.org/algorithms.pdf + BOOST_MATH_STD_USING + T k_fact = 1; + T tk_fact = 1; + T sum = 1; + T term; + T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits())) : tools::epsilon(); + + for(unsigned k = 1;; ++k) + { + k_fact *= k; + tk_fact *= (2 * k) * (2 * k - 1); + term = k_fact * k_fact / (tk_fact * (2 * k + 1) * (2 * k + 1)); + sum += term; + if(term < lim) + { + break; + } + } + return boost::math::constants::pi >() + * log(2 + boost::math::constants::root_three >()) + / 8 + + 3 * sum / 8; +} + +namespace khinchin_detail{ + +template +T zeta_polynomial_series(T s, T sc, int digits) +{ + BOOST_MATH_STD_USING + // + // This is algorithm 3 from: + // + // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, + // Canadian Mathematical Society, Conference Proceedings, 2000. + // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf + // + BOOST_MATH_STD_USING + int n = (digits * 19) / 53; + T sum = 0; + T two_n = ldexp(T(1), n); + int ej_sign = 1; + for(int j = 0; j < n; ++j) + { + sum += ej_sign * -two_n / pow(T(j + 1), s); + ej_sign = -ej_sign; + } + T ej_sum = 1; + T ej_term = 1; + for(int j = n; j <= 2 * n - 1; ++j) + { + sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s); + ej_sign = -ej_sign; + ej_term *= 2 * n - j; + ej_term /= j - n + 1; + ej_sum += ej_term; + } + return -sum / (two_n * (1 - pow(T(2), sc))); +} + +template +T khinchin(int digits) +{ + BOOST_MATH_STD_USING + T sum = 0; + T term; + T lim = ldexp(T(1), 1-digits); + T factor = 0; + unsigned last_k = 1; + T num = 1; + for(unsigned n = 1;; ++n) + { + for(unsigned k = last_k; k <= 2 * n - 1; ++k) + { + factor += num / k; + num = -num; + } + last_k = 2 * n; + term = (zeta_polynomial_series(T(2 * n), T(1 - T(2 * n)), digits) - 1) * factor / n; + sum += term; + if(term < lim) + break; + } + return exp(sum / boost::math::constants::ln_two >()); +} + +} + +template +template +inline T constant_khinchin::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + int n = N ? (std::min)(N, tools::digits()) : tools::digits(); + return khinchin_detail::khinchin(n); +} + +template +template +inline T constant_extreme_value_skewness::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] + BOOST_MATH_STD_USING + T ev(12 * sqrt(static_cast(6)) * zeta_three > >() + / pi_cubed > >() ); + +//T ev( +//"1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150" +//"1894272048688553376986765366075828644841024041679714157616857834895702411080704529137366329462558680" +//"2015498788776135705587959418756809080074611906006528647805347822929577145038743873949415294942796280" +//"0895597703063466053535550338267721294164578901640163603544404938283861127819804918174973533694090594" +//"3094963822672055237678432023017824416203652657301470473548274848068762500300316769691474974950757965" +//"8640779777748741897542093874605477776538884083378029488863880220988107155275203245233994097178778984" +//"3488995668362387892097897322246698071290011857605809901090220903955815127463328974447572119951192970" +//"3684453635456559086126406960279692862247058250100678008419431185138019869693206366891639436908462809" +//"9756051372711251054914491837034685476095423926553367264355374652153595857163724698198860485357368964" +//"3807049634423621246870868566707915720704996296083373077647528285782964567312903914752617978405994377" +//"9064157147206717895272199736902453130842229559980076472936976287378945035706933650987259357729800315"); + + return ev; +} + +namespace detail{ +// +// Calculation of the Glaisher constant depends upon calculating the +// derivative of the zeta function at 2, we can then use the relation: +// zeta'(2) = 1/6 pi^2 [euler + ln(2pi)-12ln(A)] +// To get the constant A. +// See equation 45 at http://mathworld.wolfram.com/RiemannZetaFunction.html. +// +// The derivative of the zeta function is computed by direct differentiation +// of the relation: +// (1-2^(1-s))zeta(s) = SUM(n=0, INF){ (-n)^n / (n+1)^s } +// Which gives us 2 slowly converging but alternating sums to compute, +// for this we use Algorithm 1 from "Convergent Acceleration of Alternating Series", +// Henri Cohen, Fernando Rodriguez Villegas and Don Zagier, Experimental Mathematics 9:1 (1999). +// See http://www.math.utexas.edu/users/villegas/publications/conv-accel.pdf +// +template +T zeta_series_derivative_2(unsigned digits) +{ + // Derivative of the series part, evaluated at 2: + BOOST_MATH_STD_USING + int n = digits * 301 * 13 / 10000; + T d = pow(3 + sqrt(T(8)), n); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + T s = 0; + for(int k = 0; k < n; ++k) + { + T a = -log(T(k+1)) / ((k+1) * (k+1)); + c = b - c; + s = s + c * a; + b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); + } + return s / d; +} + +template +T zeta_series_2(unsigned digits) +{ + // Series part of zeta at 2: + BOOST_MATH_STD_USING + int n = digits * 301 * 13 / 10000; + T d = pow(3 + sqrt(T(8)), n); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + T s = 0; + for(int k = 0; k < n; ++k) + { + T a = T(1) / ((k + 1) * (k + 1)); + c = b - c; + s = s + c * a; + b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); + } + return s / d; +} + +template +inline T zeta_series_lead_2() +{ + // lead part at 2: + return 2; +} + +template +inline T zeta_series_derivative_lead_2() +{ + // derivative of lead part at 2: + return -2 * boost::math::constants::ln_two(); +} + +template +inline T zeta_derivative_2(unsigned n) +{ + // zeta derivative at 2: + return zeta_series_derivative_2(n) * zeta_series_lead_2() + + zeta_series_derivative_lead_2() * zeta_series_2(n); +} + +} // namespace detail + +template +template +inline T constant_glaisher::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + + BOOST_MATH_STD_USING + typedef policies::policy > forwarding_policy; + int n = N ? (std::min)(N, tools::digits()) : tools::digits(); + T v = detail::zeta_derivative_2(n); + v *= 6; + v /= boost::math::constants::pi() * boost::math::constants::pi(); + v -= boost::math::constants::euler(); + v -= log(2 * boost::math::constants::pi()); + v /= -12; + return exp(v); + + /* + // from http://mpmath.googlecode.com/svn/data/glaisher.txt + // 20,000 digits of the Glaisher-Kinkelin constant A = exp(1/2 - zeta'(-1)) + // Computed using A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12) + // with Euler-Maclaurin summation for zeta'(2). + T g( + "1.282427129100622636875342568869791727767688927325001192063740021740406308858826" + "46112973649195820237439420646120399000748933157791362775280404159072573861727522" + "14334327143439787335067915257366856907876561146686449997784962754518174312394652" + "76128213808180219264516851546143919901083573730703504903888123418813674978133050" + "93770833682222494115874837348064399978830070125567001286994157705432053927585405" + "81731588155481762970384743250467775147374600031616023046613296342991558095879293" + "36343887288701988953460725233184702489001091776941712153569193674967261270398013" + "52652668868978218897401729375840750167472114895288815996668743164513890306962645" + "59870469543740253099606800842447417554061490189444139386196089129682173528798629" + "88434220366989900606980888785849587494085307347117090132667567503310523405221054" + "14176776156308191919997185237047761312315374135304725819814797451761027540834943" + "14384965234139453373065832325673954957601692256427736926358821692159870775858274" + "69575162841550648585890834128227556209547002918593263079373376942077522290940187"); + + return g; + */ +} + +template +template +inline T constant_rayleigh_skewness::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // 1100 digits of the Rayleigh distribution skewness + // N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] + + BOOST_MATH_STD_USING + T rs(2 * root_pi > >() + * pi_minus_three > >() + / pow(four_minus_pi > >(), static_cast(3./2)) + ); + // 6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264, + + //"0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067" + //"9440004726436754739597525250317640394102954301685809920213808351450851396781817932734836994829371322" + //"5797376021347531983451654130317032832308462278373358624120822253764532674177325950686466133508511968" + //"2389168716630349407238090652663422922072397393006683401992961569208109477307776249225072042971818671" + //"4058887072693437217879039875871765635655476241624825389439481561152126886932506682176611183750503553" + //"1218982627032068396407180216351425758181396562859085306247387212297187006230007438534686340210168288" + //"8956816965453815849613622117088096547521391672977226658826566757207615552041767516828171274858145957" + //"6137539156656005855905288420585194082284972984285863898582313048515484073396332610565441264220790791" + //"0194897267890422924599776483890102027823328602965235306539844007677157873140562950510028206251529523" + //"7428049693650605954398446899724157486062545281504433364675815915402937209673727753199567661561209251" + //"4695589950526053470201635372590001578503476490223746511106018091907936826431407434894024396366284848"); ; + return rs; +} + +template +template +inline T constant_rayleigh_kurtosis_excess::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) + // Might provide and calculate this using pi_minus_four. + BOOST_MATH_STD_USING + return - (((static_cast(6) * pi > >() + * pi > >()) + - (static_cast(24) * pi > >()) + static_cast(16) ) + / + ((pi > >() - static_cast(4)) + * (pi > >() - static_cast(4))) + ); +} + +template +template +inline T constant_rayleigh_kurtosis::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // 3 - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) + // Might provide and calculate this using pi_minus_four. + BOOST_MATH_STD_USING + return static_cast(3) - (((static_cast(6) * pi > >() + * pi > >()) + - (static_cast(24) * pi > >()) + static_cast(16) ) + / + ((pi > >() - static_cast(4)) + * (pi > >() - static_cast(4))) + ); +} + +template +template +inline T constant_log2_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / boost::math::constants::ln_two(); +} + +template +template +inline T constant_quarter_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return boost::math::constants::pi() / 4; +} + +template +template +inline T constant_one_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / boost::math::constants::pi(); +} + +template +template +inline T constant_two_div_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 * boost::math::constants::one_div_root_pi(); +} + +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) +template +template +inline T constant_first_feigenbaum::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // We know the constant to 1018 decimal digits. + // See: http://www.plouffe.fr/simon/constants/feigenbaum.txt + // Also: https://oeis.org/A006890 + // N is in binary digits; so we multiply by log_2(10) + + static_assert(N < 3.321*1018, "\nThe first Feigenbaum constant cannot be computed at runtime; it is too expensive. It is known to 1018 decimal digits; you must request less than that."); + T alpha{"4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171659848551898151344086271420279325223124429888908908599449354632367134115324817142199474556443658237932020095610583305754586176522220703854106467494942849814533917262005687556659523398756038256372256480040951071283890611844702775854285419801113440175002428585382498335715522052236087250291678860362674527213399057131606875345083433934446103706309452019115876972432273589838903794946257251289097948986768334611626889116563123474460575179539122045562472807095202198199094558581946136877445617396074115614074243754435499204869180982648652368438702799649017397793425134723808737136211601860128186102056381818354097598477964173900328936171432159878240789776614391395764037760537119096932066998361984288981837003229412030210655743295550388845849737034727532121925706958414074661841981961006129640161487712944415901405467941800198133253378592493365883070459999938375411726563553016862529032210862320550634510679399023341675"}; + return alpha; +} + +template +template +inline T constant_plastic::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + using std::sqrt; + return (cbrt(9-sqrt(T(69))) + cbrt(9+sqrt(T(69))))/cbrt(T(18)); +} + + +template +template +inline T constant_gauss::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + using std::sqrt; + T a = sqrt(T(2)); + T g = 1; + const T scale = sqrt(std::numeric_limits::epsilon())/512; + while (a-g > scale*g) + { + T anp1 = (a + g)/2; + g = sqrt(a*g); + a = anp1; + } + + return 2/(a + g); +} + +template +template +inline T constant_dottie::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // Error analysis: cos(x(1+d)) - x(1+d) = -(sin(x)+1)xd; plug in x = 0.739 gives -1.236d; take d as half an ulp gives the termination criteria we want. + using std::cos; + using std::abs; + using std::sin; + T x{".739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246"}; + T residual = cos(x) - x; + do { + x += residual/(sin(x)+1); + residual = cos(x) - x; + } while(abs(residual) > std::numeric_limits::epsilon()); + return x; +} + + +template +template +inline T constant_reciprocal_fibonacci::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // Wikipedia says Gosper has deviced a faster algorithm for this, but I read the linked paper and couldn't see it! + // In any case, k bits per iteration is fine, though it would be better to sum from smallest to largest. + // That said, the condition number is unity, so it should be fine. + T x0 = 1; + T x1 = 1; + T sum = 2; + T diff = 1; + while (diff > std::numeric_limits::epsilon()) { + T tmp = x1 + x0; + diff = 1/tmp; + sum += diff; + x0 = x1; + x1 = tmp; + } + return sum; +} + +template +template +inline T constant_laplace_limit::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // If x is the exact root, then the approximate root is given by x(1+delta). + // Plugging this into the equation for the Laplace limit gives the residual of approximately + // 2.6389delta. Take delta as half an epsilon and give some leeway so we don't get caught in an infinite loop, + // gives a termination condition as 2eps. + using std::abs; + using std::exp; + using std::sqrt; + T x{"0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168"}; + T tmp = sqrt(1+x*x); + T etmp = exp(tmp); + T residual = x*exp(tmp) - 1 - tmp; + T df = etmp -x/tmp + etmp*x*x/tmp; + do { + x -= residual/df; + tmp = sqrt(1+x*x); + etmp = exp(tmp); + residual = x*exp(tmp) - 1 - tmp; + df = etmp -x/tmp + etmp*x*x/tmp; + } while(abs(residual) > 2*std::numeric_limits::epsilon()); + return x; +} + +#endif + +} +} +} +} // namespaces + +#endif // BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED diff --git a/third-party/boost-math/include/boost/math/constants/constants.hpp b/third-party/boost-math/include/boost/math/constants/constants.hpp new file mode 100644 index 0000000000000..df702bf899324 --- /dev/null +++ b/third-party/boost-math/include/boost/math/constants/constants.hpp @@ -0,0 +1,361 @@ +// Copyright John Maddock 2005-2006, 2011. +// Copyright Paul A. Bristow 2006-2011. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED +#define BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4127 4701) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math +{ + namespace constants + { + // To permit other calculations at about 100 decimal digits with some UDT, + // it is obviously necessary to define constants to this accuracy. + + // However, some compilers do not accept decimal digits strings as long as this. + // So the constant is split into two parts, with the 1st containing at least + // long double precision, and the 2nd zero if not needed or known. + // The 3rd part permits an exponent to be provided if necessary (use zero if none) - + // the other two parameters may only contain decimal digits (and sign and decimal point), + // and may NOT include an exponent like 1.234E99. + // The second digit string is only used if T is a User-Defined Type, + // when the constant is converted to a long string literal and lexical_casted to type T. + // (This is necessary because you can't use a numeric constant + // since even a long double might not have enough digits). + + enum construction_method + { + construct_from_float = 1, + construct_from_double = 2, + construct_from_long_double = 3, + construct_from_string = 4, + construct_from_float128 = 5, + // Must be the largest value above: + construct_max = construct_from_float128 + }; + + // + // Traits class determines how to convert from string based on whether T has a constructor + // from const char* or not: + // + template + struct dummy_size{}; + + // + // Max number of binary digits in the string representations of our constants: + // + static constexpr int max_string_digits = (101 * 1000L) / 301L; + + template + struct construction_traits + { + private: + using real_precision = typename policies::precision::type; + using float_precision = typename policies::precision::type; + using double_precision = typename policies::precision::type; + using long_double_precision = typename policies::precision::type; + public: + using type = std::integral_constant::value && (real_precision::value <= float_precision::value)? construct_from_float : + std::is_convertible::value && (real_precision::value <= double_precision::value)? construct_from_double : + std::is_convertible::value && (real_precision::value <= long_double_precision::value)? construct_from_long_double : +#ifdef BOOST_MATH_USE_FLOAT128 + std::is_convertible::value && (real_precision::value <= 113) ? construct_from_float128 : +#endif + (real_precision::value <= max_string_digits) ? construct_from_string : real_precision::value + >; + }; + +#ifdef BOOST_MATH_HAS_THREADS +#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) \ + boost::once_flag f = BOOST_ONCE_INIT;\ + boost::call_once(f, &BOOST_MATH_JOIN(BOOST_MATH_JOIN(string_, get_), name)); +#else +#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) +#endif + + namespace detail{ + + template > + struct constant_return + { + using construct_type = typename construction_traits::type; + using type = typename std::conditional< + (construct_type::value == construct_from_string) || (construct_type::value > construct_max), + const Real&, Real>::type; + }; + + template + struct constant_initializer + { + static void force_instantiate() + { + init.force_instantiate(); + } + private: + struct initializer + { + initializer() + { + F(); + } + void force_instantiate()const{} + }; + static const initializer init; + }; + + template + typename constant_initializer::initializer const constant_initializer::init; + + template )) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> + struct constant_initializer2 + { + static void force_instantiate() + { + init.force_instantiate(); + } + private: + struct initializer + { + initializer() + { + F(); + } + void force_instantiate()const{} + }; + static const initializer init; + }; + + template )) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> + typename constant_initializer2::initializer const constant_initializer2::init; + + } + +#ifdef BOOST_MATH_USE_FLOAT128 +# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ + static inline constexpr T get(const std::integral_constant&) noexcept\ + { return BOOST_MATH_JOIN(x, Q); } +#else +# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) +#endif + +#ifdef BOOST_MATH_NO_CXX11_THREAD_LOCAL +# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) constant_initializer::get_from_variable_precision>::force_instantiate(); +#else +# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) +#endif + +#define BOOST_DEFINE_MATH_CONSTANT(name, x, y)\ + namespace detail{\ + template struct BOOST_MATH_JOIN(constant_, name){\ + private:\ + /* The default implementations come next: */ \ + static inline const T& get_from_string()\ + {\ + static const T result(boost::math::tools::convert_from_string(y));\ + return result;\ + }\ + /* This one is for very high precision that is none the less known at compile time: */ \ + template static T compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant)));\ + template static inline const T& get_from_compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant)))\ + {\ + static const T result = compute();\ + return result;\ + }\ + static inline const T& get_from_variable_precision()\ + {\ + static BOOST_MATH_THREAD_LOCAL int digits = 0;\ + static BOOST_MATH_THREAD_LOCAL T value;\ + int current_digits = boost::math::tools::digits();\ + if(digits != current_digits)\ + {\ + value = current_digits > max_string_digits ? compute<0>() : T(boost::math::tools::convert_from_string(y));\ + digits = current_digits; \ + }\ + return value;\ + }\ + /* public getters come next */\ + public:\ + static inline const T& get(const std::integral_constant&)\ + {\ + constant_initializer::get_from_string >::force_instantiate();\ + return get_from_string();\ + }\ + BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant) noexcept\ + { return BOOST_MATH_JOIN(x, F); }\ + BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant&) noexcept\ + { return x; }\ + BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant&) noexcept\ + { return BOOST_MATH_JOIN(x, L); }\ + BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ + template static inline const T& get(const std::integral_constant&)\ + {\ + constant_initializer2::template get_from_compute >::force_instantiate();\ + return get_from_compute(); \ + }\ + /* This one is for true arbitrary precision, which may well vary at runtime: */ \ + static inline T get(const std::integral_constant&)\ + {\ + BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)\ + return get_from_variable_precision(); }\ + }; /* end of struct */\ + } /* namespace detail */ \ + \ + \ + /* The actual forwarding function: */ \ + template BOOST_MATH_GPU_ENABLED inline constexpr typename detail::constant_return::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) BOOST_MATH_NOEXCEPT(T)\ + { return detail:: BOOST_MATH_JOIN(constant_, name)::get(typename construction_traits::type()); }\ + template BOOST_MATH_GPU_ENABLED inline constexpr typename detail::constant_return::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)\ + { return name >(); }\ + \ + \ + /* Now the namespace specific versions: */ \ + } namespace float_constants{ static constexpr float name = BOOST_MATH_JOIN(x, F); }\ + namespace double_constants{ static constexpr double name = x; } \ + namespace long_double_constants{ static constexpr long double name = BOOST_MATH_JOIN(x, L); }\ + namespace constants{ + +#else // NVRTC simplified macro definition + +#define BOOST_DEFINE_MATH_CONSTANT(name, value, str_value) template BOOST_MATH_GPU_ENABLED constexpr T name() noexcept { return static_cast(value); } + +namespace boost { +namespace math { +namespace constants { + +#endif + + BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000e-01, "5.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") + BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333e-01, "3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333e-01") + BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(two_thirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(sixth, 1.666666666666666666666666666666666666e-01, "1.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(three_quarters, 7.500000000000000000000000000000000000e-01, "7.50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") + BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078e+00, "1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623e+00") + BOOST_DEFINE_MATH_CONSTANT(root_three, 1.732050807568877293527446341505872366e+00, "1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614142e+00") + BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") + BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680e-01, "6.93147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996418687542001481021e-01") + BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694e-01, "-3.66512920581664327012439158232669469454263447837105263053677713670561615319352738549455822856698908358302523045e-01") + BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637e+00, "1.17741002251547469101156932645969963774738568938582053852252575650002658854698492680841813836877081106747157858e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") + BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00") + BOOST_DEFINE_MATH_CONSTANT(half_pi, 1.570796326794896619231321691639751442e+00, "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00") + BOOST_DEFINE_MATH_CONSTANT(third_pi, 1.047197551196597746154214461093167628e+00, "1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550e+00") + BOOST_DEFINE_MATH_CONSTANT(sixth_pi, 5.235987755982988730771072305465838140e-01, "5.23598775598298873077107230546583814032861566562517636829157432051302734381034833104672470890352844663691347752e-01") + BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768e+00, "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303e+00") + BOOST_DEFINE_MATH_CONSTANT(two_thirds_pi, 2.094395102393195492308428922186335256e+00, "2.09439510239319549230842892218633525613144626625007054731662972820521093752413933241868988356141137865476539101e+00") + BOOST_DEFINE_MATH_CONSTANT(three_quarters_pi, 2.356194490192344928846982537459627163e+00, "2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488e+00") + BOOST_DEFINE_MATH_CONSTANT(four_thirds_pi, 4.188790204786390984616857844372670512e+00, "4.18879020478639098461685784437267051226289253250014109463325945641042187504827866483737976712282275730953078202e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620e-01, "1.59154943091895335768883763372514362034459645740456448747667344058896797634226535090113802766253085956072842727e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 3.989422804014326779399460599343818684e-01, "3.98942280401432677939946059934381868475858631164934657665925829670657925899301838501252333907306936430302558863e-01") + BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182e+00, "1.77245385090551602729816748334114518279754945612238712821380778985291128459103218137495065673854466541622682362e+00") + BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626e+00, "1.25331413731550025120788264240552262650349337030496915831496178817114682730392098747329791918902863305800498633e+00") + BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253e+00, "2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659583837805726611600997267e+00") + BOOST_DEFINE_MATH_CONSTANT(log_root_two_pi, 9.189385332046727417803297364056176398e-01, "9.18938533204672741780329736405617639861397473637783412817151540482765695927260397694743298635954197622005646625e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") + BOOST_DEFINE_MATH_CONSTANT(root_one_div_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") + BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841e-01, "1.41592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513e-01") + BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158e-01, "8.58407346410206761537356616720497115802830600624894179025055407692183593713791001371965174657882932017851913487e-01") + //BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807e-01, "7.95316767371597544348395335056806580727639173327713205445302234388856268267518187590758006888600828436839800178e-01") + BOOST_DEFINE_MATH_CONSTANT(pi_pow_e, 2.245915771836104547342715220454373502e+01, "2.24591577183610454734271522045437350275893151339966922492030025540669260403991179123185197527271430315314500731e+01") + BOOST_DEFINE_MATH_CONSTANT(pi_sqr, 9.869604401089358618834490999876151135e+00, "9.86960440108935861883449099987615113531369940724079062641334937622004482241920524300177340371855223182402591377e+00") + BOOST_DEFINE_MATH_CONSTANT(pi_sqr_div_six, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") + BOOST_DEFINE_MATH_CONSTANT(pi_cubed, 3.100627668029982017547631506710139520e+01, "3.10062766802998201754763150671013952022252885658851076941445381038063949174657060375667010326028861930301219616e+01") + BOOST_DEFINE_MATH_CONSTANT(cbrt_pi, 1.464591887561523263020142527263790391e+00, "1.46459188756152326302014252726379039173859685562793717435725593713839364979828626614568206782035382089750397002e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_cbrt_pi, 6.827840632552956814670208331581645981e-01, "6.82784063255295681467020833158164598108367515632448804042681583118899226433403918237673501922595519865685577274e-01") + BOOST_DEFINE_MATH_CONSTANT(log2_e, 1.44269504088896340735992468100189213742664595415298, "1.44269504088896340735992468100189213742664595415298593413544940693110921918118507988552662289350634449699751830965e+00") + BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497e+00, "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193e+00") + BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534e-01, "6.06530659712633423603799534991180453441918135487186955682892158735056519413748423998647611507989456026423789794e-01") + BOOST_DEFINE_MATH_CONSTANT(exp_minus_one, 3.678794411714423215955237701614608674e-01, "3.67879441171442321595523770161460867445811131031767834507836801697461495744899803357147274345919643746627325277e-01") + BOOST_DEFINE_MATH_CONSTANT(e_pow_pi, 2.314069263277926900572908636794854738e+01, "2.31406926327792690057290863679485473802661062426002119934450464095243423506904527835169719970675492196759527048e+01") + BOOST_DEFINE_MATH_CONSTANT(root_e, 1.648721270700128146848650787814163571e+00, "1.64872127070012814684865078781416357165377610071014801157507931164066102119421560863277652005636664300286663776e+00") + BOOST_DEFINE_MATH_CONSTANT(log10_e, 4.342944819032518276511289189166050822e-01, "4.34294481903251827651128918916605082294397005803666566114453783165864649208870774729224949338431748318706106745e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_log10_e, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") + BOOST_DEFINE_MATH_CONSTANT(ln_ten, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") + BOOST_DEFINE_MATH_CONSTANT(degree, 1.745329251994329576923690768488612713e-02, "1.74532925199432957692369076848861271344287188854172545609719144017100911460344944368224156963450948221230449251e-02") + BOOST_DEFINE_MATH_CONSTANT(radian, 5.729577951308232087679815481410517033e+01, "5.72957795130823208767981548141051703324054724665643215491602438612028471483215526324409689958511109441862233816e+01") + BOOST_DEFINE_MATH_CONSTANT(sin_one, 8.414709848078965066525023216302989996e-01, "8.41470984807896506652502321630298999622563060798371065672751709991910404391239668948639743543052695854349037908e-01") + BOOST_DEFINE_MATH_CONSTANT(cos_one, 5.403023058681397174009366074429766037e-01, "5.40302305868139717400936607442976603732310420617922227670097255381100394774471764517951856087183089343571731160e-01") + BOOST_DEFINE_MATH_CONSTANT(sinh_one, 1.175201193643801456882381850595600815e+00, "1.17520119364380145688238185059560081515571798133409587022956541301330756730432389560711745208962339184041953333e+00") + BOOST_DEFINE_MATH_CONSTANT(cosh_one, 1.543080634815243778477905620757061682e+00, "1.54308063481524377847790562075706168260152911236586370473740221471076906304922369896426472643554303558704685860e+00") + BOOST_DEFINE_MATH_CONSTANT(phi, 1.618033988749894848204586834365638117e+00, "1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475408808e+00") + BOOST_DEFINE_MATH_CONSTANT(ln_phi, 4.812118250596034474977589134243684231e-01, "4.81211825059603447497758913424368423135184334385660519661018168840163867608221774412009429122723474997231839958e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_ln_phi, 2.078086921235027537601322606117795767e+00, "2.07808692123502753760132260611779576774219226778328348027813992191974386928553540901445615414453604821933918634e+00") + BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310e-01, "5.77215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749514631447250e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_euler, 1.732454714600633473583025315860829681e+00, "1.73245471460063347358302531586082968115577655226680502204843613287065531408655243008832840219409928068072365714e+00") + BOOST_DEFINE_MATH_CONSTANT(euler_sqr, 3.331779238077186743183761363552442266e-01, "3.33177923807718674318376136355244226659417140249629743150833338002265793695756669661263268631715977303039565603e-01") + BOOST_DEFINE_MATH_CONSTANT(zeta_two, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") + BOOST_DEFINE_MATH_CONSTANT(zeta_three, 1.202056903159594285399738161511449990e+00, "1.20205690315959428539973816151144999076498629234049888179227155534183820578631309018645587360933525814619915780e+00") + BOOST_DEFINE_MATH_CONSTANT(catalan, 9.159655941772190150546035149323841107e-01, "9.15965594177219015054603514932384110774149374281672134266498119621763019776254769479356512926115106248574422619e-01") + BOOST_DEFINE_MATH_CONSTANT(glaisher, 1.282427129100622636875342568869791727e+00, "1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237439420646120e+00") + BOOST_DEFINE_MATH_CONSTANT(khinchin, 2.685452001065306445309714835481795693e+00, "2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515346591e+00") + BOOST_DEFINE_MATH_CONSTANT(extreme_value_skewness, 1.139547099404648657492793019389846112e+00, "1.13954709940464865749279301938984611208759979583655182472165571008524800770607068570718754688693851501894272049e+00") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis, 3.245089300687638062848660410619754415e+00, "3.24508930068763806284866041061975441541706673178920936177133764493367904540874159051490619368679348977426462633e+00") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis_excess, 2.450893006876380628486604106197544154e-01, "2.45089300687638062848660410619754415417066731789209361771337644933679045408741590514906193686793489774264626328e-01") + + BOOST_DEFINE_MATH_CONSTANT(two_div_pi, 6.366197723675813430755350534900574481e-01, "6.36619772367581343075535053490057448137838582961825794990669376235587190536906140360455211065012343824291370907e-01") + BOOST_DEFINE_MATH_CONSTANT(root_two_div_pi, 7.978845608028653558798921198687637369e-01, "7.97884560802865355879892119868763736951717262329869315331851659341315851798603677002504667814613872860605117725e-01") + BOOST_DEFINE_MATH_CONSTANT(quarter_pi, 0.785398163397448309615660845819875721049292, "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773") + BOOST_DEFINE_MATH_CONSTANT(one_div_pi, 0.3183098861837906715377675267450287240689192, "0.31830988618379067153776752674502872406891929148091289749533468811779359526845307018022760553250617191214568545351") + BOOST_DEFINE_MATH_CONSTANT(two_div_root_pi, 1.12837916709551257389615890312154517168810125, "1.12837916709551257389615890312154517168810125865799771368817144342128493688298682897348732040421472688605669581272") + + BOOST_DEFINE_MATH_CONSTANT(first_feigenbaum, 4.66920160910299067185320382046620161725818557747576863274, "4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171") + BOOST_DEFINE_MATH_CONSTANT(plastic, 1.324717957244746025960908854478097340734404056901733364534, "1.32471795724474602596090885447809734073440405690173336453401505030282785124554759405469934798178728032991") + BOOST_DEFINE_MATH_CONSTANT(gauss, 0.834626841674073186281429732799046808993993013490347002449, "0.83462684167407318628142973279904680899399301349034700244982737010368199270952641186969116035127532412906785") + BOOST_DEFINE_MATH_CONSTANT(dottie, 0.739085133215160641655312087673873404013411758900757464965, "0.739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246") + BOOST_DEFINE_MATH_CONSTANT(reciprocal_fibonacci, 3.35988566624317755317201130291892717968890513, "3.35988566624317755317201130291892717968890513373196848649555381532513031899668338361541621645679008729704") + BOOST_DEFINE_MATH_CONSTANT(laplace_limit, 0.662743419349181580974742097109252907056233549115022417, "0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168") + +template +BOOST_MATH_GPU_ENABLED inline constexpr T tau() { return two_pi(); } + +} // namespace constants +} // namespace math +} // namespace boost + +// +// We deliberately include this *after* all the declarations above, +// that way the calculation routines can call on other constants above: +// +// NVRTC will not have a type that needs runtime calculation +// +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +#endif // BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED + + diff --git a/third-party/boost-math/include/boost/math/constants/info.hpp b/third-party/boost-math/include/boost/math/constants/info.hpp new file mode 100644 index 0000000000000..b30c651e67a01 --- /dev/null +++ b/third-party/boost-math/include/boost/math/constants/info.hpp @@ -0,0 +1,169 @@ +// Copyright John Maddock 2010. +// 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) + +#ifdef _MSC_VER +# pragma once +#endif + +#ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED +#define BOOST_MATH_CONSTANTS_INFO_INCLUDED + +#include +#include +#include +#ifndef BOOST_MATH_NO_RTTI +#include +#endif + +namespace boost{ namespace math{ namespace constants{ + + namespace detail{ + + template + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) + { + #ifndef BOOST_MATH_NO_RTTI + return typeid(T).name(); + #else + return "unknown"; + #endif + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float)) + { + return "float"; + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double)) + { + return "double"; + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double)) + { + return "long double"; + } + + } + +template +void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) +{ + using detail::nameof; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + os << + "Information on the Implementation and Handling of \n" + "Mathematical Constants for Type " << nameof() << + "\n\n" + "Checking for std::numeric_limits<" << nameof() << "> specialisation: " << + (std::numeric_limits::is_specialized ? "yes" : "no") << std::endl; + if(std::numeric_limits::is_specialized) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the radix is " << std::numeric_limits::radix << ".\n"; + if (std::numeric_limits::radix == 2) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" << std::numeric_limits::digits << " binary digits.\n"; + } + else if (std::numeric_limits::radix == 10) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" << std::numeric_limits::digits10 << " decimal digits.\n"; + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" + << std::numeric_limits::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit. + } + else + { + os << "Unknown radix = " << std::numeric_limits::radix << "\n"; + } + } + typedef typename boost::math::policies::precision::type precision_type; + if(precision_type::value) + { + if (std::numeric_limits::radix == 2) + { + os << + "boost::math::policies::precision<" << nameof() << ", " << nameof() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n"; + } + else if (std::numeric_limits::radix == 10) + { + os << + "boost::math::policies::precision<" << nameof() << ", " << nameof() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n"; + } + else + { + os << "Unknown radix = " << std::numeric_limits::radix << "\n"; + } + } + else + { + os << + "boost::math::policies::precision<" << nameof() << ", Policy> \n" + "reports that there is no compile type precision available.\n" + "boost::math::tools::digits<" << nameof() << ">() \n" + "reports that the current runtime precision is \n" << + boost::math::tools::digits() << " binary digits.\n"; + } + + typedef typename construction_traits::type construction_type; + + switch(construction_type::value) + { + case 0: + os << + "No compile time precision is available, the construction method \n" + "will be decided at runtime and results will not be cached \n" + "- this may lead to poor runtime performance.\n" + "Current runtime precision indicates that\n"; + if(boost::math::tools::digits() > max_string_digits) + { + os << "the constant will be recalculated on each call.\n"; + } + else + { + os << "the constant will be constructed from a string on each call.\n"; + } + break; + case 1: + os << + "The constant will be constructed from a float.\n"; + break; + case 2: + os << + "The constant will be constructed from a double.\n"; + break; + case 3: + os << + "The constant will be constructed from a long double.\n"; + break; + case 4: + os << + "The constant will be constructed from a string (and the result cached).\n"; + break; + default: + os << + "The constant will be calculated (and the result cached).\n"; + break; + } + os << std::endl; +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +template +void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) +{ + print_info_on_type >(os); +} + +}}} // namespaces + +#endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp new file mode 100644 index 0000000000000..ae5af191f5048 --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp @@ -0,0 +1,1012 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement quadruple-precision support. + +#ifndef BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ +#define BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ + +#include +#include + +#if (defined(__GNUC__) && defined(BOOST_HAS_FLOAT128)) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) && defined(__GNUC__) + // Several versions of Mingw and probably cygwin too have broken + // libquadmath implementations that segfault as soon as you call + // expq or any function that depends on it. +#define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +#endif + +// Here is a helper function used for raising the value of a given +// floating-point type to the power of n, where n has integral type. +namespace boost { + namespace math { + namespace cstdfloat { + namespace detail { + + template + inline float_type pown(const float_type& x, const integer_type p) + { + const bool isneg = (x < 0); + const bool isnan = (x != x); + const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + if (isnan) { return x; } + + if (isinf) { return std::numeric_limits::quiet_NaN(); } + + const bool x_is_neg = (x < 0); + const float_type abs_x = (x_is_neg ? -x : x); + + if (p < static_cast(0)) + { + if (abs_x < (std::numeric_limits::min)()) + { + return (x_is_neg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + else + { + return float_type(1) / pown(x, static_cast(-p)); + } + } + + if (p == static_cast(0)) + { + return float_type(1); + } + else + { + if (p == static_cast(1)) { return x; } + + if (abs_x > (std::numeric_limits::max)()) + { + return (x_is_neg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + if (p == static_cast(2)) { return (x * x); } + else if (p == static_cast(3)) { return ((x * x) * x); } + else if (p == static_cast(4)) { const float_type x2 = (x * x); return (x2 * x2); } + else + { + // The variable xn stores the binary powers of x. + float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1)); + float_type xn(x); + + integer_type p2 = p; + + while (integer_type(p2 /= 2) != integer_type(0)) + { + // Square xn for each binary power. + xn *= xn; + + const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0)); + + if (has_binary_power) + { + // Multiply the result with each binary power contained in the exponent. + result *= xn; + } + } + + return result; + } + } + } + + } + } + } +} // boost::math::cstdfloat::detail + +// We will now define preprocessor symbols representing quadruple-precision functions. +#if defined(__INTEL_COMPILER) +#define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq +#define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq +#define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq +#define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq +#define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq +#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) +#define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq +#endif +#define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq +#define BOOST_CSTDFLOAT_FLOAT128_EXP __expq +#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q +#define BOOST_CSTDFLOAT_FLOAT128_POW __powq +#define BOOST_CSTDFLOAT_FLOAT128_LOG __logq +#define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q +#define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq +#define BOOST_CSTDFLOAT_FLOAT128_COS __cosq +#define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq +#define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq +#define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq +#define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq +#define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq +#define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq +#define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq +#define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq +#define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q +#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq +// begin more functions +#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER __remainderq +#define BOOST_CSTDFLOAT_FLOAT128_REMQUO __remquoq +#define BOOST_CSTDFLOAT_FLOAT128_FMA __fmaq +#define BOOST_CSTDFLOAT_FLOAT128_FMAX __fmaxq +#define BOOST_CSTDFLOAT_FLOAT128_FMIN __fminq +#define BOOST_CSTDFLOAT_FLOAT128_FDIM __fdimq +#define BOOST_CSTDFLOAT_FLOAT128_NAN __nanq +//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 __exp2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG2 __log2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG1P __log1pq +#define BOOST_CSTDFLOAT_FLOAT128_CBRT __cbrtq +#define BOOST_CSTDFLOAT_FLOAT128_HYPOT __hypotq +#define BOOST_CSTDFLOAT_FLOAT128_ERF __erfq +#define BOOST_CSTDFLOAT_FLOAT128_ERFC __erfcq +#define BOOST_CSTDFLOAT_FLOAT128_LLROUND __llroundq +#define BOOST_CSTDFLOAT_FLOAT128_LROUND __lroundq +#define BOOST_CSTDFLOAT_FLOAT128_ROUND __roundq +#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT __nearbyintq +#define BOOST_CSTDFLOAT_FLOAT128_LLRINT __llrintq +#define BOOST_CSTDFLOAT_FLOAT128_LRINT __lrintq +#define BOOST_CSTDFLOAT_FLOAT128_RINT __rintq +#define BOOST_CSTDFLOAT_FLOAT128_MODF __modfq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN __scalblnq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBN __scalbnq +#define BOOST_CSTDFLOAT_FLOAT128_ILOGB __ilogbq +#define BOOST_CSTDFLOAT_FLOAT128_LOGB __logbq +#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER __nextafterq +//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD __nexttowardq +#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN __copysignq +#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT __signbitq +//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY __fpclassifyq +//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE __isfiniteq +#define BOOST_CSTDFLOAT_FLOAT128_ISINF __isinfq +#define BOOST_CSTDFLOAT_FLOAT128_ISNAN __isnanq +//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL __isnormalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER __isgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL __isgreaterequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS __islessq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL __islessequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER __islessgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED __isunorderedq +// end more functions +#elif defined(__GNUC__) +#define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq +#define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq +#define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq +#define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq +#define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq +#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) +#define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq +#endif +#define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq +#define BOOST_CSTDFLOAT_FLOAT128_POW powq +#define BOOST_CSTDFLOAT_FLOAT128_LOG logq +#define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q +#define BOOST_CSTDFLOAT_FLOAT128_SIN sinq +#define BOOST_CSTDFLOAT_FLOAT128_COS cosq +#define BOOST_CSTDFLOAT_FLOAT128_TAN tanq +#define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq +#define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq +#define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q +#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq +#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) +#define BOOST_CSTDFLOAT_FLOAT128_EXP expq +#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q +#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq +#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq +#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq +#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq +#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq +#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +#define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch +#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch +#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch +#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +// begin more functions +#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER remainderq +#define BOOST_CSTDFLOAT_FLOAT128_REMQUO remquoq +#define BOOST_CSTDFLOAT_FLOAT128_FMA fmaq +#define BOOST_CSTDFLOAT_FLOAT128_FMAX fmaxq +#define BOOST_CSTDFLOAT_FLOAT128_FMIN fminq +#define BOOST_CSTDFLOAT_FLOAT128_FDIM fdimq +#define BOOST_CSTDFLOAT_FLOAT128_NAN nanq +//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 exp2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG2 log2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG1P log1pq +#define BOOST_CSTDFLOAT_FLOAT128_CBRT cbrtq +#define BOOST_CSTDFLOAT_FLOAT128_HYPOT hypotq +#define BOOST_CSTDFLOAT_FLOAT128_ERF erfq +#define BOOST_CSTDFLOAT_FLOAT128_ERFC erfcq +#define BOOST_CSTDFLOAT_FLOAT128_LLROUND llroundq +#define BOOST_CSTDFLOAT_FLOAT128_LROUND lroundq +#define BOOST_CSTDFLOAT_FLOAT128_ROUND roundq +#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT nearbyintq +#define BOOST_CSTDFLOAT_FLOAT128_LLRINT llrintq +#define BOOST_CSTDFLOAT_FLOAT128_LRINT lrintq +#define BOOST_CSTDFLOAT_FLOAT128_RINT rintq +#define BOOST_CSTDFLOAT_FLOAT128_MODF modfq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN scalblnq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBN scalbnq +#define BOOST_CSTDFLOAT_FLOAT128_ILOGB ilogbq +#define BOOST_CSTDFLOAT_FLOAT128_LOGB logbq +#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER nextafterq +//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD nexttowardq +#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN copysignq +#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT signbitq +//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY fpclassifyq +//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE isfiniteq +#define BOOST_CSTDFLOAT_FLOAT128_ISINF isinfq +#define BOOST_CSTDFLOAT_FLOAT128_ISNAN isnanq +//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL isnormalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER isgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL isgreaterequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS islessq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL islessequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER islessgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED isunorderedq +// end more functions +#endif + +// Implement quadruple-precision functions in the namespace +// boost::math::cstdfloat::detail. Subsequently inject these into the +// std namespace via *using* directive. + +// Begin with some forward function declarations. Also implement patches +// for compilers that have broken float128 exponential functions. + +extern "C" int quadmath_snprintf(char*, std::size_t, const char*, ...) BOOST_MATH_NOTHROW; + +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP(boost::math::cstdfloat::detail::float_internal128_t, int) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP(boost::math::cstdfloat::detail::float_internal128_t, int*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMOD(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN2(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + +// begin more functions +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMAINDER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMQUO(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, int*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMA(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMAX(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMIN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FDIM(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NAN(const char*) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP2 (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG2(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG1P(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CBRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_HYPOT(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERF(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERFC(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLRINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LRINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_RINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_MODF(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBLN(boost::math::cstdfloat::detail::float_internal128_t, long int) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBN(boost::math::cstdfloat::detail::float_internal128_t, int) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ILOGB(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOGB(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISFINITE (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISINF(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISNAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ISNORMAL (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATER (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESS (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + // end more functions + +#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) + +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; + +#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS + +// Forward declaration of the patched exponent function, exp(x). +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x); + +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Compute exp(x) - 1 for x small. + + // Use an order-12 Pade approximation of the exponential function. + // PadeApproximant[Exp[x] - 1, {x, 0, 12, 12}]. + + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + float_type sum; + + if (x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)) + { + sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1); + } + else + { + const float_type x2 = (x * x); + + const float_type top = ((((( float_type(BOOST_FLOAT128_C(2.4087176110456818621091195109360728010934088788572E-13)) * x2 + + float_type(BOOST_FLOAT128_C(9.2735628025258751691201101171038802842096241836000E-10))) * x2 + + float_type(BOOST_FLOAT128_C(9.0806726962333369656024118266681195742980640005812E-07))) * x2 + + float_type(BOOST_FLOAT128_C(3.1055900621118012422360248447204968944099378881988E-04))) * x2 + + float_type(BOOST_FLOAT128_C(3.6231884057971014492753623188405797101449275362319E-02))) * x2 + + float_type(BOOST_FLOAT128_C(1.00000000000000000000000000000000000000000000000000000))) + ; + + const float_type bot = (((((((((((( float_type(BOOST_FLOAT128_C(+7.7202487533515444298369215094104897470942592271063E-16)) * x + + float_type(BOOST_FLOAT128_C(-1.2043588055228409310545597554680364005467044394286E-13))) * x + + float_type(BOOST_FLOAT128_C(+9.2735628025258751691201101171038802842096241836000E-12))) * x + + float_type(BOOST_FLOAT128_C(-4.6367814012629375845600550585519401421048120918000E-10))) * x + + float_type(BOOST_FLOAT128_C(+1.6692413044546575304416198210786984511577323530480E-08))) * x + + float_type(BOOST_FLOAT128_C(-4.5403363481166684828012059133340597871490320002906E-07))) * x + + float_type(BOOST_FLOAT128_C(+9.5347063310450038138825324180015255530129672006102E-06))) * x + + float_type(BOOST_FLOAT128_C(-1.5527950310559006211180124223602484472049689440994E-04))) * x + + float_type(BOOST_FLOAT128_C(+1.9409937888198757763975155279503105590062111801242E-03))) * x + + float_type(BOOST_FLOAT128_C(-1.8115942028985507246376811594202898550724637681159E-02))) * x + + float_type(BOOST_FLOAT128_C(+1.1956521739130434782608695652173913043478260869565E-01))) * x + + float_type(BOOST_FLOAT128_C(-0.50000000000000000000000000000000000000000000000000000))) * x + + float_type(BOOST_FLOAT128_C(+1.00000000000000000000000000000000000000000000000000000))) + ; + + sum = (x * top) / bot; + } + + return sum; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the expq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + // Scale the argument x to the range (-ln2 < x < ln2). + constexpr float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299)); + const float_type x_over_ln2 = x * one_over_ln2; + + int n; + + if (x != x) + { + // The argument is NaN. + return std::numeric_limits::quiet_NaN(); + } + else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) + { + // The absolute value of the argument exceeds ln2. + n = static_cast(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2)); + } + else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) + { + // The absolute value of the argument is less than ln2. + n = 0; + } + else + { + // The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality). + return float_type(2); + } + + // Check if the argument is very near an integer. + const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS)) + { + // Return e^n for arguments very near an integer. + return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast(floor_of_x)); + } + + // Compute the scaled argument alpha. + const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)); + + // Compute the polynomial approximation of expm1(alpha) and add to it + // in order to obtain the scaled result. + const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1); + + // Rescale the result and return it. + return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the sinhq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + // Here, we use the following: + // Set: ex = exp(x) + // Set: em1 = expm1(x) + // Then + // sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1 + // sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1 + + const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1)) + { + const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); + + return ((em1 * 2) + (em1 * em1)) / (ex * 2); + } + else + { + return (ex - (float_type(1) / ex)) / 2; + } +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the coshq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + return (ex + (float_type(1) / ex)) / 2; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the tanhq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + const float_type ex_minus = (float_type(1) / ex_plus); + return (ex_plus - ex_minus) / (ex_plus + ex_minus); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the asinh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1))); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the acosh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type zp(x + float_type(1)); + const float_type zm(x - float_type(1)); + + return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp))); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the atanh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + return (::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x) + - ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the tgammaq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + if (x > float_type(0)) + { + return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x)); + } + else if (x < float_type(0)) + { + // For x < 0, compute tgamma(-x) and use the reflection formula. + const float_type positive_x = -x; + float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x); + const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x); + + // Take the reflection checks (slightly adapted) from . + const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x)); + + constexpr float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511); + + if (floor_of_z_is_equal_to_z) + { + const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); + + return (is_odd ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x); + + gamma_value *= sinpx_value; + + const bool result_is_too_large_to_represent = ((::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1)) + && (((std::numeric_limits::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi)); + + if (result_is_too_large_to_represent) + { + const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); + + return (is_odd ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + gamma_value = -my_pi / gamma_value; + + if ((gamma_value > float_type(0)) || (gamma_value < float_type(0))) + { + return gamma_value; + } + else + { + // The value of gamma is too small to represent. Return 0.0 here. + return float_type(0); + } + } + else + { + // Gamma of zero is complex infinity. Return NaN here. + return std::numeric_limits::quiet_NaN(); + } +} +#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS + +// Define the quadruple-precision functions in the namespace boost::math::cstdfloat::detail. + +namespace boost { + namespace math { + namespace cstdfloat { + namespace detail { + inline boost::math::cstdfloat::detail::float_internal128_t ldexp(boost::math::cstdfloat::detail::float_internal128_t x, int n) { return ::BOOST_CSTDFLOAT_FLOAT128_LDEXP(x, n); } + inline boost::math::cstdfloat::detail::float_internal128_t frexp(boost::math::cstdfloat::detail::float_internal128_t x, int* pn) { return ::BOOST_CSTDFLOAT_FLOAT128_FREXP(x, pn); } + inline boost::math::cstdfloat::detail::float_internal128_t fabs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t abs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t floor(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); } + inline boost::math::cstdfloat::detail::float_internal128_t ceil(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sqrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t trunc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC(x); } + inline boost::math::cstdfloat::detail::float_internal128_t exp(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); } + inline boost::math::cstdfloat::detail::float_internal128_t expm1(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); } + inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, a); } + inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, int a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, boost::math::cstdfloat::detail::float_internal128_t(a)); } + inline boost::math::cstdfloat::detail::float_internal128_t log(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x); } + inline boost::math::cstdfloat::detail::float_internal128_t log10(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t asin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t acos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t atan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t asinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t acosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t atanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t fmod(boost::math::cstdfloat::detail::float_internal128_t a, boost::math::cstdfloat::detail::float_internal128_t b) { return ::BOOST_CSTDFLOAT_FLOAT128_FMOD(a, b); } + inline boost::math::cstdfloat::detail::float_internal128_t atan2(boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN2(y, x); } + inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); } + // begin more functions + inline boost::math::cstdfloat::detail::float_internal128_t remainder(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_REMAINDER(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t remquo(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, int* z) { return ::BOOST_CSTDFLOAT_FLOAT128_REMQUO(x, y, z); } + inline boost::math::cstdfloat::detail::float_internal128_t fma(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return BOOST_CSTDFLOAT_FLOAT128_FMA(x, y, z); } + + inline boost::math::cstdfloat::detail::float_internal128_t fmax(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmax(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmax(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t fmin(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmin(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmin(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + + inline boost::math::cstdfloat::detail::float_internal128_t fdim(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FDIM(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t nanq(const char* x) { return ::BOOST_CSTDFLOAT_FLOAT128_NAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t exp2(boost::math::cstdfloat::detail::float_internal128_t x) + { + return ::BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t(2), x); + } + inline boost::math::cstdfloat::detail::float_internal128_t log2(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG2(x); } + inline boost::math::cstdfloat::detail::float_internal128_t log1p(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG1P(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cbrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CBRT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x*x + y * y + z * z); } + inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + hypot(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + hypot(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + + + inline boost::math::cstdfloat::detail::float_internal128_t erf(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERF(x); } + inline boost::math::cstdfloat::detail::float_internal128_t erfc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERFC(x); } + inline long long int llround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLROUND(x); } + inline long int lround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LROUND(x); } + inline boost::math::cstdfloat::detail::float_internal128_t round(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ROUND(x); } + inline boost::math::cstdfloat::detail::float_internal128_t nearbyint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(x); } + inline long long int llrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLRINT(x); } + inline long int lrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LRINT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t rint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_RINT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t modf(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t* y) { return ::BOOST_CSTDFLOAT_FLOAT128_MODF(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t scalbln(boost::math::cstdfloat::detail::float_internal128_t x, long int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBLN(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t scalbn(boost::math::cstdfloat::detail::float_internal128_t x, int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBN(x, y); } + inline int ilogb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ILOGB(x); } + inline boost::math::cstdfloat::detail::float_internal128_t logb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOGB(x); } + inline boost::math::cstdfloat::detail::float_internal128_t nextafter(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t nexttoward(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return -(::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(-x, -y)); } + inline boost::math::cstdfloat::detail::float_internal128_t copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(x, y); } + inline bool signbit BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(x); } + inline int fpclassify BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) + { + if (::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x)) + return FP_NAN; + else if (::BOOST_CSTDFLOAT_FLOAT128_ISINF(x)) + return FP_INFINITE; + else if (x == BOOST_FLOAT128_C(0.0)) + return FP_ZERO; + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_CSTDFLOAT_FLOAT128_MIN) + return FP_SUBNORMAL; + else + return FP_NORMAL; + } + inline bool isfinite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) + { + return !::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) && !::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); + } + inline bool isinf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); } + inline bool isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x); } + inline bool isnormal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return boost::math::cstdfloat::detail::fpclassify BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) == FP_NORMAL; } + inline bool isgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x > y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + inline bool isgreaterequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x >= y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreaterequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreaterequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreaterequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreaterequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + inline bool isless BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x < y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isless BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isless BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isless BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isless BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool islessequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x <= y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessequal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool islessgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return (x < y) || (x > y); + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessgreater BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool isunordered BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) || ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isunordered BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isunordered BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isunordered BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isunordered BOOST_MATH_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + // end more functions + } + } + } +} // boost::math::cstdfloat::detail + +// We will now inject the quadruple-precision functions +// into the std namespace. This is done via *using* directive. +namespace std +{ + using boost::math::cstdfloat::detail::ldexp; + using boost::math::cstdfloat::detail::frexp; + using boost::math::cstdfloat::detail::fabs; + +#if !(defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && (__GNUC__ >= 7)) +#if (defined(__clang__) && !(!defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128))) || (__GNUC__ <= 6 && !defined(__clang__)) + // workaround for clang using libstdc++ and old GCC + using boost::math::cstdfloat::detail::abs; +#endif +#endif + + using boost::math::cstdfloat::detail::floor; + using boost::math::cstdfloat::detail::ceil; + using boost::math::cstdfloat::detail::sqrt; + using boost::math::cstdfloat::detail::trunc; + using boost::math::cstdfloat::detail::exp; + using boost::math::cstdfloat::detail::expm1; + using boost::math::cstdfloat::detail::pow; + using boost::math::cstdfloat::detail::log; + using boost::math::cstdfloat::detail::log10; + using boost::math::cstdfloat::detail::sin; + using boost::math::cstdfloat::detail::cos; + using boost::math::cstdfloat::detail::tan; + using boost::math::cstdfloat::detail::asin; + using boost::math::cstdfloat::detail::acos; + using boost::math::cstdfloat::detail::atan; + using boost::math::cstdfloat::detail::sinh; + using boost::math::cstdfloat::detail::cosh; + using boost::math::cstdfloat::detail::tanh; + using boost::math::cstdfloat::detail::asinh; + using boost::math::cstdfloat::detail::acosh; + using boost::math::cstdfloat::detail::atanh; + using boost::math::cstdfloat::detail::fmod; + using boost::math::cstdfloat::detail::atan2; + using boost::math::cstdfloat::detail::lgamma; + using boost::math::cstdfloat::detail::tgamma; + + // begin more functions + using boost::math::cstdfloat::detail::remainder; + using boost::math::cstdfloat::detail::remquo; + using boost::math::cstdfloat::detail::fma; + using boost::math::cstdfloat::detail::fmax; + using boost::math::cstdfloat::detail::fmin; + using boost::math::cstdfloat::detail::fdim; + using boost::math::cstdfloat::detail::nanq; + using boost::math::cstdfloat::detail::exp2; + using boost::math::cstdfloat::detail::log2; + using boost::math::cstdfloat::detail::log1p; + using boost::math::cstdfloat::detail::cbrt; + using boost::math::cstdfloat::detail::hypot; + using boost::math::cstdfloat::detail::erf; + using boost::math::cstdfloat::detail::erfc; + using boost::math::cstdfloat::detail::llround; + using boost::math::cstdfloat::detail::lround; + using boost::math::cstdfloat::detail::round; + using boost::math::cstdfloat::detail::nearbyint; + using boost::math::cstdfloat::detail::llrint; + using boost::math::cstdfloat::detail::lrint; + using boost::math::cstdfloat::detail::rint; + using boost::math::cstdfloat::detail::modf; + using boost::math::cstdfloat::detail::scalbln; + using boost::math::cstdfloat::detail::scalbn; + using boost::math::cstdfloat::detail::ilogb; + using boost::math::cstdfloat::detail::logb; + using boost::math::cstdfloat::detail::nextafter; + using boost::math::cstdfloat::detail::nexttoward; + using boost::math::cstdfloat::detail::copysign; + using boost::math::cstdfloat::detail::signbit; + using boost::math::cstdfloat::detail::fpclassify; + using boost::math::cstdfloat::detail::isfinite; + using boost::math::cstdfloat::detail::isinf; + using boost::math::cstdfloat::detail::isnan; + using boost::math::cstdfloat::detail::isnormal; + using boost::math::cstdfloat::detail::isgreater; + using boost::math::cstdfloat::detail::isgreaterequal; + using boost::math::cstdfloat::detail::isless; + using boost::math::cstdfloat::detail::islessequal; + using boost::math::cstdfloat::detail::islessgreater; + using boost::math::cstdfloat::detail::isunordered; + // end more functions + +} // namespace std + +// We will now remove the preprocessor symbols representing quadruple-precision +// functions from the preprocessor. + +#undef BOOST_CSTDFLOAT_FLOAT128_LDEXP +#undef BOOST_CSTDFLOAT_FLOAT128_FREXP +#undef BOOST_CSTDFLOAT_FLOAT128_FABS +#undef BOOST_CSTDFLOAT_FLOAT128_FLOOR +#undef BOOST_CSTDFLOAT_FLOAT128_CEIL +#undef BOOST_CSTDFLOAT_FLOAT128_SQRT +#undef BOOST_CSTDFLOAT_FLOAT128_TRUNC +#undef BOOST_CSTDFLOAT_FLOAT128_EXP +#undef BOOST_CSTDFLOAT_FLOAT128_EXPM1 +#undef BOOST_CSTDFLOAT_FLOAT128_POW +#undef BOOST_CSTDFLOAT_FLOAT128_LOG +#undef BOOST_CSTDFLOAT_FLOAT128_LOG10 +#undef BOOST_CSTDFLOAT_FLOAT128_SIN +#undef BOOST_CSTDFLOAT_FLOAT128_COS +#undef BOOST_CSTDFLOAT_FLOAT128_TAN +#undef BOOST_CSTDFLOAT_FLOAT128_ASIN +#undef BOOST_CSTDFLOAT_FLOAT128_ACOS +#undef BOOST_CSTDFLOAT_FLOAT128_ATAN +#undef BOOST_CSTDFLOAT_FLOAT128_SINH +#undef BOOST_CSTDFLOAT_FLOAT128_COSH +#undef BOOST_CSTDFLOAT_FLOAT128_TANH +#undef BOOST_CSTDFLOAT_FLOAT128_ASINH +#undef BOOST_CSTDFLOAT_FLOAT128_ACOSH +#undef BOOST_CSTDFLOAT_FLOAT128_ATANH +#undef BOOST_CSTDFLOAT_FLOAT128_FMOD +#undef BOOST_CSTDFLOAT_FLOAT128_ATAN2 +#undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA +#undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA + +// begin more functions +#undef BOOST_CSTDFLOAT_FLOAT128_REMAINDER +#undef BOOST_CSTDFLOAT_FLOAT128_REMQUO +#undef BOOST_CSTDFLOAT_FLOAT128_FMA +#undef BOOST_CSTDFLOAT_FLOAT128_FMAX +#undef BOOST_CSTDFLOAT_FLOAT128_FMIN +#undef BOOST_CSTDFLOAT_FLOAT128_FDIM +#undef BOOST_CSTDFLOAT_FLOAT128_NAN +#undef BOOST_CSTDFLOAT_FLOAT128_EXP2 +#undef BOOST_CSTDFLOAT_FLOAT128_LOG2 +#undef BOOST_CSTDFLOAT_FLOAT128_LOG1P +#undef BOOST_CSTDFLOAT_FLOAT128_CBRT +#undef BOOST_CSTDFLOAT_FLOAT128_HYPOT +#undef BOOST_CSTDFLOAT_FLOAT128_ERF +#undef BOOST_CSTDFLOAT_FLOAT128_ERFC +#undef BOOST_CSTDFLOAT_FLOAT128_LLROUND +#undef BOOST_CSTDFLOAT_FLOAT128_LROUND +#undef BOOST_CSTDFLOAT_FLOAT128_ROUND +#undef BOOST_CSTDFLOAT_FLOAT128_NEARBYINT +#undef BOOST_CSTDFLOAT_FLOAT128_LLRINT +#undef BOOST_CSTDFLOAT_FLOAT128_LRINT +#undef BOOST_CSTDFLOAT_FLOAT128_RINT +#undef BOOST_CSTDFLOAT_FLOAT128_MODF +#undef BOOST_CSTDFLOAT_FLOAT128_SCALBLN +#undef BOOST_CSTDFLOAT_FLOAT128_SCALBN +#undef BOOST_CSTDFLOAT_FLOAT128_ILOGB +#undef BOOST_CSTDFLOAT_FLOAT128_LOGB +#undef BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER +#undef BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD +#undef BOOST_CSTDFLOAT_FLOAT128_COPYSIGN +#undef BOOST_CSTDFLOAT_FLOAT128_SIGNBIT +#undef BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY +#undef BOOST_CSTDFLOAT_FLOAT128_ISFINITE +#undef BOOST_CSTDFLOAT_FLOAT128_ISINF +#undef BOOST_CSTDFLOAT_FLOAT128_ISNAN +#undef BOOST_CSTDFLOAT_FLOAT128_ISNORMAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATER +#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESS +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER +#undef BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED +// end more functions + +#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ + diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp new file mode 100644 index 0000000000000..f79ff6d4234cf --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement quadruple-precision (and extended) support for . + +#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ + + #include + #include + #include + #include + + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined. + #endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + #define BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE boost::math::cstdfloat::detail::float_internal128_t + #include + #undef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp new file mode 100644 index 0000000000000..a4007ee1868f8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp @@ -0,0 +1,813 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement a specialization of std::complex<> for *anything* that +// is defined as BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE. + +#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ + + #if defined(__GNUC__) + #pragma GCC system_header + #endif + + #include + #include + #include + + namespace std + { + // Forward declarations. + template + class complex; + + template<> + class complex; + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex&); + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex&); + + inline complex conj (const complex&); + inline complex proj (const complex&); + + inline complex polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0); + + inline complex sqrt (const complex&); + + inline complex sin (const complex&); + inline complex cos (const complex&); + inline complex tan (const complex&); + inline complex asin (const complex&); + inline complex acos (const complex&); + inline complex atan (const complex&); + + inline complex exp (const complex&); + inline complex log (const complex&); + inline complex log10(const complex&); + + inline complex pow (const complex&, + int); + inline complex pow (const complex&, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&); + inline complex pow (const complex&, + const complex&); + inline complex pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, + const complex&); + + inline complex sinh (const complex&); + inline complex cosh (const complex&); + inline complex tanh (const complex&); + + inline complex asinh(const complex&); + inline complex acosh(const complex&); + inline complex atanh(const complex&); + + template + inline std::basic_ostream& operator<<(std::basic_ostream&, const std::complex&); + + template + inline std::basic_istream& operator>>(std::basic_istream&, std::complex&); + + // Template specialization of the complex class. + template<> + class complex + { + public: + typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type; + + complex(const complex&); + complex(const complex&); + complex(const complex&); + + #if defined(BOOST_NO_CXX11_CONSTEXPR) + complex(const value_type& r = value_type(), + const value_type& i = value_type()) : re(r), + im(i) { } + + template + explicit complex(const complex& x) : re(x.real()), + im(x.imag()) { } + + const value_type& real() const { return re; } + const value_type& imag() const { return im; } + + value_type& real() { return re; } + value_type& imag() { return im; } + #else + constexpr complex(const value_type& r = value_type(), + const value_type& i = value_type()) : re(r), + im(i) { } + + template + explicit constexpr complex(const complex& x) : re(x.real()), + im(x.imag()) { } + + value_type real() const { return re; } + value_type imag() const { return im; } + #endif + + void real(value_type r) { re = r; } + void imag(value_type i) { im = i; } + + complex& operator=(const value_type& v) + { + re = v; + im = value_type(0); + return *this; + } + + complex& operator+=(const value_type& v) + { + re += v; + return *this; + } + + complex& operator-=(const value_type& v) + { + re -= v; + return *this; + } + + complex& operator*=(const value_type& v) + { + re *= v; + im *= v; + return *this; + } + + complex& operator/=(const value_type& v) + { + re /= v; + im /= v; + return *this; + } + + template + complex& operator=(const complex& x) + { + re = x.real(); + im = x.imag(); + return *this; + } + + template + complex& operator+=(const complex& x) + { + re += x.real(); + im += x.imag(); + return *this; + } + + template + complex& operator-=(const complex& x) + { + re -= x.real(); + im -= x.imag(); + return *this; + } + + template + complex& operator*=(const complex& x) + { + const value_type tmp_real = (re * x.real()) - (im * x.imag()); + im = (re * x.imag()) + (im * x.real()); + re = tmp_real; + return *this; + } + + template + complex& operator/=(const complex& x) + { + const value_type tmp_real = (re * x.real()) + (im * x.imag()); + const value_type the_norm = std::norm(x); + im = ((im * x.real()) - (re * x.imag())) / the_norm; + re = tmp_real / the_norm; + return *this; + } + + private: + value_type re; + value_type im; + }; + + // Constructors from built-in complex representation of floating-point types. + inline complex::complex(const complex& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { } + inline complex::complex(const complex& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { } + inline complex::complex(const complex& ld) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.imag())) { } + } // namespace std + + namespace boost { namespace math { namespace cstdfloat { namespace detail { + template inline std::complex multiply_by_i(const std::complex& x) + { + // Multiply x (in C) by I (the imaginary component), and return the result. + return std::complex(-x.imag(), x.real()); + } + } } } } // boost::math::cstdfloat::detail + + namespace std + { + // ISO/IEC 14882:2011, Section 26.4.7, specific values. + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex& x) { return x.real(); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex& x) { return x.imag(); } + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex& x) { using std::atan2; return atan2(x.imag(), x.real()); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); } + + inline complex conj (const complex& x) { return complex(x.real(), -x.imag()); } + + inline complex proj (const complex& x) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits::max)(); + if ( (x.real() > m) + || (x.real() < -m) + || (x.imag() > m) + || (x.imag() < -m)) + { + // We have an infinity, return a normalized infinity, respecting the sign of the imaginary part: + return complex(std::numeric_limits::infinity(), x.imag() < 0 ? -0 : 0); + } + return x; + } + + inline complex polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& rho, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& theta) + { + using std::sin; + using std::cos; + + return complex(rho * cos(theta), rho * sin(theta)); + } + + // Global add, sub, mul, div. + inline complex operator+(const complex& u, const complex& v) { return complex(u.real() + v.real(), u.imag() + v.imag()); } + inline complex operator-(const complex& u, const complex& v) { return complex(u.real() - v.real(), u.imag() - v.imag()); } + + inline complex operator*(const complex& u, const complex& v) + { + return complex((u.real() * v.real()) - (u.imag() * v.imag()), + (u.real() * v.imag()) + (u.imag() * v.real())); + } + + inline complex operator/(const complex& u, const complex& v) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v); + + return complex(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm, + ((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm); + } + + inline complex operator+(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() + v, u.imag()); } + inline complex operator-(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() - v, u.imag()); } + inline complex operator*(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() * v, u.imag() * v); } + inline complex operator/(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() / v, u.imag() / v); } + + inline complex operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u + v.real(), v.imag()); } + inline complex operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u - v.real(), -v.imag()); } + inline complex operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u * v.real(), u * v.imag()); } + inline complex operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); } + + // Unary plus / minus. + inline complex operator+(const complex& u) { return u; } + inline complex operator-(const complex& u) { return complex(-u.real(), -u.imag()); } + + // Equality and inequality. + inline bool operator==(const complex& x, const complex& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); } + inline bool operator==(const complex& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() == y) && (x.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator!=(const complex& x, const complex& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); } + inline bool operator!=(const complex& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() != y) || (x.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator!=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex& y) { return ((x != y.real()) || (y.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + + // ISO/IEC 14882:2011, Section 26.4.8, transcendentals. + inline complex sqrt(const complex& x) + { + using std::fabs; + using std::sqrt; + + // Compute sqrt(x) for x in C: + // sqrt(x) = (s , xi / 2s) : for xr > 0, + // (|xi| / 2s, +-s) : for xr < 0, + // (sqrt(xi), sqrt(xi) : for xr = 0, + // where s = sqrt{ [ |xr| + sqrt(xr^2 + xi^2) ] / 2 }, + // and the +- sign is the same as the sign of xi. + + if(x.real() > 0) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); + + return complex(s, x.imag() / (s * 2)); + } + else if(x.real() < 0) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); + + const bool imag_is_neg = (x.imag() < 0); + + return complex(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); + } + else + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); + + return complex(sqrt_xi_half, sqrt_xi_half); + } + } + + inline complex sin(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return complex(sin_x * cosh_y, cos_x * sinh_y); + } + + inline complex cos(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return complex(cos_x * cosh_y, -(sin_x * sinh_y)); + } + + inline complex tan(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return ( complex(sin_x * cosh_y, cos_x * sinh_y) + / complex(cos_x * cosh_y, -sin_x * sinh_y)); + } + + inline complex asin(const complex& x) + { + return -boost::math::cstdfloat::detail::multiply_by_i(std::log(boost::math::cstdfloat::detail::multiply_by_i(x) + std::sqrt(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - (x * x)))); + } + + inline complex acos(const complex& x) + { + return boost::math::constants::half_pi() - std::asin(x); + } + + inline complex atan(const complex& x) + { + const complex izz = boost::math::cstdfloat::detail::multiply_by_i(x); + + return boost::math::cstdfloat::detail::multiply_by_i(std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - izz) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + izz)) / 2; + } + + inline complex exp(const complex& x) + { + using std::exp; + + return std::polar(exp(x.real()), x.imag()); + } + + inline complex log(const complex& x) + { + using std::atan2; + using std::log; + + const bool re_isneg = (x.real() < 0); + const bool re_isnan = (x.real() != x.real()); + const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits::max)()) + : bool(-x.real() > (std::numeric_limits::max)())); + + const bool im_isneg = (x.imag() < 0); + const bool im_isnan = (x.imag() != x.imag()); + const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits::max)()) + : bool(-x.imag() > (std::numeric_limits::max)())); + + if(re_isnan || im_isnan) { return x; } + + if(re_isinf || im_isinf) + { + return complex(std::numeric_limits::infinity(), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0)); + } + + const bool re_iszero = ((re_isneg || (x.real() > 0)) == false); + + if(re_iszero) + { + const bool im_iszero = ((im_isneg || (x.imag() > 0)) == false); + + if(im_iszero) + { + return std::complex + ( + -std::numeric_limits::infinity(), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0) + ); + } + else + { + if(im_isneg == false) + { + return std::complex + ( + log(x.imag()), + boost::math::constants::half_pi() + ); + } + else + { + return std::complex + ( + log(-x.imag()), + -boost::math::constants::half_pi() + ); + } + } + } + else + { + return complex(log(std::norm(x)) / 2, atan2(x.imag(), x.real())); + } + } + + inline complex log10(const complex& x) + { + return std::log(x) / boost::math::constants::ln_ten(); + } + + inline complex pow(const complex& x, + int p) + { + const bool re_isneg = (x.real() < 0); + const bool re_isnan = (x.real() != x.real()); + const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits::max)()) + : bool(-x.real() > (std::numeric_limits::max)())); + + const bool im_isneg = (x.imag() < 0); + const bool im_isnan = (x.imag() != x.imag()); + const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits::max)()) + : bool(-x.imag() > (std::numeric_limits::max)())); + + if(re_isnan || im_isnan) { return x; } + + if(re_isinf || im_isinf) + { + return complex(std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN()); + } + + if(p < 0) + { + if(std::abs(x) < (std::numeric_limits::min)()) + { + return complex(std::numeric_limits::infinity(), + std::numeric_limits::infinity()); + } + else + { + return BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / std::pow(x, -p); + } + } + + if(p == 0) + { + return complex(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)); + } + else + { + if(p == 1) { return x; } + + if(std::abs(x) > (std::numeric_limits::max)()) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + + return complex(re, im); + } + + if (p == 2) { return (x * x); } + else if(p == 3) { return ((x * x) * x); } + else if(p == 4) { const complex x2 = (x * x); return (x2 * x2); } + else + { + // The variable xn stores the binary powers of x. + complex result(((p % 2) != 0) ? x : complex(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); + complex xn (x); + + int p2 = p; + + while((p2 /= 2) != 0) + { + // Square xn for each binary power. + xn *= xn; + + const bool has_binary_power = ((p2 % 2) != 0); + + if(has_binary_power) + { + // Multiply the result with each binary power contained in the exponent. + result *= xn; + } + } + + return result; + } + } + } + + inline complex pow(const complex& x, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& a) + { + const bool x_im_isneg = (x.imag() < 0); + const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); + + if(x_im_iszero) + { + using std::pow; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE pxa = pow(x.real(), a); + + return complex(pxa, BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)); + } + else + { + return std::exp(a * std::log(x)); + } + } + + inline complex pow(const complex& x, + const complex& a) + { + const bool x_im_isneg = (x.imag() < 0); + const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); + + if(x_im_iszero) + { + using std::pow; + + return pow(x.real(), a); + } + else + { + return std::exp(a * std::log(x)); + } + } + + inline complex pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, + const complex& a) + { + const bool x_isneg = (x < 0); + const bool x_isnan = (x != x); + const bool x_isinf = ((!x_isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + const bool a_re_isneg = (a.real() < 0); + const bool a_re_isnan = (a.real() != a.real()); + const bool a_re_isinf = ((!a_re_isneg) ? bool(+a.real() > (std::numeric_limits::max)()) + : bool(-a.real() > (std::numeric_limits::max)())); + + const bool a_im_isneg = (a.imag() < 0); + const bool a_im_isnan = (a.imag() != a.imag()); + const bool a_im_isinf = ((!a_im_isneg) ? bool(+a.imag() > (std::numeric_limits::max)()) + : bool(-a.imag() > (std::numeric_limits::max)())); + + const bool args_is_nan = (x_isnan || a_re_isnan || a_im_isnan); + const bool a_is_finite = (!(a_re_isnan || a_re_isinf || a_im_isnan || a_im_isinf)); + + complex result; + + if(args_is_nan) + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + else if(x_isinf) + { + if(a_is_finite) + { + result = + complex + ( + std::numeric_limits::infinity(), + std::numeric_limits::infinity() + ); + } + else + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + } + else if(x > 0) + { + result = std::exp(a * std::log(x)); + } + else if(x < 0) + { + using std::acos; + using std::log; + + const complex + cpx_lg_x + ( + log(-x), + acos(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(-1)) + ); + + result = std::exp(a * cpx_lg_x); + } + else + { + if(a_is_finite) + { + result = + complex + ( + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0) + ); + } + else + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + } + + return result; + } + + inline complex sinh(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; + + return complex(cos_y * sinh_x, cosh_x * sin_y); + } + + inline complex cosh(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; + + return complex(cos_y * cosh_x, sin_y * sinh_x); + } + + inline complex tanh(const complex& x) + { + const complex ex_plus = std::exp(x); + const complex ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus; + + return (ex_plus - ex_minus) / (ex_plus + ex_minus); + } + + inline complex asinh(const complex& x) + { + return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); + } + + inline complex acosh(const complex& x) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1); + + const complex zp(x.real() + my_one, x.imag()); + const complex zm(x.real() - my_one, x.imag()); + + return std::log(x + (zp * std::sqrt(zm / zp))); + } + + inline complex atanh(const complex& x) + { + return (std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + x) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - x)) / 2.0; + } + + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const std::complex& x) + { + std::basic_ostringstream ostr; + + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + ostr << char_type('(') + << x.real() + << char_type(',') + << x.imag() + << char_type(')'); + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, std::complex& x) + { + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx; + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix; + + char_type the_char; + + static_cast(is >> the_char); + + if(the_char == static_cast('(')) + { + static_cast(is >> rx >> the_char); + + if(the_char == static_cast(',')) + { + static_cast(is >> ix >> the_char); + + if(the_char == static_cast(')')) + { + x = complex(rx, ix); + } + else + { + is.setstate(ios_base::failbit); + } + } + else if(the_char == static_cast(')')) + { + x = rx; + } + else + { + is.setstate(ios_base::failbit); + } + } + else + { + static_cast(is.putback(the_char)); + + static_cast(is >> rx); + + x = rx; + } + + return is; + } + } // namespace std + +#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp new file mode 100644 index 0000000000000..2ae2aea33be8d --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp @@ -0,0 +1,822 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement quadruple-precision I/O stream operations. + +#ifndef BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ + + #include + #include + #include + + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + +namespace boost { + namespace math { + namespace detail { + // + // What follows is the input streaming code: this is not "proper" iostream code at all + // but that's hard to write. + // For now just pull in all the characters that could possibly form the number + // and let libquadmath's string parser make use of it. This fixes most use cases + // including CSV type formats such as those used by the Random lib. + // + inline std::string read_string_while(std::istream& is, std::string const& permitted_chars) + { + std::ios_base::iostate state = std::ios_base::goodbit; + const std::istream::sentry sentry_check(is); + std::string result; + + if (sentry_check) + { + int c = is.rdbuf()->sgetc(); + + for (;; c = is.rdbuf()->snextc()) + if (std::istream::traits_type::eq_int_type(std::istream::traits_type::eof(), c)) + { // end of file: + state |= std::ios_base::eofbit; + break; + } + else if (permitted_chars.find_first_of(std::istream::traits_type::to_char_type(c)) == std::string::npos) + { + // Invalid numeric character, stop reading: + //is.rdbuf()->sputbackc(static_cast(c)); + break; + } + else + { + result.append(1, std::istream::traits_type::to_char_type(c)); + } + } + + if (!result.size()) + state |= std::ios_base::failbit; + is.setstate(state); + return result; + } + + } + } +} + +#if defined(__GNUC__) && !defined(BOOST_MATH_TEST_IO_AS_INTEL_QUAD) + + // Forward declarations of quadruple-precision string functions. + extern "C" int quadmath_snprintf(char *str, size_t size, const char *format, ...) BOOST_MATH_NOTHROW; + extern "C" boost::math::cstdfloat::detail::float_internal128_t strtoflt128(const char*, char **) BOOST_MATH_NOTHROW; + + namespace std + { + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::basic_ostringstream ostr; + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + char my_buffer[64U]; + + const int my_prec = static_cast(os.precision()); + const int my_digits = ((my_prec == 0) ? 36 : my_prec); + + const std::ios_base::fmtflags my_flags = os.flags(); + + char my_format_string[8U]; + + std::size_t my_format_string_index = 0U; + + my_format_string[my_format_string_index] = '%'; + ++my_format_string_index; + + if(my_flags & std::ios_base::showpos) { my_format_string[my_format_string_index] = '+'; ++my_format_string_index; } + if(my_flags & std::ios_base::showpoint) { my_format_string[my_format_string_index] = '#'; ++my_format_string_index; } + + my_format_string[my_format_string_index + 0U] = '.'; + my_format_string[my_format_string_index + 1U] = '*'; + my_format_string[my_format_string_index + 2U] = 'Q'; + + my_format_string_index += 3U; + + char the_notation_char; + + if (my_flags & std::ios_base::scientific) { the_notation_char = 'e'; } + else if(my_flags & std::ios_base::fixed) { the_notation_char = 'f'; } + else { the_notation_char = 'g'; } + + my_format_string[my_format_string_index + 0U] = the_notation_char; + my_format_string[my_format_string_index + 1U] = 0; + + const int v = ::quadmath_snprintf(my_buffer, + static_cast(sizeof(my_buffer)), + my_format_string, + my_digits, + x); + + if(v < 0) { BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed internally in quadmath_snprintf().")); } + + if(v >= static_cast(sizeof(my_buffer) - 1U)) + { + // Evidently there is a really long floating-point string here, + // such as a small decimal representation in non-scientific notation. + // So we have to use dynamic memory allocation for the output + // string buffer. + + char* my_buffer2 = nullptr; + +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + my_buffer2 = new char[v + 3]; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const std::bad_alloc&) + { + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed while allocating memory.")); + } +#endif + const int v2 = ::quadmath_snprintf(my_buffer2, + v + 3, + my_format_string, + my_digits, + x); + + if(v2 >= v + 3) + { + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed.")); + } + + static_cast(ostr << my_buffer2); + + delete [] my_buffer2; + } + else + { + static_cast(ostr << my_buffer); + } + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::string str = boost::math::detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY"); + + char* p_end; + + x = strtoflt128(str.c_str(), &p_end); + + if(static_cast(p_end - str.c_str()) != static_cast(str.length())) + { + for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) + { + static_cast(is.putback(*it)); + } + + is.setstate(ios_base::failbit); + + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); + } + + return is; + } + } + +#elif defined(__INTEL_COMPILER) || defined(BOOST_MATH_TEST_IO_AS_INTEL_QUAD) + + // The section for I/O stream support for the ICC compiler is particularly + // long, because these functions must be painstakingly synthesized from + // manually-written routines (ICC does not support I/O stream operations + // for its _Quad type). + + // The following string-extraction routines are based on the methodology + // used in Boost.Multiprecision by John Maddock and Christopher Kormanyos. + // This methodology has been slightly modified here for boost::float128_t. + + + #include + #include + + namespace boost { namespace math { namespace cstdfloat { namespace detail { + + template + void format_float_string(string_type& str, + int my_exp, + int digits, + const std::ios_base::fmtflags f, + const bool iszero) + { + typedef typename string_type::size_type size_type; + + const bool scientific = ((f & std::ios_base::scientific) == std::ios_base::scientific); + const bool fixed = ((f & std::ios_base::fixed) == std::ios_base::fixed); + const bool showpoint = ((f & std::ios_base::showpoint) == std::ios_base::showpoint); + const bool showpos = ((f & std::ios_base::showpos) == std::ios_base::showpos); + + const bool b_neg = ((str.size() != 0U) && (str[0] == '-')); + + if(b_neg) + { + str.erase(0, 1); + } + + if(digits == 0) + { + digits = static_cast((std::max)(str.size(), size_type(16))); + } + + if(iszero || str.empty() || (str.find_first_not_of('0') == string_type::npos)) + { + // We will be printing zero, even though the value might not + // actually be zero (it just may have been rounded to zero). + str = "0"; + + if(scientific || fixed) + { + str.append(1, '.'); + str.append(size_type(digits), '0'); + + if(scientific) + { + str.append("e+00"); + } + } + else + { + if(showpoint) + { + str.append(1, '.'); + if(digits > 1) + { + str.append(size_type(digits - 1), '0'); + } + } + } + + if(b_neg) + { + str.insert(0U, 1U, '-'); + } + else if(showpos) + { + str.insert(0U, 1U, '+'); + } + + return; + } + + if(!fixed && !scientific && !showpoint) + { + // Suppress trailing zeros. + typename string_type::iterator pos = str.end(); + + while(pos != str.begin() && *--pos == '0') { ; } + + if(pos != str.end()) + { + ++pos; + } + + str.erase(pos, str.end()); + + if(str.empty()) + { + str = '0'; + } + } + else if(!fixed || (my_exp >= 0)) + { + // Pad out the end with zero's if we need to. + + std::ptrdiff_t chars = static_cast(str.size()); + chars = digits - chars; + + if(scientific) + { + ++chars; + } + + if(chars > 0) + { + str.append(static_cast(chars), '0'); + } + } + + if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits))) + { + if((1 + my_exp) > static_cast(str.size())) + { + // Just pad out the end with zeros. + str.append(static_cast((1 + my_exp) - static_cast(str.size())), '0'); + + if(showpoint || fixed) + { + str.append("."); + } + } + else if(my_exp + 1 < static_cast(str.size())) + { + if(my_exp < 0) + { + str.insert(0U, static_cast(-1 - my_exp), '0'); + str.insert(0U, "0."); + } + else + { + // Insert the decimal point: + str.insert(static_cast(my_exp + 1), 1, '.'); + } + } + else if(showpoint || fixed) // we have exactly the digits we require to left of the point + { + str += "."; + } + + if(fixed) + { + // We may need to add trailing zeros. + int l = static_cast(str.find('.') + 1U); + l = digits - (static_cast(str.size()) - l); + + if(l > 0) + { + str.append(size_type(l), '0'); + } + } + } + else + { + // Scientific format: + if(showpoint || (str.size() > 1)) + { + str.insert(1U, 1U, '.'); + } + + str.append(1U, 'e'); + + string_type e = std::to_string(std::abs(my_exp)); + + if(e.size() < 2U) + { + e.insert(0U, 2U - e.size(), '0'); + } + + if(my_exp < 0) + { + e.insert(0U, 1U, '-'); + } + else + { + e.insert(0U, 1U, '+'); + } + + str.append(e); + } + + if(b_neg) + { + str.insert(0U, 1U, '-'); + } + else if(showpos) + { + str.insert(0U, 1U, '+'); + } + } + + template inline void eval_convert_to(type_a* pa, const float_type& cb) { *pa = static_cast(cb); } + template inline void eval_add (float_type& b, const type_a& a) { b += a; } + template inline void eval_subtract (float_type& b, const type_a& a) { b -= a; } + template inline void eval_multiply (float_type& b, const type_a& a) { b *= a; } + template inline void eval_multiply (float_type& b, const float_type& cb, const float_type& cb2) { b = (cb * cb2); } + template inline void eval_divide (float_type& b, const type_a& a) { b /= a; } + template inline void eval_log10 (float_type& b, const float_type& cb) { b = std::log10(cb); } + template inline void eval_floor (float_type& b, const float_type& cb) { b = std::floor(cb); } + + inline void round_string_up_at(std::string& s, int pos, int& expon) + { + // This subroutine rounds up a string representation of a + // number at the given position pos. + + if(pos < 0) + { + s.insert(0U, 1U, '1'); + s.erase(s.size() - 1U); + ++expon; + } + else if(s[pos] == '9') + { + s[pos] = '0'; + round_string_up_at(s, pos - 1, expon); + } + else + { + if((pos == 0) && (s[pos] == '0') && (s.size() == 1)) + { + ++expon; + } + + ++s[pos]; + } + } + + template + std::string convert_to_string(float_type& x, + std::streamsize digits, + const std::ios_base::fmtflags f) + { + const bool isneg = (x < 0); + const bool iszero = ((!isneg) ? bool(+x < (std::numeric_limits::min)()) + : bool(-x < (std::numeric_limits::min)())); + const bool isnan = (x != x); + const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + int expon = 0; + + if(digits <= 0) { digits = std::numeric_limits::max_digits10; } + + const int org_digits = static_cast(digits); + + std::string result; + + if(iszero) + { + result = "0"; + } + else if(isinf) + { + if(x < 0) + { + return "-inf"; + } + else + { + return ((f & std::ios_base::showpos) == std::ios_base::showpos) ? "+inf" : "inf"; + } + } + else if(isnan) + { + return "nan"; + } + else + { + // Start by figuring out the base-10 exponent. + if(isneg) { x = -x; } + + float_type t; + constexpr float_type ten = 10; + + eval_log10(t, x); + eval_floor(t, t); + eval_convert_to(&expon, t); + + if(-expon > std::numeric_limits::max_exponent10 - 3) + { + int e = -expon / 2; + + const float_type t2 = boost::math::cstdfloat::detail::pown(ten, e); + + eval_multiply(t, t2, x); + eval_multiply(t, t2); + + if((expon & 1) != 0) + { + eval_multiply(t, ten); + } + } + else + { + t = boost::math::cstdfloat::detail::pown(ten, -expon); + eval_multiply(t, x); + } + + // Make sure that the value lies between [1, 10), and adjust if not. + if(t < 1) + { + eval_multiply(t, 10); + + --expon; + } + else if(t >= 10) + { + eval_divide(t, 10); + + ++expon; + } + + float_type digit; + int cdigit; + + // Adjust the number of digits required based on formatting options. + if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1)) + { + digits += (expon + 1); + } + + if((f & std::ios_base::scientific) == std::ios_base::scientific) + { + ++digits; + } + + // Extract the base-10 digits one at a time. + for(int i = 0; i < digits; ++i) + { + eval_floor(digit, t); + eval_convert_to(&cdigit, digit); + + result += static_cast('0' + cdigit); + + eval_subtract(t, digit); + eval_multiply(t, ten); + } + if (result.size() == 0) + result = "0"; + + // Possibly round the result. + if(digits >= 0) + { + eval_floor(digit, t); + eval_convert_to(&cdigit, digit); + eval_subtract(t, digit); + + if((cdigit == 5) && (t == 0)) + { + // Use simple bankers rounding. + + if((static_cast(*result.rbegin() - '0') & 1) != 0) + { + round_string_up_at(result, static_cast(result.size() - 1U), expon); + if (digits == 0) digits = 1; + } + } + else if(cdigit >= 5) + { + round_string_up_at(result, static_cast(result.size() - 1u), expon); + if (digits == 0) digits = 1; + } + } + } + + while((result.size() > static_cast(digits)) && result.size()) + { + // We may get here as a result of rounding. + + if(result.size() > 1U) + { + result.erase(result.size() - 1U); + } + else + { + if(expon > 0) + { + --expon; // so we put less padding in the result. + } + else + { + ++expon; + } + + ++digits; + } + } + + if(isneg) + { + result.insert(0U, 1U, '-'); + } + + format_float_string(result, expon, org_digits, f, iszero); + + return result; + } + + template + bool convert_from_string(float_type& value, const char* p) + { + value = 0; + + if((p == nullptr) || (*p == '\0')) + { + return false; + } + + bool is_neg = false; + bool is_neg_expon = false; + + constexpr int ten = 10; + + int expon = 0; + int digits_seen = 0; + + constexpr int max_digits = std::numeric_limits::max_digits10 + 1; + + if(*p == '+') + { + ++p; + } + else if(*p == '-') + { + is_neg = true; + ++p; + } + + const bool isnan = ((std::strcmp(p, "nan") == 0) || (std::strcmp(p, "NaN") == 0) || (std::strcmp(p, "NAN") == 0)); + + if(isnan) + { + eval_divide(value, 0); + + if(is_neg) + { + value = -value; + } + + return true; + } + + const bool isinf = ((std::strcmp(p, "inf") == 0) || (std::strcmp(p, "Inf") == 0) || (std::strcmp(p, "INF") == 0)); + + if(isinf) + { + value = 1; + eval_divide(value, 0); + + if(is_neg) + { + value = -value; + } + + return true; + } + + // Grab all the leading digits before the decimal point. + while(std::isdigit(*p)) + { + eval_multiply(value, ten); + eval_add(value, static_cast(*p - '0')); + ++p; + ++digits_seen; + } + + if(*p == '.') + { + // Grab everything after the point, stop when we've seen + // enough digits, even if there are actually more available. + + ++p; + + while(std::isdigit(*p)) + { + eval_multiply(value, ten); + eval_add(value, static_cast(*p - '0')); + ++p; + --expon; + + if(++digits_seen > max_digits) + { + break; + } + } + + while(std::isdigit(*p)) + { + ++p; + } + } + + // Parse the exponent. + if((*p == 'e') || (*p == 'E')) + { + ++p; + + if(*p == '+') + { + ++p; + } + else if(*p == '-') + { + is_neg_expon = true; + ++p; + } + + int e2 = 0; + + while(std::isdigit(*p)) + { + e2 *= 10; + e2 += (*p - '0'); + ++p; + } + + if(is_neg_expon) + { + e2 = -e2; + } + + expon += e2; + } + + if(expon) + { + // Scale by 10^expon. Note that 10^expon can be outside the range + // of our number type, even though the result is within range. + // If that looks likely, then split the calculation in two parts. + float_type t; + t = ten; + + if(expon > (std::numeric_limits::min_exponent10 + 2)) + { + t = boost::math::cstdfloat::detail::pown(t, expon); + eval_multiply(value, t); + } + else + { + t = boost::math::cstdfloat::detail::pown(t, (expon + digits_seen + 1)); + eval_multiply(value, t); + t = ten; + t = boost::math::cstdfloat::detail::pown(t, (-digits_seen - 1)); + eval_multiply(value, t); + } + } + + if(is_neg) + { + value = -value; + } + + return (*p == '\0'); + } + } } } } // boost::math::cstdfloat::detail + + namespace std + { + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const boost::math::cstdfloat::detail::float_internal128_t& x) + { + boost::math::cstdfloat::detail::float_internal128_t non_const_x = x; + + const std::string str = boost::math::cstdfloat::detail::convert_to_string(non_const_x, + os.precision(), + os.flags()); + + std::basic_ostringstream ostr; + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + static_cast(ostr << str); + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::string str = boost::math::detail::read_string_while(is, "+-eE.0123456789infINFnanNANinfinityINFINITY"); + + const bool conversion_is_ok = boost::math::cstdfloat::detail::convert_from_string(x, str.c_str()); + + if(false == conversion_is_ok) + { + for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) + { + static_cast(is.putback(*it)); + } + + is.setstate(ios_base::failbit); + + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); + } + + return is; + } + } + + #endif // Use __GNUC__ or __INTEL_COMPILER libquadmath + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp new file mode 100644 index 0000000000000..59c614781d14b --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement quadruple-precision std::numeric_limits<> support. + +#ifndef BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + #define BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + + #include + + #if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) + // + // This is the only way we can avoid + // warning: non-standard suffix on floating constant [-Wpedantic] + // when building with -Wall -pedantic. Neither __extension__ + // nor #pragma diagnostic ignored work :( + // + #pragma GCC system_header + #endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) && (!defined(_GLIBCXX_RELEASE) || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 14)) + + #include + #include + + // Define the name of the global quadruple-precision function to be used for + // calculating quiet_NaN() in the specialization of std::numeric_limits<>. + #if defined(__INTEL_COMPILER) + #define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq + #elif defined(__GNUC__) + #define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq + #endif + + // Forward declaration of the quadruple-precision square root function. + extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + + namespace std + { + template<> + class numeric_limits + { + public: + static constexpr bool is_specialized = true; + static boost::math::cstdfloat::detail::float_internal128_t (min) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MIN; } + static boost::math::cstdfloat::detail::float_internal128_t (max) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MAX; } + static boost::math::cstdfloat::detail::float_internal128_t lowest() noexcept { return -(max)(); } + static constexpr int digits = 113; + static constexpr int digits10 = 33; + static constexpr int max_digits10 = 36; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; + static boost::math::cstdfloat::detail::float_internal128_t epsilon () { return BOOST_CSTDFLOAT_FLOAT128_EPS; } + static boost::math::cstdfloat::detail::float_internal128_t round_error() { return BOOST_FLOAT128_C(0.5); } + static constexpr int min_exponent = -16381; + static constexpr int min_exponent10 = static_cast((min_exponent * 301L) / 1000L); + static constexpr int max_exponent = +16384; + static constexpr int max_exponent10 = static_cast((max_exponent * 301L) / 1000L); + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_present; + static constexpr bool has_denorm_loss = false; + static boost::math::cstdfloat::detail::float_internal128_t infinity () { return BOOST_FLOAT128_C(1.0) / BOOST_FLOAT128_C(0.0); } + static boost::math::cstdfloat::detail::float_internal128_t quiet_NaN () { return -(::BOOST_CSTDFLOAT_FLOAT128_SQRT(BOOST_FLOAT128_C(-1.0))); } + static boost::math::cstdfloat::detail::float_internal128_t signaling_NaN() { return BOOST_FLOAT128_C(0.0); } + static boost::math::cstdfloat::detail::float_internal128_t denorm_min () { return BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN; } + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; + }; + } // namespace std + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + diff --git a/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp new file mode 100644 index 0000000000000..b64276558ba89 --- /dev/null +++ b/third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// 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) +// + +// Implement the types for floating-point typedefs having specified widths. + +#ifndef BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ + #define BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ + + #include + #include + #include + + // This is the beginning of the preamble. + + // In this preamble, the preprocessor is used to query certain + // preprocessor definitions from . Based on the results + // of these queries, an attempt is made to automatically detect + // the presence of built-in floating-point types having specified + // widths. These are *thought* to be conformant with IEEE-754, + // whereby an unequivocal test based on std::numeric_limits<> + // follows below. + + // In addition, various macros that are used for initializing + // floating-point literal values having specified widths and + // some basic min/max values are defined. + + // First, we will pre-load certain preprocessor definitions + // with a dummy value. + + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 0 + + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 + + // Ensure that the compiler has a radix-2 floating-point representation. + #if (!defined(FLT_RADIX) || ((defined(FLT_RADIX) && (FLT_RADIX != 2)))) + #error The compiler does not support any radix-2 floating-point types required for . + #endif + + // Check if built-in float is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(FLT_MANT_DIG) && defined(FLT_MAX_EXP)) + #if ((FLT_MANT_DIG == 11) && (FLT_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX FLT_MAX + #elif((FLT_MANT_DIG == 24) && (FLT_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX FLT_MAX + #elif((FLT_MANT_DIG == 53) && (FLT_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX FLT_MAX + #elif((FLT_MANT_DIG == 64) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX FLT_MAX + #elif((FLT_MANT_DIG == 113) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX FLT_MAX + #endif + #endif + + // Check if built-in double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(DBL_MANT_DIG) && defined(DBL_MAX_EXP)) + #if ((DBL_MANT_DIG == 11) && (DBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX DBL_MAX + #elif((DBL_MANT_DIG == 24) && (DBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX DBL_MAX + #elif((DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX DBL_MAX + #elif((DBL_MANT_DIG == 64) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX DBL_MAX + #elif((DBL_MANT_DIG == 113) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX DBL_MAX + #endif + #endif + + // Disable check long double capability even if supported by compiler since some math runtime + // implementations are broken for long double. + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + // Check if built-in long double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(LDBL_MANT_DIG) && defined(LDBL_MAX_EXP)) + #if ((LDBL_MANT_DIG == 11) && (LDBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 24) && (LDBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 64) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 113) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX LDBL_MAX + #endif + #endif + #endif + + // Check if quadruple-precision is supported. Here, we are checking + // for the presence of __float128 from GCC's quadmath.h or _Quad + // from ICC's /Qlong-double flag). To query these, we use the + // BOOST_MATH_USE_FLOAT128 pre-processor definition from + // . + + #if (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + // Specify the underlying name of the internal 128-bit floating-point type definition. + namespace boost { namespace math { namespace cstdfloat { namespace detail { + #if defined(__GNUC__) + typedef __float128 float_internal128_t; + #elif defined(__INTEL_COMPILER) + typedef _Quad float_internal128_t; + #else + #error "Sorry, the compiler is neither GCC, nor Intel, I don't know how to configure ." + #endif + } } } } // boost::math::cstdfloat::detail + + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE boost::math::cstdfloat::detail::float_internal128_t + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## Q) + #define BOOST_CSTDFLOAT_FLOAT128_MIN 3.36210314311209350626267781732175260e-4932Q + #define BOOST_CSTDFLOAT_FLOAT128_MAX 1.18973149535723176508575932662800702e+4932Q + #define BOOST_CSTDFLOAT_FLOAT128_EPS 1.92592994438723585305597794258492732e-0034Q + #define BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN 6.475175119438025110924438958227646552e-4966Q + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + + // This is the end of the preamble, and also the end of the + // sections providing support for the C++ standard library + // for quadruple-precision. + + // Now we use the results of the queries that have been obtained + // in the preamble (far above) for the final type definitions in + // the namespace boost. + + // Make sure that the compiler has any floating-point type(s) whatsoever. + #if ( (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #error The compiler does not support any of the floating-point types required for . + #endif + + // The following section contains the various min/max macros + // for the *leastN and *fastN types. + + #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOAT_LEAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOAT_FAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #define BOOST_FLOAT_LEAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOAT_LEAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOAT_FAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #define BOOST_FLOAT_LEAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOAT_LEAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOAT_FAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #define BOOST_FLOAT_LEAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOAT_LEAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOAT_FAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #define BOOST_FLOAT_LEAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) + #define BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T + + #define BOOST_FLOAT_FAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOAT_LEAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOAT_FAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #define BOOST_FLOAT_LEAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #endif + + // The following section contains the various min/max macros + // for the *floatmax types. + + #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT16_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT32_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT64_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT80_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT128_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #else + #error The maximum available floating-point width for is undefined. + #endif + + // And finally..., we define the floating-point typedefs having + // specified widths. The types are defined in the namespace boost. + + // For simplicity, the least and fast types are type defined identically + // as the corresponding fixed-width type. This behavior may, however, + // be modified when being optimized for a given compiler implementation. + + // In addition, a clear assessment of IEEE-754 conformance is carried out + // using compile-time assertion. + + namespace boost + { + #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float16_t; + typedef boost::float16_t float_fast16_t; + typedef boost::float16_t float_least16_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 11, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_16_MIN + #undef BOOST_CSTDFLOAT_FLOAT_16_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float32_t; + typedef boost::float32_t float_fast32_t; + typedef boost::float32_t float_least32_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 24, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 128, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_32_MIN + #undef BOOST_CSTDFLOAT_FLOAT_32_MAX + #endif + +#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && defined(__SUNPRO_CC) +#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE +#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 +#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE +#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 +#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH +#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 +#endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float64_t; + typedef boost::float64_t float_fast64_t; + typedef boost::float64_t float_least64_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 53, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 1024, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_64_MIN + #undef BOOST_CSTDFLOAT_FLOAT_64_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float80_t; + typedef boost::float80_t float_fast80_t; + typedef boost::float80_t float_least80_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 64, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16384, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_80_MIN + #undef BOOST_CSTDFLOAT_FLOAT_80_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float128_t; + typedef boost::float128_t float_fast128_t; + typedef boost::float128_t float_least128_t; + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + // This configuration does not *yet* support std::numeric_limits. + // Support for std::numeric_limits is added in the detail + // file . + #else + static_assert(std::numeric_limits::is_iec559 == true, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 113, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16384, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + #endif + + #undef BOOST_CSTDFLOAT_FLOAT_128_MIN + #undef BOOST_CSTDFLOAT_FLOAT_128_MAX + #endif + + #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) + typedef boost::float16_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) + typedef boost::float32_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) + typedef boost::float64_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) + typedef boost::float80_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) + typedef boost::float128_t floatmax_t; + #else + #error The maximum available floating-point width for is undefined. + #endif + + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + } + // namespace boost + +#endif // BOOST_MATH_CSTDFLOAT_BASE_TYPES_2014_01_09_HPP_ + diff --git a/third-party/boost-math/include/boost/math/differentiation/autodiff.hpp b/third-party/boost-math/include/boost/math/differentiation/autodiff.hpp new file mode 100644 index 0000000000000..b8880f24dea46 --- /dev/null +++ b/third-party/boost-math/include/boost/math/differentiation/autodiff.hpp @@ -0,0 +1,2061 @@ +// Copyright Matthew Pulver 2018 - 2019. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP +#define BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace differentiation { +// Automatic Differentiation v1 +inline namespace autodiff_v1 { +namespace detail { + +template +struct promote_args_n { + using type = typename tools::promote_args::type>::type; +}; + +template +struct promote_args_n { + using type = typename tools::promote_arg::type; +}; + +} // namespace detail + +template +using promote = typename detail::promote_args_n::type; + +namespace detail { + +template +class fvar; + +template +struct is_fvar_impl : std::false_type {}; + +template +struct is_fvar_impl> : std::true_type {}; + +template +using is_fvar = is_fvar_impl::type>; + +template +struct nest_fvar { + using type = fvar::type, Order>; +}; + +template +struct nest_fvar { + using type = fvar; +}; + +template +struct get_depth_impl : std::integral_constant {}; + +template +struct get_depth_impl> + : std::integral_constant::value + 1> {}; + +template +using get_depth = get_depth_impl::type>; + +template +struct get_order_sum_t : std::integral_constant {}; + +template +struct get_order_sum_t> + : std::integral_constant::value + Order> {}; + +template +using get_order_sum = get_order_sum_t::type>; + +template +struct get_root_type { + using type = RealType; +}; + +template +struct get_root_type> { + using type = typename get_root_type::type; +}; + +template +struct type_at { + using type = RealType; +}; + +template +struct type_at, Depth> { + using type = typename std::conditional, + typename type_at::type>::type; +}; + +template +using get_type_at = typename type_at::type; + +// Satisfies Boost's Conceptual Requirements for Real Number Types. +// https://www.boost.org/libs/math/doc/html/math_toolkit/real_concepts.html +template +class fvar { + protected: + std::array v; + + public: + using root_type = typename get_root_type::type; // RealType in the root fvar. + + fvar() = default; + + // Initialize a variable or constant. + fvar(root_type const&, bool const is_variable); + + // RealType(cr) | RealType | RealType is copy constructible. + fvar(fvar const&) = default; + + // Be aware of implicit casting from one fvar<> type to another by this copy constructor. + template + fvar(fvar const&); + + // RealType(ca) | RealType | RealType is copy constructible from the arithmetic types. + explicit fvar(root_type const&); // Initialize a constant. (No epsilon terms.) + + template + fvar(RealType2 const& ca); // Supports any RealType2 for which static_cast(ca) compiles. + + // r = cr | RealType& | Assignment operator. + fvar& operator=(fvar const&) = default; + + // r = ca | RealType& | Assignment operator from the arithmetic types. + // Handled by constructor that takes a single parameter of generic type. + // fvar& operator=(root_type const&); // Set a constant. + + // r += cr | RealType& | Adds cr to r. + template + fvar& operator+=(fvar const&); + + // r += ca | RealType& | Adds ar to r. + fvar& operator+=(root_type const&); + + // r -= cr | RealType& | Subtracts cr from r. + template + fvar& operator-=(fvar const&); + + // r -= ca | RealType& | Subtracts ca from r. + fvar& operator-=(root_type const&); + + // r *= cr | RealType& | Multiplies r by cr. + template + fvar& operator*=(fvar const&); + + // r *= ca | RealType& | Multiplies r by ca. + fvar& operator*=(root_type const&); + + // r /= cr | RealType& | Divides r by cr. + template + fvar& operator/=(fvar const&); + + // r /= ca | RealType& | Divides r by ca. + fvar& operator/=(root_type const&); + + // -r | RealType | Unary Negation. + fvar operator-() const; + + // +r | RealType& | Identity Operation. + fvar const& operator+() const; + + // cr + cr2 | RealType | Binary Addition + template + promote> operator+(fvar const&) const; + + // cr + ca | RealType | Binary Addition + fvar operator+(root_type const&) const; + + // ca + cr | RealType | Binary Addition + template + friend fvar operator+(typename fvar::root_type const&, + fvar const&); + + // cr - cr2 | RealType | Binary Subtraction + template + promote> operator-(fvar const&) const; + + // cr - ca | RealType | Binary Subtraction + fvar operator-(root_type const&) const; + + // ca - cr | RealType | Binary Subtraction + template + friend fvar operator-(typename fvar::root_type const&, + fvar const&); + + // cr * cr2 | RealType | Binary Multiplication + template + promote> operator*(fvar const&)const; + + // cr * ca | RealType | Binary Multiplication + fvar operator*(root_type const&)const; + + // ca * cr | RealType | Binary Multiplication + template + friend fvar operator*(typename fvar::root_type const&, + fvar const&); + + // cr / cr2 | RealType | Binary Subtraction + template + promote> operator/(fvar const&) const; + + // cr / ca | RealType | Binary Subtraction + fvar operator/(root_type const&) const; + + // ca / cr | RealType | Binary Subtraction + template + friend fvar operator/(typename fvar::root_type const&, + fvar const&); + + // For all comparison overloads, only the root term is compared. + + // cr == cr2 | bool | Equality Comparison + template + bool operator==(fvar const&) const; + + // cr == ca | bool | Equality Comparison + bool operator==(root_type const&) const; + + // ca == cr | bool | Equality Comparison + template + friend bool operator==(typename fvar::root_type const&, fvar const&); + + // cr != cr2 | bool | Inequality Comparison + template + bool operator!=(fvar const&) const; + + // cr != ca | bool | Inequality Comparison + bool operator!=(root_type const&) const; + + // ca != cr | bool | Inequality Comparison + template + friend bool operator!=(typename fvar::root_type const&, fvar const&); + + // cr <= cr2 | bool | Less than equal to. + template + bool operator<=(fvar const&) const; + + // cr <= ca | bool | Less than equal to. + bool operator<=(root_type const&) const; + + // ca <= cr | bool | Less than equal to. + template + friend bool operator<=(typename fvar::root_type const&, fvar const&); + + // cr >= cr2 | bool | Greater than equal to. + template + bool operator>=(fvar const&) const; + + // cr >= ca | bool | Greater than equal to. + bool operator>=(root_type const&) const; + + // ca >= cr | bool | Greater than equal to. + template + friend bool operator>=(typename fvar::root_type const&, fvar const&); + + // cr < cr2 | bool | Less than comparison. + template + bool operator<(fvar const&) const; + + // cr < ca | bool | Less than comparison. + bool operator<(root_type const&) const; + + // ca < cr | bool | Less than comparison. + template + friend bool operator<(typename fvar::root_type const&, fvar const&); + + // cr > cr2 | bool | Greater than comparison. + template + bool operator>(fvar const&) const; + + // cr > ca | bool | Greater than comparison. + bool operator>(root_type const&) const; + + // ca > cr | bool | Greater than comparison. + template + friend bool operator>(typename fvar::root_type const&, fvar const&); + + // Will throw std::out_of_range if Order < order. + template + get_type_at at(size_t order, Orders... orders) const; + + template + get_type_at derivative(Orders... orders) const; + + const RealType& operator[](size_t) const; + + fvar inverse() const; // Multiplicative inverse. + + fvar& negate(); // Negate and return reference to *this. + + static constexpr size_t depth = get_depth::value; // Number of nested std::array. + + static constexpr size_t order_sum = get_order_sum::value; + + explicit operator root_type() const; // Must be explicit, otherwise overloaded operators are ambiguous. + + template ::type>::value>> + explicit operator T() const; // Must be explicit; multiprecision has trouble without the std::enable_if + + fvar& set_root(root_type const&); + + // Apply coefficients using horner method. + template + promote, Fvar, Fvars...> apply_coefficients(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_coefficients(size_t const order, Func const& f) const; + + // Use when function returns derivative(i)/factorial(i) and may have some infinite derivatives. + template + promote, Fvar, Fvars...> apply_coefficients_nonhorner(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_coefficients_nonhorner(size_t const order, Func const& f) const; + + // Apply derivatives using horner method. + template + promote, Fvar, Fvars...> apply_derivatives(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_derivatives(size_t const order, Func const& f) const; + + // Use when function returns derivative(i) and may have some infinite derivatives. + template + promote, Fvar, Fvars...> apply_derivatives_nonhorner(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_derivatives_nonhorner(size_t const order, Func const& f) const; + + private: + RealType epsilon_inner_product(size_t z0, + size_t isum0, + size_t m0, + fvar const& cr, + size_t z1, + size_t isum1, + size_t m1, + size_t j) const; + + fvar epsilon_multiply(size_t z0, size_t isum0, fvar const& cr, size_t z1, size_t isum1) const; + + fvar epsilon_multiply(size_t z0, size_t isum0, root_type const& ca) const; + + fvar inverse_apply() const; + + fvar& multiply_assign_by_root_type(bool is_root, root_type const&); + + template + friend class fvar; + + template + friend std::ostream& operator<<(std::ostream&, fvar const&); + + // C++11 Compatibility +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + template + void fvar_cpp11(std::true_type, RootType const& ca, bool const is_variable); + + template + void fvar_cpp11(std::false_type, RootType const& ca, bool const is_variable); + + template + get_type_at at_cpp11(std::true_type, size_t order, Orders... orders) const; + + template + get_type_at at_cpp11(std::false_type, size_t order, Orders... orders) const; + + template + fvar epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const; + + template + fvar epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const; + + template + fvar epsilon_multiply_cpp11(std::true_type, SizeType z0, size_t isum0, root_type const& ca) const; + + template + fvar epsilon_multiply_cpp11(std::false_type, SizeType z0, size_t isum0, root_type const& ca) const; + + template + fvar& multiply_assign_by_root_type_cpp11(std::true_type, bool is_root, RootType const& ca); + + template + fvar& multiply_assign_by_root_type_cpp11(std::false_type, bool is_root, RootType const& ca); + + template + fvar& negate_cpp11(std::true_type, RootType const&); + + template + fvar& negate_cpp11(std::false_type, RootType const&); + + template + fvar& set_root_cpp11(std::true_type, RootType const& root); + + template + fvar& set_root_cpp11(std::false_type, RootType const& root); +#endif +}; + +// Standard Library Support Requirements + +// fabs(cr1) | RealType +template +fvar fabs(fvar const&); + +// abs(cr1) | RealType +template +fvar abs(fvar const&); + +// ceil(cr1) | RealType +template +fvar ceil(fvar const&); + +// floor(cr1) | RealType +template +fvar floor(fvar const&); + +// exp(cr1) | RealType +template +fvar exp(fvar const&); + +// pow(cr, ca) | RealType +template +fvar pow(fvar const&, typename fvar::root_type const&); + +// pow(ca, cr) | RealType +template +fvar pow(typename fvar::root_type const&, fvar const&); + +// pow(cr1, cr2) | RealType +template +promote, fvar> pow(fvar const&, + fvar const&); + +// sqrt(cr1) | RealType +template +fvar sqrt(fvar const&); + +// log(cr1) | RealType +template +fvar log(fvar const&); + +// frexp(cr1, &i) | RealType +template +fvar frexp(fvar const&, int*); + +// ldexp(cr1, i) | RealType +template +fvar ldexp(fvar const&, int); + +// cos(cr1) | RealType +template +fvar cos(fvar const&); + +// sin(cr1) | RealType +template +fvar sin(fvar const&); + +// asin(cr1) | RealType +template +fvar asin(fvar const&); + +// tan(cr1) | RealType +template +fvar tan(fvar const&); + +// atan(cr1) | RealType +template +fvar atan(fvar const&); + +// atan2(cr, ca) | RealType +template +fvar atan2(fvar const&, typename fvar::root_type const&); + +// atan2(ca, cr) | RealType +template +fvar atan2(typename fvar::root_type const&, fvar const&); + +// atan2(cr1, cr2) | RealType +template +promote, fvar> atan2(fvar const&, + fvar const&); + +// fmod(cr1,cr2) | RealType +template +promote, fvar> fmod(fvar const&, + fvar const&); + +// round(cr1) | RealType +template +fvar round(fvar const&); + +// iround(cr1) | int +template +int iround(fvar const&); + +template +long lround(fvar const&); + +template +long long llround(fvar const&); + +// trunc(cr1) | RealType +template +fvar trunc(fvar const&); + +template +long double truncl(fvar const&); + +// itrunc(cr1) | int +template +int itrunc(fvar const&); + +template +long long lltrunc(fvar const&); + +// Additional functions +template +fvar acos(fvar const&); + +template +fvar acosh(fvar const&); + +template +fvar asinh(fvar const&); + +template +fvar atanh(fvar const&); + +template +fvar cosh(fvar const&); + +template +fvar digamma(fvar const&); + +template +fvar erf(fvar const&); + +template +fvar erfc(fvar const&); + +template +fvar lambert_w0(fvar const&); + +template +fvar lgamma(fvar const&); + +template +fvar sinc(fvar const&); + +template +fvar sinh(fvar const&); + +template +fvar tanh(fvar const&); + +template +fvar tgamma(fvar const&); + +template +struct zero : std::integral_constant {}; + +} // namespace detail + +template +using autodiff_fvar = typename detail::nest_fvar::type; + +template +autodiff_fvar make_fvar(RealType const& ca) { + return autodiff_fvar(ca, true); +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +namespace detail { + +template +auto make_fvar_for_tuple(std::index_sequence, RealType const& ca) { + return make_fvar::value..., Order>(ca); +} + +template +auto make_ftuple_impl(std::index_sequence, RealTypes const&... ca) { + return std::make_tuple(make_fvar_for_tuple(std::make_index_sequence{}, ca)...); +} + +} // namespace detail + +template +auto make_ftuple(RealTypes const&... ca) { + static_assert(sizeof...(Orders) == sizeof...(RealTypes), + "Number of Orders must match number of function parameters."); + return detail::make_ftuple_impl(std::index_sequence_for{}, ca...); +} +#endif + +namespace detail { + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +template +fvar::fvar(root_type const& ca, bool const is_variable) { + if constexpr (is_fvar::value) { + v.front() = RealType(ca, is_variable); + if constexpr (0 < Order) + std::fill(v.begin() + 1, v.end(), static_cast(0)); + } else { + v.front() = ca; + if constexpr (0 < Order) + v[1] = static_cast(static_cast(is_variable)); + if constexpr (1 < Order) + std::fill(v.begin() + 2, v.end(), static_cast(0)); + } +} +#endif + +template +template +fvar::fvar(fvar const& cr) { + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + v[i] = static_cast(cr.v[i]); + BOOST_MATH_IF_CONSTEXPR (Order2 < Order) + std::fill(v.begin() + (Order2 + 1), v.end(), static_cast(0)); +} + +template +fvar::fvar(root_type const& ca) : v{{static_cast(ca)}} {} + +// Can cause compiler error if RealType2 cannot be cast to root_type. +template +template +fvar::fvar(RealType2 const& ca) : v{{static_cast(ca)}} {} + +/* +template +fvar& fvar::operator=(root_type const& ca) +{ + v.front() = static_cast(ca); + if constexpr (0 < Order) + std::fill(v.begin()+1, v.end(), static_cast(0)); + return *this; +} +*/ + +template +template +fvar& fvar::operator+=(fvar const& cr) { + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + v[i] += cr.v[i]; + return *this; +} + +template +fvar& fvar::operator+=(root_type const& ca) { + v.front() += ca; + return *this; +} + +template +template +fvar& fvar::operator-=(fvar const& cr) { + for (size_t i = 0; i <= Order; ++i) + v[i] -= cr.v[i]; + return *this; +} + +template +fvar& fvar::operator-=(root_type const& ca) { + v.front() -= ca; + return *this; +} + +template +template +fvar& fvar::operator*=(fvar const& cr) { + using diff_t = typename std::array::difference_type; + promote const zero(0); + BOOST_MATH_IF_CONSTEXPR (Order <= Order2) + for (size_t i = 0, j = Order; i <= Order; ++i, --j) + v[j] = std::inner_product(v.cbegin(), v.cend() - diff_t(i), cr.v.crbegin() + diff_t(i), zero); + else { + for (size_t i = 0, j = Order; i <= Order - Order2; ++i, --j) + v[j] = std::inner_product(cr.v.cbegin(), cr.v.cend(), v.crbegin() + diff_t(i), zero); + for (size_t i = Order - Order2 + 1, j = Order2 - 1; i <= Order; ++i, --j) + v[j] = std::inner_product(cr.v.cbegin(), cr.v.cbegin() + diff_t(j + 1), v.crbegin() + diff_t(i), zero); + } + return *this; +} + +template +fvar& fvar::operator*=(root_type const& ca) { + return multiply_assign_by_root_type(true, ca); +} + +template +template +fvar& fvar::operator/=(fvar const& cr) { + using diff_t = typename std::array::difference_type; + RealType const zero(0); + v.front() /= cr.v.front(); + BOOST_MATH_IF_CONSTEXPR (Order < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, --j, --k) + (v[i] -= std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); + else BOOST_MATH_IF_CONSTEXPR (0 < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) + (v[i] -= std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); + else + for (size_t i = 1; i <= Order; ++i) + v[i] /= cr.v.front(); + return *this; +} + +template +fvar& fvar::operator/=(root_type const& ca) { + std::for_each(v.begin(), v.end(), [&ca](RealType& x) { x /= ca; }); + return *this; +} + +template +fvar fvar::operator-() const { + fvar retval(*this); + retval.negate(); + return retval; +} + +template +fvar const& fvar::operator+() const { + return *this; +} + +template +template +promote, fvar> fvar::operator+( + fvar const& cr) const { + promote, fvar> retval; + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + retval.v[i] = v[i] + cr.v[i]; + BOOST_MATH_IF_CONSTEXPR (Order < Order2) + for (size_t i = Order + 1; i <= Order2; ++i) + retval.v[i] = cr.v[i]; + else BOOST_MATH_IF_CONSTEXPR (Order2 < Order) + for (size_t i = Order2 + 1; i <= Order; ++i) + retval.v[i] = v[i]; + return retval; +} + +template +fvar fvar::operator+(root_type const& ca) const { + fvar retval(*this); + retval.v.front() += ca; + return retval; +} + +template +fvar operator+(typename fvar::root_type const& ca, + fvar const& cr) { + return cr + ca; +} + +template +template +promote, fvar> fvar::operator-( + fvar const& cr) const { + promote, fvar> retval; + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + retval.v[i] = v[i] - cr.v[i]; + BOOST_MATH_IF_CONSTEXPR (Order < Order2) + for (auto i = Order + 1; i <= Order2; ++i) + retval.v[i] = -cr.v[i]; + else BOOST_MATH_IF_CONSTEXPR (Order2 < Order) + for (auto i = Order2 + 1; i <= Order; ++i) + retval.v[i] = v[i]; + return retval; +} + +template +fvar fvar::operator-(root_type const& ca) const { + fvar retval(*this); + retval.v.front() -= ca; + return retval; +} + +template +fvar operator-(typename fvar::root_type const& ca, + fvar const& cr) { + fvar mcr = -cr; // Has same address as retval in operator-() due to NRVO. + mcr += ca; + return mcr; // <-- This allows for NRVO. The following does not. --> return mcr += ca; +} + +template +template +promote, fvar> fvar::operator*( + fvar const& cr) const { + using diff_t = typename std::array::difference_type; + promote const zero(0); + promote, fvar> retval; + BOOST_MATH_IF_CONSTEXPR (Order < Order2) + for (size_t i = 0, j = Order, k = Order2; i <= Order2; ++i, j && --j, --k) + retval.v[i] = std::inner_product(v.cbegin(), v.cend() - diff_t(j), cr.v.crbegin() + diff_t(k), zero); + else + for (size_t i = 0, j = Order2, k = Order; i <= Order; ++i, j && --j, --k) + retval.v[i] = std::inner_product(cr.v.cbegin(), cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero); + return retval; +} + +template +fvar fvar::operator*(root_type const& ca) const { + fvar retval(*this); + retval *= ca; + return retval; +} + +template +fvar operator*(typename fvar::root_type const& ca, + fvar const& cr) { + return cr * ca; +} + +template +template +promote, fvar> fvar::operator/( + fvar const& cr) const { + using diff_t = typename std::array::difference_type; + promote const zero(0); + promote, fvar> retval; + retval.v.front() = v.front() / cr.v.front(); + BOOST_MATH_IF_CONSTEXPR (Order < Order2) { + for (size_t i = 1, j = Order2 - 1; i <= Order; ++i, --j) + retval.v[i] = + (v[i] - std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero)) / + cr.v.front(); + for (size_t i = Order + 1, j = Order2 - Order - 1; i <= Order2; ++i, --j) + retval.v[i] = + -std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero) / + cr.v.front(); + } else BOOST_MATH_IF_CONSTEXPR (0 < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) + retval.v[i] = + (v[i] - std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(k), zero)) / + cr.v.front(); + else + for (size_t i = 1; i <= Order; ++i) + retval.v[i] = v[i] / cr.v.front(); + return retval; +} + +template +fvar fvar::operator/(root_type const& ca) const { + fvar retval(*this); + retval /= ca; + return retval; +} + +template +fvar operator/(typename fvar::root_type const& ca, + fvar const& cr) { + using diff_t = typename std::array::difference_type; + fvar retval; + retval.v.front() = ca / cr.v.front(); + BOOST_MATH_IF_CONSTEXPR (0 < Order) { + RealType const zero(0); + for (size_t i = 1, j = Order - 1; i <= Order; ++i, --j) + retval.v[i] = + -std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero) / + cr.v.front(); + } + return retval; +} + +template +template +bool fvar::operator==(fvar const& cr) const { + return v.front() == cr.v.front(); +} + +template +bool fvar::operator==(root_type const& ca) const { + return v.front() == ca; +} + +template +bool operator==(typename fvar::root_type const& ca, fvar const& cr) { + return ca == cr.v.front(); +} + +template +template +bool fvar::operator!=(fvar const& cr) const { + return v.front() != cr.v.front(); +} + +template +bool fvar::operator!=(root_type const& ca) const { + return v.front() != ca; +} + +template +bool operator!=(typename fvar::root_type const& ca, fvar const& cr) { + return ca != cr.v.front(); +} + +template +template +bool fvar::operator<=(fvar const& cr) const { + return v.front() <= cr.v.front(); +} + +template +bool fvar::operator<=(root_type const& ca) const { + return v.front() <= ca; +} + +template +bool operator<=(typename fvar::root_type const& ca, fvar const& cr) { + return ca <= cr.v.front(); +} + +template +template +bool fvar::operator>=(fvar const& cr) const { + return v.front() >= cr.v.front(); +} + +template +bool fvar::operator>=(root_type const& ca) const { + return v.front() >= ca; +} + +template +bool operator>=(typename fvar::root_type const& ca, fvar const& cr) { + return ca >= cr.v.front(); +} + +template +template +bool fvar::operator<(fvar const& cr) const { + return v.front() < cr.v.front(); +} + +template +bool fvar::operator<(root_type const& ca) const { + return v.front() < ca; +} + +template +bool operator<(typename fvar::root_type const& ca, fvar const& cr) { + return ca < cr.v.front(); +} + +template +template +bool fvar::operator>(fvar const& cr) const { + return v.front() > cr.v.front(); +} + +template +bool fvar::operator>(root_type const& ca) const { + return v.front() > ca; +} + +template +bool operator>(typename fvar::root_type const& ca, fvar const& cr) { + return ca > cr.v.front(); +} + + /*** Other methods and functions ***/ + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order)/factorial(order) +// Use this when you have the polynomial coefficients, rather than just the derivatives. E.g. See atan2(). +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = (std::min)(order, order_sum); + promote, Fvar, Fvars...> accumulator = cr.apply_coefficients( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...); + while (i--) + (accumulator *= epsilon) += cr.apply_coefficients( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...); + return accumulator; +} +#endif + +// f : order -> derivative(order)/factorial(order) +// Use this when you have the polynomial coefficients, rather than just the derivatives. E.g. See atan(). +template +template +fvar fvar::apply_coefficients(size_t const order, Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + size_t i = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t i = order < order_sum ? order : order_sum; +#endif + fvar accumulator = f(i); + while (i--) + (accumulator *= epsilon) += f(i); + return accumulator; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + promote, Fvar, Fvars...> accumulator = cr.apply_coefficients_nonhorner( + order, + [&f](auto... indices) { return f(0, static_cast(indices)...); }, + std::forward(fvars)...); + size_t const i_max = (std::min)(order, order_sum); + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_coefficients_nonhorner( + order - i, + [&f, i](auto... indices) { return f(i, static_cast(indices)...); }, + std::forward(fvars)...), + 0, + 0); + } + return accumulator; +} +#endif + +// f : order -> coefficient(order) +template +template +fvar fvar::apply_coefficients_nonhorner(size_t const order, + Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + fvar accumulator = fvar(f(0u)); +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + size_t const i_max = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t const i_max = order < order_sum ? order : order_sum; +#endif + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply(i, 0, f(i)); + } + return accumulator; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = (std::min)(order, order_sum); + promote, Fvar, Fvars...> accumulator = + cr.apply_derivatives( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...) / + factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += + cr.apply_derivatives( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...) / + factorial(static_cast(i)); + return accumulator; +} +#endif + +// f : order -> derivative(order) +template +template +fvar fvar::apply_derivatives(size_t const order, Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + size_t i = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t i = order < order_sum ? order : order_sum; +#endif + fvar accumulator = f(i) / factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += f(i) / factorial(static_cast(i)); + return accumulator; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + promote, Fvar, Fvars...> accumulator = cr.apply_derivatives_nonhorner( + order, + [&f](auto... indices) { return f(0, static_cast(indices)...); }, + std::forward(fvars)...); + size_t const i_max = (std::min)(order, order_sum); + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_derivatives_nonhorner( + order - i, + [&f, i](auto... indices) { return f(i, static_cast(indices)...); }, + std::forward(fvars)...) / + factorial(static_cast(i)), + 0, + 0); + } + return accumulator; +} +#endif + +// f : order -> derivative(order) +template +template +fvar fvar::apply_derivatives_nonhorner(size_t const order, + Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + fvar accumulator = fvar(f(0u)); +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + size_t const i_max = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t const i_max = order < order_sum ? order : order_sum; +#endif + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply(i, 0, f(i) / factorial(static_cast(i))); + } + return accumulator; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at fvar::at(size_t order, Orders... orders) const { + if constexpr (0 < sizeof...(Orders)) + return v.at(order).at(static_cast(orders)...); + else + return v.at(order); +} +#endif + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at, sizeof...(Orders)> fvar::derivative( + Orders... orders) const { + static_assert(sizeof...(Orders) <= depth, + "Number of parameters to derivative(...) cannot exceed fvar::depth."); + return at(static_cast(orders)...) * + (... * factorial(static_cast(orders))); +} +#endif + +template +const RealType& fvar::operator[](size_t i) const { + return v[i]; +} + +template +RealType fvar::epsilon_inner_product(size_t z0, + size_t const isum0, + size_t const m0, + fvar const& cr, + size_t z1, + size_t const isum1, + size_t const m1, + size_t const j) const { + static_assert(is_fvar::value, "epsilon_inner_product() must have 1 < depth."); + RealType accumulator = RealType(); + auto const i0_max = m1 < j ? j - m1 : 0; + for (auto i0 = m0, i1 = j - m0; i0 <= i0_max; ++i0, --i1) + accumulator += v[i0].epsilon_multiply(z0, isum0 + i0, cr.v[i1], z1, isum1 + i1); + return accumulator; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + using diff_t = typename std::array::difference_type; + RealType const zero(0); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + if constexpr (is_fvar::value) + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = epsilon_inner_product(z0, isum0, m0, cr, z1, isum1, m1, j); + else + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = std::inner_product( + v.cbegin() + diff_t(m0), v.cend() - diff_t(i + m1), cr.v.crbegin() + diff_t(i + m0), zero); + return retval; +} +#endif + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +// When called from outside this method, z0 should be non-zero. Otherwise if z0=0 then it will give an +// incorrect result of 0 when the root value is 0 and ca=inf, when instead the correct product is nan. +// If z0=0 then use the regular multiply operator*() instead. +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + if constexpr (is_fvar::value) + for (size_t i = m0; i <= Order; ++i) + retval.v[i] = retval.v[i].epsilon_multiply(z0, isum0 + i, ca); + else + for (size_t i = m0; i <= Order; ++i) + if (retval.v[i] != static_cast(0)) + retval.v[i] *= ca; + return retval; +} +#endif + +template +fvar fvar::inverse() const { + return static_cast(*this) == 0 ? inverse_apply() : 1 / *this; +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::negate() { + if constexpr (is_fvar::value) + std::for_each(v.begin(), v.end(), [](RealType& r) { r.negate(); }); + else + std::for_each(v.begin(), v.end(), [](RealType& a) { a = -a; }); + return *this; +} +#endif + +// This gives log(0.0) = depth(1)(-inf,inf,-inf,inf,-inf,inf) +// 1 / *this: log(0.0) = depth(1)(-inf,inf,-inf,-nan,-nan,-nan) +template +fvar fvar::inverse_apply() const { + root_type derivatives[order_sum + 1]; // LCOV_EXCL_LINE This causes a false negative on lcov coverage test. + root_type const x0 = static_cast(*this); + *derivatives = 1 / x0; + for (size_t i = 1; i <= order_sum; ++i) + derivatives[i] = -derivatives[i - 1] * i / x0; + return apply_derivatives_nonhorner(order_sum, [&derivatives](size_t j) { return derivatives[j]; }); +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::multiply_assign_by_root_type(bool is_root, + root_type const& ca) { + auto itr = v.begin(); + if constexpr (is_fvar::value) { + itr->multiply_assign_by_root_type(is_root, ca); + for (++itr; itr != v.end(); ++itr) + itr->multiply_assign_by_root_type(false, ca); + } else { + if (is_root || *itr != 0) + *itr *= ca; // Skip multiplication of 0 by ca=inf to avoid nan, except when is_root. + for (++itr; itr != v.end(); ++itr) + if (*itr != 0) + *itr *= ca; + } + return *this; +} +#endif + +template +fvar::operator root_type() const { + return static_cast(v.front()); +} + +template +template +fvar::operator T() const { + return static_cast(static_cast(v.front())); +} + +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::set_root(root_type const& root) { + if constexpr (is_fvar::value) + v.front().set_root(root); + else + v.front() = root; + return *this; +} +#endif + +// Standard Library Support Requirements + +template +fvar fabs(fvar const& cr) { + typename fvar::root_type const zero(0); + return cr < zero ? -cr + : cr == zero ? fvar() // Canonical fabs'(0) = 0. + : cr; // Propagate NaN. +} + +template +fvar abs(fvar const& cr) { + return fabs(cr); +} + +template +fvar ceil(fvar const& cr) { + using std::ceil; + return fvar(ceil(static_cast::root_type>(cr))); +} + +template +fvar floor(fvar const& cr) { + using std::floor; + return fvar(floor(static_cast::root_type>(cr))); +} + +template +fvar exp(fvar const& cr) { + using std::exp; + constexpr size_t order = fvar::order_sum; + using root_type = typename fvar::root_type; + root_type const d0 = exp(static_cast(cr)); + return cr.apply_derivatives(order, [&d0](size_t) { return d0; }); +} + +template +fvar pow(fvar const& x, + typename fvar::root_type const& y) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x0 = static_cast(x); + root_type derivatives[order + 1]{pow(x0, y)}; + if (fabs(x0) < std::numeric_limits::epsilon()) { + root_type coef = 1; + for (size_t i = 0; i < order && y - i != 0; ++i) { + coef *= y - i; + derivatives[i + 1] = coef * pow(x0, y - (i + 1)); + } + return x.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + } else { + for (size_t i = 0; i < order && y - i != 0; ++i) + derivatives[i + 1] = (y - i) * derivatives[i] / x0; + return x.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i]; }); + } +} + +template +fvar pow(typename fvar::root_type const& x, + fvar const& y) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const y0 = static_cast(y); + root_type derivatives[order + 1]; + *derivatives = pow(x, y0); + root_type const logx = log(x); + for (size_t i = 0; i < order; ++i) + derivatives[i + 1] = derivatives[i] * logx; + return y.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i]; }); +} + +template +promote, fvar> pow(fvar const& x, + fvar const& y) { + BOOST_MATH_STD_USING + using return_type = promote, fvar>; + using root_type = typename return_type::root_type; + constexpr size_t order = return_type::order_sum; + root_type const x0 = static_cast(x); + root_type const y0 = static_cast(y); + root_type dxydx[order + 1]{pow(x0, y0)}; + BOOST_MATH_IF_CONSTEXPR (order == 0) + return return_type(*dxydx); + else { + for (size_t i = 0; i < order && y0 - i != 0; ++i) + dxydx[i + 1] = (y0 - i) * dxydx[i] / x0; + std::array, order + 1> lognx; + lognx.front() = fvar(1); +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + lognx[1] = log(make_fvar(x0)); +#else // for compilers that compile this branch when order == 0. + lognx[(std::min)(size_t(1), order)] = log(make_fvar(x0)); +#endif + for (size_t i = 1; i < order; ++i) + lognx[i + 1] = lognx[i] * lognx[1]; + auto const f = [&dxydx, &lognx](size_t i, size_t j) { + size_t binomial = 1; + root_type sum = dxydx[i] * static_cast(lognx[j]); + for (size_t k = 1; k <= i; ++k) { + (binomial *= (i - k + 1)) /= k; // binomial_coefficient(i,k) + sum += binomial * dxydx[i - k] * lognx[j].derivative(k); + } + return sum; + }; + if (fabs(x0) < std::numeric_limits::epsilon()) + return x.apply_derivatives_nonhorner(order, f, y); + return x.apply_derivatives(order, f, y); + } +} + +template +fvar sqrt(fvar const& cr) { + using std::sqrt; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type derivatives[order + 1]; + root_type const x = static_cast(cr); + *derivatives = sqrt(x); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(*derivatives); + else { + root_type numerator = root_type(0.5); + root_type powers = 1; +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + derivatives[1] = numerator / *derivatives; +#else // for compilers that compile this branch when order == 0. + derivatives[(std::min)(size_t(1), order)] = numerator / *derivatives; +#endif + using diff_t = typename std::array::difference_type; + for (size_t i = 2; i <= order; ++i) { + numerator *= static_cast(-0.5) * ((static_cast(i) << 1) - 3); + powers *= x; + derivatives[i] = numerator / (powers * *derivatives); + } + auto const f = [&derivatives](size_t i) { return derivatives[i]; }; + if (cr < std::numeric_limits::epsilon()) + return cr.apply_derivatives_nonhorner(order, f); + return cr.apply_derivatives(order, f); + } +} + +// Natural logarithm. If cr==0 then derivative(i) may have nans due to nans from inverse(). +template +fvar log(fvar const& cr) { + using std::log; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = log(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto const d1 = make_fvar(static_cast(cr)).inverse(); // log'(x) = 1 / x + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar frexp(fvar const& cr, int* exp) { + using std::exp2; + using std::frexp; + using root_type = typename fvar::root_type; + frexp(static_cast(cr), exp); + return cr * static_cast(exp2(-*exp)); +} + +template +fvar ldexp(fvar const& cr, int exp) { + // argument to std::exp2 must be casted to root_type, otherwise std::exp2 returns double (always) + using std::exp2; + return cr * exp2(static_cast::root_type>(exp)); +} + +template +fvar cos(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = cos(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const d1 = -sin(static_cast(cr)); + root_type const derivatives[4]{d0, d1, -d0, -d1}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 3]; }); + } +} + +template +fvar sin(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = sin(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const d1 = cos(static_cast(cr)); + root_type const derivatives[4]{d0, d1, -d0, -d1}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 3]; }); + } +} + +template +fvar asin(fvar const& cr) { + using std::asin; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = asin(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x).negate() += 1).inverse(); // asin'(x) = 1 / sqrt(1-x*x). + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar tan(fvar const& cr) { + using std::tan; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = tan(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto c = cos(make_fvar(static_cast(cr))); + auto const d1 = (c *= c).inverse(); // tan'(x) = 1 / cos(x)^2 + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan(fvar const& cr) { + using std::atan; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = ((x *= x) += 1).inverse(); // atan'(x) = 1 / (x*x+1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan2(fvar const& cr, + typename fvar::root_type const& ca) { + using std::atan2; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan2(static_cast(cr), ca); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto y = make_fvar(static_cast(cr)); + auto const d1 = ca / ((y *= y) += (ca * ca)); // (d/dy)atan2(y,x) = x / (y*y+x*x) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan2(typename fvar::root_type const& ca, + fvar const& cr) { + using std::atan2; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan2(ca, static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = -ca / ((x *= x) += (ca * ca)); // (d/dx)atan2(y,x) = -y / (x*x+y*y) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +promote, fvar> atan2(fvar const& cr1, + fvar const& cr2) { + using std::atan2; + using return_type = promote, fvar>; + using root_type = typename return_type::root_type; + constexpr size_t order = return_type::order_sum; + root_type const y = static_cast(cr1); + root_type const x = static_cast(cr2); + root_type const d00 = atan2(y, x); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return return_type(d00); + else { + constexpr size_t order1 = fvar::order_sum; + constexpr size_t order2 = fvar::order_sum; + auto x01 = make_fvar::root_type, order2 - 1>(x); + auto const d01 = -y / ((x01 *= x01) += (y * y)); + auto y10 = make_fvar::root_type, order1 - 1>(y); + auto x10 = make_fvar::root_type, 0, order2>(x); + auto const d10 = x10 / ((x10 * x10) + (y10 *= y10)); + auto const f = [&d00, &d01, &d10](size_t i, size_t j) { + return i ? d10[i - 1][j] / i : j ? d01[j - 1] / j : d00; + }; + return cr1.apply_coefficients(order, f, cr2); + } +} + +template +promote, fvar> fmod(fvar const& cr1, + fvar const& cr2) { + using boost::math::trunc; + auto const numer = static_cast::root_type>(cr1); + auto const denom = static_cast::root_type>(cr2); + return cr1 - cr2 * trunc(numer / denom); +} + +template +fvar round(fvar const& cr) { + using boost::math::round; + return fvar(round(static_cast::root_type>(cr))); +} + +template +int iround(fvar const& cr) { + using boost::math::iround; + return iround(static_cast::root_type>(cr)); +} + +template +long lround(fvar const& cr) { + using boost::math::lround; + return lround(static_cast::root_type>(cr)); +} + +template +long long llround(fvar const& cr) { + using boost::math::llround; + return llround(static_cast::root_type>(cr)); +} + +template +fvar trunc(fvar const& cr) { + using boost::math::trunc; + return fvar(trunc(static_cast::root_type>(cr))); +} + +template +long double truncl(fvar const& cr) { + using std::truncl; + return truncl(static_cast::root_type>(cr)); +} + +template +int itrunc(fvar const& cr) { + using boost::math::itrunc; + return itrunc(static_cast::root_type>(cr)); +} + +template +long long lltrunc(fvar const& cr) { + using boost::math::lltrunc; + return lltrunc(static_cast::root_type>(cr)); +} + +template +std::ostream& operator<<(std::ostream& out, fvar const& cr) { + out << "depth(" << cr.depth << ")(" << cr.v.front(); + for (size_t i = 1; i <= Order; ++i) + out << ',' << cr.v[i]; + return out << ')'; +} + +// Additional functions + +template +fvar acos(fvar const& cr) { + using std::acos; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = acos(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x).negate() += 1).inverse().negate(); // acos'(x) = -1 / sqrt(1-x*x). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar acosh(fvar const& cr) { + using boost::math::acosh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = acosh(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x) -= 1).inverse(); // acosh'(x) = 1 / sqrt(x*x-1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar asinh(fvar const& cr) { + using boost::math::asinh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = asinh(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x) += 1).inverse(); // asinh'(x) = 1 / sqrt(x*x+1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atanh(fvar const& cr) { + using boost::math::atanh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atanh(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = ((x *= x).negate() += 1).inverse(); // atanh'(x) = 1 / (1-x*x) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar cosh(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = cosh(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const derivatives[2]{d0, sinh(static_cast(cr))}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 1]; }); + } +} + +template +fvar digamma(fvar const& cr) { + using boost::math::digamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x = static_cast(cr); + root_type const d0 = digamma(x); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + static_assert(order <= static_cast((std::numeric_limits::max)()), + "order exceeds maximum derivative for boost::math::polygamma()."); + return cr.apply_derivatives( + order, [&x, &d0](size_t i) { return i ? boost::math::polygamma(static_cast(i), x) : d0; }); + } +} + +template +fvar erf(fvar const& cr) { + using boost::math::erf; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = erf(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); // d1 = 2/sqrt(pi)*exp(-x*x) + auto const d1 = 2 * constants::one_div_root_pi() * exp((x *= x).negate()); + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar erfc(fvar const& cr) { + using boost::math::erfc; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = erfc(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); // erfc'(x) = -erf'(x) + auto const d1 = -2 * constants::one_div_root_pi() * exp((x *= x).negate()); + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar lambert_w0(fvar const& cr) { + using std::exp; + using boost::math::lambert_w0; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type derivatives[order + 1]; + *derivatives = lambert_w0(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(*derivatives); + else { + root_type const expw = exp(*derivatives); + derivatives[1] = 1 / (static_cast(cr) + expw); + BOOST_MATH_IF_CONSTEXPR (order == 1) + return cr.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + else { + using diff_t = typename std::array::difference_type; + root_type d1powers = derivatives[1] * derivatives[1]; + root_type const x = derivatives[1] * expw; + derivatives[2] = d1powers * (-1 - x); + std::array coef{{-1, -1}}; // as in derivatives[2]. + for (size_t n = 3; n <= order; ++n) { + coef[n - 1] = coef[n - 2] * -static_cast(2 * n - 3); + for (size_t j = n - 2; j != 0; --j) + (coef[j] *= -static_cast(n - 1)) -= (n + j - 2) * coef[j - 1]; + coef[0] *= -static_cast(n - 1); + d1powers *= derivatives[1]; + derivatives[n] = + d1powers * std::accumulate(coef.crend() - diff_t(n - 1), + coef.crend(), + coef[n - 1], + [&x](root_type const& a, root_type const& b) { return a * x + b; }); + } + return cr.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + } + } +} + +template +fvar lgamma(fvar const& cr) { + using std::lgamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x = static_cast(cr); + root_type const d0 = lgamma(x); + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + static_assert(order <= static_cast((std::numeric_limits::max)()) + 1, + "order exceeds maximum derivative for boost::math::polygamma()."); + return cr.apply_derivatives( + order, [&x, &d0](size_t i) { return i ? boost::math::polygamma(static_cast(i - 1), x) : d0; }); + } +} + +template +fvar sinc(fvar const& cr) { + if (cr != 0) + return sin(cr) / cr; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type taylor[order + 1]{1}; // sinc(0) = 1 + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(*taylor); + else { + for (size_t n = 2; n <= order; n += 2) + taylor[n] = (1 - static_cast(n & 2)) / factorial(static_cast(n + 1)); + return cr.apply_coefficients_nonhorner(order, [&taylor](size_t i) { return taylor[i]; }); + } +} + +template +fvar sinh(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = sinh(static_cast(cr)); + BOOST_MATH_IF_CONSTEXPR (fvar::order_sum == 0) + return fvar(d0); + else { + root_type const derivatives[2]{d0, cosh(static_cast(cr))}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 1]; }); + } +} + +template +fvar tanh(fvar const& cr) { + fvar retval = exp(cr * 2); + fvar const denom = retval + 1; + (retval -= 1) /= denom; + return retval; +} + +template +fvar tgamma(fvar const& cr) { + using std::tgamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + BOOST_MATH_IF_CONSTEXPR (order == 0) + return fvar(tgamma(static_cast(cr))); + else { + if (cr < 0) + return constants::pi() / (sin(constants::pi() * cr) * tgamma(1 - cr)); + return exp(lgamma(cr)).set_root(tgamma(static_cast(cr))); + } +} + +} // namespace detail +} // namespace autodiff_v1 +} // namespace differentiation +} // namespace math +} // namespace boost + +namespace std { + +// boost::math::tools::digits() is handled by this std::numeric_limits<> specialization, +// and similarly for max_value, min_value, log_max_value, log_min_value, and epsilon. +template +class numeric_limits> + : public numeric_limits::root_type> { +}; + +} // namespace std + +namespace boost { +namespace math { +namespace tools { +namespace detail { + +template +using autodiff_fvar_type = differentiation::detail::fvar; + +template +using autodiff_root_type = typename autodiff_fvar_type::root_type; +} // namespace detail + +// See boost/math/tools/promotion.hpp +template +struct promote_args, + detail::autodiff_fvar_type> { + using type = detail::autodiff_fvar_type::type, +#ifndef BOOST_MATH_NO_CXX14_CONSTEXPR + (std::max)(Order0, Order1)>; +#else + Order0; +#endif +}; + +template +struct promote_args> { + using type = detail::autodiff_fvar_type::type, Order>; +}; + +template +struct promote_args, RealType1> { + using type = detail::autodiff_fvar_type::type, Order0>; +}; + +template +struct promote_args> { + using type = detail::autodiff_fvar_type::type, Order1>; +}; + +template +inline constexpr destination_t real_cast(detail::autodiff_fvar_type const& from_v) + noexcept(BOOST_MATH_IS_FLOAT(destination_t) && BOOST_MATH_IS_FLOAT(RealType)) { + return real_cast(static_cast>(from_v)); +} + +} // namespace tools + +namespace policies { + +template +using fvar_t = differentiation::detail::fvar; +template +struct evaluation, Policy> { + using type = fvar_t::type, Order>; +}; + +template +struct evaluation, Policy> { + using type = + fvar_t::type, Order>; +}; + +} // namespace policies +} // namespace math +} // namespace boost + +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#include "autodiff_cpp11.hpp" +#endif + +#endif // BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP diff --git a/third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp b/third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp new file mode 100644 index 0000000000000..1624c494eeb04 --- /dev/null +++ b/third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp @@ -0,0 +1,387 @@ +// Copyright Matthew Pulver 2018 - 2019. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// Contributors: +// * Kedar R. Bhat - C++11 compatibility. + +// Notes: +// * Any changes to this file should always be downstream from autodiff.cpp. +// C++17 is a higher-level language and is easier to maintain. For example, a number of functions which are +// lucidly read in autodiff.cpp are forced to be split into multiple structs/functions in this file for +// C++11. +// * Use of typename RootType and SizeType is a hack to prevent Visual Studio 2015 from compiling functions +// that are never called, that would otherwise produce compiler errors. Also forces functions to be inline. + +#ifndef BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP +#error \ + "Do not #include this file directly. This should only be #included by autodiff.hpp for C++11 compatibility." +#endif + +#include +#include + +namespace boost { +namespace math { + +namespace mp = tools::meta_programming; + +namespace differentiation { +inline namespace autodiff_v1 { +namespace detail { + +template +fvar::fvar(root_type const& ca, bool const is_variable) { + fvar_cpp11(is_fvar{}, ca, is_variable); +} + +template +template +void fvar::fvar_cpp11(std::true_type, RootType const& ca, bool const is_variable) { + v.front() = RealType(ca, is_variable); + if (0 < Order) + std::fill(v.begin() + 1, v.end(), static_cast(0)); +} + +template +template +void fvar::fvar_cpp11(std::false_type, RootType const& ca, bool const is_variable) { + v.front() = ca; + if (0 < Order) { + v[1] = static_cast(static_cast(is_variable)); + if (1 < Order) + std::fill(v.begin() + 2, v.end(), static_cast(0)); + } +} + +template +template +get_type_at fvar::at_cpp11(std::true_type, + size_t order, + Orders...) const { + return v.at(order); +} + +template +template +get_type_at fvar::at_cpp11(std::false_type, + size_t order, + Orders... orders) const { + return v.at(order).at(orders...); +} + +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at fvar::at(size_t order, Orders... orders) const { + return at_cpp11(std::integral_constant{}, order, orders...); +} + +template +constexpr T product(Ts...) { + return static_cast(1); +} + +template +constexpr T product(T factor, Ts... factors) { + return factor * product(factors...); +} + +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at, sizeof...(Orders)> fvar::derivative( + Orders... orders) const { + static_assert(sizeof...(Orders) <= depth, + "Number of parameters to derivative(...) cannot exceed fvar::depth."); + return at(static_cast(orders)...) * + product(boost::math::factorial(static_cast(orders))...); +} + +template +class Curry { + Func const& f_; + size_t const i_; + + public: + template // typename SizeType to force inline constructor. + Curry(Func const& f, SizeType i) : f_(f), i_(static_cast(i)) {} + template + RootType operator()(Indices... indices) const { + using unsigned_t = typename std::make_unsigned::type...>::type; + return f_(i_, static_cast(indices)...); + } +}; + +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = order < order_sum ? order : order_sum; + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_coefficients( + order - i, Curry(f, i), std::forward(fvars)...); + while (i--) + (accumulator *= epsilon) += cr.apply_coefficients( + order - i, Curry(f, i), std::forward(fvars)...); + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_coefficients_nonhorner( + order, Curry(f, 0), std::forward(fvars)...); + size_t const i_max = order < order_sum ? order : order_sum; + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_coefficients_nonhorner( + order - i, Curry(f, i), std::forward(fvars)...), + 0, + 0); + } + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = order < order_sum ? order : order_sum; + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = + cr.apply_derivatives( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += + cr.apply_derivatives( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)); + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_derivatives_nonhorner( + order, Curry(f, 0), std::forward(fvars)...); + size_t const i_max = order < order_sum ? order : order_sum; + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_derivatives_nonhorner( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)), + 0, + 0); + } + return accumulator; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = epsilon_inner_product(z0, isum0, m0, cr, z1, isum1, m1, j); + return retval; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + using ssize_t = typename std::make_signed::type; + RealType const zero(0); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = std::inner_product( + v.cbegin() + ssize_t(m0), v.cend() - ssize_t(i + m1), cr.v.crbegin() + ssize_t(i + m0), zero); + return retval; +} + +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + return epsilon_multiply_cpp11(is_fvar{}, z0, isum0, cr, z1, isum1); +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + for (size_t i = m0; i <= Order; ++i) + retval.v[i] = retval.v[i].epsilon_multiply(z0, isum0 + i, ca); + return retval; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + for (size_t i = m0; i <= Order; ++i) + if (retval.v[i] != static_cast(0)) + retval.v[i] *= ca; + return retval; +} + +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + root_type const& ca) const { + return epsilon_multiply_cpp11(is_fvar{}, z0, isum0, ca); +} + +template +template +fvar& fvar::multiply_assign_by_root_type_cpp11(std::true_type, + bool is_root, + RootType const& ca) { + auto itr = v.begin(); + itr->multiply_assign_by_root_type(is_root, ca); + for (++itr; itr != v.end(); ++itr) + itr->multiply_assign_by_root_type(false, ca); + return *this; +} + +template +template +fvar& fvar::multiply_assign_by_root_type_cpp11(std::false_type, + bool is_root, + RootType const& ca) { + auto itr = v.begin(); + if (is_root || *itr != 0) + *itr *= ca; // Skip multiplication of 0 by ca=inf to avoid nan, except when is_root. + for (++itr; itr != v.end(); ++itr) + if (*itr != 0) + *itr *= ca; + return *this; +} + +template +fvar& fvar::multiply_assign_by_root_type(bool is_root, + root_type const& ca) { + return multiply_assign_by_root_type_cpp11(is_fvar{}, is_root, ca); +} + +template +template +fvar& fvar::negate_cpp11(std::true_type, RootType const&) { + std::for_each(v.begin(), v.end(), [](RealType& r) { r.negate(); }); + return *this; +} + +template +template +fvar& fvar::negate_cpp11(std::false_type, RootType const&) { + std::for_each(v.begin(), v.end(), [](RealType& a) { a = -a; }); + return *this; +} + +template +fvar& fvar::negate() { + return negate_cpp11(is_fvar{}, static_cast(*this)); +} + +template +template +fvar& fvar::set_root_cpp11(std::true_type, RootType const& root) { + v.front().set_root(root); + return *this; +} + +template +template +fvar& fvar::set_root_cpp11(std::false_type, RootType const& root) { + v.front() = root; + return *this; +} + +template +fvar& fvar::set_root(root_type const& root) { + return set_root_cpp11(is_fvar{}, root); +} + +template +auto make_fvar_for_tuple(mp::index_sequence, RealType const& ca) + -> decltype(make_fvar::value..., Order>(ca)) { + return make_fvar::value..., Order>(ca); +} + +template +auto make_ftuple_impl(mp::index_sequence, RealTypes const&... ca) + -> decltype(std::make_tuple(make_fvar_for_tuple(mp::make_index_sequence{}, + ca)...)) { + return std::make_tuple(make_fvar_for_tuple(mp::make_index_sequence{}, ca)...); +} + +} // namespace detail + +template +auto make_ftuple(RealTypes const&... ca) + -> decltype(detail::make_ftuple_impl(mp::index_sequence_for{}, + ca...)) { + static_assert(sizeof...(Orders) == sizeof...(RealTypes), + "Number of Orders must match number of function parameters."); + return detail::make_ftuple_impl(mp::index_sequence_for{}, ca...); +} + +} // namespace autodiff_v1 +} // namespace differentiation +} // namespace math +} // namespace boost diff --git a/third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp b/third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp new file mode 100644 index 0000000000000..1375bac7adf3d --- /dev/null +++ b/third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp @@ -0,0 +1,266 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_DIFFERENTIATION_FINITE_DIFFERENCE_HPP +#define BOOST_MATH_DIFFERENTIATION_FINITE_DIFFERENCE_HPP + +/* + * Performs numerical differentiation by finite-differences. + * + * All numerical differentiation using finite-differences are ill-conditioned, and these routines are no exception. + * A simple argument demonstrates that the error is unbounded as h->0. + * Take the one sides finite difference formula f'(x) = (f(x+h)-f(x))/h. + * The evaluation of f induces an error as well as the error from the finite-difference approximation, giving + * |f'(x) - (f(x+h) -f(x))/h| < h|f''(x)|/2 + (|f(x)|+|f(x+h)|)eps/h =: g(h), where eps is the unit roundoff for the type. + * It is reasonable to choose h in a way that minimizes the maximum error bound g(h). + * The value of h that minimizes g is h = sqrt(2eps(|f(x)| + |f(x+h)|)/|f''(x)|), and for this value of h the error bound is + * sqrt(2eps(|f(x+h) +f(x)||f''(x)|)). + * In fact it is not necessary to compute the ratio (|f(x+h)| + |f(x)|)/|f''(x)|; the error bound of ~\sqrt{\epsilon} still holds if we set it to one. + * + * + * For more details on this method of analysis, see + * + * http://www.uio.no/studier/emner/matnat/math/MAT-INF1100/h08/kompendiet/diffint.pdf + * http://web.archive.org/web/20150420195907/http://www.uio.no/studier/emner/matnat/math/MAT-INF1100/h08/kompendiet/diffint.pdf + * + * + * It can be shown on general grounds that when choosing the optimal h, the maximum error in f'(x) is ~(|f(x)|eps)^k/k+1|f^(k-1)(x)|^1/k+1. + * From this we can see that full precision can be recovered in the limit k->infinity. + * + * References: + * + * 1) Fornberg, Bengt. "Generation of finite difference formulas on arbitrarily spaced grids." Mathematics of computation 51.184 (1988): 699-706. + * + * + * The second algorithm, the complex step derivative, is not ill-conditioned. + * However, it requires that your function can be evaluated at complex arguments. + * The idea is that f(x+ih) = f(x) +ihf'(x) - h^2f''(x) + ... so f'(x) \approx Im[f(x+ih)]/h. + * No subtractive cancellation occurs. The error is ~ eps|f'(x)| + eps^2|f'''(x)|/6; hard to beat that. + * + * References: + * + * 1) Squire, William, and George Trapp. "Using complex variables to estimate derivatives of real functions." Siam Review 40.1 (1998): 110-112. + */ + +#include +#include + +namespace boost{ namespace math{ namespace differentiation { + +namespace detail { + template + Real make_xph_representable(Real x, Real h) + { + using std::numeric_limits; + // Redefine h so that x + h is representable. Not using this trick leads to large error. + // The compiler flag -ffast-math evaporates these operations . . . + Real temp = x + h; + h = temp - x; + // Handle the case x + h == x: + if (h == 0) + { + h = boost::math::nextafter(x, (numeric_limits::max)()) - x; + } + return h; + } +} + +template +Real complex_step_derivative(const F f, Real x) +{ + // Is it really this easy? Yes. + // Note that some authors recommend taking the stepsize h to be smaller than epsilon(), some recommending use of the min(). + // This idea was tested over a few billion test cases and found the make the error *much* worse. + // Even 2eps and eps/2 made the error worse, which was surprising. + using std::complex; + using std::numeric_limits; + constexpr const Real step = (numeric_limits::epsilon)(); + constexpr const Real inv_step = 1/(numeric_limits::epsilon)(); + return f(complex(x, step)).imag()*inv_step; +} + +namespace detail { + + template + struct fd_tag {}; + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<1>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^1/2 + // Note that this estimate of h differs from the best estimate by a factor of sqrt((|f(x)| + |f(x+h)|)/|f''(x)|). + // Since this factor is invariant under the scaling f -> kf, then we are somewhat justified in approximating it by 1. + // This approximation will get better as we move to higher orders of accuracy. + Real h = 2 * sqrt(eps); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real y0 = f(x); + Real diff = yh - y0; + if (error) + { + Real ym = f(x - h); + Real ypph = abs(yh - 2 * y0 + ym) / h; + // h*|f''(x)|*0.5 + (|f(x+h)+|f(x)|)*eps/h + *error = ypph / 2 + (abs(yh) + abs(y0))*eps / h; + } + return diff / h; + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<2>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^2/3 + // See the previous discussion to understand determination of h and the error bound. + // Series[(f[x+h] - f[x-h])/(2*h), {h, 0, 4}] + Real h = pow(3 * eps, static_cast(1) / static_cast(3)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real diff = yh - ymh; + if (error) + { + Real yth = f(x + 2 * h); + Real ymth = f(x - 2 * h); + *error = eps * (abs(yh) + abs(ymh)) / (2 * h) + abs((yth - ymth) / 2 - diff) / (6 * h); + } + + return diff / (2 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<4>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^4/5 + Real h = pow(Real(11.25)*eps, static_cast(1) / static_cast(5)); + h = detail::make_xph_representable(x, h); + Real ymth = f(x - 2 * h); + Real yth = f(x + 2 * h); + Real yh = f(x + h); + Real ymh = f(x - h); + Real y2 = ymth - yth; + Real y1 = yh - ymh; + if (error) + { + // Mathematica code to extract the remainder: + // Series[(f[x-2*h]+ 8*f[x+h] - 8*f[x-h] - f[x+2*h])/(12*h), {h, 0, 7}] + Real y_three_h = f(x + 3 * h); + Real y_m_three_h = f(x - 3 * h); + // Error from fifth derivative: + *error = abs((y_three_h - y_m_three_h) / 2 + 2 * (ymth - yth) + 5 * (yh - ymh) / 2) / (30 * h); + // Error from function evaluation: + *error += eps * (abs(yth) + abs(ymth) + 8 * (abs(ymh) + abs(yh))) / (12 * h); + } + return (y2 + 8 * y1) / (12 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<6>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^6/7 + // Error: h^6f^(7)(x)/140 + 5|f(x)|eps/h + Real h = pow(eps / 168, static_cast(1) / static_cast(7)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real y1 = yh - ymh; + Real y2 = f(x - 2 * h) - f(x + 2 * h); + Real y3 = f(x + 3 * h) - f(x - 3 * h); + + if (error) + { + // Mathematica code to generate fd scheme for 7th derivative: + // Sum[(-1)^i*Binomial[7, i]*(f[x+(3-i)*h] + f[x+(4-i)*h])/2, {i, 0, 7}] + // Mathematica to demonstrate that this is a finite difference formula for 7th derivative: + // Series[(f[x+4*h]-f[x-4*h] + 6*(f[x-3*h] - f[x+3*h]) + 14*(f[x-h] - f[x+h] + f[x+2*h] - f[x-2*h]))/2, {h, 0, 15}] + Real y7 = (f(x + 4 * h) - f(x - 4 * h) - 6 * y3 - 14 * y1 - 14 * y2) / 2; + *error = abs(y7) / (140 * h) + 5 * (abs(yh) + abs(ymh))*eps / h; + } + return (y3 + 9 * y2 + 45 * y1) / (60 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<8>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^8/9. + // In double precision, we only expect to lose two digits of precision while using this formula, at the cost of 8 function evaluations. + // Error: h^8|f^(9)(x)|/630 + 7|f(x)|eps/h assuming 7 unstabilized additions. + // Mathematica code to get the error: + // Series[(f[x+h]-f[x-h])*(4/5) + (1/5)*(f[x-2*h] - f[x+2*h]) + (4/105)*(f[x+3*h] - f[x-3*h]) + (1/280)*(f[x-4*h] - f[x+4*h]), {h, 0, 9}] + // If we used Kahan summation, we could get the max error down to h^8|f^(9)(x)|/630 + |f(x)|eps/h. + Real h = pow(Real(551.25)*eps, static_cast(1) / static_cast(9)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real y1 = yh - ymh; + Real y2 = f(x - 2 * h) - f(x + 2 * h); + Real y3 = f(x + 3 * h) - f(x - 3 * h); + Real y4 = f(x - 4 * h) - f(x + 4 * h); + + Real tmp1 = 3 * y4 / 8 + 4 * y3; + Real tmp2 = 21 * y2 + 84 * y1; + + if (error) + { + // Mathematica code to generate fd scheme for 7th derivative: + // Sum[(-1)^i*Binomial[9, i]*(f[x+(4-i)*h] + f[x+(5-i)*h])/2, {i, 0, 9}] + // Mathematica to demonstrate that this is a finite difference formula for 7th derivative: + // Series[(f[x+5*h]-f[x- 5*h])/2 + 4*(f[x-4*h] - f[x+4*h]) + 27*(f[x+3*h] - f[x-3*h])/2 + 24*(f[x-2*h] - f[x+2*h]) + 21*(f[x+h] - f[x-h]), {h, 0, 15}] + Real f9 = (f(x + 5 * h) - f(x - 5 * h)) / 2 + 4 * y4 + 27 * y3 / 2 + 24 * y2 + 21 * y1; + *error = abs(f9) / (630 * h) + 7 * (abs(yh) + abs(ymh))*eps / h; + } + return (tmp1 + tmp2) / (105 * h); + } + + template + Real finite_difference_derivative(const F, Real, Real*, const tag&) + { + // Always fails, but condition is template-arg-dependent so only evaluated if we get instantiated. + static_assert(sizeof(Real) == 0, "Finite difference not implemented for this order: try 1, 2, 4, 6 or 8"); + } + +} + +template +inline Real finite_difference_derivative(const F f, Real x, Real* error = nullptr) +{ + return detail::finite_difference_derivative(f, x, error, detail::fd_tag()); +} + +}}} // namespaces +#endif diff --git a/third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp b/third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp new file mode 100644 index 0000000000000..4103f538d705d --- /dev/null +++ b/third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp @@ -0,0 +1,591 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_DIFFERENTIATION_LANCZOS_SMOOTHING_HPP +#define BOOST_MATH_DIFFERENTIATION_LANCZOS_SMOOTHING_HPP +#include // for std::abs +#include +#include // to nan initialize +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math::differentiation { + +namespace detail { +template +class discrete_legendre { + public: + explicit discrete_legendre(std::size_t n, Real x) : m_n{n}, m_r{2}, m_x{x}, + m_qrm2{1}, m_qrm1{x}, + m_qrm2p{0}, m_qrm1p{1}, + m_qrm2pp{0}, m_qrm1pp{0} + { + using std::abs; + BOOST_MATH_ASSERT_MSG(abs(m_x) <= 1, "Three term recurrence is stable only for |x| <=1."); + // The integer n indexes a family of discrete Legendre polynomials indexed by k <= 2*n + } + + Real norm_sq(int r) const + { + Real prod = Real(2) / Real(2 * r + 1); + for (int k = -r; k <= r; ++k) { + prod *= Real(2 * m_n + 1 + k) / Real(2 * m_n); + } + return prod; + } + + Real next() + { + Real N = 2 * m_n + 1; + Real num = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) * m_qrm2; + Real tmp = (2 * m_r - 1) * m_x * m_qrm1 - num / Real(4 * m_n * m_n); + m_qrm2 = m_qrm1; + m_qrm1 = tmp / m_r; + ++m_r; + return m_qrm1; + } + + Real next_prime() + { + Real N = 2 * m_n + 1; + Real s = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) / Real(4 * m_n * m_n); + Real tmp1 = ((2 * m_r - 1) * m_x * m_qrm1 - s * m_qrm2) / m_r; + Real tmp2 = ((2 * m_r - 1) * (m_qrm1 + m_x * m_qrm1p) - s * m_qrm2p) / m_r; + m_qrm2 = m_qrm1; + m_qrm1 = tmp1; + m_qrm2p = m_qrm1p; + m_qrm1p = tmp2; + ++m_r; + return m_qrm1p; + } + + Real next_dbl_prime() + { + Real N = 2*m_n + 1; + Real trm1 = 2*m_r - 1; + Real s = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) / Real(4 * m_n * m_n); + Real rqrpp = 2*trm1*m_qrm1p + trm1*m_x*m_qrm1pp - s*m_qrm2pp; + Real tmp1 = ((2 * m_r - 1) * m_x * m_qrm1 - s * m_qrm2) / m_r; + Real tmp2 = ((2 * m_r - 1) * (m_qrm1 + m_x * m_qrm1p) - s * m_qrm2p) / m_r; + m_qrm2 = m_qrm1; + m_qrm1 = tmp1; + m_qrm2p = m_qrm1p; + m_qrm1p = tmp2; + m_qrm2pp = m_qrm1pp; + m_qrm1pp = rqrpp/m_r; + ++m_r; + return m_qrm1pp; + } + + Real operator()(Real x, std::size_t k) + { + BOOST_MATH_ASSERT_MSG(k <= 2 * m_n, "r <= 2n is required."); + if (k == 0) + { + return 1; + } + if (k == 1) + { + return x; + } + Real qrm2 = 1; + Real qrm1 = x; + Real N = 2 * m_n + 1; + for (std::size_t r = 2; r <= k; ++r) { + Real num = (r - 1) * (N * N - (r - 1) * (r - 1)) * qrm2; + Real tmp = (2 * r - 1) * x * qrm1 - num / Real(4 * m_n * m_n); + qrm2 = qrm1; + qrm1 = tmp / r; + } + return qrm1; + } + + Real prime(Real x, std::size_t k) { + BOOST_MATH_ASSERT_MSG(k <= 2 * m_n, "r <= 2n is required."); + if (k == 0) { + return 0; + } + if (k == 1) { + return 1; + } + Real qrm2 = 1; + Real qrm1 = x; + Real qrm2p = 0; + Real qrm1p = 1; + Real N = 2 * m_n + 1; + for (std::size_t r = 2; r <= k; ++r) { + Real s = + (r - 1) * (N * N - (r - 1) * (r - 1)) / Real(4 * m_n * m_n); + Real tmp1 = ((2 * r - 1) * x * qrm1 - s * qrm2) / r; + Real tmp2 = ((2 * r - 1) * (qrm1 + x * qrm1p) - s * qrm2p) / r; + qrm2 = qrm1; + qrm1 = tmp1; + qrm2p = qrm1p; + qrm1p = tmp2; + } + return qrm1p; + } + + private: + std::size_t m_n; + std::size_t m_r; + Real m_x; + Real m_qrm2; + Real m_qrm1; + Real m_qrm2p; + Real m_qrm1p; + Real m_qrm2pp; + Real m_qrm1pp; +}; + +template +std::vector interior_velocity_filter(std::size_t n, std::size_t p) { + auto dlp = discrete_legendre(n, 0); + std::vector coeffs(p+1); + coeffs[1] = 1/dlp.norm_sq(1); + for (std::size_t l = 3; l < p + 1; l += 2) + { + dlp.next_prime(); + coeffs[l] = dlp.next_prime()/ dlp.norm_sq(l); + } + + // We could make the filter length n, as f[0] = 0, + // but that'd make the indexing awkward when applying the filter. + std::vector f(n + 1); + // This value should never be read, but this is the correct value *if it is read*. + // Hmm, should it be a nan then? I'm not gonna agonize. + f[0] = 0; + for (std::size_t j = 1; j < f.size(); ++j) + { + Real arg = Real(j) / Real(n); + dlp = discrete_legendre(n, arg); + f[j] = coeffs[1]*arg; + for (std::size_t l = 3; l <= p; l += 2) + { + dlp.next(); + f[j] += coeffs[l]*dlp.next(); + } + f[j] /= (n * n); + } + return f; +} + +template +std::vector boundary_velocity_filter(std::size_t n, std::size_t p, int64_t s) +{ + std::vector coeffs(p+1, std::numeric_limits::quiet_NaN()); + Real sn = Real(s) / Real(n); + auto dlp = discrete_legendre(n, sn); + coeffs[0] = 0; + coeffs[1] = 1/dlp.norm_sq(1); + for (std::size_t l = 2; l < p + 1; ++l) + { + // Calculation of the norms is common to all filters, + // so it seems like an obvious optimization target. + // I tried this: The spent in computing the norms time is not negligible, + // but still a small fraction of the total compute time. + // Hence I'm not refactoring out these norm calculations. + coeffs[l] = dlp.next_prime()/ dlp.norm_sq(l); + } + + std::vector f(2*n + 1); + for (std::size_t k = 0; k < f.size(); ++k) + { + Real j = Real(k) - Real(n); + Real arg = j/Real(n); + dlp = discrete_legendre(n, arg); + f[k] = coeffs[1]*arg; + for (std::size_t l = 2; l <= p; ++l) + { + f[k] += coeffs[l]*dlp.next(); + } + f[k] /= (n * n); + } + return f; +} + +template +std::vector acceleration_filter(std::size_t n, std::size_t p, int64_t s) +{ + BOOST_MATH_ASSERT_MSG(p <= 2*n, "Approximation order must be <= 2*n"); + BOOST_MATH_ASSERT_MSG(p > 2, "Approximation order must be > 2"); + + std::vector coeffs(p+1, std::numeric_limits::quiet_NaN()); + Real sn = Real(s) / Real(n); + auto dlp = discrete_legendre(n, sn); + coeffs[0] = 0; + coeffs[1] = 0; + for (std::size_t l = 2; l < p + 1; ++l) + { + coeffs[l] = dlp.next_dbl_prime()/ dlp.norm_sq(l); + } + + std::vector f(2*n + 1, 0); + for (std::size_t k = 0; k < f.size(); ++k) + { + Real j = Real(k) - Real(n); + Real arg = j/Real(n); + dlp = discrete_legendre(n, arg); + for (std::size_t l = 2; l <= p; ++l) + { + f[k] += coeffs[l]*dlp.next(); + } + f[k] /= (n * n * n); + } + return f; +} + + +} // namespace detail + +template +class discrete_lanczos_derivative { +public: + discrete_lanczos_derivative(Real const & spacing, + std::size_t n = 18, + std::size_t approximation_order = 3) + : m_dt{spacing} + { + static_assert(!std::is_integral_v, + "Spacing must be a floating point type."); + BOOST_MATH_ASSERT_MSG(spacing > 0, + "Spacing between samples must be > 0."); + + if constexpr (order == 1) + { + BOOST_MATH_ASSERT_MSG(approximation_order <= 2 * n, + "The approximation order must be <= 2n"); + BOOST_MATH_ASSERT_MSG(approximation_order >= 2, + "The approximation order must be >= 2"); + + if constexpr (std::is_same_v || std::is_same_v) + { + auto interior = detail::interior_velocity_filter(n, approximation_order); + m_f.resize(interior.size()); + for (std::size_t j = 0; j < interior.size(); ++j) + { + m_f[j] = static_cast(interior[j])/m_dt; + } + } + else + { + m_f = detail::interior_velocity_filter(n, approximation_order); + for (auto & x : m_f) + { + x /= m_dt; + } + } + + m_boundary_filters.resize(n); + // This for loop is a natural candidate for parallelization. + // But does it matter? Probably not. + for (std::size_t i = 0; i < n; ++i) + { + if constexpr (std::is_same_v || std::is_same_v) + { + int64_t s = static_cast(i) - static_cast(n); + auto bf = detail::boundary_velocity_filter(n, approximation_order, s); + m_boundary_filters[i].resize(bf.size()); + for (std::size_t j = 0; j < bf.size(); ++j) + { + m_boundary_filters[i][j] = static_cast(bf[j])/m_dt; + } + } + else + { + int64_t s = static_cast(i) - static_cast(n); + m_boundary_filters[i] = detail::boundary_velocity_filter(n, approximation_order, s); + for (auto & bf : m_boundary_filters[i]) + { + bf /= m_dt; + } + } + } + } + else if constexpr (order == 2) + { + // High precision isn't warranted for small p; only for large p. + // (The computation appears stable for large n.) + // But given that the filters are reusable for many vectors, + // it's better to do a high precision computation and then cast back, + // since the resulting cost is a factor of 2, and the cost of the filters not working is hours of debugging. + if constexpr (std::is_same_v || std::is_same_v) + { + auto f = detail::acceleration_filter(n, approximation_order, 0); + m_f.resize(n+1); + for (std::size_t i = 0; i < m_f.size(); ++i) + { + m_f[i] = static_cast(f[i+n])/(m_dt*m_dt); + } + m_boundary_filters.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + int64_t s = static_cast(i) - static_cast(n); + auto bf = detail::acceleration_filter(n, approximation_order, s); + m_boundary_filters[i].resize(bf.size()); + for (std::size_t j = 0; j < bf.size(); ++j) + { + m_boundary_filters[i][j] = static_cast(bf[j])/(m_dt*m_dt); + } + } + } + else + { + // Given that the purpose is denoising, for higher precision calculations, + // the default precision should be fine. + auto f = detail::acceleration_filter(n, approximation_order, 0); + m_f.resize(n+1); + for (std::size_t i = 0; i < m_f.size(); ++i) + { + m_f[i] = f[i+n]/(m_dt*m_dt); + } + m_boundary_filters.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + int64_t s = static_cast(i) - static_cast(n); + m_boundary_filters[i] = detail::acceleration_filter(n, approximation_order, s); + for (auto & bf : m_boundary_filters[i]) + { + bf /= (m_dt*m_dt); + } + } + } + } + else + { + BOOST_MATH_ASSERT_MSG(false, "Derivatives of order 3 and higher are not implemented."); + } + } + + Real get_spacing() const + { + return m_dt; + } + + template + Real operator()(RandomAccessContainer const & v, std::size_t i) const + { + static_assert(std::is_same_v, + "The type of the values in the vector provided does not match the type in the filters."); + + BOOST_MATH_ASSERT_MSG(std::size(v) >= m_boundary_filters[0].size(), + "Vector must be at least as long as the filter length"); + + if constexpr (order==1) + { + if (i >= m_f.size() - 1 && i <= std::size(v) - m_f.size()) + { + // The filter has length >= 1: + Real dvdt = m_f[1] * (v[i + 1] - v[i - 1]); + for (std::size_t j = 2; j < m_f.size(); ++j) + { + dvdt += m_f[j] * (v[i + j] - v[i - j]); + } + return dvdt; + } + + // m_f.size() = N+1 + if (i < m_f.size() - 1) + { + auto &bf = m_boundary_filters[i]; + Real dvdt = bf[0]*v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[j]; + } + return dvdt; + } + + if (i > std::size(v) - m_f.size() && i < std::size(v)) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real dvdt = bf[0]*v[std::size(v)-1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[std::size(v) - 1 - j]; + } + return -dvdt; + } + } + else if constexpr (order==2) + { + if (i >= m_f.size() - 1 && i <= std::size(v) - m_f.size()) + { + Real d2vdt2 = m_f[0]*v[i]; + for (std::size_t j = 1; j < m_f.size(); ++j) + { + d2vdt2 += m_f[j] * (v[i + j] + v[i - j]); + } + return d2vdt2; + } + + // m_f.size() = N+1 + if (i < m_f.size() - 1) + { + auto &bf = m_boundary_filters[i]; + Real d2vdt2 = bf[0]*v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[j]; + } + return d2vdt2; + } + + if (i > std::size(v) - m_f.size() && i < std::size(v)) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real d2vdt2 = bf[0] * v[std::size(v) - 1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[std::size(v) - 1 - j]; + } + return d2vdt2; + } + } + + // OOB access: + std::string msg = "Out of bounds access in Lanczos derivative."; + msg += "Input vector has length " + std::to_string(std::size(v)) + ", but user requested access at index " + std::to_string(i) + "."; + throw std::out_of_range(msg); + return std::numeric_limits::quiet_NaN(); + } + + template + void operator()(RandomAccessContainer const & v, RandomAccessContainer & w) const + { + static_assert(std::is_same_v, + "The type of the values in the vector provided does not match the type in the filters."); + if (&w[0] == &v[0]) + { + throw std::logic_error("This transform cannot be performed in-place."); + } + + if (std::size(v) < m_boundary_filters[0].size()) + { + std::string msg = "The input vector must be at least as long as the filter length. "; + msg += "The input vector has length = " + std::to_string(std::size(v)) + ", the filter has length " + std::to_string(m_boundary_filters[0].size()); + throw std::length_error(msg); + } + + if (std::size(w) < std::size(v)) + { + std::string msg = "The output vector (containing the derivative) must be at least as long as the input vector."; + msg += "The output vector has length = " + std::to_string(std::size(w)) + ", the input vector has length " + std::to_string(std::size(v)); + throw std::length_error(msg); + } + + if constexpr (order==1) + { + for (std::size_t i = 0; i < m_f.size() - 1; ++i) + { + auto &bf = m_boundary_filters[i]; + Real dvdt = bf[0] * v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[j]; + } + w[i] = dvdt; + } + + for(std::size_t i = m_f.size() - 1; i <= std::size(v) - m_f.size(); ++i) + { + Real dvdt = m_f[1] * (v[i + 1] - v[i - 1]); + for (std::size_t j = 2; j < m_f.size(); ++j) + { + dvdt += m_f[j] *(v[i + j] - v[i - j]); + } + w[i] = dvdt; + } + + + for(std::size_t i = std::size(v) - m_f.size() + 1; i < std::size(v); ++i) + { + int k = std::size(v) - 1 - i; + auto &f = m_boundary_filters[k]; + Real dvdt = f[0] * v[std::size(v) - 1];; + for (std::size_t j = 1; j < f.size(); ++j) + { + dvdt += f[j] * v[std::size(v) - 1 - j]; + } + w[i] = -dvdt; + } + } + else if constexpr (order==2) + { + // m_f.size() = N+1 + for (std::size_t i = 0; i < m_f.size() - 1; ++i) + { + auto &bf = m_boundary_filters[i]; + Real d2vdt2 = 0; + for (std::size_t j = 0; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[j]; + } + w[i] = d2vdt2; + } + + for (std::size_t i = m_f.size() - 1; i <= std::size(v) - m_f.size(); ++i) + { + Real d2vdt2 = m_f[0]*v[i]; + for (std::size_t j = 1; j < m_f.size(); ++j) + { + d2vdt2 += m_f[j] * (v[i + j] + v[i - j]); + } + w[i] = d2vdt2; + } + + for (std::size_t i = std::size(v) - m_f.size() + 1; i < std::size(v); ++i) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real d2vdt2 = bf[0] * v[std::size(v) - 1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[std::size(v) - 1 - j]; + } + w[i] = d2vdt2; + } + } + } + + template + RandomAccessContainer operator()(RandomAccessContainer const & v) const + { + RandomAccessContainer w(std::size(v)); + this->operator()(v, w); + return w; + } + + + // Don't copy; too big. + discrete_lanczos_derivative( const discrete_lanczos_derivative & ) = delete; + discrete_lanczos_derivative& operator=(const discrete_lanczos_derivative&) = delete; + + // Allow moves: + discrete_lanczos_derivative(discrete_lanczos_derivative&&) noexcept = default; + discrete_lanczos_derivative& operator=(discrete_lanczos_derivative&&) noexcept = default; + +private: + std::vector m_f; + std::vector> m_boundary_filters; + Real m_dt; +}; + +} // namespaces +#endif diff --git a/third-party/boost-math/include/boost/math/distributions.hpp b/third-party/boost-math/include/boost/math/distributions.hpp new file mode 100644 index 0000000000000..0834db870aecb --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions.hpp @@ -0,0 +1,58 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007, 2009, 2010. + +// 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) + +// This file includes *all* the distributions. +// this *may* be convenient if many are used +// - to avoid including each distribution individually. + +#ifndef BOOST_MATH_DISTRIBUTIONS_HPP +#define BOOST_MATH_DISTRIBUTIONS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/arcsine.hpp b/third-party/boost-math/include/boost/math/distributions/arcsine.hpp new file mode 100644 index 0000000000000..29feac48fe78a --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/arcsine.hpp @@ -0,0 +1,548 @@ +// boost/math/distributions/arcsine.hpp + +// Copyright John Maddock 2014. +// Copyright Paul A. Bristow 2014. +// Copyright Matt Borland 2024. + +// 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) + +// http://en.wikipedia.org/wiki/arcsine_distribution + +// The arcsine Distribution is a continuous probability distribution. +// http://en.wikipedia.org/wiki/Arcsine_distribution +// http://www.wolframalpha.com/input/?i=ArcSinDistribution + +// Standard arcsine distribution is a special case of beta distribution with both a & b = one half, +// and 0 <= x <= 1. + +// It is generalized to include any bounded support a <= x <= b from 0 <= x <= 1 +// by Wolfram and Wikipedia, +// but using location and scale parameters by +// Virtual Laboratories in Probability and Statistics http://www.math.uah.edu/stat/index.html +// http://www.math.uah.edu/stat/special/Arcsine.html +// The end-point version is simpler and more obvious, so we implement that. +// TODO Perhaps provide location and scale functions? + + +#ifndef BOOST_MATH_DIST_ARCSINE_HPP +#define BOOST_MATH_DIST_ARCSINE_HPP + +#include +#include +#include +#include // complements. +#include // error checks. +#include +#include // isnan. +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#include // For std::domain_error. +#endif + +#if defined (BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4702) // Unreachable code, +// in domain_error_imp in error_handling. +#endif + +namespace boost +{ + namespace math + { + namespace arcsine_detail + { + // Common error checking routines for arcsine distribution functions: + // Duplicating for x_min and x_max provides specific error messages. + template + BOOST_MATH_GPU_ENABLED inline bool check_x_min(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x_min argument is %1%, but must be finite !", x, pol); + return false; + } + return true; + } // bool check_x_min + + template + BOOST_MATH_GPU_ENABLED inline bool check_x_max(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x_max argument is %1%, but must be finite !", x, pol); + return false; + } + return true; + } // bool check_x_max + + + template + BOOST_MATH_GPU_ENABLED inline bool check_x_minmax(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol) + { // Check x_min < x_max + if (x_min >= x_max) + { + constexpr auto msg = "x_max argument is %1%, but must be > x_min"; + *result = policies::raise_domain_error( + function, + msg, x_max, pol); + // "x_max argument is %1%, but must be > x_min !", x_max, pol); + // "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better. + // But would require replication of all helpers functions in /policies/error_handling.hpp for two values, + // as well as two value versions of raise_error, raise_domain_error and do_format + return false; + } + return true; + } // bool check_x_minmax + + template + BOOST_MATH_GPU_ENABLED inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if ((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + BOOST_MATH_GPU_ENABLED inline bool check_x(const char* function, const RealType& x_min, const RealType& x_max, const RealType& x, RealType* result, const Policy& pol) + { // Check x finite and x_min < x < x_max. + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be finite !", x, pol); + return false; + } + if ((x < x_min) || (x > x_max)) + { + // std::cout << x_min << ' ' << x << x_max << std::endl; + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be x_min < x < x_max !", x, pol); + // For example: + // Error in function boost::math::pdf(arcsine_distribution const&, double) : x argument is -1.01, but must be x_min < x < x_max ! + // TODO Perhaps show values of x_min and x_max? + return false; + } + return true; + } // bool check_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol) + { // Check both x_min and x_max finite, and x_min < x_max. + return check_x_min(function, x_min, result, pol) + && check_x_max(function, x_max, result, pol) + && check_x_minmax(function, x_min, x_max, result, pol); + } // bool check_dist + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_x(const char* function, const RealType& x_min, const RealType& x_max, RealType x, RealType* result, const Policy& pol) + { + return check_dist(function, x_min, x_max, result, pol) + && arcsine_detail::check_x(function, x_min, x_max, x, result, pol); + } // bool check_dist_and_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, const RealType& x_min, const RealType& x_max, RealType p, RealType* result, const Policy& pol) + { + return check_dist(function, x_min, x_max, result, pol) + && check_prob(function, p, result, pol); + } // bool check_dist_and_prob + + } // namespace arcsine_detail + + template > + class arcsine_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED arcsine_distribution(RealType x_min = 0, RealType x_max = 1) : m_x_min(x_min), m_x_max(x_max) + { // Default beta (alpha = beta = 0.5) is standard arcsine with x_min = 0, x_max = 1. + // Generalized to allow x_min and x_max to be specified. + RealType result; + arcsine_detail::check_dist( + "boost::math::arcsine_distribution<%1%>::arcsine_distribution", + m_x_min, + m_x_max, + &result, Policy()); + } // arcsine_distribution constructor. + // Accessor functions: + BOOST_MATH_GPU_ENABLED RealType x_min() const + { + return m_x_min; + } + BOOST_MATH_GPU_ENABLED RealType x_max() const + { + return m_x_max; + } + + private: + RealType m_x_min; // Two x min and x max parameters of the arcsine distribution. + RealType m_x_max; + }; // template class arcsine_distribution + + // Convenient typedef to construct double version. + typedef arcsine_distribution arcsine; + + #ifdef __cpp_deduction_guides + template + arcsine_distribution(RealType)->arcsine_distribution::type>; + template + arcsine_distribution(RealType, RealType)->arcsine_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const arcsine_distribution& dist) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(dist.x_min()), static_cast(dist.x_max())); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const arcsine_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(dist.x_min()), static_cast(dist.x_max())); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const arcsine_distribution& dist) + { // Mean of arcsine distribution . + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::mean(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const arcsine_distribution& dist) + { // Variance of standard arcsine distribution = (1-0)/8 = 0.125. + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist( + "boost::math::variance(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_max - x_min) * (x_max - x_min) / 8; + } // variance + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const arcsine_distribution& /* dist */) + { //There are always [*two] values for the mode, at ['x_min] and at ['x_max], default 0 and 1, + // so instead we raise the exception domain_error. + return policies::raise_domain_error( + "boost::math::mode(arcsine_distribution<%1%>&)", + "The arcsine distribution has two modes at x_min and x_max: " + "so the return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); + } // mode + + template + BOOST_MATH_GPU_ENABLED inline RealType median(const arcsine_distribution& dist) + { // Median of arcsine distribution (a + b) / 2 == mean. + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + RealType result; + if (false == arcsine_detail::check_dist( + "boost::math::median(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::skewness(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return 0; + } // skewness + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis_excess(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + result = -3; + return result / 2; + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + + return 3 + kurtosis_excess(dist); + } // kurtosis + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const arcsine_distribution& dist, const RealType& xx) + { // Probability Density/Mass Function arcsine. + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // For ADL of std functions. + + constexpr auto function = "boost::math::pdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType lo = dist.x_min(); + RealType hi = dist.x_max(); + RealType x = xx; + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + lo, hi, x, + &result, Policy())) + { + return result; + } + using boost::math::constants::pi; + result = static_cast(1) / (pi() * sqrt((x - lo) * (hi - x))); + return result; + } // pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const arcsine_distribution& dist, const RealType& x) + { // Cumulative Distribution Function arcsine. + BOOST_MATH_STD_USING // For ADL of std functions. + + constexpr auto function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + x_min, x_max, x, + &result, Policy())) + { + return result; + } + // Special cases: + if (x == x_min) + { + return 0; + } + else if (x == x_max) + { + return 1; + } + using boost::math::constants::pi; + result = static_cast(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi(); + return result; + } // arcsine cdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function arcsine. + BOOST_MATH_STD_USING // For ADL of std functions. + constexpr auto function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType x = c.param; + arcsine_distribution const& dist = c.dist; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + x_min, x_max, x, + &result, Policy())) + { + return result; + } + if (x == x_min) + { + return 0; + } + else if (x == x_max) + { + return 1; + } + using boost::math::constants::pi; + // Naive version x = 1 - x; + // result = static_cast(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi(); + // is less accurate, so use acos instead of asin for complement. + result = static_cast(2) * acos(sqrt((x - x_min) / (x_max - x_min))) / pi(); + return result; + } // arcsine ccdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const arcsine_distribution& dist, const RealType& p) + { + // Quantile or Percent Point arcsine function or + // Inverse Cumulative probability distribution function CDF. + // Return x (0 <= x <= 1), + // for a given probability p (0 <= p <= 1). + // These functions take a probability as an argument + // and return a value such that the probability that a random variable x + // will be less than or equal to that value + // is whatever probability you supplied as an argument. + BOOST_MATH_STD_USING // For ADL of std functions. + + using boost::math::constants::half_pi; + + constexpr auto function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)"; + + RealType result = 0; // of argument checks: + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist_and_prob( + function, + x_min, x_max, p, + &result, Policy())) + { + return result; + } + // Special cases: + if (p == 0) + { + return 0; + } + if (p == 1) + { + return 1; + } + + RealType sin2hpip = sin(half_pi() * p); + RealType sin2hpip2 = sin2hpip * sin2hpip; + result = -x_min * sin2hpip2 + x_min + x_max * sin2hpip2; + + return result; + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { + // Complement Quantile or Percent Point arcsine function. + // Return the number of expected x for a given + // complement of the probability q. + BOOST_MATH_STD_USING // For ADL of std functions. + + using boost::math::constants::half_pi; + constexpr auto function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)"; + + // Error checks: + RealType q = c.param; + const arcsine_distribution& dist = c.dist; + RealType result = 0; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist_and_prob( + function, + x_min, + x_max, + q, + &result, Policy())) + { + return result; + } + // Special cases: + if (q == 1) + { + return 0; + } + if (q == 0) + { + return 1; + } + // Naive RealType p = 1 - q; result = sin(half_pi() * p); loses accuracy, so use a cos alternative instead. + //result = cos(half_pi() * q); // for arcsine(0,1) + //result = result * result; + // For generalized arcsine: + RealType cos2hpip = cos(half_pi() * q); + RealType cos2hpip2 = cos2hpip * cos2hpip; + result = -x_min * cos2hpip2 + x_min + x_max * cos2hpip2; + + return result; + } // Quantile Complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DIST_ARCSINE_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/bernoulli.hpp b/third-party/boost-math/include/boost/math/distributions/bernoulli.hpp new file mode 100644 index 0000000000000..bfb5bf6180938 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/bernoulli.hpp @@ -0,0 +1,349 @@ +// boost\math\distributions\bernoulli.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. +// Copyright Matt Borland 2024. + +// 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) + +// http://en.wikipedia.org/wiki/bernoulli_distribution +// http://mathworld.wolfram.com/BernoulliDistribution.html + +// bernoulli distribution is the discrete probability distribution of +// the number (k) of successes, in a single Bernoulli trials. +// It is a version of the binomial distribution when n = 1. + +// But note that the bernoulli distribution +// (like others including the poisson, binomial & negative binomial) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +#ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP +#define BOOST_MATH_SPECIAL_BERNOULLI_HPP + +#include +#include +#include +#include +#include // complements +#include // error checks +#include // isnan. +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#endif + +namespace boost +{ + namespace math + { + namespace bernoulli_detail + { + // Common error checking routines for bernoulli distribution functions: + template + BOOST_MATH_GPU_ENABLED inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& /* pol */) + { + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy()); + return false; + } + return true; + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const boost::math::true_type&) + { + return check_success_fraction(function, p, result, Policy()); + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const boost::math::false_type&) + { + return true; + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */) + { + return check_dist(function, p, result, Policy(), typename policies::constructor_error_check::type()); + } + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, p, result, Policy(), typename policies::method_error_check::type()) == false) + { + return false; + } + if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1))) + { + *result = policies::raise_domain_error( + function, + "Number of successes argument is %1%, but must be 0 or 1 !", k, pol); + return false; + } + return true; + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */) + { + if((check_dist(function, p, result, Policy(), typename policies::method_error_check::type()) && detail::check_probability(function, prob, result, Policy())) == false) + { + return false; + } + return true; + } + } // namespace bernoulli_detail + + + template > + class bernoulli_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED bernoulli_distribution(RealType p = 0.5) : m_p(p) + { // Default probability = half suits 'fair' coin tossing + // where probability of heads == probability of tails. + RealType result; // of checks. + bernoulli_detail::check_dist( + "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution", + m_p, + &result, Policy()); + } // bernoulli_distribution constructor. + + BOOST_MATH_GPU_ENABLED RealType success_fraction() const + { // Probability. + return m_p; + } + + private: + RealType m_p; // success_fraction + }; // template class bernoulli_distribution + + typedef bernoulli_distribution bernoulli; + + #ifdef __cpp_deduction_guides + template + bernoulli_distribution(RealType)->bernoulli_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const bernoulli_distribution& /* dist */) + { // Range of permissible values for random variable k = {0, 1}. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const bernoulli_distribution& /* dist */) + { // Range of supported values for random variable k = {0, 1}. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const bernoulli_distribution& dist) + { // Mean of bernoulli distribution = p (n = 1). + return dist.success_fraction(); + } // mean + + // Rely on derived_accessors quantile(half) + //template + //inline RealType median(const bernoulli_distribution& dist) + //{ // Median of bernoulli distribution is not defined. + // return tools::domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const bernoulli_distribution& dist) + { // Variance of bernoulli distribution =p * q. + return dist.success_fraction() * (1 - dist.success_fraction()); + } // variance + + template + BOOST_MATH_GPU_ENABLED RealType pdf(const bernoulli_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + // Error check: + RealType result = 0; // of checks. + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::pdf(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), // 0 to 1 + k, // 0 or 1 + &result, Policy())) + { + return result; + } + // Assume k is integral. + if (k == 0) + { + return 1 - dist.success_fraction(); // 1 - p + } + else // k == 1 + { + return dist.success_fraction(); // p + } + } // pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const bernoulli_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Bernoulli. + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::cdf(bernoulli_distribution<%1%>, %1%)", + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return 1 - p; + } + else + { // k == 1 + return 1; + } + } // bernoulli cdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function bernoulli. + RealType const& k = c.param; + bernoulli_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + // Error checks: + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::cdf(bernoulli_distribution<%1%>, %1%)", + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return p; + } + else + { // k == 1 + return 0; + } + } // bernoulli cdf complement + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const bernoulli_distribution& dist, const RealType& p) + { // Quantile or Percent Point Bernoulli function. + // Return the number of expected successes k either 0 or 1. + // for a given probability p. + + RealType result = 0; // of error checks: + if(false == bernoulli_detail::check_dist_and_prob( + "boost::math::quantile(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), + p, + &result, Policy())) + { + return result; + } + if (p <= (1 - dist.success_fraction())) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + else + { + return 1; + } + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point bernoulli function. + // Return the number of expected successes k for a given + // complement of the probability q. + // + // Error checks: + RealType q = c.param; + const bernoulli_distribution& dist = c.dist; + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_prob( + "boost::math::quantile(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), + q, + &result, Policy())) + { + return result; + } + + if (q <= 1 - dist.success_fraction()) + { // // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 1; + } + else + { + return 0; + } + } // quantile complemented. + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const bernoulli_distribution& dist) + { + return static_cast((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1 + } + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const bernoulli_distribution& dist) + { + BOOST_MATH_STD_USING; // Aid ADL for sqrt. + RealType p = dist.success_fraction(); + return (1 - 2 * p) / sqrt(p * (1 - p)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const bernoulli_distribution& dist) + { + RealType p = dist.success_fraction(); + // Note Wolfram says this is kurtosis in text, but gamma2 is the kurtosis excess, + // and Wikipedia also says this is the kurtosis excess formula. + // return (6 * p * p - 6 * p + 1) / (p * (1 - p)); + // But Wolfram kurtosis article gives this simpler formula for kurtosis excess: + return 1 / (1 - p) + 1/p -6; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const bernoulli_distribution& dist) + { + RealType p = dist.success_fraction(); + return 1 / (1 - p) + 1/p -6 + 3; + // Simpler than: + // return (6 * p * p - 6 * p + 1) / (p * (1 - p)) + 3; + } + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP + + + diff --git a/third-party/boost-math/include/boost/math/distributions/beta.hpp b/third-party/boost-math/include/boost/math/distributions/beta.hpp new file mode 100644 index 0000000000000..fef991a8703f5 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/beta.hpp @@ -0,0 +1,584 @@ +// boost\math\distributions\beta.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2006. +// Copyright Matt Borland 2023. + +// 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) + +// http://en.wikipedia.org/wiki/Beta_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm +// http://mathworld.wolfram.com/BetaDistribution.html + +// The Beta Distribution is a continuous probability distribution. +// The beta distribution is used to model events which are constrained to take place +// within an interval defined by maxima and minima, +// so is used extensively in PERT and other project management systems +// to describe the time to completion. +// The cdf of the beta distribution is used as a convenient way +// of obtaining the sum over a set of binomial outcomes. +// The beta distribution is also used in Bayesian statistics. + +#ifndef BOOST_MATH_DIST_BETA_HPP +#define BOOST_MATH_DIST_BETA_HPP + +#include +#include +#include +#include // for beta. +#include // complements. +#include // error checks +#include // isnan. +#include // for root finding. +#include + +#if defined (BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code +// in domain_error_imp in error_handling +#endif + +namespace boost +{ + namespace math + { + namespace beta_detail + { + // Common error checking routines for beta distribution functions: + template + BOOST_MATH_GPU_ENABLED inline bool check_alpha(const char* function, const RealType& alpha, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(alpha) || (alpha <= 0)) + { + *result = policies::raise_domain_error( + function, + "Alpha argument is %1%, but must be > 0 !", alpha, pol); + return false; + } + return true; + } // bool check_alpha + + template + BOOST_MATH_GPU_ENABLED inline bool check_beta(const char* function, const RealType& beta, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(beta) || (beta <= 0)) + { + *result = policies::raise_domain_error( + function, + "Beta argument is %1%, but must be > 0 !", beta, pol); + return false; + } + return true; + } // bool check_beta + + template + BOOST_MATH_GPU_ENABLED inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + BOOST_MATH_GPU_ENABLED inline bool check_x(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(x) || (x < 0) || (x > 1)) + { + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be >= 0 and <= 1 !", x, pol); + return false; + } + return true; + } // bool check_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& alpha, const RealType& beta, RealType* result, const Policy& pol) + { // Check both alpha and beta. + return check_alpha(function, alpha, result, pol) + && check_beta(function, beta, result, pol); + } // bool check_dist + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_x(const char* function, const RealType& alpha, const RealType& beta, RealType x, RealType* result, const Policy& pol) + { + return check_dist(function, alpha, beta, result, pol) + && beta_detail::check_x(function, x, result, pol); + } // bool check_dist_and_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, const RealType& alpha, const RealType& beta, RealType p, RealType* result, const Policy& pol) + { + return check_dist(function, alpha, beta, result, pol) + && check_prob(function, p, result, pol); + } // bool check_dist_and_prob + + template + BOOST_MATH_GPU_ENABLED inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(mean) || (mean <= 0)) + { + *result = policies::raise_domain_error( + function, + "mean argument is %1%, but must be > 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean + template + BOOST_MATH_GPU_ENABLED inline bool check_variance(const char* function, const RealType& variance, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(variance) || (variance <= 0)) + { + *result = policies::raise_domain_error( + function, + "variance argument is %1%, but must be > 0 !", variance, pol); + return false; + } + return true; + } // bool check_variance + } // namespace beta_detail + + // typedef beta_distribution beta; + // is deliberately NOT included to avoid a name clash with the beta function. + // Use beta_distribution<> mybeta(...) to construct type double. + + template > + class beta_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED beta_distribution(RealType l_alpha = 1, RealType l_beta = 1) : m_alpha(l_alpha), m_beta(l_beta) + { + RealType result; + beta_detail::check_dist( + "boost::math::beta_distribution<%1%>::beta_distribution", + m_alpha, + m_beta, + &result, Policy()); + } // beta_distribution constructor. + // Accessor functions: + BOOST_MATH_GPU_ENABLED RealType alpha() const + { + return m_alpha; + } + BOOST_MATH_GPU_ENABLED RealType beta() const + { // . + return m_beta; + } + + // Estimation of the alpha & beta parameters. + // http://en.wikipedia.org/wiki/Beta_distribution + // gives formulae in section on parameter estimation. + // Also NIST EDA page 3 & 4 give the same. + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm + // http://www.epi.ucdavis.edu/diagnostictests/betabuster.html + + BOOST_MATH_GPU_ENABLED static RealType find_alpha( + RealType mean, // Expected value of mean. + RealType variance) // Expected value of variance. + { + constexpr auto function = "boost::math::beta_distribution<%1%>::find_alpha"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_mean(function, mean, &result, Policy()) + && beta_detail::check_variance(function, variance, &result, Policy()) + ) + ) + { + return result; + } + return mean * (( (mean * (1 - mean)) / variance)- 1); + } // RealType find_alpha + + BOOST_MATH_GPU_ENABLED static RealType find_beta( + RealType mean, // Expected value of mean. + RealType variance) // Expected value of variance. + { + constexpr auto function = "boost::math::beta_distribution<%1%>::find_beta"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_mean(function, mean, &result, Policy()) + && + beta_detail::check_variance(function, variance, &result, Policy()) + ) + ) + { + return result; + } + return (1 - mean) * (((mean * (1 - mean)) /variance)-1); + } // RealType find_beta + + // Estimate alpha & beta from either alpha or beta, and x and probability. + // Uses for these parameter estimators are unclear. + + BOOST_MATH_GPU_ENABLED static RealType find_alpha( + RealType beta, // from beta. + RealType x, // x. + RealType probability) // cdf + { + constexpr auto function = "boost::math::beta_distribution<%1%>::find_alpha"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_prob(function, probability, &result, Policy()) + && + beta_detail::check_beta(function, beta, &result, Policy()) + && + beta_detail::check_x(function, x, &result, Policy()) + ) + ) + { + return result; + } + return static_cast(ibeta_inva(beta, x, probability, Policy())); + } // RealType find_alpha(beta, a, probability) + + BOOST_MATH_GPU_ENABLED static RealType find_beta( + // ibeta_invb(T b, T x, T p); (alpha, x, cdf,) + RealType alpha, // alpha. + RealType x, // probability x. + RealType probability) // probability cdf. + { + constexpr auto function = "boost::math::beta_distribution<%1%>::find_beta"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_prob(function, probability, &result, Policy()) + && + beta_detail::check_alpha(function, alpha, &result, Policy()) + && + beta_detail::check_x(function, x, &result, Policy()) + ) + ) + { + return result; + } + return static_cast(ibeta_invb(alpha, x, probability, Policy())); + } // RealType find_beta(alpha, x, probability) + + private: + RealType m_alpha; // Two parameters of the beta distribution. + RealType m_beta; + }; // template class beta_distribution + + #ifdef __cpp_deduction_guides + template + beta_distribution(RealType)->beta_distribution::type>; + template + beta_distribution(RealType, RealType)->beta_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const beta_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const beta_distribution& /* dist */) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const beta_distribution& dist) + { // Mean of beta distribution = np. + return dist.alpha() / (dist.alpha() + dist.beta()); + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const beta_distribution& dist) + { // Variance of beta distribution = np(1-p). + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (a * b) / ((a + b ) * (a + b) * (a + b + 1)); + } // variance + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const beta_distribution& dist) + { + constexpr auto function = "boost::math::mode(beta_distribution<%1%> const&)"; + + RealType result; + if ((dist.alpha() <= 1)) + { + result = policies::raise_domain_error( + function, + "mode undefined for alpha = %1%, must be > 1!", dist.alpha(), Policy()); + return result; + } + + if ((dist.beta() <= 1)) + { + result = policies::raise_domain_error( + function, + "mode undefined for beta = %1%, must be > 1!", dist.beta(), Policy()); + return result; + } + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (a-1) / (a + b - 2); + } // mode + + //template + //inline RealType median(const beta_distribution& dist) + //{ // Median of beta distribution is not defined. + // return tools::domain_error(function, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + + //But WILL be provided by the derived accessor as quantile(0.5). + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const beta_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (2 * (b-a) * sqrt(a + b + 1)) / ((a + b + 2) * sqrt(a * b)); + } // skewness + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const beta_distribution& dist) + { + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType a_2 = a * a; + RealType n = 6 * (a_2 * a - a_2 * (2 * b - 1) + b * b * (b + 1) - 2 * a * b * (b + 2)); + RealType d = a * b * (a + b + 2) * (a + b + 3); + return n / d; + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const beta_distribution& dist) + { + return 3 + kurtosis_excess(dist); + } // kurtosis + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const beta_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + constexpr auto function = "boost::math::pdf(beta_distribution<%1%> const&, %1%)"; + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + using boost::math::beta; + + // Corner cases: check_x ensures x element of [0, 1], but PDF is 0 for x = 0 and x = 1. PDF EQN: + // https://wikimedia.org/api/rest_v1/media/math/render/svg/125fdaa41844a8703d1a8610ac00fbf3edacc8e7 + if(x == 0) + { + if (a == 1) + { + return static_cast(1 / beta(a, b)); + } + else if (a < 1) + { + policies::raise_overflow_error(function, nullptr, Policy()); + } + else + { + return RealType(0); + } + } + else if (x == 1) + { + if (b == 1) + { + return static_cast(1 / beta(a, b)); + } + else if (b < 1) + { + policies::raise_overflow_error(function, nullptr, Policy()); + } + else + { + return RealType(0); + } + } + + return static_cast(ibeta_derivative(a, b, x, Policy())); + } // pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const beta_distribution& dist, const RealType& x) + { // Cumulative Distribution Function beta. + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)"; + + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + // Special cases: + if (x == 0) + { + return 0; + } + else if (x == 1) + { + return 1; + } + return static_cast(ibeta(a, b, x, Policy())); + } // beta cdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function beta. + + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)"; + + RealType const& x = c.param; + beta_distribution const& dist = c.dist; + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + if (x == 0) + { + return RealType(1); + } + else if (x == 1) + { + return RealType(0); + } + // Calculate cdf beta using the incomplete beta function. + // Use of ibeta here prevents cancellation errors in calculating + // 1 - x if x is very small, perhaps smaller than machine epsilon. + return static_cast(ibetac(a, b, x, Policy())); + } // beta cdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const beta_distribution& dist, const RealType& p) + { // Quantile or Percent Point beta function or + // Inverse Cumulative probability distribution function CDF. + // Return x (0 <= x <= 1), + // for a given probability p (0 <= p <= 1). + // These functions take a probability as an argument + // and return a value such that the probability that a random variable x + // will be less than or equal to that value + // is whatever probability you supplied as an argument. + + constexpr auto function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)"; + + RealType result = 0; // of argument checks: + RealType a = dist.alpha(); + RealType b = dist.beta(); + if(false == beta_detail::check_dist_and_prob( + function, + a, b, p, + &result, Policy())) + { + return result; + } + // Special cases: + if (p == 0) + { + return RealType(0); + } + if (p == 1) + { + return RealType(1); + } + return static_cast(ibeta_inv(a, b, p, static_cast(nullptr), Policy())); + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Complement Quantile or Percent Point beta function . + // Return the number of expected x for a given + // complement of the probability q. + + constexpr auto function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)"; + + // + // Error checks: + RealType q = c.param; + const beta_distribution& dist = c.dist; + RealType result = 0; + RealType a = dist.alpha(); + RealType b = dist.beta(); + if(false == beta_detail::check_dist_and_prob( + function, + a, + b, + q, + &result, Policy())) + { + return result; + } + // Special cases: + if(q == 1) + { + return RealType(0); + } + if(q == 0) + { + return RealType(1); + } + + return static_cast(ibetac_inv(a, b, q, static_cast(nullptr), Policy())); + } // Quantile Complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DIST_BETA_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/binomial.hpp b/third-party/boost-math/include/boost/math/distributions/binomial.hpp new file mode 100644 index 0000000000000..b17893e422c14 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/binomial.hpp @@ -0,0 +1,729 @@ +// boost\math\distributions\binomial.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. + +// 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) + +// http://en.wikipedia.org/wiki/binomial_distribution + +// Binomial distribution is the discrete probability distribution of +// the number (k) of successes, in a sequence of +// n independent (yes or no, success or failure) Bernoulli trials. + +// It expresses the probability of a number of events occurring in a fixed time +// if these events occur with a known average rate (probability of success), +// and are independent of the time since the last event. + +// The number of cars that pass through a certain point on a road during a given period of time. +// The number of spelling mistakes a secretary makes while typing a single page. +// The number of phone calls at a call center per minute. +// The number of times a web server is accessed per minute. +// The number of light bulbs that burn out in a certain amount of time. +// The number of roadkill found per unit length of road + +// http://en.wikipedia.org/wiki/binomial_distribution + +// Given a sample of N measured values k[i], +// we wish to estimate the value of the parameter x (mean) +// of the binomial population from which the sample was drawn. +// To calculate the maximum likelihood value = 1/N sum i = 1 to N of k[i] + +// Also may want a function for EXACTLY k. + +// And probability that there are EXACTLY k occurrences is +// exp(-x) * pow(x, k) / factorial(k) +// where x is expected occurrences (mean) during the given interval. +// For example, if events occur, on average, every 4 min, +// and we are interested in number of events occurring in 10 min, +// then x = 10/4 = 2.5 + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366i.htm + +// The binomial distribution is used when there are +// exactly two mutually exclusive outcomes of a trial. +// These outcomes are appropriately labeled "success" and "failure". +// The binomial distribution is used to obtain +// the probability of observing x successes in N trials, +// with the probability of success on a single trial denoted by p. +// The binomial distribution assumes that p is fixed for all trials. + +// P(x, p, n) = n!/(x! * (n-x)!) * p^x * (1-p)^(n-x) + +// http://mathworld.wolfram.com/BinomialCoefficient.html + +// The binomial coefficient (n; k) is the number of ways of picking +// k unordered outcomes from n possibilities, +// also known as a combination or combinatorial number. +// The symbols _nC_k and (n; k) are used to denote a binomial coefficient, +// and are sometimes read as "n choose k." +// (n; k) therefore gives the number of k-subsets possible out of a set of n distinct items. + +// For example: +// The 2-subsets of {1,2,3,4} are the six pairs {1,2}, {1,3}, {1,4}, {2,3}, {2,4}, and {3,4}, so (4; 2)==6. + +// http://functions.wolfram.com/GammaBetaErf/Binomial/ for evaluation. + +// But note that the binomial distribution +// (like others including the poisson, negative binomial & Bernoulli) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +#ifndef BOOST_MATH_SPECIAL_BINOMIAL_HPP +#define BOOST_MATH_SPECIAL_BINOMIAL_HPP + +#include +#include +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include // error checks +#include // isnan. +#include // for root finding. + +#include + +namespace boost +{ + namespace math + { + + template + class binomial_distribution; + + namespace binomial_detail{ + // common error checking routines for binomial distribution functions: + template + BOOST_MATH_CUDA_ENABLED inline bool check_N(const char* function, const RealType& N, RealType* result, const Policy& pol) + { + if((N < 0) || !(boost::math::isfinite)(N)) + { + *result = policies::raise_domain_error( + function, + "Number of Trials argument is %1%, but must be >= 0 !", N, pol); + return false; + } + return true; + } + template + BOOST_MATH_CUDA_ENABLED inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + template + BOOST_MATH_CUDA_ENABLED inline bool check_dist(const char* function, const RealType& N, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction( + function, p, result, pol) + && check_N( + function, N, result, pol); + } + template + BOOST_MATH_CUDA_ENABLED inline bool check_dist_and_k(const char* function, const RealType& N, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, N, p, result, pol) == false) + return false; + if((k < 0) || !(boost::math::isfinite)(k)) + { + *result = policies::raise_domain_error( + function, + "Number of Successes argument is %1%, but must be >= 0 !", k, pol); + return false; + } + if(k > N) + { + *result = policies::raise_domain_error( + function, + "Number of Successes argument is %1%, but must be <= Number of Trials !", k, pol); + return false; + } + return true; + } + template + BOOST_MATH_CUDA_ENABLED inline bool check_dist_and_prob(const char* function, const RealType& N, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, N, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + return false; + return true; + } + + template + BOOST_MATH_CUDA_ENABLED T inverse_binomial_cornish_fisher(T n, T sf, T p, T q, const Policy& pol) + { + BOOST_MATH_STD_USING + // mean: + T m = n * sf; + // standard deviation: + T sigma = sqrt(n * sf * (1 - sf)); + // skewness + T sk = (1 - 2 * sf) / sigma; + // kurtosis: + // T k = (1 - 6 * sf * (1 - sf) ) / (n * sf * (1 - sf)); + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + /* + // Add on correction due to kurtosis. + // Disabled for now, seems to make things worse? + // + if(n >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + */ + w = m + sigma * w; + if(w < tools::min_value()) + return sqrt(tools::min_value()); + if(w > n) + return n; + return w; + } + + template + BOOST_MATH_CUDA_ENABLED RealType quantile_imp(const binomial_distribution& dist, const RealType& p, const RealType& q, bool comp) + { // Quantile or Percent Point Binomial function. + // Return the number of expected successes k, + // for a given probability p. + // + // Error checks: + BOOST_MATH_STD_USING // ADL of std names + RealType result = 0; + RealType trials = dist.trials(); + RealType success_fraction = dist.success_fraction(); + if(false == binomial_detail::check_dist_and_prob( + "boost::math::quantile(binomial_distribution<%1%> const&, %1%)", + trials, + success_fraction, + p, + &result, Policy())) + { + return result; + } + + // Special cases: + // + if(p == 0) + { // There may actually be no answer to this question, + // since the probability of zero successes may be non-zero, + // but zero is the best we can do: + return 0; + } + if(p == 1 || success_fraction == 1) + { // Probability of n or fewer successes is always one, + // so n is the most sensible answer here: + return trials; + } + if (p <= pow(1 - success_fraction, trials)) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; // So the only reasonable result is zero. + } // And root finder would fail otherwise. + + // Solve for quantile numerically: + // + RealType guess = binomial_detail::inverse_binomial_cornish_fisher(trials, success_fraction, p, q, Policy()); + RealType factor = 8; + if(trials > 100) + factor = 1.01f; // guess is pretty accurate + else if((trials > 10) && (trials - 1 > guess) && (guess > 3)) + factor = 1.15f; // less accurate but OK. + else if(trials < 10) + { + // pretty inaccurate guess in this area: + if(guess > trials / 64) + { + guess = trials / 4; + factor = 2; + } + else + guess = trials / 1024; + } + else + factor = 2; // trials largish, but in far tails. + + typedef typename Policy::discrete_quantile_type discrete_quantile_type; + std::uintmax_t max_iter = policies::get_max_root_iterations(); + result = detail::inverse_discrete_quantile( + dist, + comp ? q : p, + comp, + guess, + factor, + RealType(1), + discrete_quantile_type(), + max_iter); + return result; + } // quantile + + } + + template > + class binomial_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + binomial_distribution(RealType n = 1, RealType p = 0.5) : m_n(n), m_p(p) + { // Default n = 1 is the Bernoulli distribution + // with equal probability of 'heads' or 'tails. + RealType r; + binomial_detail::check_dist( + "boost::math::binomial_distribution<%1%>::binomial_distribution", + m_n, + m_p, + &r, Policy()); + } // binomial_distribution constructor. + + BOOST_MATH_CUDA_ENABLED RealType success_fraction() const + { // Probability. + return m_p; + } + BOOST_MATH_CUDA_ENABLED RealType trials() const + { // Total number of trials. + return m_n; + } + + enum interval_type{ + clopper_pearson_exact_interval, + jeffreys_prior_interval + }; + + // + // Estimation of the success fraction parameter. + // The best estimate is actually simply successes/trials, + // these functions are used + // to obtain confidence intervals for the success fraction. + // + BOOST_MATH_CUDA_ENABLED static RealType find_lower_bound_on_p( + RealType trials, + RealType successes, + RealType probability, + interval_type t = clopper_pearson_exact_interval) + { + BOOST_MATH_STATIC const char* function = "boost::math::binomial_distribution<%1%>::find_lower_bound_on_p"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, trials, RealType(0), successes, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, trials, RealType(0), probability, &result, Policy())) + { return result; } + + if(successes == 0) + return 0; + + // NOTE!!! The Clopper Pearson formula uses "successes" not + // "successes+1" as usual to get the lower bound, + // see http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + return (t == clopper_pearson_exact_interval) ? ibeta_inv(successes, trials - successes + 1, probability, static_cast(nullptr), Policy()) + : ibeta_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast(nullptr), Policy()); + } + BOOST_MATH_CUDA_ENABLED static RealType find_upper_bound_on_p( + RealType trials, + RealType successes, + RealType probability, + interval_type t = clopper_pearson_exact_interval) + { + BOOST_MATH_STATIC const char* function = "boost::math::binomial_distribution<%1%>::find_upper_bound_on_p"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, trials, RealType(0), successes, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, trials, RealType(0), probability, &result, Policy())) + { return result; } + + if(trials == successes) + return 1; + + return (t == clopper_pearson_exact_interval) ? ibetac_inv(successes + 1, trials - successes, probability, static_cast(nullptr), Policy()) + : ibetac_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast(nullptr), Policy()); + } + // Estimate number of trials parameter: + // + // "How many trials do I need to be P% sure of seeing k events?" + // or + // "How many trials can I have to be P% sure of seeing fewer than k events?" + // + BOOST_MATH_CUDA_ENABLED static RealType find_minimum_number_of_trials( + RealType k, // number of events + RealType p, // success fraction + RealType alpha) // risk level + { + BOOST_MATH_STATIC const char* function = "boost::math::binomial_distribution<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, k, p, k, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, k, p, alpha, &result, Policy())) + { return result; } + + result = ibetac_invb(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } + + BOOST_MATH_CUDA_ENABLED static RealType find_maximum_number_of_trials( + RealType k, // number of events + RealType p, // success fraction + RealType alpha) // risk level + { + BOOST_MATH_STATIC const char* function = "boost::math::binomial_distribution<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, k, p, k, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, k, p, alpha, &result, Policy())) + { return result; } + + result = ibeta_invb(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } + + private: + RealType m_n; // Not sure if this shouldn't be an int? + RealType m_p; // success_fraction + }; // template class binomial_distribution + + typedef binomial_distribution<> binomial; + // typedef binomial_distribution binomial; + // IS now included since no longer a name clash with function binomial. + //typedef binomial_distribution binomial; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + binomial_distribution(RealType)->binomial_distribution::type>; + template + binomial_distribution(RealType,RealType)->binomial_distribution::type>; + #endif + + template + BOOST_MATH_CUDA_ENABLED const boost::math::pair range(const binomial_distribution& dist) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), dist.trials()); + } + + template + BOOST_MATH_CUDA_ENABLED const boost::math::pair support(const binomial_distribution& dist) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(0), dist.trials()); + } + + template + BOOST_MATH_CUDA_ENABLED inline RealType mean(const binomial_distribution& dist) + { // Mean of Binomial distribution = np. + return dist.trials() * dist.success_fraction(); + } // mean + + template + BOOST_MATH_CUDA_ENABLED inline RealType variance(const binomial_distribution& dist) + { // Variance of Binomial distribution = np(1-p). + return dist.trials() * dist.success_fraction() * (1 - dist.success_fraction()); + } // variance + + template + BOOST_MATH_CUDA_ENABLED RealType pdf(const binomial_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType n = dist.trials(); + + // Error check: + RealType result = 0; // initialization silences some compiler warnings + if(false == binomial_detail::check_dist_and_k( + "boost::math::pdf(binomial_distribution<%1%> const&, %1%)", + n, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + // Special cases of success_fraction, regardless of k successes and regardless of n trials. + if (dist.success_fraction() == 0) + { // probability of zero successes is 1: + return static_cast(k == 0 ? 1 : 0); + } + if (dist.success_fraction() == 1) + { // probability of n successes is 1: + return static_cast(k == n ? 1 : 0); + } + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + if (n == 0) + { + return 1; // Probability = 1 = certainty. + } + if (k == n) + { // binomial coeffic (n n) = 1, + // n ^ 0 = 1 + return pow(dist.success_fraction(), k); // * pow((1 - dist.success_fraction()), (n - k)) = 1 + } + + // Probability of getting exactly k successes + // if C(n, k) is the binomial coefficient then: + // + // f(k; n,p) = C(n, k) * p^k * (1-p)^(n-k) + // = (n!/(k!(n-k)!)) * p^k * (1-p)^(n-k) + // = (tgamma(n+1) / (tgamma(k+1)*tgamma(n-k+1))) * p^k * (1-p)^(n-k) + // = p^k (1-p)^(n-k) / (beta(k+1, n-k+1) * (n+1)) + // = ibeta_derivative(k+1, n-k+1, p) / (n+1) + // + using boost::math::ibeta_derivative; // a, b, x + return ibeta_derivative(k+1, n-k+1, dist.success_fraction(), Policy()) / (n+1); + + } // pdf + + template + BOOST_MATH_CUDA_ENABLED inline RealType cdf(const binomial_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Binomial. + // The random variate k is the number of successes in n trials. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + + // Returns the sum of the terms 0 through k of the Binomial Probability Density/Mass: + // + // i=k + // -- ( n ) i n-i + // > | | p (1-p) + // -- ( i ) + // i=0 + + // The terms are not summed directly instead + // the incomplete beta integral is employed, + // according to the formula: + // P = I[1-p]( n-k, k+1). + // = 1 - I[p](k + 1, n - k) + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType n = dist.trials(); + RealType p = dist.success_fraction(); + + // Error check: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + "boost::math::cdf(binomial_distribution<%1%> const&, %1%)", + n, + p, + k, + &result, Policy())) + { + return result; + } + if (k == n) + { + return 1; + } + + // Special cases, regardless of k. + if (p == 0) + { // This need explanation: + // the pdf is zero for all cases except when k == 0. + // For zero p the probability of zero successes is one. + // Therefore the cdf is always 1: + // the probability of k or *fewer* successes is always 1 + // if there are never any successes! + return 1; + } + if (p == 1) + { // This is correct but needs explanation: + // when k = 1 + // all the cdf and pdf values are zero *except* when k == n, + // and that case has been handled above already. + return 0; + } + // + // P = I[1-p](n - k, k + 1) + // = 1 - I[p](k + 1, n - k) + // Use of ibetac here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // + // Note that we do not use a finite sum here, since the incomplete + // beta uses a finite sum internally for integer arguments, so + // we'll just let it take care of the necessary logic. + // + return ibetac(k + 1, n - k, p, Policy()); + } // binomial cdf + + template + BOOST_MATH_CUDA_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Binomial. + // The random variate k is the number of successes in n trials. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + + // Returns the sum of the terms k+1 through n of the Binomial Probability Density/Mass: + // + // i=n + // -- ( n ) i n-i + // > | | p (1-p) + // -- ( i ) + // i=k+1 + + // The terms are not summed directly instead + // the incomplete beta integral is employed, + // according to the formula: + // Q = 1 -I[1-p]( n-k, k+1). + // = I[p](k + 1, n - k) + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType const& k = c.param; + binomial_distribution const& dist = c.dist; + RealType n = dist.trials(); + RealType p = dist.success_fraction(); + + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + "boost::math::cdf(binomial_distribution<%1%> const&, %1%)", + n, + p, + k, + &result, Policy())) + { + return result; + } + + if (k == n) + { // Probability of greater than n successes is necessarily zero: + return 0; + } + + // Special cases, regardless of k. + if (p == 0) + { + // This need explanation: the pdf is zero for all + // cases except when k == 0. For zero p the probability + // of zero successes is one. Therefore the cdf is always + // 1: the probability of *more than* k successes is always 0 + // if there are never any successes! + return 0; + } + if (p == 1) + { + // This needs explanation, when p = 1 + // we always have n successes, so the probability + // of more than k successes is 1 as long as k < n. + // The k == n case has already been handled above. + return 1; + } + // + // Calculate cdf binomial using the incomplete beta function. + // Q = 1 -I[1-p](n - k, k + 1) + // = I[p](k + 1, n - k) + // Use of ibeta here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // + // Note that we do not use a finite sum here, since the incomplete + // beta uses a finite sum internally for integer arguments, so + // we'll just let it take care of the necessary logic. + // + return ibeta(k + 1, n - k, p, Policy()); + } // binomial cdf + + template + BOOST_MATH_CUDA_ENABLED inline RealType quantile(const binomial_distribution& dist, const RealType& p) + { + return binomial_detail::quantile_imp(dist, p, RealType(1-p), false); + } // quantile + + template + BOOST_MATH_CUDA_ENABLED RealType quantile(const complemented2_type, RealType>& c) + { + return binomial_detail::quantile_imp(c.dist, RealType(1-c.param), c.param, true); + } // quantile + + template + BOOST_MATH_CUDA_ENABLED inline RealType mode(const binomial_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return floor(p * (n + 1)); + } + + template + BOOST_MATH_CUDA_ENABLED inline RealType median(const binomial_distribution& dist) + { // Bounds for the median of the negative binomial distribution + // VAN DE VEN R. ; WEBER N. C. ; + // Univ. Sydney, school mathematics statistics, Sydney N.S.W. 2006, AUSTRALIE + // Metrika (Metrika) ISSN 0026-1335 CODEN MTRKA8 + // 1993, vol. 40, no3-4, pp. 185-189 (4 ref.) + + // Bounds for median and 50 percentage point of binomial and negative binomial distribution + // Metrika, ISSN 0026-1335 (Print) 1435-926X (Online) + // Volume 41, Number 1 / December, 1994, DOI 10.1007/BF01895303 + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + // Wikipedia says one of floor(np) -1, floor (np), floor(np) +1 + return floor(p * n); // Chose the middle value. + } + + template + BOOST_MATH_CUDA_ENABLED inline RealType skewness(const binomial_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return (1 - 2 * p) / sqrt(n * p * (1 - p)); + } + + template + BOOST_MATH_CUDA_ENABLED inline RealType kurtosis(const binomial_distribution& dist) + { + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return 3 - 6 / n + 1 / (n * p * (1 - p)); + } + + template + BOOST_MATH_CUDA_ENABLED inline RealType kurtosis_excess(const binomial_distribution& dist) + { + RealType p = dist.success_fraction(); + RealType q = 1 - p; + RealType n = dist.trials(); + return (1 - 6 * p * q) / (n * p * q); + } + + } // namespace math + } // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_BINOMIAL_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/cauchy.hpp b/third-party/boost-math/include/boost/math/distributions/cauchy.hpp new file mode 100644 index 0000000000000..00a9ac9ac94b1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/cauchy.hpp @@ -0,0 +1,379 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2007. +// Copyright Matt Borland 2024. + +// 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) + +#ifndef BOOST_STATS_CAUCHY_HPP +#define BOOST_STATS_CAUCHY_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#endif + +namespace boost{ namespace math +{ + +template +class cauchy_distribution; + +namespace detail +{ + +template +BOOST_MATH_GPU_ENABLED RealType cdf_imp(const cauchy_distribution& dist, const RealType& x, bool complement) +{ + // + // This calculates the cdf of the Cauchy distribution and/or its complement. + // + // This implementation uses the formula + // + // cdf = atan2(1, -x)/pi + // + // where x is the standardized (i.e. shifted and scaled) domain variable. + // + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::cdf(cauchy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + #ifdef BOOST_MATH_HAS_GPU_SUPPORT + if(x > tools::max_value()) + { + return static_cast((complement) ? 0 : 1); + } + if(x < -tools::max_value()) + { + return static_cast((complement) ? 1 : 0); + } + #else + if(boost::math::numeric_limits::has_infinity && x == boost::math::numeric_limits::infinity()) + { // cdf +infinity is unity. + return static_cast((complement) ? 0 : 1); + } + if(boost::math::numeric_limits::has_infinity && x == -boost::math::numeric_limits::infinity()) + { // cdf -infinity is zero. + return static_cast((complement) ? 1 : 0); + } + #endif + if(false == detail::check_x(function, x, &result, Policy())) + { // Catches x == NaN + return result; + } + RealType x_std = static_cast((complement) ? 1 : -1)*(x - location) / scale; + return atan2(static_cast(1), x_std) / constants::pi(); +} // cdf + +template +BOOST_MATH_GPU_ENABLED RealType quantile_imp( + const cauchy_distribution& dist, + RealType p, + bool complement) +{ + // This routine implements the quantile for the Cauchy distribution, + // the value p may be the probability, or its complement if complement=true. + // + // The procedure calculates the distance from the + // mid-point of the distribution. This is either added or subtracted + // from the location parameter depending on whether `complement` is true. + // + constexpr auto function = "boost::math::quantile(cauchy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + // Special cases: + if(p == 1) + { + return (complement ? -1 : 1) * policies::raise_overflow_error(function, 0, Policy()); + } + if(p == 0) + { + return (complement ? 1 : -1) * policies::raise_overflow_error(function, 0, Policy()); + } + + if(p > 0.5) + { + p = p - 1; + } + if(p == 0.5) // special case: + { + return location; + } + result = -scale / tan(constants::pi() * p); + return complement ? RealType(location - result) : RealType(location + result); +} // quantile + +} // namespace detail + +template > +class cauchy_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED cauchy_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_a(l_location), m_hg(l_scale) + { + constexpr auto function = "boost::math::cauchy_distribution<%1%>::cauchy_distribution"; + RealType result; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + } // cauchy_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return m_a; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_hg; + } + +private: + RealType m_a; // The location, this is the median of the distribution. + RealType m_hg; // The scale )or shape), this is the half width at half height. +}; + +typedef cauchy_distribution cauchy; + +#ifdef __cpp_deduction_guides +template +cauchy_distribution(RealType)->cauchy_distribution::type>; +template +cauchy_distribution(RealType,RealType)->cauchy_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const cauchy_distribution&) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const cauchy_distribution& ) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const cauchy_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(cauchy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(boost::math::numeric_limits::has_infinity && abs(x) == boost::math::numeric_limits::infinity()) + //{ // pdf + and - infinity is zero. + // return 0; + //} + + if(false == detail::check_x(function, x, &result, Policy())) + { // Catches x = NaN + return result; + } + + RealType xs = (x - location) / scale; + result = 1 / (constants::pi() * scale * (1 + xs * xs)); + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const cauchy_distribution& dist, const RealType& x) +{ + return detail::cdf_imp(dist, x, false); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const cauchy_distribution& dist, const RealType& p) +{ + return detail::quantile_imp(dist, p, false); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const cauchy_distribution&) +{ // There is no mean: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Cauchy Distribution has no mean"); + + return policies::raise_domain_error( + "boost::math::mean(cauchy<%1%>&)", + "The Cauchy distribution does not have a mean: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const cauchy_distribution& /*dist*/) +{ + // There is no variance: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Cauchy Distribution has no variance"); + + return policies::raise_domain_error( + "boost::math::variance(cauchy<%1%>&)", + "The Cauchy distribution does not have a variance: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const cauchy_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const cauchy_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const cauchy_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Cauchy Distribution has no skewness"); + + return policies::raise_domain_error( + "boost::math::skewness(cauchy<%1%>&)", + "The Cauchy distribution does not have a skewness: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const cauchy_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Cauchy Distribution has no kurtosis"); + + return policies::raise_domain_error( + "boost::math::kurtosis(cauchy<%1%>&)", + "The Cauchy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const cauchy_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Cauchy Distribution has no kurtosis excess"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(cauchy<%1%>&)", + "The Cauchy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const cauchy_distribution & dist) +{ + using std::log; + return log(2*constants::two_pi()*dist.scale()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_CAUCHY_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/chi_squared.hpp b/third-party/boost-math/include/boost/math/distributions/chi_squared.hpp new file mode 100644 index 0000000000000..3944569e89354 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/chi_squared.hpp @@ -0,0 +1,347 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2008, 2010. + +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP +#define BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP + +#include +#include +#include +#include +#include +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include + +namespace boost{ namespace math{ + +template > +class chi_squared_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit chi_squared_distribution(RealType i) : m_df(i) + { + RealType result; + detail::check_df( + "boost::math::chi_squared_distribution<%1%>::chi_squared_distribution", m_df, &result, Policy()); + } // chi_squared_distribution + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom()const + { + return m_df; + } + + // Parameter estimation: + BOOST_MATH_GPU_ENABLED static RealType find_degrees_of_freedom( + RealType difference_from_variance, + RealType alpha, + RealType beta, + RealType variance, + RealType hint = 100); + +private: + // + // Data member: + // + RealType m_df; // degrees of freedom is a positive real number. +}; // class chi_squared_distribution + +using chi_squared = chi_squared_distribution; + +#ifdef __cpp_deduction_guides +template +chi_squared_distribution(RealType)->chi_squared_distribution::type>; +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const chi_squared_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(static_cast(0), boost::math::numeric_limits::infinity()); // 0 to + infinity. + } + else + { + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // 0 to + max. + } +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const chi_squared_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(0), tools::max_value()); // 0 to + infinity. +} + +template +BOOST_MATH_GPU_ENABLED RealType pdf(const chi_squared_distribution& dist, const RealType& chi_square) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType degrees_of_freedom = dist.degrees_of_freedom(); + // Error check: + RealType error_result; + + constexpr auto function = "boost::math::pdf(const chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + if(chi_square == 0) + { + // Handle special cases: + if(degrees_of_freedom < 2) + { + return policies::raise_overflow_error( + function, 0, Policy()); + } + else if(degrees_of_freedom == 2) + { + return 0.5f; + } + else + { + return 0; + } + } + + return gamma_p_derivative(degrees_of_freedom / 2, chi_square / 2, Policy()) / 2; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const chi_squared_distribution& dist, const RealType& chi_square) +{ + RealType degrees_of_freedom = dist.degrees_of_freedom(); + // Error check: + RealType error_result; + constexpr auto function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + return boost::math::gamma_p(degrees_of_freedom / 2, chi_square / 2, Policy()); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const chi_squared_distribution& dist, const RealType& p) +{ + RealType degrees_of_freedom = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == + ( + detail::check_df(function, degrees_of_freedom, &error_result, Policy()) + && detail::check_probability(function, p, &error_result, Policy())) + ) + return error_result; + + return 2 * boost::math::gamma_p_inv(degrees_of_freedom / 2, p, Policy()); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + RealType const& degrees_of_freedom = c.dist.degrees_of_freedom(); + RealType const& chi_square = c.param; + constexpr auto function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + return boost::math::gamma_q(degrees_of_freedom / 2, chi_square / 2, Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + RealType const& degrees_of_freedom = c.dist.degrees_of_freedom(); + RealType const& q = c.param; + constexpr auto function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == ( + detail::check_df(function, degrees_of_freedom, &error_result, Policy()) + && detail::check_probability(function, q, &error_result, Policy())) + ) + return error_result; + + return 2 * boost::math::gamma_q_inv(degrees_of_freedom / 2, q, Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const chi_squared_distribution& dist) +{ // Mean of Chi-Squared distribution = v. + return dist.degrees_of_freedom(); +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const chi_squared_distribution& dist) +{ // Variance of Chi-Squared distribution = 2v. + return 2 * dist.degrees_of_freedom(); +} // variance + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::mode(const chi_squared_distribution<%1%>&)"; + + if(df < 2) + return policies::raise_domain_error( + function, + "Chi-Squared distribution only has a mode for degrees of freedom >= 2, but got degrees of freedom = %1%.", + df, Policy()); + return df - 2; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const chi_squared_distribution& dist) +{ + BOOST_MATH_STD_USING // For ADL + RealType df = dist.degrees_of_freedom(); + return sqrt (8 / df); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + return 3 + 12 / df; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + return 12 / df; +} + +// +// Parameter estimation comes last: +// +namespace detail +{ + +template +struct df_estimator +{ + BOOST_MATH_GPU_ENABLED df_estimator(RealType a, RealType b, RealType variance, RealType delta) + : alpha(a), beta(b), ratio(delta/variance) + { // Constructor + } + + BOOST_MATH_GPU_ENABLED RealType operator()(const RealType& df) + { + if(df <= tools::min_value()) + return 1; + chi_squared_distribution cs(df); + + RealType result; + if(ratio > 0) + { + RealType r = 1 + ratio; + result = cdf(cs, quantile(complement(cs, alpha)) / r) - beta; + } + else + { // ratio <= 0 + RealType r = 1 + ratio; + result = cdf(complement(cs, quantile(cs, alpha) / r)) - beta; + } + return result; + } +private: + RealType alpha; + RealType beta; + RealType ratio; // Difference from variance / variance, so fractional. +}; + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED RealType chi_squared_distribution::find_degrees_of_freedom( + RealType difference_from_variance, + RealType alpha, + RealType beta, + RealType variance, + RealType hint) +{ + constexpr auto function = "boost::math::chi_squared_distribution<%1%>::find_degrees_of_freedom(%1%,%1%,%1%,%1%,%1%)"; + // Check for domain errors: + RealType error_result; + if(false == + detail::check_probability(function, alpha, &error_result, Policy()) + && detail::check_probability(function, beta, &error_result, Policy())) + { // Either probability is outside 0 to 1. + return error_result; + } + + if(hint <= 0) + { // No hint given, so guess df = 1. + hint = 1; + } + + detail::df_estimator f(alpha, beta, variance, difference_from_variance); + tools::eps_tolerance tol(policies::digits()); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + boost::math::pair r = + tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy()); + RealType result = r.first + (r.second - r.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to how many degrees of freedom are required or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/complement.hpp b/third-party/boost-math/include/boost/math/distributions/complement.hpp new file mode 100644 index 0000000000000..c63b8a504142c --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/complement.hpp @@ -0,0 +1,198 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Paul A. Bristow 2006. +// (C) Copyright Matt Borland 2024 +// 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) + +#ifndef BOOST_STATS_COMPLEMENT_HPP +#define BOOST_STATS_COMPLEMENT_HPP + +#include + +// +// This code really defines our own tuple type. +// It would be nice to reuse boost::math::tuple +// while retaining our own type safety, but it's +// not clear if that's possible. In any case this +// code is *very* lightweight. +// +namespace boost{ namespace math{ + +template +struct complemented2_type +{ + BOOST_MATH_GPU_ENABLED complemented2_type( + const Dist& d, + const RealType& p1) + : dist(d), + param(p1) {} + + const Dist& dist; + const RealType& param; + +private: + complemented2_type& operator=(const complemented2_type&) = delete; +}; + +template +struct complemented3_type +{ + BOOST_MATH_GPU_ENABLED complemented3_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2) + : dist(d), + param1(p1), + param2(p2) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; +private: + complemented3_type& operator=(const complemented3_type&) = delete; +}; + +template +struct complemented4_type +{ + BOOST_MATH_GPU_ENABLED complemented4_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3) + : dist(d), + param1(p1), + param2(p2), + param3(p3) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; +private: + complemented4_type& operator=(const complemented4_type&) = delete; +}; + +template +struct complemented5_type +{ + BOOST_MATH_GPU_ENABLED complemented5_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; +private: + complemented5_type& operator=(const complemented5_type&) = delete; +}; + +template +struct complemented6_type +{ + BOOST_MATH_GPU_ENABLED complemented6_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4, + const RealType5& p5) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4), + param5(p5) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; + const RealType5& param5; +private: + complemented6_type& operator=(const complemented6_type&) = delete; +}; + +template +struct complemented7_type +{ + BOOST_MATH_GPU_ENABLED complemented7_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4, + const RealType5& p5, + const RealType6& p6) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4), + param5(p5), + param6(p6) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; + const RealType5& param5; + const RealType6& param6; +private: + complemented7_type& operator=(const complemented7_type&) = delete; +}; + +template +BOOST_MATH_GPU_ENABLED inline complemented2_type complement(const Dist& d, const RealType& r) +{ + return complemented2_type(d, r); +} + +template +BOOST_MATH_GPU_ENABLED inline complemented3_type complement(const Dist& d, const RealType1& r1, const RealType2& r2) +{ + return complemented3_type(d, r1, r2); +} + +template +BOOST_MATH_GPU_ENABLED inline complemented4_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3) +{ + return complemented4_type(d, r1, r2, r3); +} + +template +BOOST_MATH_GPU_ENABLED inline complemented5_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4) +{ + return complemented5_type(d, r1, r2, r3, r4); +} + +template +BOOST_MATH_GPU_ENABLED inline complemented6_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5) +{ + return complemented6_type(d, r1, r2, r3, r4, r5); +} + +template +BOOST_MATH_GPU_ENABLED inline complemented7_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5, const RealType6& r6) +{ + return complemented7_type(d, r1, r2, r3, r4, r5, r6); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_STATS_COMPLEMENT_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp b/third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp new file mode 100644 index 0000000000000..06e3c105bd2b0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp @@ -0,0 +1,228 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007, 2012. +// Copyright Matt Borland 2024 + +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP +#define BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP + +#include +#include +#include +#include +// using boost::math::isfinite; +// using boost::math::isnan; + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost{ namespace math{ namespace detail +{ + +template +BOOST_MATH_GPU_ENABLED inline bool check_probability(const char* function, RealType const& prob, RealType* result, const Policy& pol) +{ + if((prob < 0) || (prob > 1) || !(boost::math::isfinite)(prob)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", prob, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_df(const char* function, RealType const& df, RealType* result, const Policy& pol) +{ // df > 0 but NOT +infinity allowed. + if((df <= 0) || !(boost::math::isfinite)(df)) + { + *result = policies::raise_domain_error( + function, + "Degrees of freedom argument is %1%, but must be > 0 !", df, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_df_gt0_to_inf(const char* function, RealType const& df, RealType* result, const Policy& pol) +{ // df > 0 or +infinity are allowed. + if( (df <= 0) || (boost::math::isnan)(df) ) + { // is bad df <= 0 or NaN or -infinity. + *result = policies::raise_domain_error( + function, + "Degrees of freedom argument is %1%, but must be > 0 !", df, pol); + return false; + } + return true; +} // check_df_gt0_to_inf + + +template +BOOST_MATH_GPU_ENABLED inline bool check_scale( + const char* function, + RealType scale, + RealType* result, + const Policy& pol) +{ + if((scale <= 0) || !(boost::math::isfinite)(scale)) + { // Assume scale == 0 is NOT valid for any distribution. + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be > 0 !", scale, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_location( + const char* function, + RealType location, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(location)) + { + *result = policies::raise_domain_error( + function, + "Location parameter is %1%, but must be finite!", location, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_x( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + // Note that this test catches both infinity and NaN. + // Some distributions permit x to be infinite, so these must be tested 1st and return, + // leaving this test to catch any NaNs. + // See Normal, Logistic, Laplace and Cauchy for example. + if(!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite!", x, pol); + return false; + } + return true; +} // bool check_x + +template +BOOST_MATH_GPU_ENABLED inline bool check_x_not_NaN( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + // Note that this test catches only NaN. + // Some distributions permit x to be infinite, leaving this test to catch any NaNs. + // See Normal, Logistic, Laplace and Cauchy for example. + if ((boost::math::isnan)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite or + or - infinity!", x, pol); + return false; + } + return true; +} // bool check_x_not_NaN + +template +BOOST_MATH_GPU_ENABLED inline bool check_x_gt0( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(x <= 0) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be > 0!", x, pol); + return false; + } + + return true; + // Note that this test catches both infinity and NaN. + // Some special cases permit x to be infinite, so these must be tested 1st, + // leaving this test to catch any NaNs. See Normal and cauchy for example. +} // bool check_x_gt0 + +template +BOOST_MATH_GPU_ENABLED inline bool check_positive_x( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(x) || (x < 0)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite and >= 0!", x, pol); + return false; + } + return true; + // Note that this test catches both infinity and NaN. + // Some special cases permit x to be infinite, so these must be tested 1st, + // leaving this test to catch any NaNs. see Normal and cauchy for example. +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_non_centrality( + const char* function, + RealType ncp, + RealType* result, + const Policy& pol) +{ + BOOST_MATH_STATIC const RealType upper_limit = static_cast((boost::math::numeric_limits::max)()) - boost::math::policies::get_max_root_iterations(); + + if((ncp < 0) || !(boost::math::isfinite)(ncp) || ncp > upper_limit) + { + *result = policies::raise_domain_error( + function, + "Non centrality parameter is %1%, but must be > 0, and a countable value such that x+1 != x", ncp, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_finite( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(x)) + { // Assume scale == 0 is NOT valid for any distribution. + *result = policies::raise_domain_error( + function, + "Parameter is %1%, but must be finite !", x, pol); + return false; + } + return true; +} + +} // namespace detail +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp b/third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp new file mode 100644 index 0000000000000..90679ef21f7a6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp @@ -0,0 +1,190 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_DERIVED_HPP +#define BOOST_STATS_DERIVED_HPP + +// This file implements various common properties of distributions +// that can be implemented in terms of other properties: +// variance OR standard deviation (see note below), +// hazard, cumulative hazard (chf), coefficient_of_variation. +// +// Note that while both variance and standard_deviation are provided +// here, each distribution MUST SPECIALIZE AT LEAST ONE OF THESE +// otherwise these two versions will just call each other over and over +// until stack space runs out ... + +// Of course there may be more efficient means of implementing these +// that are specific to a particular distribution, but these generic +// versions give these properties "for free" with most distributions. +// +// In order to make use of this header, it must be included AT THE END +// of the distribution header, AFTER the distribution and its core +// property accessors have been defined: this is so that compilers +// that implement 2-phase lookup and early-type-checking of templates +// can find the definitions referred to herein. +// + +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4723) // potential divide by 0 +// Suppressing spurious warning in coefficient_of_variation +#endif + +namespace boost{ namespace math{ + +template +BOOST_MATH_GPU_ENABLED typename Distribution::value_type variance(const Distribution& dist); + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type standard_deviation(const Distribution& dist) +{ + BOOST_MATH_STD_USING // ADL of sqrt. + return sqrt(variance(dist)); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type variance(const Distribution& dist) +{ + typename Distribution::value_type result = standard_deviation(dist); + return result * result; +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type hazard(const Distribution& dist, const RealType& x) +{ // hazard function + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ + typedef typename Distribution::value_type value_type; + typedef typename Distribution::policy_type policy_type; + value_type p = cdf(complement(dist, x)); + value_type d = pdf(dist, x); + if(d > p * tools::max_value()) + return policies::raise_overflow_error( + "boost::math::hazard(const Distribution&, %1%)", nullptr, policy_type()); + if(d == 0) + { + // This protects against 0/0, but is it the right thing to do? + return 0; + } + return d / p; +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x) +{ // cumulative hazard function. + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ + BOOST_MATH_STD_USING + return -log(cdf(complement(dist, x))); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type coefficient_of_variation(const Distribution& dist) +{ + typedef typename Distribution::value_type value_type; + typedef typename Distribution::policy_type policy_type; + + using std::abs; + + value_type m = mean(dist); + value_type d = standard_deviation(dist); + if((abs(m) < 1) && (d > abs(m) * tools::max_value())) + { // Checks too that m is not zero, + return policies::raise_overflow_error("boost::math::coefficient_of_variation(const Distribution&, %1%)", nullptr, policy_type()); + } + return d / m; // so MSVC warning on zerodivide is spurious, and suppressed. +} +// +// Next follow overloads of some of the standard accessors with mixed +// argument types. We just use a typecast to forward on to the "real" +// implementation with all arguments of the same type: +// +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type pdf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return pdf(dist, static_cast(x)); +} +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type logpdf(const Distribution& dist, const RealType& x) +{ + using std::log; + typedef typename Distribution::value_type value_type; + return log(pdf(dist, static_cast(x))); +} +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type cdf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return cdf(dist, static_cast(x)); +} +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type logcdf(const Distribution& dist, const Realtype& x) +{ + using std::log; + using value_type = typename Distribution::value_type; + return log(cdf(dist, static_cast(x))); +} +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type quantile(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return quantile(dist, static_cast(x)); +} +/* +template +inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return chf(dist, static_cast(x)); +} +*/ +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type cdf(const complemented2_type& c) +{ + typedef typename Distribution::value_type value_type; + return cdf(complement(c.dist, static_cast(c.param))); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type logcdf(const complemented2_type& c) +{ + using std::log; + typedef typename Distribution::value_type value_type; + return log(cdf(complement(c.dist, static_cast(c.param)))); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type quantile(const complemented2_type& c) +{ + typedef typename Distribution::value_type value_type; + return quantile(complement(c.dist, static_cast(c.param))); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type median(const Dist& d) +{ // median - default definition for those distributions for which a + // simple closed form is not known, + // and for which a domain_error and/or NaN generating function is NOT defined. + typedef typename Dist::value_type value_type; + return quantile(d, static_cast(0.5f)); +} + +} // namespace math +} // namespace boost + + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_STATS_DERIVED_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp b/third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp new file mode 100644 index 0000000000000..9306c815da816 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp @@ -0,0 +1,145 @@ +// Copyright John Maddock 2008. + +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP + +#include +#include +#include // function minimization for mode +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct pdf_minimizer +{ + BOOST_MATH_GPU_ENABLED pdf_minimizer(const Dist& d) + : dist(d) {} + + BOOST_MATH_GPU_ENABLED typename Dist::value_type operator()(const typename Dist::value_type& x) + { + return -pdf(dist, x); + } +private: + Dist dist; +}; + +template +BOOST_MATH_GPU_ENABLED typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0) +{ + BOOST_MATH_STD_USING + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + // + // Need to begin by bracketing the maxima of the PDF: + // + value_type maxval; + value_type upper_bound = guess; + value_type lower_bound; + value_type v = pdf(dist, guess); + if(v == 0) + { + // + // Oops we don't know how to handle this, or even in which + // direction we should move in, treat as an evaluation error: + // + return policies::raise_evaluation_error(function, "Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type()); // LCOV_EXCL_LINE + } + do + { + maxval = v; + if(step != 0) + upper_bound += step; + else + upper_bound *= 2; + v = pdf(dist, upper_bound); + }while(maxval < v); + + lower_bound = upper_bound; + do + { + maxval = v; + if(step != 0) + lower_bound -= step; + else + lower_bound /= 2; + v = pdf(dist, lower_bound); + }while(maxval < v); + + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + + value_type result = tools::brent_find_minima( + pdf_minimizer(dist), + lower_bound, + upper_bound, + policies::digits(), + max_iter).first; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, // LCOV_EXCL_LINE + "Unable to locate solution in a reasonable time: either there is no answer to the mode of the distribution" // LCOV_EXCL_LINE + " or the answer is infinite. Current best guess is %1%", result, policy_type()); // LCOV_EXCL_LINE + } + return result; +} +// +// As above,but confined to the interval [0,1]: +// +template +BOOST_MATH_GPU_ENABLED typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function) +{ + BOOST_MATH_STD_USING + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + // + // Need to begin by bracketing the maxima of the PDF: + // + value_type maxval; + value_type upper_bound = guess; + value_type lower_bound; + value_type v = pdf(dist, guess); + do + { + maxval = v; + upper_bound = 1 - (1 - upper_bound) / 2; + if(upper_bound == 1) + return 1; + v = pdf(dist, upper_bound); + }while(maxval < v); + + lower_bound = upper_bound; + do + { + maxval = v; + lower_bound /= 2; + if(lower_bound < tools::min_value()) + return 0; + v = pdf(dist, lower_bound); + }while(maxval < v); + + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + + value_type result = tools::brent_find_minima( + pdf_minimizer(dist), + lower_bound, + upper_bound, + policies::digits(), + max_iter).first; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to the mode of the distribution or the answer is infinite. Current best guess is %1%", result, policy_type()); // LCOV_EXCL_LINE + } + return result; +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp b/third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp new file mode 100644 index 0000000000000..917532566fa96 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp @@ -0,0 +1,100 @@ +// Copyright John Maddock 2008. +// 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) + +#ifndef BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP +#define BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP + +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct generic_quantile_finder +{ + using value_type = typename Dist::value_type; + using policy_type = typename Dist::policy_type; + + BOOST_MATH_GPU_ENABLED generic_quantile_finder(const Dist& d, value_type t, bool c) + : dist(d), target(t), comp(c) {} + + BOOST_MATH_GPU_ENABLED value_type operator()(const value_type& x) + { + return comp ? + value_type(target - cdf(complement(dist, x))) + : value_type(cdf(dist, x) - target); + } + +private: + Dist dist; + value_type target; + bool comp; +}; + +template +BOOST_MATH_GPU_ENABLED inline T check_range_result(const T& x, const Policy& pol, const char* function) +{ + if((x >= 0) && (x < tools::min_value())) + { + return policies::raise_underflow_error(function, nullptr, pol); + } + if(x <= -tools::max_value()) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + if(x >= tools::max_value()) + { + return policies::raise_overflow_error(function, nullptr, pol); + } + return x; +} + +template +BOOST_MATH_GPU_ENABLED typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function) +{ + using value_type = typename Dist::value_type; + using policy_type = typename Dist::policy_type; + using forwarding_policy = typename policies::normalise< + policy_type, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + // + // Special cases first: + // + if(p == 0) + { + return comp + ? check_range_result(range(dist).second, forwarding_policy(), function) + : check_range_result(range(dist).first, forwarding_policy(), function); + } + if(p == 1) + { + return !comp + ? check_range_result(range(dist).second, forwarding_policy(), function) + : check_range_result(range(dist).first, forwarding_policy(), function); + } + + generic_quantile_finder f(dist, p, comp); + tools::eps_tolerance tol(policies::digits() - 3); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + boost::math::pair ir = tools::bracket_and_solve_root( + f, guess, value_type(2), true, tol, max_iter, forwarding_policy()); + value_type result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, forwarding_policy()); // LCOV_EXCL_LINE + } + return result; +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp new file mode 100644 index 0000000000000..60e29bc10c519 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp @@ -0,0 +1,101 @@ +// Copyright 2008 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_CDF_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_CDF_HPP + +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + + template + T hypergeometric_cdf_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, bool invert, const Policy& pol) + { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + BOOST_MATH_STD_USING + T result = 0; + T mode = floor(T(r + 1) * T(n + 1) / (N + 2)); + if(x < mode) + { + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + const auto lower_limit = static_cast((std::max)(INT64_C(0), static_cast(n + r) - static_cast(N))); + while(diff > (invert ? T(1) : result) * tools::epsilon()) + { + diff = T(x) * T((N + x) - n - r) * diff / (T(1 + n - x) * T(1 + r - x)); + result += diff; + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(x == lower_limit) + break; + --x; + } + } + else + { + invert = !invert; + const auto upper_limit = (std::min)(r, n); + if(x != upper_limit) + { + ++x; + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + while((x <= upper_limit) && (diff > (invert ? T(1) : result) * tools::epsilon())) + { + diff = T(n - x) * T(r - x) * diff / (T(x + 1) * T((N + x + 1) - n - r)); + result += diff; + ++x; + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + if(invert) + result = 1 - result; + return result; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } + + template + inline T hypergeometric_cdf(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, bool invert, const Policy&) + { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type result; + result = detail::hypergeometric_cdf_imp(x, r, n, N, invert, forwarding_policy()); + if(result > 1) + { + result = 1; + } + if(result < 0) + { + result = 0; + } + return policies::checked_narrowing_cast(result, "boost::math::hypergeometric_cdf<%1%>(%1%,%1%,%1%,%1%)"); + } + +}}} // namespaces + +#endif + diff --git a/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp new file mode 100644 index 0000000000000..0ec3065eb332c --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp @@ -0,0 +1,490 @@ +// Copyright 2008 Gautam Sewani +// Copyright 2008 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_INSTRUMENT +#include +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +void bubble_down_one(T* first, T* last, Func f) +{ + using std::swap; + T* next = first; + ++next; + while((next != last) && (!f(*first, *next))) + { + swap(*first, *next); + ++first; + ++next; + } +} + +template +struct sort_functor +{ + sort_functor(const T* exponents) : m_exponents(exponents){} + bool operator()(std::size_t i, std::size_t j) + { + return m_exponents[i] > m_exponents[j]; + } +private: + const T* m_exponents; +}; + +template +T hypergeometric_pdf_lanczos_imp(T /*dummy*/, std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Lanczos&, const Policy&) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_FPU + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(N); + BOOST_MATH_INSTRUMENT_VARIABLE(typeid(Lanczos).name()); + + T bases[9] = { + T(n) + static_cast(Lanczos::g()) + 0.5f, + T(r) + static_cast(Lanczos::g()) + 0.5f, + T(N - n) + static_cast(Lanczos::g()) + 0.5f, + T(N - r) + static_cast(Lanczos::g()) + 0.5f, + 1 / (T(N) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(n - x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(r - x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(N - n - r + x) + static_cast(Lanczos::g()) + 0.5f) + }; + T exponents[9] = { + n + T(0.5f), + r + T(0.5f), + N - n + T(0.5f), + N - r + T(0.5f), + N + T(0.5f), + x + T(0.5f), + n - x + T(0.5f), + r - x + T(0.5f), + N - n - r + x + T(0.5f) + }; + int base_e_factors[9] = { + -1, -1, -1, -1, 1, 1, 1, 1, 1 + }; + int sorted_indexes[9] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8 + }; +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + std::sort(sorted_indexes, sorted_indexes + 9, sort_functor(exponents)); +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + + do{ + exponents[sorted_indexes[0]] -= exponents[sorted_indexes[1]]; + bases[sorted_indexes[1]] *= bases[sorted_indexes[0]]; + if((bases[sorted_indexes[1]] < tools::min_value()) && (exponents[sorted_indexes[1]] != 0)) + { + return 0; + } + base_e_factors[sorted_indexes[1]] += base_e_factors[sorted_indexes[0]]; + bubble_down_one(sorted_indexes, sorted_indexes + 9, sort_functor(exponents)); + +#ifdef BOOST_MATH_INSTRUMENT + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + }while(exponents[sorted_indexes[1]] > 1); + + // + // Combine equal powers: + // + std::size_t j = 8; + while(exponents[sorted_indexes[j]] == 0) --j; + while(j) + { + while(j && (exponents[sorted_indexes[j-1]] == exponents[sorted_indexes[j]])) + { + bases[sorted_indexes[j-1]] *= bases[sorted_indexes[j]]; + exponents[sorted_indexes[j]] = 0; + base_e_factors[sorted_indexes[j-1]] += base_e_factors[sorted_indexes[j]]; + bubble_down_one(sorted_indexes + j, sorted_indexes + 9, sort_functor(exponents)); + --j; + } + --j; + +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_VARIABLE(j); + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + } + +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + + T result; + BOOST_MATH_INSTRUMENT_VARIABLE(bases[sorted_indexes[0]] * exp(static_cast(base_e_factors[sorted_indexes[0]]))); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[sorted_indexes[0]]); + { + BOOST_FPU_EXCEPTION_GUARD + result = pow(bases[sorted_indexes[0]] * exp(static_cast(base_e_factors[sorted_indexes[0]])), exponents[sorted_indexes[0]]); + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + for(std::size_t i = 1; (i < 9) && (exponents[sorted_indexes[i]] > 0); ++i) + { + BOOST_FPU_EXCEPTION_GUARD + if(result < tools::min_value()) + return 0; // short circuit further evaluation + if(exponents[sorted_indexes[i]] == 1) + result *= bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]])); + else if(exponents[sorted_indexes[i]] == 0.5f) + result *= sqrt(bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]]))); + else + result *= pow(bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]])), exponents[sorted_indexes[i]]); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + + result *= Lanczos::lanczos_sum_expG_scaled(static_cast(n + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(r + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - n + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - r + 1)) + / + ( Lanczos::lanczos_sum_expG_scaled(static_cast(N + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(n - x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(r - x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - n - r + x + 1))); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result; +} + +template +T hypergeometric_pdf_lanczos_imp(T /*dummy*/, std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const boost::math::lanczos::undefined_lanczos&, const Policy& pol) +{ + BOOST_MATH_STD_USING + return exp( + boost::math::lgamma(T(n + 1), pol) + + boost::math::lgamma(T(r + 1), pol) + + boost::math::lgamma(T(N - n + 1), pol) + + boost::math::lgamma(T(N - r + 1), pol) + - boost::math::lgamma(T(N + 1), pol) + - boost::math::lgamma(T(x + 1), pol) + - boost::math::lgamma(T(n - x + 1), pol) + - boost::math::lgamma(T(r - x + 1), pol) + - boost::math::lgamma(T(N - n - r + x + 1), pol)); +} + +template +inline T integer_power(const T& x, int ex) +{ + if(ex < 0) + return 1 / integer_power(x, -ex); + switch(ex) + { + case 0: + return 1; + case 1: + return x; + case 2: + return x * x; + case 3: + return x * x * x; + case 4: + return boost::math::pow<4>(x); + case 5: + return boost::math::pow<5>(x); + case 6: + return boost::math::pow<6>(x); + case 7: + return boost::math::pow<7>(x); + case 8: + return boost::math::pow<8>(x); + } + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + return pow(x, T(ex)); +#else + return static_cast(pow(x, ex)); +#endif +} +template +struct hypergeometric_pdf_prime_loop_result_entry +{ + T value; + const hypergeometric_pdf_prime_loop_result_entry* next; +}; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4510 4512 4610) +#endif + +struct hypergeometric_pdf_prime_loop_data +{ + const std::uint64_t x; + const std::uint64_t r; + const std::uint64_t n; + const std::uint64_t N; + std::size_t prime_index; + std::uint64_t current_prime; +}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hypergeometric_pdf_prime_loop_result_entry& result) +{ + while(data.current_prime <= data.N) + { + std::uint64_t base = data.current_prime; + std::uint64_t prime_powers = 0; + while(base <= data.N) + { + prime_powers += data.n / base; + prime_powers += data.r / base; + prime_powers += (data.N - data.n) / base; + prime_powers += (data.N - data.r) / base; + prime_powers -= data.N / base; + prime_powers -= data.x / base; + prime_powers -= (data.n - data.x) / base; + prime_powers -= (data.r - data.x) / base; + prime_powers -= (data.N - data.n - data.r + data.x) / base; + base *= data.current_prime; + } + if(prime_powers) + { + T p = integer_power(static_cast(data.current_prime), static_cast(prime_powers)); + if((p > 1) && (tools::max_value() / p < result.value)) + { + // + // The next calculation would overflow, use recursion + // to sidestep the issue: + // + hypergeometric_pdf_prime_loop_result_entry t = { p, &result }; + data.current_prime = prime(static_cast(++data.prime_index)); + return hypergeometric_pdf_prime_loop_imp(data, t); + } + if((p < 1) && (tools::min_value() / p > result.value)) + { + // + // The next calculation would underflow, use recursion + // to sidestep the issue: + // + hypergeometric_pdf_prime_loop_result_entry t = { p, &result }; + data.current_prime = prime(static_cast(++data.prime_index)); + return hypergeometric_pdf_prime_loop_imp(data, t); + } + result.value *= p; + } + data.current_prime = prime(static_cast(++data.prime_index)); + } + // + // When we get to here we have run out of prime factors, + // the overall result is the product of all the partial + // results we have accumulated on the stack so far, these + // are in a linked list starting with "data.head" and ending + // with "result". + // + // All that remains is to multiply them together, taking + // care not to overflow or underflow. + // + // Enumerate partial results >= 1 in variable i + // and partial results < 1 in variable j: + // + hypergeometric_pdf_prime_loop_result_entry const *i, *j; + i = &result; + while(i && i->value < 1) + i = i->next; + j = &result; + while(j && j->value >= 1) + j = j->next; + + T prod = 1; + + while(i || j) + { + while(i && ((prod <= 1) || (j == 0))) + { + prod *= i->value; + i = i->next; + while(i && i->value < 1) + i = i->next; + } + while(j && ((prod >= 1) || (i == 0))) + { + prod *= j->value; + j = j->next; + while(j && j->value >= 1) + j = j->next; + } + } + + return prod; +} + +template +inline T hypergeometric_pdf_prime_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&) +{ + hypergeometric_pdf_prime_loop_result_entry result = { 1, 0 }; + hypergeometric_pdf_prime_loop_data data = { x, r, n, N, 0, prime(0) }; + return hypergeometric_pdf_prime_loop_imp(data, result); +} + +template +T hypergeometric_pdf_factorial_imp(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&) +{ + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(N <= boost::math::max_factorial::value); + T result = boost::math::unchecked_factorial(static_cast(n)); + T num[3] = { + boost::math::unchecked_factorial(static_cast(r)), + boost::math::unchecked_factorial(static_cast(N - n)), + boost::math::unchecked_factorial(static_cast(N - r)) + }; + T denom[5] = { + boost::math::unchecked_factorial(static_cast(N)), + boost::math::unchecked_factorial(static_cast(x)), + boost::math::unchecked_factorial(static_cast(n - x)), + boost::math::unchecked_factorial(static_cast(r - x)), + boost::math::unchecked_factorial(static_cast(N - n - r + x)) + }; + std::size_t i = 0; + std::size_t j = 0; + while((i < 3) || (j < 5)) + { + while((j < 5) && ((result >= 1) || (i >= 3))) + { + result /= denom[j]; + ++j; + } + while((i < 3) && ((result <= 1) || (j >= 5))) + { + result *= num[i]; + ++i; + } + } + return result; +} + + +template +inline typename tools::promote_args::type + hypergeometric_pdf(std::uint64_t x, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type result; + if(N <= boost::math::max_factorial::value) + { + // + // If N is small enough then we can evaluate the PDF via the factorials + // directly: table lookup of the factorials gives the best performance + // of the methods available: + // + result = detail::hypergeometric_pdf_factorial_imp(x, r, n, N, forwarding_policy()); + } + else if(N <= boost::math::prime(boost::math::max_prime - 1)) + { + // + // If N is no larger than the largest prime number in our lookup table + // (104729) then we can use prime factorisation to evaluate the PDF, + // this is slow but accurate: + // + result = detail::hypergeometric_pdf_prime_imp(x, r, n, N, forwarding_policy()); + } + else + { + // + // Catch all case - use the lanczos approximation - where available - + // to evaluate the ratio of factorials. This is reasonably fast + // (almost as quick as using logarithmic evaluation in terms of lgamma) + // but only a few digits better in accuracy than using lgamma: + // + result = detail::hypergeometric_pdf_lanczos_imp(value_type(), x, r, n, N, evaluation_type(), forwarding_policy()); + } + + if(result > 1) + { + result = 1; + } + if(result < 0) + { + result = 0; + } + + return policies::checked_narrowing_cast(result, "boost::math::hypergeometric_pdf<%1%>(%1%,%1%,%1%,%1%)"); +} + +}}} // namespaces + +#endif + diff --git a/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp new file mode 100644 index 0000000000000..2441a73309679 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp @@ -0,0 +1,245 @@ +// Copyright 2008 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline std::uint64_t round_x_from_p(std::uint64_t x, T p, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t /*ubound*/, const policies::discrete_quantile&) +{ + if((p < cum * fudge_factor) && (x != lbound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x-1); + return --x; + } + return x; +} + +template +inline std::uint64_t round_x_from_p(std::uint64_t x, T p, T cum, T fudge_factor, std::uint64_t /*lbound*/, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if((cum < p * fudge_factor) && (x != ubound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x+1); + return ++x; + } + return x; +} + +template +inline std::uint64_t round_x_from_p(std::uint64_t x, T p, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if(p >= 0.5) + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline std::uint64_t round_x_from_p(std::uint64_t x, T p, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if(p >= 0.5) + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline std::uint64_t round_x_from_p(std::uint64_t x, T /*p*/, T /*cum*/, T /*fudge_factor*/, std::uint64_t /*lbound*/, std::uint64_t /*ubound*/, const policies::discrete_quantile&) +{ + return x; +} + +template +inline std::uint64_t round_x_from_q(std::uint64_t x, T q, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t /*ubound*/, const policies::discrete_quantile&) +{ + if((q * fudge_factor > cum) && (x != lbound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x-1); + return --x; + } + return x; +} + +template +inline std::uint64_t round_x_from_q(std::uint64_t x, T q, T cum, T fudge_factor, std::uint64_t /*lbound*/, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if((q < cum * fudge_factor) && (x != ubound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x+1); + return ++x; + } + return x; +} + +template +inline std::uint64_t round_x_from_q(std::uint64_t x, T q, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if(q < 0.5) + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline std::uint64_t round_x_from_q(std::uint64_t x, T q, T cum, T fudge_factor, std::uint64_t lbound, std::uint64_t ubound, const policies::discrete_quantile&) +{ + if(q >= 0.5) + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline std::uint64_t round_x_from_q(std::uint64_t x, T /*q*/, T /*cum*/, T /*fudge_factor*/, std::uint64_t /*lbound*/, std::uint64_t /*ubound*/, const policies::discrete_quantile&) +{ + return x; +} + +template +std::uint64_t hypergeometric_quantile_imp(T p, T q, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy& pol) +{ +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + typedef typename Policy::discrete_quantile_type discrete_quantile_type; + BOOST_MATH_STD_USING + BOOST_FPU_EXCEPTION_GUARD + T result; + T fudge_factor = 1 + tools::epsilon() * ((N <= boost::math::prime(boost::math::max_prime - 1)) ? 50 : 2 * N); + std::uint64_t base = static_cast((std::max)(0, static_cast(n + r) - static_cast(N))); + std::uint64_t lim = (std::min)(r, n); + + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(N); + BOOST_MATH_INSTRUMENT_VARIABLE(fudge_factor); + BOOST_MATH_INSTRUMENT_VARIABLE(base); + BOOST_MATH_INSTRUMENT_VARIABLE(lim); + + if(p <= 0.5) + { + std::uint64_t x = base; + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + if (diff == 0) + { + ++x; + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + T log_pdf = boost::math::lgamma(static_cast(n + 1), pol) + + boost::math::lgamma(static_cast(r + 1), pol) + + boost::math::lgamma(static_cast(N - n + 1), pol) + + boost::math::lgamma(static_cast(N - r + 1), pol) + - boost::math::lgamma(static_cast(N + 1), pol) + - boost::math::lgamma(static_cast(x + 1), pol) + - boost::math::lgamma(static_cast(n - x + 1), pol) + - boost::math::lgamma(static_cast(r - x + 1), pol) + - boost::math::lgamma(static_cast(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value()) + { + log_pdf += -log(static_cast(x + 1)) + log(static_cast(n - x)) + log(static_cast(r - x)) - log(static_cast(N - n - r + x + 1)); + ++x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceeding: + diff = hypergeometric_pdf(x, r, n, N, pol); + } + while(result < p) + { + diff = (diff > tools::min_value() * 8) + ? T(n - x) * T(r - x) * diff / (T(x + 1) * T(N + x + 1 - n - r)) + : hypergeometric_pdf(x + 1, r, n, N, pol); + if(result + diff / 2 > p) + break; + ++x; + result += diff; +#ifdef BOOST_MATH_INSTRUMENT + if(diff != 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } +#endif + } + return round_x_from_p(x, p, result, fudge_factor, base, lim, discrete_quantile_type()); + } + else + { + std::uint64_t x = lim; + result = 0; + T diff = hypergeometric_pdf(x, r, n, N, pol); + if (diff == 0) + { + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + --x; + T log_pdf = boost::math::lgamma(static_cast(n + 1), pol) + + boost::math::lgamma(static_cast(r + 1), pol) + + boost::math::lgamma(static_cast(N - n + 1), pol) + + boost::math::lgamma(static_cast(N - r + 1), pol) + - boost::math::lgamma(static_cast(N + 1), pol) + - boost::math::lgamma(static_cast(x + 1), pol) + - boost::math::lgamma(static_cast(n - x + 1), pol) + - boost::math::lgamma(static_cast(r - x + 1), pol) + - boost::math::lgamma(static_cast(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value()) + { + log_pdf += log(static_cast(x)) - log(static_cast(n - x + 1)) - log(static_cast(r - x + 1)) + log(static_cast(N - n - r + x)); + --x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceeding: + diff = hypergeometric_pdf(x, r, n, N, pol); + } + while(result + diff / 2 < q) + { + result += diff; + diff = (diff > tools::min_value() * 8) + ? x * T(N + x - n - r) * diff / (T(1 + n - x) * T(1 + r - x)) + : hypergeometric_pdf(x - 1, r, n, N, pol); + --x; +#ifdef BOOST_MATH_INSTRUMENT + if(diff != 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } +#endif + } + return round_x_from_q(x, q, result, fudge_factor, base, lim, discrete_quantile_type()); + } +#ifdef _MSC_VER +# pragma warning(pop) +#endif +} + +template +inline std::uint64_t hypergeometric_quantile(T p, T q, std::uint64_t r, std::uint64_t n, std::uint64_t N, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::assert_undefined<> >::type forwarding_policy; + + return detail::hypergeometric_quantile_imp(p, q, r, n, N, forwarding_policy()); +} + +}}} // namespaces + +#endif + diff --git a/third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp b/third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp new file mode 100644 index 0000000000000..ac4a2b2318044 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp @@ -0,0 +1,583 @@ +// Copyright John Maddock 2007. +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// Functor for root finding algorithm: +// +template +struct distribution_quantile_finder +{ + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + + BOOST_MATH_GPU_ENABLED distribution_quantile_finder(const Dist d, value_type p, bool c) + : dist(d), target(p), comp(c) {} + + BOOST_MATH_GPU_ENABLED value_type operator()(value_type const& x) + { + return comp ? value_type(target - cdf(complement(dist, x))) : value_type(cdf(dist, x) - target); + } + +private: + Dist dist; + value_type target; + bool comp; +}; +// +// The purpose of adjust_bounds, is to toggle the last bit of the +// range so that both ends round to the same integer, if possible. +// If they do both round the same then we terminate the search +// for the root *very* quickly when finding an integer result. +// At the point that this function is called we know that "a" is +// below the root and "b" above it, so this change can not result +// in the root no longer being bracketed. +// +template +BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& /* a */, Real& /* b */, Tol const& /* tol */){} + +template +BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& /* a */, Real& b, tools::equal_floor const& /* tol */) +{ + BOOST_MATH_STD_USING + b -= tools::epsilon() * b; +} + +template +BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& a, Real& /* b */, tools::equal_ceil const& /* tol */) +{ + BOOST_MATH_STD_USING + a += tools::epsilon() * a; +} + +template +BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& a, Real& b, tools::equal_nearest_integer const& /* tol */) +{ + BOOST_MATH_STD_USING + a += tools::epsilon() * a; + b -= tools::epsilon() * b; +} +// +// This is where all the work is done: +// +template +BOOST_MATH_GPU_ENABLED typename Dist::value_type + do_inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool comp, + typename Dist::value_type guess, + const typename Dist::value_type& multiplier, + typename Dist::value_type adder, + const Tolerance& tol, + boost::math::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + + constexpr auto function = "boost::math::do_inverse_discrete_quantile<%1%>"; + + BOOST_MATH_STD_USING + + distribution_quantile_finder f(dist, p, comp); + // + // Max bounds of the distribution: + // + value_type min_bound, max_bound; + boost::math::tie(min_bound, max_bound) = support(dist); + + if(guess > max_bound) + guess = max_bound; + if(guess < min_bound) + guess = min_bound; + + value_type fa = f(guess); + boost::math::uintmax_t count = max_iter - 1; + value_type fb(fa), a(guess), b =0; // Compiler warning C4701: potentially uninitialized local variable 'b' used + + if(fa == 0) + return guess; + + // + // For small expected results, just use a linear search: + // + if(guess < 10) + { + b = a; + while((a < 10) && (fa * fb >= 0)) + { + if(fb <= 0) + { + a = b; + b = a + 1; + if(b > max_bound) + b = max_bound; + fb = f(b); + --count; + if(fb == 0) + return b; + if(a == b) + return b; // can't go any higher! + } + else + { + b = a; + a = BOOST_MATH_GPU_SAFE_MAX(value_type(b - 1), value_type(0)); + if(a < min_bound) + a = min_bound; + fa = f(a); + --count; + if(fa == 0) + return a; + if(a == b) + return a; // We can't go any lower than this! + } + } + } + // + // Try and bracket using a couple of additions first, + // we're assuming that "guess" is likely to be accurate + // to the nearest int or so: + // + else if((adder != 0) && (a + adder != a)) + { + // + // If we're looking for a large result, then bump "adder" up + // by a bit to increase our chances of bracketing the root: + // + //adder = BOOST_MATH_GPU_SAFE_MAX(adder, 0.001f * guess); + if(fa < 0) + { + b = a + adder; + if(b > max_bound) + b = max_bound; + } + else + { + b = BOOST_MATH_GPU_SAFE_MAX(value_type(a - adder), value_type(0)); + if(b < min_bound) + b = min_bound; + } + fb = f(b); + --count; + if(fb == 0) + return b; + if(count && (fa * fb >= 0)) + { + // + // We didn't bracket the root, try + // once more: + // + a = b; + fa = fb; + if(fa < 0) + { + b = a + adder; + if(b > max_bound) + b = max_bound; + } + else + { + b = BOOST_MATH_GPU_SAFE_MAX(value_type(a - adder), value_type(0)); + if(b < min_bound) + b = min_bound; + } + fb = f(b); + --count; + } + if(a > b) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(fa, fb); + } + } + // + // If the root hasn't been bracketed yet, try again + // using the multiplier this time: + // + if((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fa < 0) + { + // + // Zero is to the right of x2, so walk upwards + // until we find it: + // + while(((boost::math::sign)(fb) == (boost::math::sign)(fa)) && (a != b)) + { + if(count == 0) + return policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, policy_type()); // LCOV_EXCL_LINE + a = b; + fa = fb; + b *= multiplier; + if(b > max_bound) + b = max_bound; + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while(((boost::math::sign)(fb) == (boost::math::sign)(fa)) && (a != b)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return 0; + } + if(count == 0) + return policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, policy_type()); // LCOV_EXCL_LINE + b = a; + fb = fa; + a /= multiplier; + if(a < min_bound) + a = min_bound; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + } + max_iter -= count; + if(fa == 0) + return a; + if(fb == 0) + return b; + if(a == b) + return b; // Ran out of bounds trying to bracket - there is no answer! + // + // Adjust bounds so that if we're looking for an integer + // result, then both ends round the same way: + // + adjust_bounds(a, b, tol); + // + // We don't want zero or denorm lower bounds: + // + if(a < tools::min_value()) + a = tools::min_value(); + // + // Go ahead and find the root: + // + boost::math::pair r = toms748_solve(f, a, b, fa, fb, tol, count, policy_type()); + max_iter += count; + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", r.first, policy_type()); // LCOV_EXCL_LINE + } + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + return (r.first + r.second) / 2; +} +// +// Some special routine for rounding up and down: +// We want to check and see if we are very close to an integer, and if so test to see if +// that integer is an exact root of the cdf. We do this because our root finder only +// guarantees to find *a root*, and there can sometimes be many consecutive floating +// point values which are all roots. This is especially true if the target probability +// is very close 1. +// +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type round_to_floor(const Dist& d, typename Dist::value_type result, typename Dist::value_type p, bool c) +{ + BOOST_MATH_STD_USING + typename Dist::value_type cc = ceil(result); + typename Dist::value_type pp = cc <= support(d).second ? c ? cdf(complement(d, cc)) : cdf(d, cc) : 1; + if(pp == p) + result = cc; + else + result = floor(result); + // + // Now find the smallest integer <= result for which we get an exact root: + // + while(result != 0) + { + #ifdef BOOST_MATH_HAS_GPU_SUPPORT + cc = floor(::nextafter(result, -tools::max_value())); + #else + cc = floor(float_prior(result)); + #endif + if(cc < support(d).first) + break; + pp = c ? cdf(complement(d, cc)) : cdf(d, cc); + if(c ? pp > p : pp < p) + break; + result = cc; + } + + return result; +} + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type round_to_ceil(const Dist& d, typename Dist::value_type result, typename Dist::value_type p, bool c) +{ + BOOST_MATH_STD_USING + typename Dist::value_type cc = floor(result); + typename Dist::value_type pp = cc >= support(d).first ? c ? cdf(complement(d, cc)) : cdf(d, cc) : 0; + if(pp == p) + result = cc; + else + result = ceil(result); + // + // Now find the largest integer >= result for which we get an exact root: + // + while(true) + { + #ifdef BOOST_MATH_HAS_GPU_SUPPORT + cc = ceil(::nextafter(result, tools::max_value())); + #else + cc = ceil(float_next(result)); + #endif + if(cc > support(d).second) + break; + pp = c ? cdf(complement(d, cc)) : cdf(d, cc); + if(c ? pp < p : pp > p) + break; + result = cc; + } + + return result; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +// +// Now finally are the public API functions. +// There is one overload for each policy, +// each one is responsible for selecting the correct +// termination condition, and rounding the result +// to an int where required. +// +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + typename Dist::value_type p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + if(p > 0.5) + { + p = 1 - p; + c = !c; + } + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return do_inverse_discrete_quantile( + dist, + p, + c, + guess, + multiplier, + adder, + tools::eps_tolerance(policies::digits()), + max_iter); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // What happens next depends on whether we're looking for an + // upper or lower quantile: + // + if(pp < 0.5f) + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : (value_type)floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); + // else: + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (value_type)ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // What happens next depends on whether we're looking for an + // upper or lower quantile: + // + if(pp < 0.5f) + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); + // else: + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + boost::math::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // Note that we adjust the guess to the nearest half-integer: + // this increase the chances that we will bracket the root + // with two results that both round to the same integer quickly. + // + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 0.5f ? value_type(1.5f) : floor(guess + 0.5f) + 0.5f), + multiplier, + adder, + tools::equal_nearest_integer(), + max_iter) + 0.5f, p, c); +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE + diff --git a/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp b/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp new file mode 100644 index 0000000000000..0d43db16f21ae --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/empirical_cumulative_distribution_function.hpp @@ -0,0 +1,73 @@ +// Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP +#define BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost { namespace math{ + +template +class empirical_cumulative_distribution_function { + using Real = typename RandomAccessContainer::value_type; +public: + empirical_cumulative_distribution_function(RandomAccessContainer && v, bool sorted = false) + { + if (v.size() == 0) { + throw std::domain_error("At least one sample is required to compute an empirical CDF."); + } + m_v = std::move(v); + if (!sorted) { + std::sort(m_v.begin(), m_v.end()); + } + } + + auto operator()(Real x) const { + if constexpr (std::is_integral_v) + { + if (x < m_v[0]) { + return static_cast(0); + } + if (x >= m_v[m_v.size()-1]) { + return static_cast(1); + } + auto it = std::upper_bound(m_v.begin(), m_v.end(), x); + return static_cast(std::distance(m_v.begin(), it))/static_cast(m_v.size()); + } + else + { + if (x < m_v[0]) { + return Real(0); + } + if (x >= m_v[m_v.size()-1]) { + return Real(1); + } + auto it = std::upper_bound(m_v.begin(), m_v.end(), x); + return static_cast(std::distance(m_v.begin(), it))/static_cast(m_v.size()); + } + } + + RandomAccessContainer&& return_data() { + return std::move(m_v); + } + +private: + RandomAccessContainer m_v; +}; + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/distributions/exponential.hpp b/third-party/boost-math/include/boost/math/distributions/exponential.hpp new file mode 100644 index 0000000000000..9d45ac4933097 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/exponential.hpp @@ -0,0 +1,352 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024 +// 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) + +#ifndef BOOST_STATS_EXPONENTIAL_HPP +#define BOOST_STATS_EXPONENTIAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#endif + +namespace boost{ namespace math{ + +namespace detail{ +// +// Error check: +// +template +BOOST_MATH_GPU_ENABLED inline bool verify_lambda(const char* function, RealType l, RealType* presult, const Policy& pol) +{ + if((l <= 0) || !(boost::math::isfinite)(l)) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"lambda\" must be > 0, but was: %1%.", l, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool verify_exp_x(const char* function, RealType x, RealType* presult, const Policy& pol) +{ + if((x < 0) || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error( + function, + "The random variable must be >= 0, but was: %1%.", x, pol); + return false; + } + return true; +} + +} // namespace detail + +template > +class exponential_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit exponential_distribution(RealType l_lambda = 1) + : m_lambda(l_lambda) + { + RealType err; + detail::verify_lambda("boost::math::exponential_distribution<%1%>::exponential_distribution", l_lambda, &err, Policy()); + } // exponential_distribution + + BOOST_MATH_GPU_ENABLED RealType lambda()const { return m_lambda; } + +private: + RealType m_lambda; +}; + +using exponential = exponential_distribution; + +#ifdef __cpp_deduction_guides +template +exponential_distribution(RealType)->exponential_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const exponential_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(static_cast(0), boost::math::numeric_limits::infinity()); // 0 to + infinity. + } + else + { + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // 0 to + max + } +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const exponential_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return boost::math::pair(min_value(), max_value()); + // min_value() to avoid a discontinuity at x = 0. +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(const exponential_distribution<%1%>&, %1%)"; + + RealType lambda = dist.lambda(); + RealType result = 0; + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + // Workaround for VC11/12 bug: + if ((boost::math::isinf)(x)) + return 0; + result = lambda * exp(-lambda * x); + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)"; + + RealType lambda = dist.lambda(); + RealType result = -boost::math::numeric_limits::infinity(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + + result = log(lambda) - lambda * x; + return result; +} // logpdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + result = -boost::math::expm1(-x * lambda, Policy()); + + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + result = boost::math::log1p(-exp(-x * lambda), Policy()); + + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const exponential_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return 0; + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = -boost::math::log1p(-p, Policy()) / lambda; + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = c.dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, c.param, &result, Policy())) + return result; + // Workaround for VC11/12 bug: + if (c.param >= tools::max_value()) + return 0; + result = exp(-c.param * lambda); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = c.dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, c.param, &result, Policy())) + return result; + // Workaround for VC11/12 bug: + if (c.param >= tools::max_value()) + return 0; + result = -c.param * lambda; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = c.dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + + RealType q = c.param; + if(0 == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 1) + return 0; + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = -log(q) / lambda; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const exponential_distribution& dist) +{ + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda("boost::math::mean(const exponential_distribution<%1%>&)", lambda, &result, Policy())) + return result; + return 1 / lambda; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const exponential_distribution& dist) +{ + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda("boost::math::standard_deviation(const exponential_distribution<%1%>&)", lambda, &result, Policy())) + return result; + return 1 / lambda; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const exponential_distribution& /*dist*/) +{ + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const exponential_distribution& dist) +{ + using boost::math::constants::ln_two; + return ln_two() / dist.lambda(); // ln(2) / lambda +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const exponential_distribution& /*dist*/) +{ + return 2; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const exponential_distribution& /*dist*/) +{ + return 9; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const exponential_distribution& /*dist*/) +{ + return 6; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const exponential_distribution& dist) +{ + using std::log; + return 1 - log(dist.lambda()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_EXPONENTIAL_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/extreme_value.hpp b/third-party/boost-math/include/boost/math/distributions/extreme_value.hpp new file mode 100644 index 0000000000000..73454d29d4b85 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/extreme_value.hpp @@ -0,0 +1,392 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_EXTREME_VALUE_HPP +#define BOOST_STATS_EXTREME_VALUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// This is the maximum extreme value distribution, see +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366g.htm +// and http://mathworld.wolfram.com/ExtremeValueDistribution.html +// Also known as a Fisher-Tippett distribution, a log-Weibull +// distribution or a Gumbel distribution. + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost{ namespace math{ + +namespace detail{ +// +// Error check: +// +template +BOOST_MATH_GPU_ENABLED inline bool verify_scale_b(const char* function, RealType b, RealType* presult, const Policy& pol) +{ + if((b <= 0) || !(boost::math::isfinite)(b)) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"b\" must be finite and > 0, but was: %1%.", b, pol); + return false; + } + return true; +} + +} // namespace detail + +template > +class extreme_value_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit extreme_value_distribution(RealType a = 0, RealType b = 1) + : m_a(a), m_b(b) + { + RealType err; + detail::verify_scale_b("boost::math::extreme_value_distribution<%1%>::extreme_value_distribution", b, &err, Policy()); + detail::check_finite("boost::math::extreme_value_distribution<%1%>::extreme_value_distribution", a, &err, Policy()); + } // extreme_value_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const { return m_a; } + BOOST_MATH_GPU_ENABLED RealType scale()const { return m_b; } + +private: + RealType m_a; + RealType m_b; +}; + +using extreme_value = extreme_value_distribution; + +#ifdef __cpp_deduction_guides +template +extreme_value_distribution(RealType)->extreme_value_distribution::type>; +template +extreme_value_distribution(RealType,RealType)->extreme_value_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const extreme_value_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair( + boost::math::numeric_limits::has_infinity ? -boost::math::numeric_limits::infinity() : -max_value(), + boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const extreme_value_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + return 0.0f; + if(0 == detail::check_x(function, x, &result, Policy())) + return result; + RealType e = (a - x) / b; + if(e < tools::log_max_value()) + result = exp(e) * exp(-exp(e)) / b; + // else.... result *must* be zero since exp(e) is infinite... + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logpdf(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = -boost::math::numeric_limits::infinity(); + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + return 0.0f; + if(0 == detail::check_x(function, x, &result, Policy())) + return result; + RealType e = (a - x) / b; + if(e < tools::log_max_value()) + result = log(1/b) + e - exp(e); + // else.... result *must* be zero since exp(e) is infinite... + return result; +} // logpdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(x)) + return x < 0 ? 0.0f : 1.0f; + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x("boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)", x, &result, Policy())) + return result; + + result = exp(-exp((a-x)/b)); + + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(x)) + return x < 0 ? 0.0f : 1.0f; + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x("boost::math::logcdf(const extreme_value_distribution<%1%>&, %1%)", x, &result, Policy())) + return result; + + result = -exp((a-x)/b); + + return result; +} // logcdf + +template +BOOST_MATH_GPU_ENABLED RealType quantile(const extreme_value_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return -policies::raise_overflow_error(function, 0, Policy()); + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = a - log(-log(p)) * b; + + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(c.param)) + return c.param < 0 ? 1.0f : 0.0f; + RealType a = c.dist.location(); + RealType b = c.dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x(function, c.param, &result, Policy())) + return result; + + result = -boost::math::expm1(-exp((a-c.param)/b), Policy()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(c.param)) + return c.param < 0 ? 1.0f : 0.0f; + RealType a = c.dist.location(); + RealType b = c.dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x(function, c.param, &result, Policy())) + return result; + + result = log1p(-exp(-exp((a-c.param)/b)), Policy()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = c.dist.location(); + RealType b = c.dist.scale(); + RealType q = c.param; + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + if(q == 1) + return -policies::raise_overflow_error(function, 0, Policy()); + + result = a - log(-boost::math::log1p(-q, Policy())) * b; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const extreme_value_distribution& dist) +{ + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b("boost::math::mean(const extreme_value_distribution<%1%>&)", b, &result, Policy())) + return result; + if (0 == detail::check_finite("boost::math::mean(const extreme_value_distribution<%1%>&)", a, &result, Policy())) + return result; + return a + constants::euler() * b; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const extreme_value_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b("boost::math::standard_deviation(const extreme_value_distribution<%1%>&)", b, &result, Policy())) + return result; + if(0 == detail::check_finite("boost::math::standard_deviation(const extreme_value_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + return constants::pi() * b / sqrt(static_cast(6)); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const extreme_value_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const extreme_value_distribution& dist) +{ + using constants::ln_ln_two; + return dist.location() - dist.scale() * ln_ln_two(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + return static_cast(1.1395470994046486574927930193898461120875997958366L); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const extreme_value_distribution& /*dist*/) +{ + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + return RealType(27) / 5; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const extreme_value_distribution& /*dist*/) +{ + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + return RealType(12) / 5; +} + + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_EXTREME_VALUE_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/find_location.hpp b/third-party/boost-math/include/boost/math/distributions/find_location.hpp new file mode 100644 index 0000000000000..33c2e64b622d4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/find_location.hpp @@ -0,0 +1,140 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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) + +#ifndef BOOST_STATS_FIND_LOCATION_HPP +#define BOOST_STATS_FIND_LOCATION_HPP + +#include // for all distribution signatures. +#include +#include +#include +#include +#include +// using boost::math::policies::policy; +// using boost::math::complement; // will be needed by users who want complement, +// but NOT placed here to avoid putting it in global scope. + +namespace boost +{ + namespace math + { + // Function to find location of random variable z + // to give probability p (given scale) + // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular), + // enforced by static_assert below. + + template + inline + typename Dist::value_type find_location( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type scale, // scale parameter, for example, normal standard deviation. + const Policy& pol + ) + { + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_location&, %1%)"; + + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol); + } + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, pol); + } + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, pol); + } + + //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) " + // << quantile(Dist(), p) << ", quan * scale " << quantile(Dist(), p) * scale << endl; + return z - (quantile(Dist(), p) * scale); + } // find_location + + template + inline // with default policy. + typename Dist::value_type find_location( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type scale) // scale parameter, for example, normal standard deviation. + { // Forward to find_location with default policy. + return (find_location(z, p, scale, policies::policy<>())); + } // find_location + + // So the user can start from the complement q = (1 - p) of the probability p, + // for example, l = find_location(complement(z, q, sd)); + + template + inline typename Dist::value_type find_location( // Default policy. + complemented3_type const& c) + { + static const char* function = "boost::math::find_location&, %1%)"; + + typename Dist::value_type p = c.param1; + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, policies::policy<>()); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, policies::policy<>()); + } + typename Dist::value_type scale = c.param2; + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, policies::policy<>()); + } + // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; + return z - quantile(Dist(), p) * scale; + } // find_location complement + + + template + inline typename Dist::value_type find_location( // Explicit policy. + complemented4_type const& c) + { + static const char* function = "boost::math::find_location&, %1%)"; + + typename Dist::value_type p = c.param1; + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, c.param3); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, c.param3); + } + typename Dist::value_type scale = c.param2; + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, c.param3); + } + // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; + return z - quantile(Dist(), p) * scale; + } // find_location complement + + } // namespace boost +} // namespace math + +#endif // BOOST_STATS_FIND_LOCATION_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/find_scale.hpp b/third-party/boost-math/include/boost/math/distributions/find_scale.hpp new file mode 100644 index 0000000000000..cd08ce95a216b --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/find_scale.hpp @@ -0,0 +1,200 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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) + +#ifndef BOOST_STATS_FIND_SCALE_HPP +#define BOOST_STATS_FIND_SCALE_HPP + +#include // for all distribution signatures. +#include +#include +// using boost::math::policies::policy; +#include +#include +#include +#include +// using boost::math::complement; // will be needed by users who want complement, +// but NOT placed here to avoid putting it in global scope. + +namespace boost +{ + namespace math + { + // Function to find location of random variable z + // to give probability p (given scale) + // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular), + // distributions that have scale. + // BOOST_STATIC_ASSERTs, see below, are used to enforce this. + + template + inline + typename Dist::value_type find_scale( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable weight z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type location, // location parameter, for example, normal distribution mean. + const Policy& pol + ) + { + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(%1%, %1%, %1%, Policy)"; + + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol); + } + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, pol); + } + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, pol); + } + + //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) " + //<< quantile(Dist(), p) << ", z - mean " << z - location + //<<", sd " << (z - location) / quantile(Dist(), p) << endl; + + //quantile(N01, 0.001) -3.09023 + //quantile(N01, 0.01) -2.32635 + //quantile(N01, 0.05) -1.64485 + //quantile(N01, 0.333333) -0.430728 + //quantile(N01, 0.5) 0 + //quantile(N01, 0.666667) 0.430728 + //quantile(N01, 0.9) 1.28155 + //quantile(N01, 0.95) 1.64485 + //quantile(N01, 0.99) 2.32635 + //quantile(N01, 0.999) 3.09023 + + typename Dist::value_type result = + (z - location) // difference between desired x and current location. + / quantile(Dist(), p); // standard distribution. + + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, "Computed scale (%1%) is <= 0!" " Was the complement intended?", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } // template find_scale + + template + inline // with default policy. + typename Dist::value_type find_scale( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type location) // location parameter, for example, mean. + { // Forward to find_scale using the default policy. + return (find_scale(z, p, location, policies::policy<>())); + } // find_scale + + template + inline typename Dist::value_type find_scale( + complemented4_type const& c) + { + //cout << "cparam1 q " << c.param1 // q + // << ", c.dist z " << c.dist // z + // << ", c.param2 l " << c.param2 // l + // << ", quantile (Dist(), c.param1 = q) " + // << quantile(Dist(), c.param1) //q + // << endl; + + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(complement(%1%, %1%, %1%, Policy))"; + + // Checks on arguments, as not complemented version, + // Explicit policy. + typename Dist::value_type q = c.param1; + if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, c.param3); + } + typename Dist::value_type location = c.param2; + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, c.param3); + } + + typename Dist::value_type result = + (c.dist - c.param2) // difference between desired x and current location. + / quantile(complement(Dist(), c.param1)); + // ( z - location) / (quantile(complement(Dist(), q)) + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, "Computed scale (%1%) is <= 0!" " Was the complement intended?", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } // template typename Dist::value_type find_scale + + // So the user can start from the complement q = (1 - p) of the probability p, + // for example, s = find_scale(complement(z, q, l)); + + template + inline typename Dist::value_type find_scale( + complemented3_type const& c) + { + //cout << "cparam1 q " << c.param1 // q + // << ", c.dist z " << c.dist // z + // << ", c.param2 l " << c.param2 // l + // << ", quantile (Dist(), c.param1 = q) " + // << quantile(Dist(), c.param1) //q + // << endl; + + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(complement(%1%, %1%, %1%, Policy))"; + + // Checks on arguments, as not complemented version, + // default policy policies::policy<>(). + typename Dist::value_type q = c.param1; + if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>()); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>()); + } + typename Dist::value_type location = c.param2; + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>()); + } + + typename Dist::value_type result = + (z - location) // difference between desired x and current location. + / quantile(complement(Dist(), q)); + // ( z - location) / (quantile(complement(Dist(), q)) + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, "Computed scale (%1%) is <= 0!" " Was the complement intended?", // LCOV_EXCL_LINE + result, policies::policy<>()); // This is only the default policy - also Want a version with Policy here. LCOV_EXCL_LINE + } + return result; + } // template typename Dist::value_type find_scale + + } // namespace boost +} // namespace math + +#endif // BOOST_STATS_FIND_SCALE_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/fisher_f.hpp b/third-party/boost-math/include/boost/math/distributions/fisher_f.hpp new file mode 100644 index 0000000000000..56b288d88e018 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/fisher_f.hpp @@ -0,0 +1,393 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP +#define BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP + +#include +#include +#include +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include + +namespace boost{ namespace math{ + +template > +class fisher_f_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED fisher_f_distribution(const RealType& i, const RealType& j) : m_df1(i), m_df2(j) + { + constexpr auto function = "fisher_f_distribution<%1%>::fisher_f_distribution"; + RealType result; + detail::check_df( + function, m_df1, &result, Policy()); + detail::check_df( + function, m_df2, &result, Policy()); + } // fisher_f_distribution + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom1()const + { + return m_df1; + } + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom2()const + { + return m_df2; + } + +private: + // + // Data members: + // + RealType m_df1; // degrees of freedom are a real number. + RealType m_df2; // degrees of freedom are a real number. +}; + +typedef fisher_f_distribution fisher_f; + +#ifdef __cpp_deduction_guides +template +fisher_f_distribution(RealType,RealType)->fisher_f_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const fisher_f_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const fisher_f_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED RealType pdf(const fisher_f_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + constexpr auto function = "boost::math::pdf(fisher_f_distribution<%1%> const&, %1%)"; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()))) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + if(x == 0) + { + // special cases: + if(df1 < 2) + return policies::raise_overflow_error( + function, 0, Policy()); + else if(df1 == 2) + return 1; + else + return 0; + } + + // + // You reach this formula by direct differentiation of the + // cdf expressed in terms of the incomplete beta. + // + // There are two versions so we don't pass a value of z + // that is very close to 1 to ibeta_derivative: for some values + // of df1 and df2, all the change takes place in this area. + // + RealType v1x = df1 * x; + RealType result; + if(v1x > df2) + { + result = (df2 * df1) / ((df2 + v1x) * (df2 + v1x)); + result *= ibeta_derivative(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()); + } + else + { + result = df2 + df1 * x; + result = (result * df1 - x * df1 * df1) / (result * result); + result *= ibeta_derivative(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); + } + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const fisher_f_distribution& dist, const RealType& x) +{ + constexpr auto function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType v1x = df1 * x; + // + // There are two equivalent formulas used here, the aim is + // to prevent the final argument to the incomplete beta + // from being too close to 1: for some values of df1 and df2 + // the rate of change can be arbitrarily large in this area, + // whilst the value we're passing will have lost information + // content as a result of being 0.999999something. Better + // to switch things around so we're passing 1-z instead. + // + return v1x > df2 + ? boost::math::ibetac(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()) + : boost::math::ibeta(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const fisher_f_distribution& dist, const RealType& p) +{ + constexpr auto function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy()))) + return error_result; + + // With optimizations turned on, gcc wrongly warns about y being used + // uninitialized unless we initialize it to something: + RealType x, y(0); + + x = boost::math::ibeta_inv(df1 / 2, df2 / 2, p, &y, Policy()); + + return df2 * x / (df1 * y); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + constexpr auto function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = c.dist.degrees_of_freedom1(); + RealType df2 = c.dist.degrees_of_freedom2(); + RealType x = c.param; + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType v1x = df1 * x; + // + // There are two equivalent formulas used here, the aim is + // to prevent the final argument to the incomplete beta + // from being too close to 1: for some values of df1 and df2 + // the rate of change can be arbitrarily large in this area, + // whilst the value we're passing will have lost information + // content as a result of being 0.999999something. Better + // to switch things around so we're passing 1-z instead. + // + return v1x > df2 + ? boost::math::ibeta(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()) + : boost::math::ibetac(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + constexpr auto function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = c.dist.degrees_of_freedom1(); + RealType df2 = c.dist.degrees_of_freedom2(); + RealType p = c.param; + // Error check: + RealType error_result = 0; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy()))) + return error_result; + + RealType x, y; + + x = boost::math::ibetac_inv(df1 / 2, df2 / 2, p, &y, Policy()); + + return df2 * x / (df1 * y); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const fisher_f_distribution& dist) +{ // Mean of F distribution = v. + constexpr auto function = "boost::math::mean(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 2) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 2 in order for the distribution to have a mean.", df2, Policy()); + } + return df2 / (df2 - 2); +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const fisher_f_distribution& dist) +{ // Variance of F distribution. + constexpr auto function = "boost::math::variance(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 4) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 4 in order for the distribution to have a valid variance.", df2, Policy()); + } + return 2 * df2 * df2 * (df1 + df2 - 2) / (df1 * (df2 - 2) * (df2 - 2) * (df2 - 4)); +} // variance + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const fisher_f_distribution& dist) +{ + constexpr auto function = "boost::math::mode(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df1 <= 2) + { + return policies::raise_domain_error( + function, "First degree of freedom was %1% but must be > 2 in order for the distribution to have a mode.", df1, Policy()); + } + return df2 * (df1 - 2) / (df1 * (df2 + 2)); +} + +//template +//inline RealType median(const fisher_f_distribution& dist) +//{ // Median of Fisher F distribution is not defined. +// return tools::domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", boost::math::numeric_limits::quiet_NaN()); +// } // median + +// Now implemented via quantile(half) in derived accessors. + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const fisher_f_distribution& dist) +{ + constexpr auto function = "boost::math::skewness(fisher_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING // ADL of std names + // See http://mathworld.wolfram.com/F-Distribution.html + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 6) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 6 in order for the distribution to have a skewness.", df2, Policy()); + } + return 2 * (df2 + 2 * df1 - 2) * sqrt((2 * df2 - 8) / (df1 * (df2 + df1 - 2))) / (df2 - 6); +} + +template +BOOST_MATH_GPU_ENABLED RealType kurtosis_excess(const fisher_f_distribution& dist); + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const fisher_f_distribution& dist) +{ + return 3 + kurtosis_excess(dist); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const fisher_f_distribution& dist) +{ + constexpr auto function = "boost::math::kurtosis_excess(fisher_f_distribution<%1%> const&)"; + // See http://mathworld.wolfram.com/F-Distribution.html + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 8) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 8 in order for the distribution to have a kurtosis.", df2, Policy()); + } + RealType df2_2 = df2 * df2; + RealType df1_2 = df1 * df1; + RealType n = -16 + 20 * df2 - 8 * df2_2 + df2_2 * df2 + 44 * df1 - 32 * df2 * df1 + 5 * df2_2 * df1 - 22 * df1_2 + 5 * df2 * df1_2; + n *= 12; + RealType d = df1 * (df2 - 6) * (df2 - 8) * (df1 + df2 - 2); + return n / d; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/fwd.hpp b/third-party/boost-math/include/boost/math/distributions/fwd.hpp new file mode 100644 index 0000000000000..c231be418d4bb --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/fwd.hpp @@ -0,0 +1,171 @@ +// fwd.hpp Forward declarations of Boost.Math distributions. + +// Copyright Paul A. Bristow 2007, 2010, 2012, 2014. +// Copyright John Maddock 2007. + +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_FWD_HPP +#define BOOST_MATH_DISTRIBUTIONS_FWD_HPP + +namespace boost{ namespace math{ + +template +class arcsine_distribution; + +template +class bernoulli_distribution; + +template +class beta_distribution; + +template +class binomial_distribution; + +template +class cauchy_distribution; + +template +class chi_squared_distribution; + +template +class exponential_distribution; + +template +class extreme_value_distribution; + +template +class fisher_f_distribution; + +template +class gamma_distribution; + +template +class geometric_distribution; + +template +class hyperexponential_distribution; + +template +class hypergeometric_distribution; + +template +class inverse_chi_squared_distribution; + +template +class inverse_gamma_distribution; + +template +class inverse_gaussian_distribution; + +template +class kolmogorov_smirnov_distribution; + +template +class landau_distribution; + +template +class mapairy_distribution; + +template +class holtsmark_distribution; + +template +class saspoint5_distribution; + +template +class laplace_distribution; + +template +class logistic_distribution; + +template +class lognormal_distribution; + +template +class negative_binomial_distribution; + +template +class non_central_beta_distribution; + +template +class non_central_chi_squared_distribution; + +template +class non_central_f_distribution; + +template +class non_central_t_distribution; + +template +class normal_distribution; + +template +class pareto_distribution; + +template +class poisson_distribution; + +template +class rayleigh_distribution; + +template +class skew_normal_distribution; + +template +class students_t_distribution; + +template +class triangular_distribution; + +template +class uniform_distribution; + +template +class weibull_distribution; + +}} // namespaces + +#define BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)\ + typedef boost::math::arcsine_distribution arcsine;\ + typedef boost::math::bernoulli_distribution bernoulli;\ + typedef boost::math::beta_distribution beta;\ + typedef boost::math::binomial_distribution binomial;\ + typedef boost::math::cauchy_distribution cauchy;\ + typedef boost::math::chi_squared_distribution chi_squared;\ + typedef boost::math::exponential_distribution exponential;\ + typedef boost::math::extreme_value_distribution extreme_value;\ + typedef boost::math::fisher_f_distribution fisher_f;\ + typedef boost::math::gamma_distribution gamma;\ + typedef boost::math::geometric_distribution geometric;\ + typedef boost::math::hypergeometric_distribution hypergeometric;\ + typedef boost::math::kolmogorov_smirnov_distribution kolmogorov_smirnov;\ + typedef boost::math::inverse_chi_squared_distribution inverse_chi_squared;\ + typedef boost::math::inverse_gaussian_distribution inverse_gaussian;\ + typedef boost::math::inverse_gamma_distribution inverse_gamma;\ + typedef boost::math::landau_distribution landau;\ + typedef boost::math::mapairy_distribution mapairy;\ + typedef boost::math::holtsmark_distribution holtsmark;\ + typedef boost::math::saspoint5_distribution saspoint5;\ + typedef boost::math::laplace_distribution laplace;\ + typedef boost::math::logistic_distribution logistic;\ + typedef boost::math::lognormal_distribution lognormal;\ + typedef boost::math::negative_binomial_distribution negative_binomial;\ + typedef boost::math::non_central_beta_distribution non_central_beta;\ + typedef boost::math::non_central_chi_squared_distribution non_central_chi_squared;\ + typedef boost::math::non_central_f_distribution non_central_f;\ + typedef boost::math::non_central_t_distribution non_central_t;\ + typedef boost::math::normal_distribution normal;\ + typedef boost::math::pareto_distribution pareto;\ + typedef boost::math::poisson_distribution poisson;\ + typedef boost::math::rayleigh_distribution rayleigh;\ + typedef boost::math::skew_normal_distribution skew_normal;\ + typedef boost::math::students_t_distribution students_t;\ + typedef boost::math::triangular_distribution triangular;\ + typedef boost::math::uniform_distribution uniform;\ + typedef boost::math::weibull_distribution weibull; + +#endif // BOOST_MATH_DISTRIBUTIONS_FWD_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/gamma.hpp b/third-party/boost-math/include/boost/math/distributions/gamma.hpp new file mode 100644 index 0000000000000..5176f906d8f38 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/gamma.hpp @@ -0,0 +1,396 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_GAMMA_HPP +#define BOOST_STATS_GAMMA_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm +// http://mathworld.wolfram.com/GammaDistribution.html +// http://en.wikipedia.org/wiki/Gamma_distribution + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ +namespace detail +{ + +template +BOOST_MATH_GPU_ENABLED inline bool check_gamma_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) +{ + if((shape <= 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0 !", shape, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_gamma_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_gamma( + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) && check_gamma_shape(function, shape, result, pol); +} + +} // namespace detail + +template > +class gamma_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit gamma_distribution(RealType l_shape, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_gamma("boost::math::gamma_distribution<%1%>::gamma_distribution", l_scale, l_shape, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType shape()const + { + return m_shape; + } + + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +// NO typedef because of clash with name of gamma function. + +#ifdef __cpp_deduction_guides +template +gamma_distribution(RealType)->gamma_distribution::type>; +template +gamma_distribution(RealType,RealType)->gamma_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const gamma_distribution& /* dist */) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const gamma_distribution& /* dist */) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return boost::math::pair(min_value(), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + return 0; + } + result = gamma_p_derivative(shape, x / scale, Policy()) / scale; + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::lgamma; + + constexpr auto function = "boost::math::logpdf(const gamma_distribution<%1%>&, %1%)"; + + RealType k = dist.shape(); + RealType theta = dist.scale(); + + RealType result = -boost::math::numeric_limits::infinity(); + if(false == detail::check_gamma(function, theta, k, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + return boost::math::numeric_limits::quiet_NaN(); + } + + result = -k*log(theta) + (k-1)*log(x) - lgamma(k) - (x/theta); + + return result; +} // logpdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + result = boost::math::gamma_p(shape, x / scale, Policy()); + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const gamma_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = gamma_p_inv(shape, p, Policy()) * scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, c.param, &result, Policy())) + return result; + + result = gamma_q(shape, c.param / scale, Policy()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = gamma_q_inv(shape, q, Policy()) * scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::mean(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = shape * scale; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::variance(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = shape * scale * scale; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::mode(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + if(shape < 1) + return policies::raise_domain_error( + function, + "The mode of the gamma distribution is only defined for values of the shape parameter >= 1, but got %1%.", + shape, Policy()); + + result = (shape - 1) * scale; + return result; +} + +//template +//inline RealType median(const gamma_distribution& dist) +//{ // Rely on default definition in derived accessors. +//} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::skewness(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = 2 / sqrt(shape); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::kurtosis_excess(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = 6 / shape; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const gamma_distribution& dist) +{ + return kurtosis_excess(dist) + 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING + + RealType k = dist.shape(); + RealType theta = dist.scale(); + return k + log(theta) + boost::math::lgamma(k) + (1-k)*digamma(k); +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_GAMMA_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/geometric.hpp b/third-party/boost-math/include/boost/math/distributions/geometric.hpp new file mode 100644 index 0000000000000..0a7b383c24f81 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/geometric.hpp @@ -0,0 +1,571 @@ +// boost\math\distributions\geometric.hpp + +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. + +// 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) + +// geometric distribution is a discrete probability distribution. +// It expresses the probability distribution of the number (k) of +// events, occurrences, failures or arrivals before the first success. +// supported on the set {0, 1, 2, 3...} + +// Note that the set includes zero (unlike some definitions that start at one). + +// The random variate k is the number of events, occurrences or arrivals. +// k argument may be integral, signed, or unsigned, or floating point. +// If necessary, it has already been promoted from an integral type. + +// Note that the geometric distribution +// (like others including the binomial, geometric & Bernoulli) +// is strictly defined as a discrete function: +// only integral values of k are envisaged. +// However because the method of calculation uses a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +// See http://en.wikipedia.org/wiki/geometric_distribution +// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html +// http://mathworld.wolfram.com/GeometricDistribution.html + +#ifndef BOOST_MATH_SPECIAL_GEOMETRIC_HPP +#define BOOST_MATH_SPECIAL_GEOMETRIC_HPP + +#include +#include +#include +#include +#include // for ibeta(a, b, x) == Ix(a, b). +#include // complement. +#include // error checks domain_error & logic_error. +#include // isnan. +#include // for root finding. +#include +#include + +#if defined (BOOST_MSVC) +# pragma warning(push) +// This believed not now necessary, so commented out. +//# pragma warning(disable: 4702) // unreachable code. +// in domain_error_imp in error_handling. +#endif + +namespace boost +{ + namespace math + { + namespace geometric_detail + { + // Common error checking routines for geometric distribution function: + template + BOOST_MATH_GPU_ENABLED inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) ) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction(function, p, result, pol); + } + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, p, result, pol) == false) + { + return false; + } + if( !(boost::math::isfinite)(k) || (k < 0) ) + { // Check k failures. + *result = policies::raise_domain_error( + function, + "Number of failures argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // Check_dist_and_k + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + { + return false; + } + return true; + } // check_dist_and_prob + } // namespace geometric_detail + + template > + class geometric_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED geometric_distribution(RealType p) : m_p(p) + { // Constructor stores success_fraction p. + RealType result; + geometric_detail::check_dist( + "geometric_distribution<%1%>::geometric_distribution", + m_p, // Check success_fraction 0 <= p <= 1. + &result, Policy()); + } // geometric_distribution constructor. + + // Private data getter class member functions. + BOOST_MATH_GPU_ENABLED RealType success_fraction() const + { // Probability of success as fraction in range 0 to 1. + return m_p; + } + BOOST_MATH_GPU_ENABLED RealType successes() const + { // Total number of successes r = 1 (for compatibility with negative binomial?). + return 1; + } + + // Parameter estimation. + // (These are copies of negative_binomial distribution with successes = 1). + BOOST_MATH_GPU_ENABLED static RealType find_lower_bound_on_p( + RealType trials, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + constexpr auto function = "boost::math::geometric<%1%>::find_lower_bound_on_p"; + RealType result = 0; // of error checks. + RealType successes = 1; + RealType failures = trials - successes; + if(false == detail::check_probability(function, alpha, &result, Policy()) + && geometric_detail::check_dist_and_k( + function, RealType(0), failures, &result, Policy())) + { + return result; + } + // Use complement ibeta_inv function for lower bound. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibeta_inv(successes, failures + 1, alpha, static_cast(nullptr), Policy()); + } // find_lower_bound_on_p + + BOOST_MATH_GPU_ENABLED static RealType find_upper_bound_on_p( + RealType trials, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + constexpr auto function = "boost::math::geometric<%1%>::find_upper_bound_on_p"; + RealType result = 0; // of error checks. + RealType successes = 1; + RealType failures = trials - successes; + if(false == geometric_detail::check_dist_and_k( + function, RealType(0), failures, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + if(failures == 0) + { + return 1; + }// Use complement ibetac_inv function for upper bound. + // Note adjusted failures value: *not* failures+1 as usual. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. Krishnamoorthy + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibetac_inv(successes, failures, alpha, static_cast(nullptr), Policy()); + } // find_upper_bound_on_p + + // Estimate number of trials : + // "How many trials do I need to be P% sure of seeing k or fewer failures?" + + BOOST_MATH_GPU_ENABLED static RealType find_minimum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + constexpr auto function = "boost::math::geometric<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_failures + + BOOST_MATH_GPU_ENABLED static RealType find_maximum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + constexpr auto function = "boost::math::geometric<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_trials complemented + + private: + //RealType m_r; // successes fixed at unity. + RealType m_p; // success_fraction + }; // template class geometric_distribution + + typedef geometric_distribution geometric; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + geometric_distribution(RealType)->geometric_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const geometric_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // max_integer? + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const geometric_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // max_integer? + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const geometric_distribution& dist) + { // Mean of geometric distribution = (1-p)/p. + return (1 - dist.success_fraction() ) / dist.success_fraction(); + } // mean + + // median implemented via quantile(half) in derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const geometric_distribution&) + { // Mode of geometric distribution = zero. + BOOST_MATH_STD_USING // ADL of std functions. + return 0; + } // mode + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const geometric_distribution& dist) + { // Variance of Binomial distribution = (1-p) / p^2. + return (1 - dist.success_fraction()) + / (dist.success_fraction() * dist.success_fraction()); + } // variance + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const geometric_distribution& dist) + { // skewness of geometric distribution = 2-p / (sqrt(r(1-p)) + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + return (2 - p) / sqrt(1 - p); + } // skewness + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const geometric_distribution& dist) + { // kurtosis of geometric distribution + // http://en.wikipedia.org/wiki/geometric is kurtosis_excess so add 3 + RealType p = dist.success_fraction(); + return 3 + (p*p - 6*p + 6) / (1 - p); + } // kurtosis + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const geometric_distribution& dist) + { // kurtosis excess of geometric distribution + // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess + RealType p = dist.success_fraction(); + return (p*p - 6*p + 6) / (1 - p); + } // kurtosis_excess + + // RealType standard_deviation(const geometric_distribution& dist) + // standard_deviation provided by derived accessors. + // RealType hazard(const geometric_distribution& dist) + // hazard of geometric distribution provided by derived accessors. + // RealType chf(const geometric_distribution& dist) + // chf of geometric distribution provided by derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const geometric_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // For ADL of math functions. + constexpr auto function = "boost::math::pdf(const geometric_distribution<%1%>&, %1%)"; + + RealType p = dist.success_fraction(); + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return p; // success_fraction + } + RealType q = 1 - p; // Inaccurate for small p? + // So try to avoid inaccuracy for large or small p. + // but has little effect > last significant bit. + //cout << "p * pow(q, k) " << result << endl; // seems best whatever p + //cout << "exp(p * k * log1p(-p)) " << p * exp(k * log1p(-p)) << endl; + //if (p < 0.5) + //{ + // result = p * pow(q, k); + //} + //else + //{ + // result = p * exp(k * log1p(-p)); + //} + result = p * pow(q, k); + return result; + } // geometric_pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const geometric_distribution& dist, const RealType& k) + { // Cumulative Distribution Function of geometric. + constexpr auto function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)"; + + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + if(k == 0) + { + return p; // success_fraction + } + //RealType q = 1 - p; // Bad for small p + //RealType probability = 1 - std::pow(q, k+1); + + RealType z = boost::math::log1p(-p, Policy()) * (k + 1); + RealType probability = -boost::math::expm1(z, Policy()); + + return probability; + } // cdf Cumulative Distribution Function geometric. + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const geometric_distribution& dist, const RealType& k) + { // Cumulative Distribution Function of geometric. + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::logcdf(const geometric_distribution<%1%>&, %1%)"; + + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + if(k == 0) + { + return log(p); // success_fraction + } + //RealType q = 1 - p; // Bad for small p + //RealType probability = 1 - std::pow(q, k+1); + + RealType z = boost::math::log1p(-p, Policy()) * (k + 1); + return log1p(-exp(z), Policy()); + } // logcdf Cumulative Distribution Function geometric. + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function geometric. + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)"; + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType const& k = c.param; + geometric_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + RealType z = boost::math::log1p(-p, Policy()) * (k+1); + RealType probability = exp(z); + return probability; + } // cdf Complemented Cumulative Distribution Function geometric. + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function geometric. + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::logcdf(const geometric_distribution<%1%>&, %1%)"; + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType const& k = c.param; + geometric_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + + return boost::math::log1p(-p, Policy()) * (k+1); + } // logcdf Complemented Cumulative Distribution Function geometric. + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const geometric_distribution& dist, const RealType& x) + { // Quantile, percentile/100 or Percent Point geometric function. + // Return the number of expected failures k for a given probability p. + + // Inverse cumulative Distribution Function or Quantile (percentile / 100) of geometric Probability. + // k argument may be integral, signed, or unsigned, or floating point. + + constexpr auto function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING // ADL of std functions. + + RealType success_fraction = dist.success_fraction(); + // Check dist and x. + RealType result = 0; + if(false == geometric_detail::check_dist_and_prob + (function, success_fraction, x, &result, Policy())) + { + return result; + } + + // Special cases. + if (x == 1) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument is 1, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (x == 0) + { // No failures are expected if P = 0. + return 0; // Total trials will be just dist.successes. + } + // if (P <= pow(dist.success_fraction(), 1)) + if (x <= success_fraction) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + if (x == 1) + { + return 0; + } + + // log(1-x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small + result = boost::math::log1p(-x, Policy()) / boost::math::log1p(-success_fraction, Policy()) - 1; + // Subtract a few epsilons here too? + // to make sure it doesn't slip over, so ceil would be one too many. + return result; + } // RealType quantile(const geometric_distribution dist, p) + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point Binomial function. + // Return the number of expected failures k for a given + // complement of the probability Q = 1 - P. + constexpr auto function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING + // Error checks: + RealType x = c.param; + const geometric_distribution& dist = c.dist; + RealType success_fraction = dist.success_fraction(); + RealType result = 0; + if(false == geometric_detail::check_dist_and_prob( + function, + success_fraction, + x, + &result, Policy())) + { + return result; + } + + // Special cases: + if(x == 1) + { // There may actually be no answer to this question, + // since the probability of zero failures may be non-zero, + return 0; // but zero is the best we can do: + } + if (-x <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy())) + { // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 0; // + } + if(x == 0) + { // Probability 1 - Q == 1 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument complement is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + // log(x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small + result = log(x) / boost::math::log1p(-success_fraction, Policy()) - 1; + return result; + + } // quantile complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_SPECIAL_GEOMETRIC_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/holtsmark.hpp b/third-party/boost-math/include/boost/math/distributions/holtsmark.hpp new file mode 100644 index 0000000000000..04f5484f4eded --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/holtsmark.hpp @@ -0,0 +1,2518 @@ +// Copyright Takuma Yoshimura 2024. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_HOLTSMARK_HPP +#define BOOST_STATS_HOLTSMARK_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#include +#endif + +namespace boost { namespace math { +template +class holtsmark_distribution; + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 4.7894e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.87352751452164445024e-1), + static_cast(1.18577398160636011811e-3), + static_cast(-2.16526599226820153260e-2), + static_cast(2.06462093371223113592e-3), + static_cast(2.43382128013710116747e-3), + static_cast(-2.15930711444603559520e-4), + static_cast(-1.04197836740809694657e-4), + static_cast(1.74679078247026597959e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(4.12654472808214997252e-3), + static_cast(2.93891863033354755743e-1), + static_cast(8.70867222155141724171e-3), + static_cast(3.15027515421842640745e-2), + static_cast(2.11141832312672190669e-3), + static_cast(1.23545521355569424975e-3), + static_cast(1.58181113865348637475e-4), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 3.0925e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.02038159607840130389e-1), + static_cast(-1.20368541260123112191e-2), + static_cast(-3.19235497414059987151e-3), + static_cast(8.88546222140257289852e-3), + static_cast(-5.37287599824602316660e-4), + static_cast(-2.39059149972922243276e-4), + static_cast(9.19551014849109417931e-5), + static_cast(-8.45210544648986348854e-6), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(6.11634701234079515138e-1), + static_cast(4.39922162828115412952e-1), + static_cast(1.73609068791154078128e-1), + static_cast(6.15831808473403962054e-2), + static_cast(1.64364949550314788638e-2), + static_cast(2.94399615562137394932e-3), + static_cast(4.99662797033514776061e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.4499e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(8.45396231261375200568e-2), + static_cast(-9.15509628797205847643e-3), + static_cast(1.82052933284907579374e-2), + static_cast(-2.44157914076021125182e-4), + static_cast(8.40871885414177705035e-4), + static_cast(7.26592615882060553326e-5), + static_cast(-1.87768359214600016641e-6), + static_cast(1.65716961206268668529e-6), + static_cast(-1.73979640146948858436e-7), + static_cast(7.24351142163396584236e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(8.88099527896838765666e-1), + static_cast(6.53896948546877341992e-1), + static_cast(2.96296982585381844864e-1), + static_cast(1.14107585229341489833e-1), + static_cast(3.08914671331207488189e-2), + static_cast(7.03139384769200902107e-3), + static_cast(1.01201814277918577790e-3), + static_cast(1.12200113270398674535e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 6.5259e-17 + BOOST_MATH_STATIC const RealType P[11] = { + static_cast(1.36729417918039395222e-2), + static_cast(1.19749117683408419115e-2), + static_cast(6.26780921592414207398e-3), + static_cast(1.84846137440857608948e-3), + static_cast(3.39307829797262466829e-4), + static_cast(2.73606960463362090866e-5), + static_cast(-1.14419838471713498717e-7), + static_cast(1.64552336875610576993e-8), + static_cast(-7.95501797873739398143e-10), + static_cast(2.55422885338760255125e-11), + static_cast(-4.12196487201928768038e-13), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(1.61334003864149486454e0), + static_cast(1.28348868912975898501e0), + static_cast(6.36594545291321210154e-1), + static_cast(2.11478937436277242988e-1), + static_cast(4.71550897200311391579e-2), + static_cast(6.64679677197059316835e-3), + static_cast(4.93706832858615742810e-4), + static_cast(9.26919465059204396228e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 3.5084e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.90649774685568282390e-3), + static_cast(7.43708409389806210196e-4), + static_cast(9.53777347766128955847e-5), + static_cast(3.79800193823252979170e-6), + static_cast(2.84836656088572745575e-8), + static_cast(-1.22715411241721187620e-10), + static_cast(8.56789906419220801109e-13), + static_cast(-4.17784858891714869163e-15), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(7.29383849235788831455e-1), + static_cast(2.16287201867831015266e-1), + static_cast(3.28789040872705709070e-2), + static_cast(2.64660789801664804789e-3), + static_cast(1.03662724048874906931e-4), + static_cast(1.47658125632566407978e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 1.4660e-19 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(3.07231582988207590928e-4), + static_cast(5.16108848485823513911e-5), + static_cast(3.05776014220862257678e-6), + static_cast(7.64787444325088143218e-8), + static_cast(7.40426355029090813961e-10), + static_cast(1.57451122102115077046e-12), + static_cast(-2.14505675750572782093e-15), + static_cast(5.11204601013038698192e-18), + static_cast(-9.00826023095223871551e-21), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(3.28966789835486457746e-1), + static_cast(4.46981634258601621625e-2), + static_cast(3.22521297380474263906e-3), + static_cast(1.31985203433890010111e-4), + static_cast(3.01507121087942156530e-6), + static_cast(3.47777238523841835495e-8), + static_cast(1.50780503777979189972e-10), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 4.2292e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(5.25741312407933720817e-5), + static_cast(2.34425802342454046697e-6), + static_cast(3.30042747965497652847e-8), + static_cast(1.58564820095683252738e-10), + static_cast(1.54070758384735212486e-13), + static_cast(-8.89232435250437247197e-17), + static_cast(8.14099948000080417199e-20), + static_cast(-4.61828164399178360925e-23), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.23544974283127158019e-1), + static_cast(6.01210465184576626802e-3), + static_cast(1.45390926665383063500e-4), + static_cast(1.80594709695117864840e-6), + static_cast(1.06088985542982155880e-8), + static_cast(2.20287881724613104903e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x * x * x); + + // Rational Approximation + // Maximum Relative Error: 2.3004e-17 + BOOST_MATH_STATIC const RealType P[4] = { + static_cast(2.99206710301074508455e-1), + static_cast(-8.62469397757826072306e-1), + static_cast(1.74661995423629075890e-1), + static_cast(8.75909164947413479137e-1), + }; + BOOST_MATH_STATIC const RealType Q[3] = { + static_cast(1.), + static_cast(-6.07405848111002255020e0), + static_cast(1.34068401972703571636e1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 4.5215e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87352751452164445024482162286994868262e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.07622509000285763173795736744991173600e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75004930885780661923539070646503039258e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.72358602484766333657370198137154157310e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80082654994455046054228833198744292689e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.53887200727615005180492399966262970151e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07684195532179300820096260852073763880e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.39151986881253768780523679256708455051e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31700721746247708002568205696938014069e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.52538425285394123789751606057231671946e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.13997198703138372752313576244312091598e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74788965317036115104204201740144738267e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.18994723428163008965406453309272880204e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.49208308902369087634036371223527932419e-11), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.07053963271862256947338846403373278592e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30146528469038357598785392812229655811e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.22168809220570888957518451361426420755e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.30911708477464424748895247790513118077e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.32037605861909345291211474811347056388e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.37380742268959889784160508321242249326e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.17777859396994816599172003124202701362e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.69357597449425742856874347560067711953e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.22061268498705703002731594804187464212e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.03685918248668999775572498175163352453e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.42037705933347925911510259098903765388e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.13651251802353350402740200231061151003e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.15390928968620849348804301589542546367e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.96186359077726620124148756657971390386e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 1.3996e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02038159607840130388931544845552929992e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.85240836242909590376775233472494840074e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.92928437142375928121954427888812334305e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.56075992368354834619445578502239925632e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85410663490566091471288623735720924369e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09160661432404033681463938555133581443e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60290555290385646856693819798655258098e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24420942563054709904053017769325945705e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.06370233020823161157791461691510091864e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.51562554221298564845071290898761434388e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.77361020844998296791409508640756247324e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.10768937536097342883548728871352580308e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.97810512763454658214572490850146305033e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.77430867682132459087084564268263825239e-11), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.30030169049261634787262795838348954434e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45935676273909940847479638179887855033e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14724239378269259016679286177700667008e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21580123796578745240828564510740594111e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70287348745451818082884807214512422940e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46859813604124308580987785473592196488e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.49627445316021031361394030382456867983e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05157712406194406440213776605199788051e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91541875103990251411297099611180353187e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47960462287955806798879139599079388744e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.80126815763067695392857052825785263211e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04569118116204820761181992270024358122e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.63024381269503801668229632579505279520e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00967434338725770754103109040982001783e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.6834e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.45396231261375200568114750897618690566e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.83107635287140466760500899510899613385e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71690205829238281191309321676655995475e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.95995611963950467634398178757261552497e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.52444689050426648467863527289016233648e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.40423239472181137610649503303203209123e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72181273738390251101985797318639680476e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.11423032981781501087311583401963332916e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37255768388351332508195641748235373885e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.25140171472943043666747084376053803301e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98925617316135247540832898350427842870e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27532592227329144332335468302536835334e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.25846339430429852334026937219420930290e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.17852693845678292024334670662803641322e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60008761860786244203651832067697976835e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.85474213475378978699789357283744252832e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.05561259222780127064607109581719435800e-15), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08902510590064634965634560548380735284e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.60127698266075086782895988567899172787e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.73299227011247478433171171063045855612e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94019328695445269130845646745771017029e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21478511930928822349285105322914093227e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.42888485420705779382804725954524839381e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36839484685440714657854206969200824442e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77082068469251728028552451884848161629e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.92625563541021144576900067220082880950e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88302521658522279293312672887766072876e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.37703703342287521257351386589629343948e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.32454189932655869016489443530062686013e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.81822848072558151338694737514507945151e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.40176559099032106726456059226930240477e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.55722115663529425797132143276461872035e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.18236697046568703899375072798708359035e-10), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 5.6207e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[20] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36729417918039395222067998266923903488e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05780369334958736210688756060527042344e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88449456199223796440901487003885388570e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20213624124017393492512893302682417041e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.95009975955570002297453163471062373746e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35668345583965001606910217518443864382e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.69006847702829685253055277085000792826e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08366922884479491780654020783735539561e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.71834368599657597252633517017213868956e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88269472722301903965736220481240654265e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37797139843759131750966129487745639531e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72390971590654495025982276782257590019e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68354503497961090303189233611418754374e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20749461042713568368181066233478264894e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.71167265100639100355339812752823628805e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37497033071709741762372104386727560387e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.08992504249040731356693038222581843266e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.03311745412603363076896897060158476094e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89266184062176002518506060373755160893e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.22157263424086267338486564980223658130e-22), + }; + BOOST_MATH_STATIC const RealType Q[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24254809760594824834854946949546737102e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66740386908805016172202899592418717176e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17175023341071972435947261868288366592e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33939409711833786730168591434519989589e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.58859674176126567295417811572162232222e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66346764121676348703738437519493817401e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.00687534341032230207422557716131339293e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57352381181825892637055619366793541271e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.23955067096868711061473058513398543786e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28279376429637301814743591831507047825e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22380760186302431267562571014519501842e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.21421839279245792393425090284615681867e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.80151544531415207189620615654737831345e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.57177992740786529976179511261318869505e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54223623314672019530719165336863142227e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26447311109866547647645308621478963788e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76514314007336173875469200193103772775e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.63785420481380041892410849615596985103e-13), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 6.8882e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90649774685568282389553481307707005425e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70151946710788532273869130544473159961e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76188245008605985768921328976193346788e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.94997481586873355765607596415761713534e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83556339450065349619118429405554762845e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.39766178753196196595432796889473826698e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48835240264191055418415753552383932859e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.23205178959384483669515397903609703992e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80665018951397281836428650435128239368e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27113208299726105096854812628329439191e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75272882929773945317046764560516449105e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.73174017370926101455204470047842394787e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.55548825213165929101134655786361059720e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.79786015549170518239230891794588988732e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73060731998834750292816218696923192789e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.62842837946576938669447109511449827857e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33878078951302606409419167741041897986e-26), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75629880937514507004822969528240262723e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43883005193126748135739157335919076027e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.26826935326347315479579835343751624245e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52263130214924169696993839078084050641e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.34708681216662922818631865761136370252e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19079618273418070513605131981401070622e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68812668867590621701228940772852924670e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81323523265546812020317698573638573275e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46655191174052062382710487986225631851e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.79864553144116347379916608661549264281e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.81866770335021233700248077520029108331e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15408288688082935176022095799735538723e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29421875915133979067465908221270435168e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74564282803894180881025348633912184161e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69782249847887916810010605635064672269e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.85875986197737611300062229945990879767e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 2.7988e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07231582988207590928480356376941073734e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35574911514921623999866392865480652576e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.60219401814297026945664630716309317015e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84927222345566515103807882976184811760e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96327408363203008584583124982694689234e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.86684048703029160378252571846517319101e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65469175974819997602752600929172261626e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.21842057555380199566706533446991680612e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.53555106309423641769303386628162522042e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.92686543698369260585325449306538016446e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01838615452860702770059987567879856504e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.65492535746962514730615062374864701860e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53395563720606494853374354984531107080e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.99957357701259203151690416786669242677e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46357124817620384236108395837490629563e-31), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02259092175256156108200465685980768901e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63438230616954606028022008517920766366e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.63880061357592661176130881772975919418e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81911305852397235014131637306820512975e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09690724408294608306577482852270088377e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11275552068434583356476295833517496456e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.24681861037105338446379750828324925566e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16034379416965004687140768474445096709e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23234481703249409689976894391287818596e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93297387560911081670605071704642179017e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50338428974314371000017727660753886621e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27897854868353937080739431205940604582e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.37798740524930029176790562876868493344e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29920082153439260734550295626576101192e-22), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 6.9688e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.25741312407933720816582583160953651639e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.04434146174674791036848306058526901384e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.68959516304795838166182070164492846877e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78859935261158263390023581309925613858e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.21854067989018450973827853792407054510e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20573856697340412957421887367218135538e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30843538021351383101589538141878424462e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.05991458689384045976214216819611949900e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.82253708752556965233757129893944884411e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.97645331663303764054986066027964294209e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.69353366461654917577775981574517182648e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59050144462227302681332505386238071973e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.85165507189649330971049854127575847359e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70711310565669331853925519429988855964e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.72047006026700174884151916064158941262e-38), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50985661940624198574968436548711898948e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81705882167596649186405364717835589894e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86537779048672498307196786015602357729e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09555188550938733096253930959407749063e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41930442687159455334801545898059105733e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.09084284266255183930305946875294557622e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.58122754063904909636061457739518406730e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.91800215912676651584368499126132687326e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.66413330532845384974993669138524203429e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65919563020196445006309683624384862816e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.61596083414169579692212575079167989319e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16321386033703806802403099255708972015e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.90892719803158002834365234646982537288e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x * x * x); + + // Rational Approximation + // Maximum Relative Error: 3.0545e-39 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[8] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.99206710301074508454959544950786401357e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.75243304700875633383991614142545185173e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.69652690455351600373808930804785330828e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.36233941060408773406522171349397343951e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.28958973553713980463808202034854958375e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.55704950313835982743029388151551925282e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.28767698270323629107775935552991333781e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.80591252844738626580182351673066365090e1), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.57593243741246726197476469913307836496e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.99458751269722094414105565700775283458e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.91043982880665229427553316951582511317e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.99054490423334526438490907473548839751e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.36948968143124830402744607365089118030e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13781639547150826385071482161074041168e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_pdf_imp_prec(const RealType& x, const boost::math::integral_constant &tag) { + BOOST_MATH_STD_USING // for ADL of std functions + + return holtsmark_pdf_plus_imp_prec(abs(x), tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_pdf_imp_prec(const RealType& x, const boost::math::integral_constant& tag) { + BOOST_MATH_STD_USING // for ADL of std functions + + return holtsmark_pdf_plus_imp_prec(abs(x), tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_pdf_imp(const holtsmark_distribution& dist, const RealType& x) { + // + // This calculates the pdf of the Holtsmark distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::pdf(holtsmark<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Holtsmark distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = holtsmark_pdf_imp_prec(u, tag_type()) / scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.5) { + // Rational Approximation + // Maximum Relative Error: 1.3147e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(5.0e-1), + static_cast(-1.34752580674786639030e-1), + static_cast(1.86318418252163378528e-2), + static_cast(1.04499798132512381447e-2), + static_cast(-1.60831910014592923855e-3), + static_cast(1.38823662364438342844e-4), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.05200341554753776087e-1), + static_cast(2.12663999430421346175e-1), + static_cast(7.23836000984872591553e-2), + static_cast(1.67941072412796299986e-2), + static_cast(4.71213644318790580839e-3), + static_cast(5.86825130959777535991e-4), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 1) { + RealType t = x - 0.5f; + + // Rational Approximation + // Maximum Relative Error: 1.6265e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(3.60595773518728397351e-1), + static_cast(5.75238626843218819756e-1), + static_cast(-3.31245319943021227117e-1), + static_cast(1.48132966310216368831e-1), + static_cast(-2.32875122617713403365e-2), + static_cast(2.08038303148835575624e-3), + static_cast(6.01511310581302829460e-6), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(2.32264360456739861886e0), + static_cast(6.39715443864749851087e-1), + static_cast(5.03940458163958921325e-1), + static_cast(8.84780893031413729292e-2), + static_cast(3.01497774031208621961e-2), + static_cast(3.45886005612108195390e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 7.4398e-20 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.43657975600729535515e-1), + static_cast(-6.02286263626532324632e-2), + static_cast(4.68361231392743283350e-2), + static_cast(-1.13497179885838883972e-3), + static_cast(1.20141595689136205012e-3), + static_cast(3.02402304689333413256e-4), + static_cast(-1.22652173865646814676e-6), + static_cast(2.29521832683440044997e-6), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(5.82002427359748247121e-1), + static_cast(3.96529686558825119743e-1), + static_cast(1.49690294526117385174e-1), + static_cast(5.15049953937764895435e-2), + static_cast(1.30218216530450637564e-2), + static_cast(2.53640337919037463659e-3), + static_cast(3.79575042317720710311e-4), + static_cast(2.94034997185982139717e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 5.6148e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(1.05039829654829164883e-1), + static_cast(1.66621813028423002562e-2), + static_cast(2.93820049104275137099e-2), + static_cast(3.36850260303189378587e-3), + static_cast(2.27925819398326978014e-3), + static_cast(1.66394162680543987783e-4), + static_cast(4.51400415642703075050e-5), + static_cast(2.12164734714059446913e-7), + static_cast(1.69306881760242775488e-8), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(9.63461239051296108254e-1), + static_cast(6.54183344973801096611e-1), + static_cast(2.92007762594247903696e-1), + static_cast(1.00918751132022401499e-1), + static_cast(2.55899135910670703945e-2), + static_cast(4.85740416919283630358e-3), + static_cast(6.11435190489589619906e-4), + static_cast(4.10953248859973756440e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 6.5866e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.05754562114095142887e-2), + static_cast(3.25462617990002726083e-2), + static_cast(1.78205524297204753048e-2), + static_cast(5.61565369088816402420e-3), + static_cast(1.05695297340067353106e-3), + static_cast(9.93588579804511250576e-5), + static_cast(2.94302107205379334662e-6), + static_cast(1.09016076876928010898e-8), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(1.51164395622515150122e0), + static_cast(1.09391911233213526071e0), + static_cast(4.77950346062744800732e-1), + static_cast(1.34082684956852773925e-1), + static_cast(2.37572579895639589816e-2), + static_cast(2.41806218388337284640e-3), + static_cast(1.10378140456646280084e-4), + static_cast(1.31559373832822136249e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 5.6575e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(9.47408470248235718880e-3), + static_cast(4.70888722333356024081e-3), + static_cast(8.66397831692913140221e-4), + static_cast(7.11721056656424862090e-5), + static_cast(2.56320582355149253994e-6), + static_cast(3.37749186035552101702e-8), + static_cast(8.32182844837952178153e-11), + static_cast(-8.80541360484428526226e-14), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(6.98261117346347123707e-1), + static_cast(1.97823959738695249267e-1), + static_cast(2.89311735096848395080e-2), + static_cast(2.30087055379997473849e-3), + static_cast(9.60592522700377510007e-5), + static_cast(1.84474415187428058231e-6), + static_cast(1.14339998084523151203e-8), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 1.4164e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.19610991747326729867e-3), + static_cast(5.11880074251341162590e-4), + static_cast(2.80704092977662888563e-5), + static_cast(6.31310155466346114729e-7), + static_cast(5.29618446795457166842e-9), + static_cast(9.20292337847562746519e-12), + static_cast(-9.16761719448360345363e-15), + static_cast(1.20433396121606479712e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(2.56283944667056551858e-1), + static_cast(2.56811818304462676948e-2), + static_cast(1.26678062261253559927e-3), + static_cast(3.17001344827541091252e-5), + static_cast(3.68737201224811007437e-7), + static_cast(1.47625352605312785910e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 9.2537e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.11172037056341397612e-3), + static_cast(7.84545643188695076893e-5), + static_cast(1.94862940242223222641e-6), + static_cast(2.02704958737259525509e-8), + static_cast(7.99772378955335076832e-11), + static_cast(6.62544230949971310060e-14), + static_cast(-3.18234118727325492149e-17), + static_cast(2.03424457039308806437e-20), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.17861198759233241198e-1), + static_cast(5.45962263583663240699e-3), + static_cast(1.25274651876378267111e-4), + static_cast(1.46857544539612002745e-6), + static_cast(8.06441204620771968579e-9), + static_cast(1.53682779460286464073e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType x_cube = x * x * x; + RealType t = static_cast((boost::math::isnormal)(x_cube) ? 1 / sqrt(x_cube) : 1 / pow(sqrt(x), 3)); + + // Rational Approximation + // Maximum Relative Error: 4.2897e-18 + BOOST_MATH_STATIC const RealType P[4] = { + static_cast(1.99471140200716338970e-1), + static_cast(-6.90933799347184400422e-1), + static_cast(4.30385245884336871950e-1), + static_cast(3.52790131116013716885e-1), + }; + BOOST_MATH_STATIC const RealType Q[3] = { + static_cast(1.), + static_cast(-5.05959751628952574534e0), + static_cast(8.04408113719341786819e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.5) { + // Rational Approximation + // Maximum Relative Error: 8.6635e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.0e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.48548242430636907136192799540229598637e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31541453581608245475805834922621529866e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.16579064508490250336159593502955219069e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61598809551362112011328341554044706550e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.15119245273512554325709429759983470969e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02145196753734867721148927112307708045e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.90817224464950088663183617156145065001e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69596202760983052482358128481956242532e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.50461337222845025623869078372182437091e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.62777995800923647521692709390412901586e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.63937253747323898965514197114021890186e-8), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76090180430550757765787254935343576341e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07685236907561593034104428156351640194e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27770556484351179553611274487979706736e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.99201460869149634331004096815257398515e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70139000408086498153685620963430185837e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74682544708653069148470666809094453722e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57607114117485446922700160080966856243e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01069214414741946409122492979083487977e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.19996282759031441186748256811206136921e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60933466092746543579699079418115420013e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.92780739162611243933581782562159603862e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 1) { + RealType t = x - 0.5; + + // Rational Approximation + // Maximum Relative Error: 7.1235e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60595773518728397925852903878144761766e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.46999595154527091473427440379143006753e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36962313432466566724352608642383560211e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08387290167105915393692028475888846796e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34156151832478939276011262838869269011e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15970594471853166393830585755485842021e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47022841547527682761332752928069503835e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.01955019188793323293925482112543902560e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.03069493388735516695142799880566783261e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61367662035593735709965982000611000987e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.62800430658278408539398798888955969345e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.22300086876618079439960709120163780513e-8), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19740977756009966244249035150363085180e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39394884078938560974435920719979860046e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.97107758486905601309707335353809421910e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.36594079604957733960211938310153276332e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.85712904264673773213248691029253356702e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.87605080555629969548037543637523346061e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.26356599628579249350545909071984757938e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.79582114368994462181480978781382155103e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.00970375323007336435151032145023199020e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.06528824060244313614177859412028348352e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.13914667697998291289987140319652513139e-7), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 6.7659e-38 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43657975600729535499895880792984203140e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.37090874182351552816526775008685285108e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70793783828569126853147999925198280654e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.27295555253412802819195403503721983066e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.95916890788873842705597506423512639342e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93625795791721417553345795882983866640e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.73237387099610415336810752053706403935e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08118655139419640900853055479087235138e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74920069862339840183963818219485580710e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59015304773612605296533206093582658838e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57256820413579442950151375512313072105e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.36240848333000575199740403759568680951e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53890585580518120552628221662318725825e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59245311730292556271235324976832000740e-10), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.49800491033591771256676595185869442663e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.35827615015880595229881139361463765537e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41657125931991211322147702760511651998e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11782602975553967179829921562737846592e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79410805176258968660086532862367842847e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22872839892405613311532856773434270554e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23742349724658114137235071924317934569e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.80350762663884259375711329227548815674e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59501693037547119094683008622867020131e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.86068186167498269806443077840917848151e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.36940342373887783231154918541990667741e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.48911186460768204167014270878839691938e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.55051094964993052272146587430780404904e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.96312716130620326771080033656930839768e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45496951385730104726429368791951742738e-10), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 9.9091e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05039829654829170780787685299556996311e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28948022754388615368533934448107849329e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.34139151583225691775740839359914493385e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13366377215523066657592295006960955345e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08045462837998791188853367062130086996e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.37648565386728404881404199616182064711e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14881702523183566448187346081007871684e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73169022445183613027772635992366708052e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.86434609673325793686202636939208406356e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20865083025640755296377488921536984172e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24550087063009488023243811976147518386e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78763689691843975658550702147832072016e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.53901449493513509116902285044951137217e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64133451376958243174967226929215155126e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78021916681275593923355425070000331160e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40116391931116431686557163556034777896e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.43891156389092896219387988411277617045e-15), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30840297297890638941129884491157396207e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16059271948787750556465175239345182035e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.32333703228724830516425197803770832978e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.74722711058640395885914966387546141874e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57544653090705553268164186689966671940e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.65943099435809995745673109708218670077e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74158626875895095042054345316232575354e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.65978318533667031874695821156329945501e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07907034178758316909655424935083792468e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.16769901831316460137104511711073411646e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.72764558714782436683712413015421717627e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.42494185105694341746192094740530489313e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.47668761140694808076322373887857100882e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06395948884595166425357861427667353718e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.04398743651684916010743222115099630062e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47852251142917253705233519146081069006e-10), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 3.2255e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[20] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05754562114095147060025732340404111260e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29082907781747007723015304584383528212e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.15736486393536930535038719804968063752e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.47619683293773846642359668429058772885e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78777185267549567154655052281449528836e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.32280474402180284471490985942690221861e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.45430564625797085273267452885960070105e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.81643129239005795245093568930666448817e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57851748656417804512189330871167578685e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.04264676511381380381909064283066657450e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.84536783037391183433322642273799250079e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.27169201994160924743393109705813711010e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.42623512076200527099335832138825884729e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.98298083389459839517970895839114237996e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71357920034737751299594537655948527288e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.98563999354325930973228648080876368296e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36248172644168880316722905969876969074e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61071663749398045880261823483568866904e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.95933262363502031836408613043245164787e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23007623135952181561484264810647517912e-21), + }; + BOOST_MATH_STATIC const RealType Q[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17760389606658547971193065026711073898e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49565543987559264712057768584303008339e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94822569926563661124528478579051628722e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14676844425183314970062115422221981422e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.35960757354198367535169328826167556715e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04865288305482048252211468989095938024e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.51599632816346741950206107526304703067e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74065824586512487126287762563576185455e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91819078437689679732215988465616022328e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.41675362609023565846569121735444698127e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17176431752708802291177040031150143262e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52367587943529121285938327286926798550e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59405168077254169099025950029539316125e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29448420654438993509041228047289503943e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.70091773726833073512661846603385666642e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.03909417984236210307694235586859612592e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.59098698207309055890188845050700901852e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28146456709550379493162440280752828165e-14), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 2.0174e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.47408470248235665279366712356669210597e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32149712567170349164953101675315481096e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.39806230477579028722350422669222849223e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19665271447867857827798702851111114658e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.06773237553503696884546088197977608676e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41294370314265386485116359052296796357e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74848600628353761723457890991084017928e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52963427970210468265870547940464851481e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.33389244528769791436454176079341120973e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.86702000100897346192018772319301428852e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04192907586200235211623448416582655030e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70804269459077260463819507381406529187e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52665761996923502719902050367236108720e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.01866635015788942430563628065687465455e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46658865059509532456423012727042498365e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.05806999626031246519161395419216393127e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.37645700309533972676063947195650607935e-26), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59608758824065179587008165265773042260e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17347162462484266250945490058846704988e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.24511137251392519285309985668265122633e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58497164094526279145784765183039854604e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40787701096334660711443654292041286786e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.34615029717812271556414485397095293077e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.17712219229282308306346195001801048971e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.24578142893420308057222282020407949529e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23429691331344898578916434987129070432e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41486460551571344910835151948209788541e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.23569151219279213399210115101532416912e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.21438860148387356361258237451828377118e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.46770060692933726695086996017149976796e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.58079984178724940266882149462170567147e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19997796316046571607659704855966005180e-17), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 4.5109e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19610991747326725339429696634365932643e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74646611039453235739153286141429338461e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13331430865337412098234177873337036811e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.58947311195482646360642638791970923726e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79226752074485124923797575635082779509e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73081326043094090549807549513512116319e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05408849431691450650464797109033182773e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75716486666270246158606737499459843698e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.81075133718930099703621109350447306080e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41318403854345256855350755520072932140e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70220987388883118699419526374266655536e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38711669183547686107032286389030018396e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31300491679098874872172866011372530771e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.99223939265527640018203019269955457925e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.18316957049006338447926554380706108087e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.47298013808154174645356607027685011183e-32), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.42561659771176310412113991024326129105e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83353398513931409985504410958429204317e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07254121026393428163401481487563215753e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36667170168890854756291846167398225330e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54019749685699795075624204463938596069e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35321766966107368759516431698755077175e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13350720091296144188972188966204719103e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38107118390482863395863404555696613407e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59267757423034664579822257229473088511e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29549090773392058626428205171445962834e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69922128600755513676564327500993739088e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31337037977667816904491472174578334375e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28088047429043940293455906253037445768e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.01213369826105495256520034997664473667e-22), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 1.2707e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11172037056341396583040940446061501972e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09383362521204903801686281772843962372e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71440982391172647693486692131238237524e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.01685075759372692173396811575536866699e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36574894913423830789864836789988898151e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.59644999935503505576091023207315968623e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.95573282292603122067959656607163690356e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.10361486103428098366627536344769789255e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80946231978997457068033851007899208222e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.39341134002270945594553624959145830111e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72307967968246649714945553177468010263e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41093409238620968003297675770440189200e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70464969040825495565297719377221881609e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.25341184125872354328990441812668510029e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.54663422572657744572284839697818435372e-36), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35632539169215377884393376342532721825e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.46975491055790597767445011183622230556e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51806800870130779095309105834725930741e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.07403939022350326847926101278370197017e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66046114012817696416892197044749060854e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.16723371111678357128668916130767948114e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22972796529973974439855811125888770710e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91073180314665062004869985842402705599e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43753004383633382914827301174981384446e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.77313206526206002175298314351042907499e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32850553089285690900825039331456226080e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.85369976595753971532524294793778805089e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28948021485210224442871255909409155592e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType x_cube = x * x * x; + RealType t = (boost::math::isnormal)(x_cube) ? 1 / sqrt(x_cube) : 1 / pow(sqrt(x), 3); + + // Rational Approximation + // Maximum Relative Error: 5.4677e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[7] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99471140200716338969973029967190934238e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.48481268366645066801385595379873318648e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64087860141734943856373451877569284231e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.45555576045996041260191574503331698473e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43290677381328916734673040799990923091e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.63011127597770211743774689830589568544e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.61127812511057623691896118746981066174e0), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.90660291309478542795359451748753358123e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60631500002415936739518466837931659008e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.88655117367497147850617559832966816275e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48350179543067311398059386524702440002e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.18873206560757944356169500452181141647e3), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? holtsmark_cdf_plus_imp_prec(x, tag) : 1 - holtsmark_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - holtsmark_cdf_plus_imp_prec(-x, tag) : holtsmark_cdf_plus_imp_prec(-x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? holtsmark_cdf_plus_imp_prec(x, tag) : 1 - holtsmark_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - holtsmark_cdf_plus_imp_prec(-x, tag) : holtsmark_cdf_plus_imp_prec(-x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_cdf_imp(const holtsmark_distribution& dist, const RealType& x, bool complement) { + // + // This calculates the cdf of the Holtsmark distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::cdf(holtsmark<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Holtsmark distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = holtsmark_cdf_imp_prec(u, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (ilogb(p) >= -2) { + RealType t = -log2(ldexp(p, 1)); + + // Rational Approximation + // Maximum Relative Error: 5.8068e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(7.59789769759814986929e-1), + static_cast(1.27515008642985381862e0), + static_cast(4.38619247097275579086e-1), + static_cast(-1.25521537863031799276e-1), + static_cast(-2.58555599127223857177e-2), + static_cast(1.20249932437303932411e-2), + static_cast(-1.36753104188136881229e-3), + static_cast(6.57491277860092595148e-5), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(2.48696501912062288766e0), + static_cast(2.06239370128871696850e0), + static_cast(5.67577904795053902651e-1), + static_cast(-2.89022828087034733385e-2), + static_cast(-2.17207943286085236479e-2), + static_cast(3.14098307020814954876e-4), + static_cast(3.51448381406676891012e-4), + static_cast(5.71995514606568751522e-5), + }; + + result = t * tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -3) { + RealType t = -log2(ldexp(p, 2)); + + // Rational Approximation + // Maximum Relative Error: 1.0339e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.84521387984759064238e-1), + static_cast(4.15763727809667641126e-1), + static_cast(-1.73610240124046440578e-2), + static_cast(-3.89915764128788049837e-2), + static_cast(1.07252911248451890192e-2), + static_cast(7.62613727089795367882e-4), + static_cast(-3.11382403581073580481e-4), + static_cast(3.93093062843177374871e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(6.76193897442484823754e-1), + static_cast(3.70953499602257825764e-2), + static_cast(-2.84211795745477605398e-2), + static_cast(2.66146101014551209760e-3), + static_cast(1.85436727973937413751e-3), + static_cast(2.00318687649825430725e-4), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 1.4431e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.46943301497773314460e-1), + static_cast(-1.07267614417424412546e-2), + static_cast(-7.21097021064631831756e-2), + static_cast(2.93948745441334193469e-2), + static_cast(-7.33259305010485915480e-4), + static_cast(-1.38660725579083612045e-3), + static_cast(2.95410432808739478857e-4), + static_cast(-2.88688017391292485867e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(-2.72809429017073648893e-2), + static_cast(-7.85526213469762960803e-2), + static_cast(2.41360900478283465241e-2), + static_cast(3.44597797125179611095e-3), + static_cast(-8.65046428689780375806e-4), + static_cast(-1.04147382037315517658e-4), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -6) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 4.8871e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(4.25344469980677332786e-1), + static_cast(3.42055470008289997369e-2), + static_cast(9.33607217644370441642e-2), + static_cast(4.57057092587794346086e-2), + static_cast(1.16149976708336017542e-2), + static_cast(6.40479797962035786337e-3), + static_cast(1.58526153828271386329e-3), + static_cast(3.84032908993313260466e-4), + static_cast(6.98960839033991110525e-5), + static_cast(9.66690587477825432174e-6), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + static_cast(1.), + static_cast(1.60044610004497775009e-1), + static_cast(2.41675490962065446592e-1), + static_cast(1.13752642382290596388e-1), + static_cast(4.05058759031434785584e-2), + static_cast(1.59432816225295660111e-2), + static_cast(4.79286678946992027479e-3), + static_cast(1.16048151070154814260e-3), + static_cast(2.01755520912887201472e-4), + static_cast(2.82884561026909054732e-5), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 6)); + + // Rational Approximation + // Maximum Relative Error: 4.8173e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(3.68520435599726877886e-1), + static_cast(8.26682725061327242371e-1), + static_cast(6.85235826889543887309e-1), + static_cast(3.28640408399661746210e-1), + static_cast(9.04801242897407528807e-2), + static_cast(1.57470088502958130451e-2), + static_cast(1.61541023176880542598e-3), + static_cast(9.78919203915954346945e-5), + static_cast(9.71371309261213597491e-8), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(2.29132755303753682133e0), + static_cast(1.95530118226232968288e0), + static_cast(9.55029685883545321419e-1), + static_cast(2.68254036588585643328e-1), + static_cast(4.61398419640231283164e-2), + static_cast(4.66131710581568432246e-3), + static_cast(2.94491397241310968725e-4), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 6.0376e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(3.48432718168951419458e-1), + static_cast(2.99680703419193973028e-1), + static_cast(1.09531896991852433149e-1), + static_cast(2.28766133215975559897e-2), + static_cast(3.09836969941710802698e-3), + static_cast(2.89346186674853481383e-4), + static_cast(1.96344583080243707169e-5), + static_cast(9.48415601271652569275e-7), + static_cast(3.08821091232356755783e-8), + static_cast(5.58003465656339818416e-10), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + static_cast(1.), + static_cast(8.73938978582311007855e-1), + static_cast(3.21771888210250878162e-1), + static_cast(6.70432401844821772827e-2), + static_cast(9.05369648218831664411e-3), + static_cast(8.50098390828726795296e-4), + static_cast(5.73568804840571459050e-5), + static_cast(2.78374120155590875053e-6), + static_cast(9.03427646135263412003e-8), + static_cast(1.63556457120944847882e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 2.2804e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(3.41419813138786920868e-1), + static_cast(1.30219412019722274099e-1), + static_cast(2.36047671342109636195e-2), + static_cast(2.67913051721210953893e-3), + static_cast(2.10896260337301129968e-4), + static_cast(1.19804595761611765179e-5), + static_cast(4.91470756460287578143e-7), + static_cast(1.38299844947707591018e-8), + static_cast(2.25766283556816829070e-10), + static_cast(-8.46510608386806647654e-18), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(3.81461950831351846380e-1), + static_cast(6.91390438866520696447e-2), + static_cast(7.84798596829449138229e-3), + static_cast(6.17735117400536913546e-4), + static_cast(3.50937328177439258136e-5), + static_cast(1.43958654321452532854e-6), + static_cast(4.05109749922716264456e-8), + static_cast(6.61306247924109415113e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 4.8545e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(3.41392032051575965049e-1), + static_cast(1.53372256183388434238e-1), + static_cast(3.33822240038718319714e-2), + static_cast(4.66328786929735228532e-3), + static_cast(4.67981207864367711082e-4), + static_cast(3.48119463063280710691e-5), + static_cast(2.17755850282052679342e-6), + static_cast(7.40424342670289242177e-8), + static_cast(4.61294046336533026640e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(4.49255524669251621744e-1), + static_cast(9.77826688966262423974e-2), + static_cast(1.36596271675764346980e-2), + static_cast(1.37080296105355418281e-3), + static_cast(1.01970588303201339768e-4), + static_cast(6.37846903580539445994e-6), + static_cast(2.16883897125962281968e-7), + static_cast(1.35121503608967367232e-8), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else { + const BOOST_MATH_STATIC_LOCAL_VARIABLE RealType c = ldexp(cbrt(constants::pi()), 1); + + RealType p_square = p * p; + + if ((boost::math::isnormal)(p_square)) { + result = 1 / (cbrt(p_square) * c); + } + else if (p > 0) { + result = 1 / (cbrt(p) * cbrt(p) * c); + } + else { + result = boost::math::numeric_limits::infinity(); + } + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (ilogb(p) >= -2) { + RealType u = -log2(ldexp(p, 1)); + + if (u < 0.5) { + // Rational Approximation + // Maximum Relative Error: 1.7987e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.59789769759815031687162026655576575384e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23247138049619855169890925442523844619e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.35351935489348780511227763760731136136e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.17321534695821967609074567968260505604e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30930523792327030433989902919481147250e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.47676800034255152477549544991291837378e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.09952071024064609787697026812259269093e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.65479872964217159571026674930672527880e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30204907832301876030269224513949605725e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.61038349134944320766567917361933431224e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.17242905696479357297850061918336600969e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43640101589433162893041733511239841220e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.39406616773257816628641556843884616119e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54871597065387376666252643921309051097e-7), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.06310038178166385607814371094968073940e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06144046990424238286303107360481469219e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17860081295611631017119482265353540470e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.26319639748358310901277622665331115333e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.25962127567362715217159291513550804588e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65543974081934423010588955830131357921e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.80331848633772107482330422252085368575e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.97426948050874772305317056836660558275e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.10722999873793200671617106731723252507e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.68871255379198546500699434161302033826e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70190278641952708999014435335172772138e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.11562497711461468804693130702653542297e-7), + }; + // LCOV_EXCL_STOP + result = u * tools::evaluate_polynomial(P, u) / (tools::evaluate_polynomial(Q, u) * cbrt(p * p)); + } + else { + RealType t = u - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 2.5554e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.63490994331899195346399558699533994243e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.68682839419340144322747963938810505658e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.63089084712442063245295709191126453412e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24910510426787025593146475670961782647e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.14005632199839351091767181535761567981e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.88144015238275997284082820907124267240e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.12015895125039876623372795832970536355e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.96386756665254981286292821446749025989e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.82855208595003635135641502084317667629e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.18007513930934295792217002090233670917e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.82563310387467580262182864644541746616e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52830681121195099547078704713089681353e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91383571211375811878311159248551586411e-8), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96820655322136936855997114940653763917e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30209571878469737819039455443404070107e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61235660141139249931521613001554108034e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.31683133997030095798635713869616211197e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.20681979279848555447978496580849290723e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.08958899028812330281115719259773001136e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02478613175545210977059079339657545008e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.68653479132148912896487809682760117627e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35166554499214836086438565154832646441e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95409975934011596023165394669416595582e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.84312112139729518216217161835365265801e-7), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + } + else if (ilogb(p) >= -3) { + RealType u = -log2(ldexp(p, 2)); + + if (u < 0.5) { + // Rational Approximation + // Maximum Relative Error: 1.0297e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.84521387984759060262188972210005114936e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70837834325236202821328032137877091515e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53856963029219911450181095566096563059e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.97659091653089105048621336944687224192e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.77726241585387617566937892474685179582e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21657224955483589784473724186837316423e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76357400631206366078287330192525531850e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.45967265853745968166172649261385754061e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.08367654892620484522749804048317330020e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41224530727710207304898458924763411052e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.02908228738160003274584644834000176496e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05702214080592377840761032481067834813e-7), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33954869248363301881659953529609341564e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.73738626674455393272550888585363920917e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.90708494363306682523722238824373341707e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.49559648492983033200126224112060119905e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.07561158260652000950392950266037061167e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30349651195547682860585068738648645100e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.21766408404123861757376277367204136764e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.22181499366766592894880124261171657846e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.74488053046587079829684775540618210211e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90504597668186854963746384968119788469e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45195198322028676384075318222338781298e-7), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, u) / (tools::evaluate_polynomial(Q, u) * cbrt(p * p)); + } + else { + RealType t = u - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 1.3688e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34418795581931891732555950599385666106e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.13006013029934051875748102515422669897e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.27990072710518465265454549585803147529e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.82530244963278920355650323928131927272e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05335741422175616606162502617378682462e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71242678756797136217651369710748524650e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.65147398836785709305701073315614307906e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23912765853731378067295654886575185240e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77861910171412622761254991979036167882e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.11971510714149983297022108523700437739e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23649928279010039670034778778065846828e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.99636080473697209793683863161785312159e-8), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.95056572065373808001002483348789719155e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.55702988004729812458415992666809422570e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.07586989542594910084052301521098115194e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96831670560124470215505714403486118412e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.86445076378084412691927796983792892534e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.75566285003039738258189045863064261980e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.18557444175572723760508226182075127685e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66667716357950609103712975111660496416e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70999480357934082364999779023268059131e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.14604868719110256415222454908306045416e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.32724040071094913191419223901752642417e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 6.6020e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46943301497773318715008398224877079279e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.85403413700924949902626248891615772650e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.02791895890363892816315784780533893399e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.89147412486638444082129846251261616763e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.93382251168424191872267997181870008850e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.68332196426082871660060467570049113632e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.88720436260994811649162949644253306037e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34099304204778307050211441936900839075e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.42970601149275611131932131801993030928e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.19329425598839605828710629592687495198e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.48826007216547106568423189194739111033e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47132934846160946190230821709692067279e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34123780321108493820637601375183345528e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.64549285026064221742294542922996905241e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72723306533295983872420985773212608299e-9), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.23756826160440280076231428938184359865e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.46557011055563840763437682311082689407e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18907861669025579159409035585375166964e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.09998981512549500250715800529896557509e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.09496663758959409482213456915225652712e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.37086325651334206453116588474211557676e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65325780110454655811120026458133145750e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.93435549562125602056160657604473721758e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34967558308250784125219085040752451132e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.73883529653464036447550624641291181317e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.88600727347267778330635397957540267359e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.26681383000234695948685993798733295748e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19871610873353691152255428262732390602e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42468017918888155246438948321084323623e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -5) { + RealType u = -log2(ldexp(p, 4)); + + if (u < 0.5) { + // Rational Approximation + // Maximum Relative Error: 5.0596e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25344469980677353573160570139298422046e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.41915371584999983192100443156935649063e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02829239548689190780023994008688591230e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29283473326959885625548350158197923999e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.01078477165670046284950196047161898687e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02714892887893367912743194877742997622e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.43133417775367444366548711083157149060e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34782994090554432391320506638030058071e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06742736859237185836735105245477248882e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.55982601406660341132288721616681417444e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.57770758189194396236862269776507019313e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.29311341249565125992213260043135188072e-8), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.54021943144355190773797361537886598583e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30965787836836308380896385568728211303e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19314242976592846926644622802257778872e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.84123785238634690769817401191138848504e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.75779029464908805680899310810660326192e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15078294915445673781718097749944059134e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84667183003626452412083824490324913477e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.59521438712225874821007396323337016693e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.90446539427779905568600432145715126083e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.21425779911599424040614866482614099753e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.00972806247654369646317764344373036462e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, u) / (tools::evaluate_polynomial(Q, u) * cbrt(p * p)); + } + else { + RealType t = u - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 8.3743e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08071367192424306005939751362206079160e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.94625900993512461462097316785202943274e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55970241156822104458842450713854737857e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.07663066299810473476390199553510422731e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.89859986209620592557993828310690990189e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04002735956724252558290154433164340078e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.28754717941144647796091692241880059406e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19307116062867039608045413276099792797e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.02377178609994923303160815309590928289e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.71739619655097982325716241977619135216e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70229045058419872036870274360537396648e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.90495731447121207951661931979310025968e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23210708203609461650368387780135568863e-8), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.93402256203255215539822867473993726421e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42452702043886045884356307934634512995e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.16981055684612802160174937997247813645e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39560623514414816165791968511612762553e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.26014275897567952035148355055139912545e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.42163967753843746501638925686714935099e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.63605648300801696460942201096159808446e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.55933967787268788177266789383155699064e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.41526208021076709058374666903111908743e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.08505866202670144225100385141263360218e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + } + else if (ilogb(p) >= -6) { + RealType t = -log2(ldexp(p, 5)); + + // Rational Approximation + // Maximum Relative Error: 2.4734e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.92042979500197776619414802317216082414e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94742044285563829335663810275331541585e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14525306632578654372860377652983462776e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88893010132758460781753381176593178775e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08491462791290535107958214106528611951e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61374431854187722720094162894017991926e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11641062509116613779440753514902522337e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12474548036763970495563846370119556004e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.48140831258790372410036499310440980121e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.26913338169355215445128368312197650848e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63109797282729701768942543985418804075e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.55296802973076575732233624155433324402e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72108609713971908723724065216410393928e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.93328436272999507339897246655916666269e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72119240610740992234979508242967886200e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17836139198065889244530078295061548097e-10), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78065342260594920160228973261455037923e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.08575070304822733863613657779515344137e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81185785915044621118680763035984134530e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87597191269586886460326897968559867853e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07903258768761230286548634868645339678e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88395769450457864233486684232536503140e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05678227243099671420442217017131559055e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.24803207742284923122212652186826674987e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06094715338829793088081672723947647238e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.96454433858093590192363331553516923090e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94509901530299070041475386866323617753e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49001710126540196485963921184736711193e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58899179756014192338509671769986887613e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.06916561094749601736592488829778059190e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 6)); + + // Rational Approximation + // Maximum Relative Error: 1.1570e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.68520435599726860132888599110871216319e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.01076105507184082206031922185510102322e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39912455237662038937400667644545834191e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51088991221663244634723139723207272560e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26465949648856746869050310379379898086e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37079746226805258449355819952819997723e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49372033421420312720741838903118544951e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95729572745049276972587492142384353131e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.92794840197452838799536047152725573779e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96897979363475104635129765703613472468e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44138843334474914059035559588791041371e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.78076328055619970057667292651627051391e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04182093251998194244585085400876144351e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04392999917657413659748817212746660436e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76006125565969084470924344826977844710e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21045181507045010640119572995692565368e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61400097324698003962179537436043636306e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.88084230973635340409728710734906398080e-11), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49319798750825059930589954921919984293e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90218243410186000622818205955425584848e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25384789213915993855434876209137054104e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.58563858782064482133038568901836564329e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39112608961600614189971858070197609546e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29192895265168981204927382938872469754e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.66418375973954918346810939649929797237e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01606040038159207768769492693779323748e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.75837675697421536953171865636865644576e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30258315910281295093103384193132807400e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.28333635097670841003561009290200071343e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.04871369296490431325621140782944603554e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05077352164673794093561693258318905067e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.28508157403208548483052311164947568580e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22527248376737724147359908626095469985e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.75479484339716254784610505187249810386e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.39990051830081888581639577552526319577e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 1.1362e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[22] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.48432718168951398420402661878962745094e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.55946442453078865766668586202885528338e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.54912640113904816247923987542554486059e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.60852745978561293262851287627328856197e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93256608166097432329211369307994852513e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.94707001299612588571704157159595918562e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40368387009950846525432054396214443833e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62326983889228773089492130483459202197e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97166112600628615762158757484340724056e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.95053681446806610424931810174198926457e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13613767164027076487881255767029235747e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46627172639536503825606138995804926378e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.26813757095977946534946955553296696736e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01393212063713249666862633388902006492e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04428602119155661411061942866480445477e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52977051350929618206095556763031195967e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63092013964238065197415324341392517794e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.77457116423818347179318334884304764609e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10372468210274291890669895933038762772e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85517152798650696598776156882211719502e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01916800572423194619358228507804954863e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.72241483171311778625855302356391965266e-26), + }; + BOOST_MATH_STATIC const RealType Q[21] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18341916009800042837726003154518652168e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19215655980509256344434487727207541208e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34380326549827252189214516628038733750e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.65069135930665131327262366757787760402e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74132905027750048531814627726862962404e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.11184893124573373947875834716323223477e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.68456853089572312034718359282699132364e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16340806625223749486884390838046244494e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45007766006724826837429360471785418874e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50443251593190111677537955057976277305e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30829464745241179175728900376502542995e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.57256894336319418553622695416919409120e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.89973763917908403951538315949652981312e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05834675579622824896206540981508286215e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32721343511724613011656816221169980981e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.77569292346900432492044041866264215291e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39903737668944675386972393000746368518e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23200083621376582032771041306045737695e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.43557805626692790539354751731913075096e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.91326410956582998375100191562832969140e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 9.1729e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41419813138786928653984591611599949126e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94225020281693988785012368481961427155e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28967134188573605597955859185818311256e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.16617725083935565014535265818666424029e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13379610773944032381149443514208866162e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06508483032198116332154635763926628153e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.89315471210589177037346413966039863126e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72993906450633221200844495419180873066e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32883391567312244751716481903540505335e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.50998889887280885500990101116973130081e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23247766687180294767338042555173653249e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.12326475887709255500757383109178584638e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11688319088825228685832870139320733695e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95381542569360703428852622701723193645e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.70730387484749668293167350494151199659e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84243405919322052861165273432136993833e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40860917180131228318146854666419586211e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.85122374200561402546731933480737679849e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.79744248200459077556218062241428072826e-32), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.68930884381361438749954611436694811868e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54944129151720429074748655153760118465e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68493670923968273171437877298940102712e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.32109946297461941811102221103314572340e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.11983030120265263999033828442555862122e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31204888358097171713697195034681853057e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38548604936907265274059071726622071821e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.82158855359673890472124017801768455208e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78564556026252472894386810079914912632e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.46854501887011863360558947087254908412e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67236380279070121978196383998000020645e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.20076045812548485396837897240357026254e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15814123143437217877762088763846289858e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67177999717442465582949551415385496304e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71135001552136641449927514544850663366e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.98449056954034104266783180068258117013e-22), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 1.8330e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41392032051575981622151194498090952488e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32651097995974052731414709779952524875e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51927763729719814565225981452897995722e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.11148082477882981299945196621348531180e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80457559655975695558885644380771202301e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96223001525552834934139567532649816367e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10625449265784963560596299595289620029e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.14785887121654524328854820350425279893e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00832358736396150660417651391240544392e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.63128732906298604011217701767305935851e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86148432181465165445355560568442172406e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44088921565424320298916604159745842835e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.95220124898384051195673049864765987092e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50531060529388128674128631193212903032e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06119051130826148039530805693452156757e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19849873960405145967462029876325494393e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66833600176986734600260382043861669021e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07829060832934383885234817363480653925e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21485411177823993142696645934560017341e-40), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.88559444380290379529260819350179144435e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.37942717465159991856146428659881557553e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.11409915376157429952160202733757574026e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.21511733003564236929107862750700281202e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74773232555012468159223116269289241483e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.24042271031862389840796415749527818562e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50790246845873571117791557191071320982e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88274886666078071130557536971927872847e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94242592538917360235050248151146832636e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45262967284548223426004177385213311949e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30081806380053435857465845326686775489e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62226426496757450797456131921060042081e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40933140159573381494354127717542598424e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.03760580312376891985077265621432029857e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.43980683769941233230954109646012150124e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.88686274782816858372719510890126716148e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07336140055510452905474533727353308321e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 5.9085e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41392031627647840832213878541731833340e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48256908849985263191468999842405689327e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.16515822909144946601084169745484248278e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.42246334265547596187501472291026180697e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.54145961608971551335283437288203286104e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64840354062369555376354747633807898689e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.38246669464526050793398379055335943951e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29684566081664150074215568847731661446e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.98456331768093420851844051941851740455e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36738267296531031235518935656891979319e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.08128287278026286279504717089979753319e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.38334581618709868951669630969696873534e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.08478537820365448038773095902465198679e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30768169494950935152733510713679558562e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49254243621461466892836128222648688091e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.17026357413798368802986708112771803774e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05630817682870951728748696694117980745e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.13881361534205323565985756195674181203e-50), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34271731953273239599863811873205236246e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27133013035186849060586077266046297964e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29542078693828543540010668640353491847e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33027698228265344545932885863767276804e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06868444562964057780556916100143215394e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.97868278672593071061800234869603536243e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79869926850283188735312536038469293739e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75298857713475428365153491580710497759e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.93449891515741631851202042430818496480e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36715626731277089013724968542144140938e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.98125789528264426869121548546848968670e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78234546049400950521459021508632294206e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83044000387150792643468853129175805308e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30111486296552039388613073915170671881e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.28628462422858134962149154420358876352e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48108558735886480279744474396456699335e-21), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else { + const BOOST_MATH_STATIC_LOCAL_VARIABLE RealType c = ldexp(cbrt(constants::pi()), 1); + + RealType p_square = p * p; + + if ((boost::math::isnormal)(p_square)) { + result = 1 / (cbrt(p_square) * c); + } + else if (p > 0) { + result = 1 / (cbrt(p) * cbrt(p) * c); + } + else { + result = boost::math::numeric_limits::infinity(); + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? holtsmark_quantile_upper_imp_prec(1 - p, tag) : -holtsmark_quantile_upper_imp_prec(1 - p, tag); + } + + return complement ? holtsmark_quantile_upper_imp_prec(p, tag) : -holtsmark_quantile_upper_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? holtsmark_quantile_upper_imp_prec(1 - p, tag) : -holtsmark_quantile_upper_imp_prec(1 - p, tag); + } + + return complement ? holtsmark_quantile_upper_imp_prec(p, tag) : -holtsmark_quantile_upper_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_quantile_imp(const holtsmark_distribution& dist, const RealType& p, bool complement) +{ + // This routine implements the quantile for the Holtsmark distribution, + // the value p may be the probability, or its complement if complement=true. + + constexpr auto function = "boost::math::quantile(holtsmark<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Holtsmark distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * holtsmark_quantile_imp_prec(p, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_entropy_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(2.06944850513462440032); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_entropy_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.0694485051346244003155800384542166381); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType holtsmark_entropy_imp(const holtsmark_distribution& dist) +{ + // This implements the entropy for the Holtsmark distribution, + + constexpr auto function = "boost::math::entropy(holtsmark<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Holtsmark distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = holtsmark_entropy_imp_prec(tag_type()) + log(scale); + + return result; +} + +} // detail + +template > +class holtsmark_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED holtsmark_distribution(RealType l_location = 0, RealType l_scale = 1) + : mu(l_location), c(l_scale) + { + constexpr auto function = "boost::math::holtsmark_distribution<%1%>::holtsmark_distribution"; + RealType result = 0; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + } // holtsmark_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return mu; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return c; + } + + private: + RealType mu; // The location parameter. + RealType c; // The scale parameter. +}; + +typedef holtsmark_distribution holtsmark; + +#ifdef __cpp_deduction_guides +template +holtsmark_distribution(RealType) -> holtsmark_distribution::type>; +template +holtsmark_distribution(RealType, RealType) -> holtsmark_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const holtsmark_distribution&) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const holtsmark_distribution&) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const holtsmark_distribution& dist, const RealType& x) +{ + return detail::holtsmark_pdf_imp(dist, x); +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const holtsmark_distribution& dist, const RealType& x) +{ + return detail::holtsmark_cdf_imp(dist, x, false); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const holtsmark_distribution& dist, const RealType& p) +{ + return detail::holtsmark_quantile_imp(dist, p, false); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::holtsmark_cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::holtsmark_quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const holtsmark_distribution &dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const holtsmark_distribution& /*dist*/) +{ + return boost::math::numeric_limits::infinity(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const holtsmark_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const holtsmark_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const holtsmark_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Holtsmark Distribution has no skewness"); + + return policies::raise_domain_error( + "boost::math::skewness(holtsmark<%1%>&)", + "The Holtsmark distribution does not have a skewness: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const holtsmark_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Holtsmark Distribution has no kurtosis"); + + return policies::raise_domain_error( + "boost::math::kurtosis(holtsmark<%1%>&)", + "The Holtsmark distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const holtsmark_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Holtsmark Distribution has no kurtosis excess"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(holtsmark<%1%>&)", + "The Holtsmark distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const holtsmark_distribution& dist) +{ + return detail::holtsmark_entropy_imp(dist); +} + +}} // namespaces + + +#endif // BOOST_STATS_HOLTSMARK_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/hyperexponential.hpp b/third-party/boost-math/include/boost/math/distributions/hyperexponential.hpp new file mode 100644 index 0000000000000..49f967d0fad07 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/hyperexponential.hpp @@ -0,0 +1,641 @@ +// Copyright 2014 Marco Guazzone (marco.guazzone@gmail.com) +// +// 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) +// +// This module implements the Hyper-Exponential distribution. +// +// References: +// - "Queueing Theory in Manufacturing Systems Analysis and Design" by H.T. Papadopolous, C. Heavey and J. Browne (Chapman & Hall/CRC, 1993) +// - http://reference.wolfram.com/language/ref/HyperexponentialDistribution.html +// - http://en.wikipedia.org/wiki/Hyperexponential_distribution +// + +#ifndef BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP +#define BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _MSC_VER +# pragma warning (push) +# pragma warning(disable:4127) // conditional expression is constant +# pragma warning(disable:4389) // '==' : signed/unsigned mismatch in test_tools +#endif // _MSC_VER + +namespace boost { namespace math { + +namespace detail { + +template +typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function); + +} // Namespace detail + + +template +class hyperexponential_distribution; + + +namespace /**/ { namespace hyperexp_detail { + +template +void normalize(std::vector& v) +{ + if(!v.size()) + return; // Our error handlers will get this later + const T sum = std::accumulate(v.begin(), v.end(), static_cast(0)); + T final_sum = 0; + const typename std::vector::iterator end = --v.end(); + for (typename std::vector::iterator it = v.begin(); + it != end; + ++it) + { + *it /= sum; + final_sum += *it; + } + *end = 1 - final_sum; // avoids round off errors, ensures the probs really do sum to 1. +} + +template +bool check_probabilities(char const* function, std::vector const& probabilities, RealT* presult, PolicyT const& pol) +{ + BOOST_MATH_STD_USING + const std::size_t n = probabilities.size(); + RealT sum = 0; + for (std::size_t i = 0; i < n; ++i) + { + if (probabilities[i] < 0 + || probabilities[i] > 1 + || !(boost::math::isfinite)(probabilities[i])) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"probabilities\" must be >= 0 and <= 1, but at least one of them was: %1%.", + probabilities[i], + pol); + return false; + } + sum += probabilities[i]; + } + + // + // We try to keep phase probabilities correctly normalized in the distribution constructors, + // however in practice we have to allow for a very slight divergence from a sum of exactly 1: + // + if (fabs(sum - 1) > tools::epsilon() * 2) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"probabilities\" must sum to 1, but their sum is: %1%.", + sum, + pol); + return false; + } + + return true; +} + +template +bool check_rates(char const* function, std::vector const& rates, RealT* presult, PolicyT const& pol) +{ + const std::size_t n = rates.size(); + for (std::size_t i = 0; i < n; ++i) + { + if (rates[i] <= 0 + || !(boost::math::isfinite)(rates[i])) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"rates\" must be > 0, but at least one of them is: %1%.", + rates[i], + pol); + return false; + } + } + return true; +} + +template +bool check_dist(char const* function, std::vector const& probabilities, std::vector const& rates, RealT* presult, PolicyT const& pol) +{ + BOOST_MATH_STD_USING + if (probabilities.size() != rates.size()) + { + *presult = policies::raise_domain_error(function, + R"(The parameters "probabilities" and "rates" must have the same length, but their size differ by: %1%.)", + fabs(static_cast(probabilities.size())-static_cast(rates.size())), + pol); + return false; + } + + return check_probabilities(function, probabilities, presult, pol) + && check_rates(function, rates, presult, pol); +} + +template +bool check_x(char const* function, RealT x, RealT* presult, PolicyT const& pol) +{ + if (x < 0 || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error(function, "The random variable must be >= 0, but is: %1%.", x, pol); + return false; + } + return true; +} + +template +bool check_probability(char const* function, RealT p, RealT* presult, PolicyT const& pol) +{ + if (p < 0 || p > 1 || (boost::math::isnan)(p)) + { + *presult = policies::raise_domain_error(function, "The probability be >= 0 and <= 1, but is: %1%.", p, pol); + return false; + } + return true; +} + +template +RealT quantile_impl(hyperexponential_distribution const& dist, RealT const& p, bool comp) +{ + // Don't have a closed form so try to numerically solve the inverse CDF... + + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = comp ? "boost::math::quantile(const boost::math::complemented2_type, %1%>&)" + : "boost::math::quantile(const boost::math::hyperexponential_distribution<%1%>&, %1%)"; + + RealT result = 0; + + if (!check_probability(function, p, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + // A possible (but inaccurate) approximation is given below, where the + // quantile is given by the weighted sum of exponential quantiles: + RealT guess = 0; + if (comp) + { + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + guess += probs[i]*quantile(complement(exp, p)); + } + } + else + { + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + guess += probs[i]*quantile(exp, p); + } + } + + // Fast return in case the Hyper-Exponential is essentially an Exponential + if (n == 1) + { + return guess; + } + + value_type q; + q = detail::generic_quantile(hyperexponential_distribution(probs, rates), + p, + guess, + comp, + function); + + result = policies::checked_narrowing_cast(q, function); + + return result; +} + +}} // Namespace ::hyperexp_detail + + +template > +class hyperexponential_distribution +{ + public: typedef RealT value_type; + public: typedef PolicyT policy_type; + + + public: hyperexponential_distribution() + : probs_(1, 1), + rates_(1, 1) + { + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Four arg constructor: no ambiguity here, the arguments must be two pairs of iterators: + public: template + hyperexponential_distribution(ProbIterT prob_first, ProbIterT prob_last, + RateIterT rate_first, RateIterT rate_last) + : probs_(prob_first, prob_last), + rates_(rate_first, rate_last) + { + hyperexp_detail::normalize(probs_); + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + private: template + struct is_iterator + { + static constexpr bool value = false; + }; + + template + struct is_iterator::difference_type>> + { + // std::iterator_traits::difference_type returns void for invalid types + static constexpr bool value = !std::is_same::difference_type, void>::value; + }; + + // Two arg constructor from 2 ranges, we SFINAE this out of existence if + // either argument type is incrementable as in that case the type is + // probably an iterator: + public: template ::value && + !is_iterator::value, bool>::type = true> + hyperexponential_distribution(ProbRangeT const& prob_range, + RateRangeT const& rate_range) + : probs_(std::begin(prob_range), std::end(prob_range)), + rates_(std::begin(rate_range), std::end(rate_range)) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Two arg constructor for a pair of iterators: we SFINAE this out of + // existence if neither argument types are incrementable. + // Note that we allow different argument types here to allow for + // construction from an array plus a pointer into that array. + public: template ::value || + is_iterator::value, bool>::type = true> + hyperexponential_distribution(RateIterT const& rate_first, + RateIterT2 const& rate_last) + : probs_(std::distance(rate_first, rate_last), 1), // will be normalized below + rates_(rate_first, rate_last) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Initializer list constructor: allows for construction from array literals: +public: hyperexponential_distribution(std::initializer_list l1, std::initializer_list l2) + : probs_(l1.begin(), l1.end()), + rates_(l2.begin(), l2.end()) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + +public: hyperexponential_distribution(std::initializer_list l1) + : probs_(l1.size(), 1), + rates_(l1.begin(), l1.end()) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Single argument constructor: argument must be a range. + public: template + hyperexponential_distribution(RateRangeT const& rate_range) + : probs_(std::distance(std::begin(rate_range), std::end(rate_range)), 1), // will be normalized below + rates_(std::begin(rate_range), std::end(rate_range)) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + public: std::vector probabilities() const + { + return probs_; + } + + public: std::vector rates() const + { + return rates_; + } + + public: std::size_t num_phases() const + { + return rates_.size(); + } + + + private: std::vector probs_; + private: std::vector rates_; +}; // class hyperexponential_distribution + + +// Convenient type synonym for double. +typedef hyperexponential_distribution hyperexponential; + + +// Range of permissible values for random variable x +template +std::pair range(hyperexponential_distribution const&) +{ + if (std::numeric_limits::has_infinity) + { + return std::make_pair(static_cast(0), std::numeric_limits::infinity()); // 0 to +inf. + } + + return std::make_pair(static_cast(0), tools::max_value()); // 0 to + +} + +// Range of supported values for random variable x. +// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. +template +std::pair support(hyperexponential_distribution const&) +{ + return std::make_pair(tools::min_value(), tools::max_value()); // to +. +} + +template +RealT pdf(hyperexponential_distribution const& dist, RealT const& x) +{ + BOOST_MATH_STD_USING + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::pdf(const boost::math::hyperexponential_distribution<%1%>&, %1%)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*pdf(exp, x); + //result += probs[i]*rates[i]*exp(-rates[i]*x); + } + + return result; +} + +template +RealT cdf(hyperexponential_distribution const& dist, RealT const& x) +{ + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::cdf(const boost::math::hyperexponential_distribution<%1%>&, %1%)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*cdf(exp, x); + } + + return result; +} + +template +RealT quantile(hyperexponential_distribution const& dist, RealT const& p) +{ + return hyperexp_detail::quantile_impl(dist, p , false); +} + +template +RealT cdf(complemented2_type, RealT> const& c) +{ + RealT const& x = c.param; + hyperexponential_distribution const& dist = c.dist; + + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::cdf(boost::math::complemented2_type&, %1%>)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*cdf(complement(exp, x)); + } + + return result; +} + + +template +RealT quantile(complemented2_type, RealT> const& c) +{ + RealT const& p = c.param; + hyperexponential_distribution const& dist = c.dist; + + return hyperexp_detail::quantile_impl(dist, p , true); +} + +template +RealT mean(hyperexponential_distribution const& dist) +{ + RealT result = 0; + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*mean(exp); + } + + return result; +} + +template +RealT variance(hyperexponential_distribution const& dist) +{ + RealT result = 0; + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + result += probs[i]/(rates[i]*rates[i]); + } + + const RealT mean = boost::math::mean(dist); + + result = 2*result-mean*mean; + + return result; +} + +template +RealT skewness(hyperexponential_distribution const& dist) +{ + BOOST_MATH_STD_USING + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + RealT s1 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i} + RealT s2 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^2} + RealT s3 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^3} + for (std::size_t i = 0; i < n; ++i) + { + const RealT p = probs[i]; + const RealT r = rates[i]; + const RealT r2 = r*r; + const RealT r3 = r2*r; + + s1 += p/r; + s2 += p/r2; + s3 += p/r3; + } + + const RealT s1s1 = s1*s1; + + const RealT num = (6*s3 - (3*(2*s2 - s1s1) + s1s1)*s1); + const RealT den = (2*s2 - s1s1); + + return num / pow(den, static_cast(1.5)); +} + +template +RealT kurtosis(hyperexponential_distribution const& dist) +{ + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + RealT s1 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i} + RealT s2 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^2} + RealT s3 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^3} + RealT s4 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^4} + for (std::size_t i = 0; i < n; ++i) + { + const RealT p = probs[i]; + const RealT r = rates[i]; + const RealT r2 = r*r; + const RealT r3 = r2*r; + const RealT r4 = r3*r; + + s1 += p/r; + s2 += p/r2; + s3 += p/r3; + s4 += p/r4; + } + + const RealT s1s1 = s1*s1; + + const RealT num = (24*s4 - 24*s3*s1 + 3*(2*(2*s2 - s1s1) + s1s1)*s1s1); + const RealT den = (2*s2 - s1s1); + + return num/(den*den); +} + +template +RealT kurtosis_excess(hyperexponential_distribution const& dist) +{ + return kurtosis(dist) - 3; +} + +template +RealT mode(hyperexponential_distribution const& /*dist*/) +{ + return 0; +} + +}} // namespace boost::math + +#ifdef _MSC_VER +#pragma warning (pop) +#endif +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL diff --git a/third-party/boost-math/include/boost/math/distributions/hypergeometric.hpp b/third-party/boost-math/include/boost/math/distributions/hypergeometric.hpp new file mode 100644 index 0000000000000..d7d1b6a06941a --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/hypergeometric.hpp @@ -0,0 +1,311 @@ +// Copyright 2008 Gautam Sewani +// Copyright 2008 John Maddock +// Copyright 2021 Paul A. Bristow +// +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_HYPERGEOMETRIC_HPP +#define BOOST_MATH_DISTRIBUTIONS_HYPERGEOMETRIC_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + + template > + class hypergeometric_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + hypergeometric_distribution(std::uint64_t r, std::uint64_t n, std::uint64_t N) // Constructor. r=defective/failures/success, n=trials/draws, N=total population. + : m_n(n), m_N(N), m_r(r) + { + static const char* function = "boost::math::hypergeometric_distribution<%1%>::hypergeometric_distribution"; + RealType ret; + check_params(function, &ret); + } + // Accessor functions. + std::uint64_t total() const + { + return m_N; + } + + std::uint64_t defective() const // successes/failures/events + { + return m_r; + } + + std::uint64_t sample_count()const + { + return m_n; + } + + bool check_params(const char* function, RealType* result)const + { + if(m_r > m_N) + { + *result = boost::math::policies::raise_domain_error( + function, "Parameter r out of range: must be <= N but got %1%", static_cast(m_r), Policy()); + return false; + } + if(m_n > m_N) + { + *result = boost::math::policies::raise_domain_error( + function, "Parameter n out of range: must be <= N but got %1%", static_cast(m_n), Policy()); + return false; + } + return true; + } + bool check_x(std::uint64_t x, const char* function, RealType* result)const + { + if(x < static_cast((std::max)(INT64_C(0), static_cast(m_n + m_r) - static_cast(m_N)))) + { + *result = boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be > 0 and > m + r - N but got %1%", static_cast(x), Policy()); + return false; + } + if(x > (std::min)(m_r, m_n)) + { + *result = boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be less than both n and r but got %1%", static_cast(x), Policy()); + return false; + } + return true; + } + + private: + // Data members: + std::uint64_t m_n; // number of items picked or drawn. + std::uint64_t m_N; // number of "total" items. + std::uint64_t m_r; // number of "defective/successes/failures/events items. + + }; // class hypergeometric_distribution + + typedef hypergeometric_distribution hypergeometric; + + template + inline const std::pair range(const hypergeometric_distribution& dist) + { // Range of permissible values for random variable x. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + const auto r = dist.defective(); + const auto n = dist.sample_count(); + const auto N = dist.total(); + const auto l = static_cast((std::max)(INT64_C(0), static_cast(n + r) - static_cast(N))); + const auto u = (std::min)(r, n); + return std::make_pair(l, u); +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } + + template + inline const std::pair support(const hypergeometric_distribution& d) + { + return range(d); + } + + template + inline RealType pdf(const hypergeometric_distribution& dist, const std::uint64_t& x) + { + static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!dist.check_params(function, &result)) + return result; + if(!dist.check_x(x, function, &result)) + return result; + + return boost::math::detail::hypergeometric_pdf( + x, dist.defective(), dist.sample_count(), dist.total(), Policy()); + } + + template + inline RealType pdf(const hypergeometric_distribution& dist, const U& x) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(x); + auto u = static_cast(lltrunc(r, typename policies::normalise >::type())); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return pdf(dist, u); + } + + template + inline RealType cdf(const hypergeometric_distribution& dist, const std::uint64_t& x) + { + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!dist.check_params(function, &result)) + return result; + if(!dist.check_x(x, function, &result)) + return result; + + return boost::math::detail::hypergeometric_cdf( + x, dist.defective(), dist.sample_count(), dist.total(), false, Policy()); + } + + template + inline RealType cdf(const hypergeometric_distribution& dist, const U& x) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(x); + auto u = static_cast(lltrunc(r, typename policies::normalise >::type())); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return cdf(dist, u); + } + + template + inline RealType cdf(const complemented2_type, std::uint64_t>& c) + { + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!c.dist.check_params(function, &result)) + return result; + if(!c.dist.check_x(c.param, function, &result)) + return result; + + return boost::math::detail::hypergeometric_cdf( + c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), true, Policy()); + } + + template + inline RealType cdf(const complemented2_type, U>& c) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(c.param); + auto u = static_cast(lltrunc(r, typename policies::normalise >::type())); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return cdf(complement(c.dist, u)); + } + + template + inline RealType quantile(const hypergeometric_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + const char* function = "boost::math::quantile(const hypergeometric_distribution<%1%>&, %1%)"; + if (false == dist.check_params(function, &result)) + return result; + + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + return static_cast(detail::hypergeometric_quantile(p, RealType(1 - p), dist.defective(), dist.sample_count(), dist.total(), Policy())); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + const char* function = "quantile(const complemented2_type, %1%>&)"; + if (false == c.dist.check_params(function, &result)) + return result; + if (false == detail::check_probability(function, c.param, &result, Policy())) + return result; + + return static_cast(detail::hypergeometric_quantile(RealType(1 - c.param), c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), Policy())); + } // quantile + + // https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution + + template + inline RealType mean(const hypergeometric_distribution& dist) + { + return static_cast(dist.defective() * dist.sample_count()) / dist.total(); + } // RealType mean(const hypergeometric_distribution& dist) + + template + inline RealType variance(const hypergeometric_distribution& dist) + { + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return n * r * (N - r) * (N - n) / (N * N * (N - 1)); + } // RealType variance(const hypergeometric_distribution& dist) + + template + inline RealType mode(const hypergeometric_distribution& dist) + { + BOOST_MATH_STD_USING + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return floor((r + 1) * (n + 1) / (N + 2)); + } + + template + inline RealType skewness(const hypergeometric_distribution& dist) + { + BOOST_MATH_STD_USING + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return (N - 2 * r) * sqrt(N - 1) * (N - 2 * n) / (sqrt(n * r * (N - r) * (N - n)) * (N - 2)); + } // RealType skewness(const hypergeometric_distribution& dist) + + template + inline RealType kurtosis_excess(const hypergeometric_distribution& dist) + { + // https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution shown as plain text: + // mean | (m n)/N + // standard deviation | sqrt((m n(N - m) (N - n))/(N - 1))/N + // variance | (m n(1 - m/N) (N - n))/((N - 1) N) + // skewness | (sqrt(N - 1) (N - 2 m) (N - 2 n))/((N - 2) sqrt(m n(N - m) (N - n))) + // kurtosis | ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n)) + // Kurtosis[HypergeometricDistribution[n, m, N]] + RealType m = static_cast(dist.defective()); // Failures or success events. (Also symbols K or M are used). + RealType n = static_cast(dist.sample_count()); // draws or trials. + RealType n2 = n * n; // n^2 + RealType N = static_cast(dist.total()); // Total population from which n draws or trials are made. + RealType N2 = N * N; // N^2 + // result = ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n)); + RealType result = ((N-1)*N2*((3*m*(N-m)*(n2*(-N)+(n-2)*N2+6*n*(N-n)))/N2-6*n*(N-n)+N*(N+1)))/(m*n*(N-3)*(N-2)*(N-m)*(N-n)); + // Agrees with kurtosis hypergeometric distribution(50,200,500) kurtosis = 2.96917 + // N[kurtosis[hypergeometricdistribution(50,200,500)], 55] 2.969174035736058474901169623721804275002985337280263464 + return result; + } // RealType kurtosis_excess(const hypergeometric_distribution& dist) + + template + inline RealType kurtosis(const hypergeometric_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } // RealType kurtosis_excess(const hypergeometric_distribution& dist) +}} // namespaces + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // include guard diff --git a/third-party/boost-math/include/boost/math/distributions/inverse_chi_squared.hpp b/third-party/boost-math/include/boost/math/distributions/inverse_chi_squared.hpp new file mode 100644 index 0000000000000..1a3c680d2360e --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/inverse_chi_squared.hpp @@ -0,0 +1,398 @@ +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP +#define BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP + +#include +#include +#include +#include // for incomplete beta. +#include // for complements. +#include // for error checks. +#include // for isfinite + +// See http://en.wikipedia.org/wiki/Scaled-inverse-chi-square_distribution +// for definitions of this scaled version. +// See http://en.wikipedia.org/wiki/Inverse-chi-square_distribution +// for unscaled version. + +// http://reference.wolfram.com/mathematica/ref/InverseChiSquareDistribution.html +// Weisstein, Eric W. "Inverse Chi-Squared Distribution." From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/InverseChi-SquaredDistribution.html + +namespace boost{ namespace math{ + +namespace detail +{ + template + BOOST_MATH_GPU_ENABLED inline bool check_inverse_chi_squared( // Check both distribution parameters. + const char* function, + RealType degrees_of_freedom, // degrees_of_freedom (aka nu). + RealType scale, // scale (aka sigma^2) + RealType* result, + const Policy& pol) + { + return check_scale(function, scale, result, pol) + && check_df(function, degrees_of_freedom, + result, pol); + } // bool check_inverse_chi_squared +} // namespace detail + +template > +class inverse_chi_squared_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED inverse_chi_squared_distribution(RealType df, RealType l_scale) : m_df(df), m_scale (l_scale) + { + RealType result; + detail::check_df( + "boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_df, &result, Policy()) + && detail::check_scale( +"boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_scale, &result, Policy()); + } // inverse_chi_squared_distribution constructor + + BOOST_MATH_GPU_ENABLED inverse_chi_squared_distribution(RealType df = 1) : m_df(df) + { + RealType result; + m_scale = 1 / m_df ; // Default scale = 1 / degrees of freedom (Wikipedia definition 1). + detail::check_df( + "boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_df, &result, Policy()); + } // inverse_chi_squared_distribution + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom()const + { + return m_df; // aka nu + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; // aka xi + } + + // Parameter estimation: NOT implemented yet. + //static RealType find_degrees_of_freedom( + // RealType difference_from_variance, + // RealType alpha, + // RealType beta, + // RealType variance, + // RealType hint = 100); + +private: + // Data members: + RealType m_df; // degrees of freedom are treated as a real number. + RealType m_scale; // distribution scale. + +}; // class chi_squared_distribution + +typedef inverse_chi_squared_distribution inverse_chi_squared; + +#ifdef __cpp_deduction_guides +template +inverse_chi_squared_distribution(RealType)->inverse_chi_squared_distribution::type>; +template +inverse_chi_squared_distribution(RealType,RealType)->inverse_chi_squared_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const inverse_chi_squared_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // 0 to + infinity. +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const inverse_chi_squared_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(static_cast(0), tools::max_value()); // 0 to + infinity. +} + +template +BOOST_MATH_GPU_ENABLED RealType pdf(const inverse_chi_squared_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + RealType error_result; + + constexpr auto function = "boost::math::pdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_inverse_chi_squared + (function, df, scale, &error_result, Policy()) + ) + { // Bad distribution. + return error_result; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { // Bad x. + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); + } + + if(x == 0) + { // Treat as special case. + return 0; + } + // Wikipedia scaled inverse chi sq (df, scale) related to inv gamma (df/2, df * scale /2) + // so use inverse gamma pdf with shape = df/2, scale df * scale /2 + // RealType shape = df /2; // inv_gamma shape + // RealType scale = df * scale/2; // inv_gamma scale + // RealType result = gamma_p_derivative(shape, scale / x, Policy()) * scale / (x * x); + RealType result = df * scale/2 / x; + if(result < tools::min_value()) + return 0; // Random variable is near enough infinite. + result = gamma_p_derivative(df/2, result, Policy()) * df * scale/2; + if(result != 0) // prevent 0 / 0, gamma_p_derivative -> 0 faster than x^2 + result /= (x * x); + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const inverse_chi_squared_distribution& dist, const RealType& x) +{ + constexpr auto function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + RealType error_result; + + if(false == + detail::check_inverse_chi_squared(function, df, scale, &error_result, Policy()) + ) + { // Bad distribution. + return error_result; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { // Bad x. + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); + } + if (x == 0) + { // Treat zero as a special case. + return 0; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = boost::math::gamma_q(shape, scale / x, Policy()); // inverse_gamma code. + return boost::math::gamma_q(df / 2, (df * (scale / 2)) / x, Policy()); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const inverse_chi_squared_distribution& dist, const RealType& p) +{ + using boost::math::gamma_q_inv; + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + + constexpr auto function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, df, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy())) + { + return error_result; + } + if(false == detail::check_probability( + function, p, &error_result, Policy())) + { + return error_result; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = scale / gamma_q_inv(shape, p, Policy()); + RealType result = gamma_q_inv(df /2, p, Policy()); + if(result == 0) + return policies::raise_overflow_error(function, "Random variable is infinite.", Policy()); + result = df * (scale / 2) / result; + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + using boost::math::gamma_q_inv; + RealType const& df = c.dist.degrees_of_freedom(); + RealType const& scale = c.dist.scale(); + RealType const& x = c.param; + constexpr auto function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, df, &error_result, Policy())) + { + return error_result; + } + if (x == 0) + { // Treat zero as a special case. + return 1; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be > 0 !", x, Policy()); + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = gamma_p(shape, scale/c.param, Policy()); use inv_gamma. + + return gamma_p(df / 2, (df * scale/2) / x, Policy()); // OK +} // cdf(complemented + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + using boost::math::gamma_q_inv; + + RealType const& df = c.dist.degrees_of_freedom(); + RealType const& scale = c.dist.scale(); + RealType const& q = c.param; + constexpr auto function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df(function, df, &error_result, Policy())) + { + return error_result; + } + if(false == detail::check_probability(function, q, &error_result, Policy())) + { + return error_result; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = scale / gamma_p_inv(shape, q, Policy()); // using inv_gamma. + RealType result = gamma_p_inv(df/2, q, Policy()); + if(result == 0) + return policies::raise_overflow_error(function, "Random variable is infinite.", Policy()); + result = (df * scale / 2) / result; + return result; +} // quantile(const complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const inverse_chi_squared_distribution& dist) +{ // Mean of inverse Chi-Squared distribution. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + + constexpr auto function = "boost::math::mean(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 2) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a mode for degrees of freedom > 2, but got degrees of freedom = %1%.", + df, Policy()); + return (df * scale) / (df - 2); +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const inverse_chi_squared_distribution& dist) +{ // Variance of inverse Chi-Squared distribution. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + constexpr auto function = "boost::math::variance(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 4) + { + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a variance for degrees of freedom > 4, but got degrees of freedom = %1%.", + df, Policy()); + } + return 2 * df * df * scale * scale / ((df - 2)*(df - 2) * (df - 4)); +} // variance + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const inverse_chi_squared_distribution& dist) +{ // mode is not defined in Mathematica. + // See Discussion section http://en.wikipedia.org/wiki/Talk:Scaled-inverse-chi-square_distribution + // for origin of the formula used below. + + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + constexpr auto function = "boost::math::mode(const inverse_chi_squared_distribution<%1%>&)"; + if(df < 0) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.", + df, Policy()); + return (df * scale) / (df + 2); +} + +//template +//inline RealType median(const inverse_chi_squared_distribution& dist) +//{ // Median is given by Quantile[dist, 1/2] +// RealType df = dist.degrees_of_freedom(); +// if(df <= 1) +// return tools::domain_error( +// BOOST_CURRENT_FUNCTION, +// "The inverse_Chi-Squared distribution only has a median for degrees of freedom >= 0, but got degrees of freedom = %1%.", +// df); +// return df; +//} +// Now implemented via quantile(half) in derived accessors. + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const inverse_chi_squared_distribution& dist) +{ + BOOST_MATH_STD_USING // For ADL + RealType df = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::skewness(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 6) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a skewness for degrees of freedom > 6, but got degrees of freedom = %1%.", + df, Policy()); + + return 4 * sqrt (2 * (df - 4)) / (df - 6); // Not a function of scale. +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const inverse_chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 8) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a kurtosis for degrees of freedom > 8, but got degrees of freedom = %1%.", + df, Policy()); + + return kurtosis_excess(dist) + 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const inverse_chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 8) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a kurtosis excess for degrees of freedom > 8, but got degrees of freedom = %1%.", + df, Policy()); + + return 12 * (5 * df - 22) / ((df - 6 )*(df - 8)); // Not a function of scale. +} + +// +// Parameter estimation comes last: +// + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/inverse_gamma.hpp b/third-party/boost-math/include/boost/math/distributions/inverse_gamma.hpp new file mode 100644 index 0000000000000..6aa798ed826a0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/inverse_gamma.hpp @@ -0,0 +1,504 @@ +// inverse_gamma.hpp + +// Copyright Paul A. Bristow 2010. +// Copyright John Maddock 2010. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_INVERSE_GAMMA_HPP +#define BOOST_STATS_INVERSE_GAMMA_HPP + +// Inverse Gamma Distribution is a two-parameter family +// of continuous probability distributions +// on the positive real line, which is the distribution of +// the reciprocal of a variable distributed according to the gamma distribution. + +// http://en.wikipedia.org/wiki/Inverse-gamma_distribution +// http://rss.acs.unt.edu/Rdoc/library/pscl/html/igamma.html + +// See also gamma distribution at gamma.hpp: +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm +// http://mathworld.wolfram.com/GammaDistribution.html +// http://en.wikipedia.org/wiki/Gamma_distribution + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ +namespace detail +{ + +template +BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma_shape( + const char* function, // inverse_gamma + RealType shape, // shape aka alpha + RealType* result, // to update, perhaps with NaN + const Policy& pol) +{ // Sources say shape argument must be > 0 + // but seems logical to allow shape zero as special case, + // returning pdf and cdf zero (but not < 0). + // (Functions like mean, variance with other limits on shape are checked + // in version including an operator & limit below). + if((shape < 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be >= 0 !", shape, pol); + return false; + } + return true; +} //bool check_inverse_gamma_shape + +template +BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_inverse_gamma( + const char* function, // TODO swap these over, so shape is first. + RealType scale, // scale aka beta + RealType shape, // shape aka alpha + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) + && check_inverse_gamma_shape(function, shape, result, pol); +} // bool check_inverse_gamma + +} // namespace detail + +template > +class inverse_gamma_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit inverse_gamma_distribution(RealType l_shape = 1, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_inverse_gamma( + "boost::math::inverse_gamma_distribution<%1%>::inverse_gamma_distribution", + l_scale, l_shape, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType shape()const + { + return m_shape; + } + + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +using inverse_gamma = inverse_gamma_distribution; +// typedef - but potential clash with name of inverse gamma *function*. +// but there is a typedef for the gamma distribution (gamma) + +#ifdef __cpp_deduction_guides +template +inverse_gamma_distribution(RealType)->inverse_gamma_distribution::type>; +template +inverse_gamma_distribution(RealType,RealType)->inverse_gamma_distribution::type>; +#endif + +// Allow random variable x to be zero, treated as a special case (unlike some definitions). + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const inverse_gamma_distribution& /* dist */) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const inverse_gamma_distribution& /* dist */) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if(x == 0) + { // Treat random variate zero as a special case. + return 0; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad. + return result; + } + result = scale / x; + if(result < tools::min_value()) + return 0; // random variable is infinite or so close as to make no difference. + result = gamma_p_derivative(shape, result, Policy()) * scale; + if(0 != result) + { + if(x < 0) + { + // x * x may under or overflow, likewise our result, + // so be extra careful about the arithmetic: + RealType lim = tools::max_value() * x; + if(lim < result) + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + result /= x; + if(lim < result) + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + result /= x; + } + result /= (x * x); + } + + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::lgamma; + + constexpr auto function = "boost::math::logpdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = -boost::math::numeric_limits::infinity(); + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if(x == 0) + { // Treat random variate zero as a special case. + return result; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad. + return result; + } + result = scale / x; + if(result < tools::min_value()) + return result; // random variable is infinite or so close as to make no difference. + + // x * x may under or overflow, likewise our result + if (!(boost::math::isfinite)(x*x)) + { + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + } + + return shape * log(scale) + (-shape-1)*log(x) - lgamma(shape) - (scale/x); +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if (x == 0) + { // Treat zero as a special case. + return 0; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad + return result; + } + result = boost::math::gamma_q(shape, scale / x, Policy()); + // result = tgamma(shape, scale / x) / tgamma(shape); // naive using tgamma + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const inverse_gamma_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::gamma_q_inv; + + constexpr auto function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = gamma_q_inv(shape, p, Policy()); + if((result < 1) && (result * tools::max_value() < scale)) + return policies::raise_overflow_error(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy()); + result = scale / result; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_inverse_gamma_x(function, c.param, &result, Policy())) + return result; + + if(c.param == 0) + return 1; // Avoid division by zero + + result = gamma_p(shape, scale/c.param, Policy()); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = gamma_p_inv(shape, q, Policy()); + if((result < 1) && (result * tools::max_value() < scale)) + return policies::raise_overflow_error(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy()); + result = scale / result; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::mean(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 1) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined mean it must be > 1", shape, Policy()); + return result; + } + result = scale / (shape - 1); + return result; +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::variance(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 2) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined variance it must be > 2", shape, Policy()); + return result; + } + result = (scale * scale) / ((shape - 1) * (shape -1) * (shape -2)); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::mode(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { + return result; + } + // Only defined for shape >= 0, but is checked by check_inverse_gamma. + result = scale / (shape + 1); + return result; +} + +//template +//inline RealType median(const gamma_distribution& dist) +//{ // Wikipedia does not define median, + // so rely on default definition quantile(0.5) in derived accessors. +// return result. +//} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::skewness(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 3) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined skewness it must be > 3", shape, Policy()); + return result; + } + result = (4 * sqrt(shape - 2) ) / (shape - 3); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::kurtosis_excess(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 4) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined kurtosis excess it must be > 4", shape, Policy()); + return result; + } + result = (30 * shape - 66) / ((shape - 3) * (shape - 4)); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const inverse_gamma_distribution& dist) +{ + constexpr auto function = "boost::math::kurtosis(const inverse_gamma_distribution<%1%>&)"; + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 4) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined kurtosis it must be > 4", shape, Policy()); + return result; + } + return kurtosis_excess(dist) + 3; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_INVERSE_GAMMA_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/inverse_gaussian.hpp b/third-party/boost-math/include/boost/math/distributions/inverse_gaussian.hpp new file mode 100644 index 0000000000000..20d3b6bdd56ba --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/inverse_gaussian.hpp @@ -0,0 +1,555 @@ +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_INVERSE_GAUSSIAN_HPP +#define BOOST_STATS_INVERSE_GAUSSIAN_HPP + +#ifdef _MSC_VER +#pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +// http://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution +// http://mathworld.wolfram.com/InverseGaussianDistribution.html + +// The normal-inverse Gaussian distribution +// also called the Wald distribution (some sources limit this to when mean = 1). + +// It is the continuous probability distribution +// that is defined as the normal variance-mean mixture where the mixing density is the +// inverse Gaussian distribution. The tails of the distribution decrease more slowly +// than the normal distribution. It is therefore suitable to model phenomena +// where numerically large values are more probable than is the case for the normal distribution. + +// The Inverse Gaussian distribution was first studied in relationship to Brownian motion. +// In 1956 M.C.K. Tweedie used the name 'Inverse Gaussian' because there is an inverse +// relationship between the time to cover a unit distance and distance covered in unit time. + +// Examples are returns from financial assets and turbulent wind speeds. +// The normal-inverse Gaussian distributions form +// a subclass of the generalised hyperbolic distributions. + +// See also + +// http://en.wikipedia.org/wiki/Normal_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Normal Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/NormalDistribution.html + +// http://www.jstatsoft.org/v26/i04/paper General class of inverse Gaussian distributions. +// ig package - withdrawn but at http://cran.r-project.org/src/contrib/Archive/ig/ + +// http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/SuppDists/html/inverse_gaussian.html +// R package for dinverse_gaussian, ... + +// http://www.statsci.org/s/inverse_gaussian.s and http://www.statsci.org/s/inverse_gaussian.html + +#include +#include +#include // for erf/erfc. +#include +#include +#include +#include // for gamma function +#include +#include +#include +#include + +namespace boost{ namespace math{ + +template > +class inverse_gaussian_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit inverse_gaussian_distribution(RealType l_mean = 1, RealType l_scale = 1) + : m_mean(l_mean), m_scale(l_scale) + { // Default is a 1,1 inverse_gaussian distribution. + constexpr auto function = "boost::math::inverse_gaussian_distribution<%1%>::inverse_gaussian_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_mean, &result, Policy()); + detail::check_x_gt0(function, l_mean, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType mean()const + { // alias for location. + return m_mean; // aka mu + } + + // Synonyms, provided to allow generic use of find_location and find_scale. + BOOST_MATH_GPU_ENABLED RealType location()const + { // location, aka mu. + return m_mean; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { // scale, aka lambda. + return m_scale; + } + + BOOST_MATH_GPU_ENABLED RealType shape()const + { // shape, aka phi = lambda/mu. + return m_scale / m_mean; + } + +private: + // + // Data members: + // + RealType m_mean; // distribution mean or location, aka mu. + RealType m_scale; // distribution standard deviation or scale, aka lambda. +}; // class normal_distribution + +using inverse_gaussian = inverse_gaussian_distribution; + +#ifdef __cpp_deduction_guides +template +inverse_gaussian_distribution(RealType)->inverse_gaussian_distribution::type>; +template +inverse_gaussian_distribution(RealType,RealType)->inverse_gaussian_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const inverse_gaussian_distribution& /*dist*/) +{ // Range of permissible values for random variable x, zero to max. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0.), max_value()); // - to + max value. +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const inverse_gaussian_distribution& /*dist*/) +{ // Range of supported values for random variable x, zero to max. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0.), max_value()); // - to + max value. +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Probability Density Function + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 0; + constexpr auto function = "boost::math::pdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + + if (x == 0) + { + return 0; // Convenient, even if not defined mathematically. + } + + result = + sqrt(scale / (constants::two_pi() * x * x * x)) + * exp(-scale * (x - mean) * (x - mean) / (2 * x * mean * mean)); + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Probability Density Function + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = -boost::math::numeric_limits::infinity(); + constexpr auto function = "boost::math::logpdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + + if (x == 0) + { + return boost::math::numeric_limits::quiet_NaN(); // Convenient, even if not defined mathematically. log(0) + } + + const RealType two_pi = boost::math::constants::two_pi(); + + result = (-scale*pow(mean - x, RealType(2))/(mean*mean*x) + log(scale) - 3*log(x) - log(two_pi)) / 2; + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Cumulative Density Function. + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + constexpr auto function = "boost::math::cdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + if (x == 0) + { + return 0; // Convenient, even if not defined mathematically. + } + // Problem with this formula for large scale > 1000 or small x + // so use normal distribution version: + // Wikipedia CDF equation http://en.wikipedia.org/wiki/Inverse_Gaussian_distribution. + + normal_distribution n01; + + RealType n0 = sqrt(scale / x); + n0 *= ((x / mean) -1); + RealType n1 = cdf(n01, n0); + RealType expfactor = exp(2 * scale / mean); + RealType n3 = - sqrt(scale / x); + n3 *= (x / mean) + 1; + RealType n4 = cdf(n01, n3); + result = n1 + expfactor * n4; + return result; +} // cdf + +template +struct inverse_gaussian_quantile_functor +{ + + BOOST_MATH_GPU_ENABLED inverse_gaussian_quantile_functor(const boost::math::inverse_gaussian_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(RealType const& x) + { + RealType c = cdf(distribution, x); + RealType fx = c - prob; // Difference cdf - value - to minimize. + RealType dx = pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } + private: + const boost::math::inverse_gaussian_distribution distribution; + RealType prob; +}; + +template +struct inverse_gaussian_quantile_complement_functor +{ + BOOST_MATH_GPU_ENABLED inverse_gaussian_quantile_complement_functor(const boost::math::inverse_gaussian_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(RealType const& x) + { + RealType c = cdf(complement(distribution, x)); + RealType fx = c - prob; // Difference cdf - value - to minimize. + RealType dx = -pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + //return std::tr1::make_tuple(fx, dx); if available. + return boost::math::make_tuple(fx, dx); + } + private: + const boost::math::inverse_gaussian_distribution distribution; + RealType prob; +}; + +namespace detail +{ + template + BOOST_MATH_GPU_ENABLED inline RealType guess_ig(RealType p, RealType mu = 1, RealType lambda = 1) + { // guess at random variate value x for inverse gaussian quantile. + BOOST_MATH_STD_USING + using boost::math::policies::policy; + // Error type. + using boost::math::policies::overflow_error; + // Action. + using boost::math::policies::ignore_error; + + using no_overthrow_policy = policy>; + + RealType x; // result is guess at random variate value x. + RealType phi = lambda / mu; + if (phi > 2.) + { // Big phi, so starting to look like normal Gaussian distribution. + // + // Whitmore, G.A. and Yalovsky, M. + // A normalising logarithmic transformation for inverse Gaussian random variables, + // Technometrics 20-2, 207-208 (1978), but using expression from + // V Seshadri, Inverse Gaussian distribution (1998) ISBN 0387 98618 9, page 6. + + normal_distribution n01; + x = mu * exp(quantile(n01, p) / sqrt(phi) - 1/(2 * phi)); + } + else + { // phi < 2 so much less symmetrical with long tail, + // so use gamma distribution as an approximation. + using boost::math::gamma_distribution; + + // Define the distribution, using gamma_nooverflow: + using gamma_nooverflow = gamma_distribution; + + gamma_nooverflow g(static_cast(0.5), static_cast(1.)); + + // R qgamma(0.2, 0.5, 1) = 0.0320923 + RealType qg = quantile(complement(g, p)); + x = lambda / (qg * 2); + // + if (x > mu/2) // x > mu /2? + { // x too large for the gamma approximation to work well. + //x = qgamma(p, 0.5, 1.0); // qgamma(0.270614, 0.5, 1) = 0.05983807 + RealType q = quantile(g, p); + // x = mu * exp(q * static_cast(0.1)); // Said to improve at high p + // x = mu * x; // Improves at high p? + x = mu * exp(q / sqrt(phi) - 1/(2 * phi)); + } + } + return x; + } // guess_ig +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const inverse_gaussian_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + // No closed form exists so guess and use Newton Raphson iteration. + + RealType mean = dist.mean(); + RealType scale = dist.scale(); + constexpr auto function = "boost::math::quantile(const inverse_gaussian_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + if (p == 0) + { + return 0; // Convenient, even if not defined mathematically? + } + if (p == 1) + { // overflow + result = policies::raise_overflow_error(function, + "probability parameter is 1, but must be < 1!", Policy()); + return result; // infinity; + } + + RealType guess = detail::guess_ig(p, dist.mean(), dist.scale()); + using boost::math::tools::max_value; + + RealType min = static_cast(0); // Minimum possible value is bottom of range of distribution. + RealType max = max_value();// Maximum possible value is top of range. + // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. + // digits used to control how accurate to try to make the result. + // To allow user to control accuracy versus speed, + int get_digits = policies::digits();// get digits from policy, + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); // and max iterations. + using boost::math::tools::newton_raphson_iterate; + result = + newton_raphson_iterate(inverse_gaussian_quantile_functor(dist, p), guess, min, max, get_digits, max_iter); + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType scale = c.dist.scale(); + RealType mean = c.dist.mean(); + RealType x = c.param; + constexpr auto function = "boost::math::cdf(const complement(inverse_gaussian_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + if(false == detail::check_positive_x(function, x, &result, Policy())) + return result; + + normal_distribution n01; + RealType n0 = sqrt(scale / x); + n0 *= ((x / mean) -1); + RealType cdf_1 = cdf(complement(n01, n0)); + + RealType expfactor = exp(2 * scale / mean); + RealType n3 = - sqrt(scale / x); + n3 *= (x / mean) + 1; + + //RealType n5 = +sqrt(scale/x) * ((x /mean) + 1); // note now positive sign. + RealType n6 = cdf(complement(n01, +sqrt(scale/x) * ((x /mean) + 1))); + // RealType n4 = cdf(n01, n3); // = + result = cdf_1 - expfactor * n6; + return result; +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = c.dist.scale(); + RealType mean = c.dist.mean(); + constexpr auto function = "boost::math::quantile(const complement(inverse_gaussian_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + RealType guess = detail::guess_ig(q, mean, scale); + // Complement. + using boost::math::tools::max_value; + + RealType min = static_cast(0); // Minimum possible value is bottom of range of distribution. + RealType max = max_value();// Maximum possible value is top of range. + // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. + // digits used to control how accurate to try to make the result. + int get_digits = policies::digits(); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + using boost::math::tools::newton_raphson_iterate; + result = newton_raphson_iterate(inverse_gaussian_quantile_complement_functor(c.dist, q), guess, min, max, get_digits, max_iter); + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const inverse_gaussian_distribution& dist) +{ // aka mu + return dist.mean(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType scale(const inverse_gaussian_distribution& dist) +{ // aka lambda + return dist.scale(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType shape(const inverse_gaussian_distribution& dist) +{ // aka phi + return dist.shape(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = sqrt(mean * mean * mean / scale); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = mean * (sqrt(1 + (9 * mean * mean)/(4 * scale * scale)) + - 3 * mean / (2 * scale)); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 3 * sqrt(mean/scale); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const inverse_gaussian_distribution& dist) +{ + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 15 * mean / scale -3; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const inverse_gaussian_distribution& dist) +{ + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 15 * mean / scale; + return result; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_INVERSE_GAUSSIAN_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/kolmogorov_smirnov.hpp b/third-party/boost-math/include/boost/math/distributions/kolmogorov_smirnov.hpp new file mode 100644 index 0000000000000..0934344134d23 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/kolmogorov_smirnov.hpp @@ -0,0 +1,511 @@ +// Kolmogorov-Smirnov 1st order asymptotic distribution +// Copyright Evan Miller 2020 +// +// 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) +// +// The Kolmogorov-Smirnov test in statistics compares two empirical distributions, +// or an empirical distribution against any theoretical distribution. It makes +// use of a specific distribution which doesn't have a formal name, but which +// is often called the Kolmogorv-Smirnov distribution for lack of anything +// better. This file implements the limiting form of this distribution, first +// identified by Andrey Kolmogorov in +// +// Kolmogorov, A. (1933) "Sulla Determinazione Empirica di una Legge di +// Distribuzione." Giornale dell' Istituto Italiano degli Attuari +// +// This limiting form of the CDF is a first-order Taylor expansion that is +// easily implemented by the fourth Jacobi Theta function (setting z=0). The +// PDF is then implemented here as a derivative of the Theta function. Note +// that this derivative is with respect to x, which enters into \tau, and not +// with respect to the z argument, which is always zero, and so the derivative +// identities in DLMF 20.4 do not apply here. +// +// A higher order order expansion is possible, and was first outlined by +// +// Pelz W, Good IJ (1976). "Approximating the Lower Tail-Areas of the +// Kolmogorov-Smirnov One-sample Statistic." Journal of the Royal Statistical +// Society B. +// +// The terms in this expansion get fairly complicated, and as far as I know the +// Pelz-Good expansion is not used in any statistics software. Someone could +// consider updating this implementation to use the Pelz-Good expansion in the +// future, but the math gets considerably hairier with each additional term. +// +// A formula for an exact version of the Kolmogorov-Smirnov test is laid out in +// Equation 2.4.4 of +// +// Durbin J (1973). "Distribution Theory for Tests Based on the Sample +// Distribution Func- tion." In SIAM CBMS-NSF Regional Conference Series in +// Applied Mathematics. SIAM, Philadelphia, PA. +// +// which is available in book form from Amazon and others. This exact version +// involves taking powers of large matrices. To do that right you need to +// compute eigenvalues and eigenvectors, which are beyond the scope of Boost. +// (Some recent work indicates the exact form can also be computed via FFT, see +// https://cran.r-project.org/web/packages/KSgeneral/KSgeneral.pdf). +// +// Even if the CDF of the exact distribution could be computed using Boost +// libraries (which would be cumbersome), the PDF would present another +// difficulty. Therefore I am limiting this implementation to the asymptotic +// form, even though the exact form has trivial values for certain specific +// values of x and n. For more on trivial values see +// +// Ruben H, Gambino J (1982). "The Exact Distribution of Kolmogorov's Statistic +// Dn for n <= 10." Annals of the Institute of Statistical Mathematics. +// +// For a good bibliography and overview of the various algorithms, including +// both exact and asymptotic forms, see +// https://www.jstatsoft.org/article/view/v039i11 +// +// As for this implementation: the distribution is parameterized by n (number +// of observations) in the spirit of chi-squared's degrees of freedom. It then +// takes a single argument x. In terms of the Kolmogorov-Smirnov statistical +// test, x represents the distribution of D_n, where D_n is the maximum +// difference between the CDFs being compared, that is, +// +// D_n = sup|F_n(x) - G(x)| +// +// In the exact distribution, x is confined to the support [0, 1], but in this +// limiting approximation, we allow x to exceed unity (similar to how a normal +// approximation always spills over any boundaries). +// +// As mentioned previously, the CDF is implemented using the \tau +// parameterization of the fourth Jacobi Theta function as +// +// CDF=theta_4(0|2*x*x*n/pi) +// +// The PDF is a hand-coded derivative of that function. Actually, there are two +// (independent) derivatives, as separate code paths are used for "small x" +// (2*x*x*n < pi) and "large x", mirroring the separate code paths in the +// Jacobi Theta implementation to achieve fast convergence. Quantiles are +// computed using a Newton-Raphson iteration from an initial guess that I +// arrived at by trial and error. +// +// The mean and variance are implemented using simple closed-form expressions. +// Skewness and kurtosis use slightly more complicated closed-form expressions +// that involve the zeta function. The mode is calculated at run-time by +// maximizing the PDF. If you have an analytical solution for the mode, feel +// free to plop it in. +// +// The CDF and PDF could almost certainly be re-implemented and sped up using a +// polynomial or rational approximation, since the only meaningful argument is +// x * sqrt(n). But that is left as an exercise for the next maintainer. +// +// In the future, the Pelz-Good approximation could be added. I suggest adding +// a second parameter representing the order, e.g. +// +// kolmogorov_smirnov_dist<>(100) // N=100, order=1 +// kolmogorov_smirnov_dist<>(100, 1) // N=100, order=1, i.e. Kolmogorov's formula +// kolmogorov_smirnov_dist<>(100, 4) // N=100, order=4, i.e. Pelz-Good formula +// +// The exact distribution could be added to the API with a special order +// parameter (e.g. 0 or infinity), or a separate distribution type altogether +// (e.g. kolmogorov_smirnov_exact_distribution). +// +#ifndef BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP +#define BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP + +#include +#include +#include +#include +#include +#include // Newton-Raphson +#include // For the mode + +namespace boost { namespace math { + +namespace detail { +template +inline RealType kolmogorov_smirnov_quantile_guess(RealType p) { + // Choose a starting point for the Newton-Raphson iteration + if (p > 0.9) + return RealType(1.8) - 5 * (1 - p); + if (p < 0.3) + return p + RealType(0.45); + return p + RealType(0.3); +} + +// d/dk (theta2(0, 1/(2*k*k/M_PI))/sqrt(2*k*k*M_PI)) +template +RealType kolmogorov_smirnov_pdf_small_x(RealType x, RealType n, const Policy&) { + BOOST_MATH_STD_USING + RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0); + RealType eps = policies::get_epsilon(); + int i = 0; + RealType pi2 = constants::pi_sqr(); + RealType x2n = x*x*n; + if (x2n*x2n == 0.0) { + return static_cast(0); + } + while (true) { + delta = exp(-RealType(i+0.5)*RealType(i+0.5)*pi2/(2*x2n)) * (RealType(i+0.5)*RealType(i+0.5)*pi2 - x2n); + + if (delta == 0.0) + break; + + if (last_delta != 0.0 && fabs(delta/last_delta) < eps) + break; + + value += delta + delta; + last_delta = delta; + i++; + } + + return value * sqrt(n) * constants::root_half_pi() / (x2n*x2n); +} + +// d/dx (theta4(0, 2*x*x*n/M_PI)) +template +inline RealType kolmogorov_smirnov_pdf_large_x(RealType x, RealType n, const Policy&) { + BOOST_MATH_STD_USING + RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0); + RealType eps = policies::get_epsilon(); + int i = 1; + while (true) { + delta = 8*x*i*i*exp(-2*i*i*x*x*n); + + if (delta == 0.0) + break; + + if (last_delta != 0.0 && fabs(delta / last_delta) < eps) + break; + + if (i%2 == 0) + delta = -delta; + + value += delta; + last_delta = delta; + i++; + } + + return value * n; +} + +} // detail + +template > + class kolmogorov_smirnov_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + // Constructor + kolmogorov_smirnov_distribution( RealType n ) : n_obs_(n) + { + RealType result; + detail::check_df( + "boost::math::kolmogorov_smirnov_distribution<%1%>::kolmogorov_smirnov_distribution", n_obs_, &result, Policy()); + } + + RealType number_of_observations()const + { + return n_obs_; + } + + private: + + RealType n_obs_; // positive integer +}; + +typedef kolmogorov_smirnov_distribution kolmogorov_k; // Convenience typedef for double version. + +#ifdef __cpp_deduction_guides +template +kolmogorov_smirnov_distribution(RealType)->kolmogorov_smirnov_distribution::type>; +#endif + +namespace detail { +template +struct kolmogorov_smirnov_quantile_functor +{ + kolmogorov_smirnov_quantile_functor(const boost::math::kolmogorov_smirnov_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + + boost::math::tuple operator()(RealType const& x) + { + RealType fx = cdf(distribution, x) - prob; // Difference cdf - value - to minimize. + RealType dx = pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } +private: + const boost::math::kolmogorov_smirnov_distribution distribution; + RealType prob; +}; + +template +struct kolmogorov_smirnov_complementary_quantile_functor +{ + kolmogorov_smirnov_complementary_quantile_functor(const boost::math::kolmogorov_smirnov_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + + boost::math::tuple operator()(RealType const& x) + { + RealType fx = cdf(complement(distribution, x)) - prob; // Difference cdf - value - to minimize. + RealType dx = -pdf(distribution, x); // pdf is the negative of the derivative of (1-CDF) + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } +private: + const boost::math::kolmogorov_smirnov_distribution distribution; + RealType prob; +}; + +template +struct kolmogorov_smirnov_negative_pdf_functor +{ + RealType operator()(RealType const& x) { + if (2*x*x < constants::pi()) { + return -kolmogorov_smirnov_pdf_small_x(x, static_cast(1), Policy()); + } + return -kolmogorov_smirnov_pdf_large_x(x, static_cast(1), Policy()); + } +}; +} // namespace detail + +template +inline const std::pair range(const kolmogorov_smirnov_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline const std::pair support(const kolmogorov_smirnov_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + // In the exact distribution, the upper limit would be 1. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline RealType pdf(const kolmogorov_smirnov_distribution& dist, const RealType& x) +{ + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType n = dist.number_of_observations(); + RealType error_result; + static const char* function = "boost::math::pdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + if (x < 0 || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Kolmogorov-Smirnov parameter was %1%, but must be > 0 !", x, Policy()); + } + + if (2*x*x*n < constants::pi()) { + return detail::kolmogorov_smirnov_pdf_small_x(x, n, Policy()); + } + + return detail::kolmogorov_smirnov_pdf_large_x(x, n, Policy()); +} // pdf + +template +inline RealType cdf(const kolmogorov_smirnov_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + static const char* function = "boost::math::cdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + RealType error_result; + RealType n = dist.number_of_observations(); + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + if((x < 0) || !(boost::math::isfinite)(x)) { + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be between > 0 !", x, Policy()); + } + + if (x*x*n == 0) + return 0; + + return jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); +} // cdf + +template +inline RealType cdf(const complemented2_type, RealType>& c) { + BOOST_MATH_STD_USING // for ADL of std function exp. + RealType x = c.param; + static const char* function = "boost::math::cdf(const complemented2_type&, %1%>)"; + RealType error_result; + kolmogorov_smirnov_distribution const& dist = c.dist; + RealType n = dist.number_of_observations(); + + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be between > 0 !", x, Policy()); + + if (x*x*n == 0) + return 1; + + if (2*x*x*n > constants::pi()) + return -jacobi_theta4m1tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); + + return RealType(1) - jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); +} // cdf (complemented) + +template +inline RealType quantile(const kolmogorov_smirnov_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + RealType n = dist.number_of_observations(); + if(false == detail::check_probability(function, p, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + RealType k = detail::kolmogorov_smirnov_quantile_guess(p) / sqrt(n); + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t max_iter = policies::get_max_root_iterations(); // and max iterations. + + RealType result = tools::newton_raphson_iterate(detail::kolmogorov_smirnov_quantile_functor(dist, p), + k, RealType(0), RealType(1), get_digits, max_iter); + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} // quantile + +template +inline RealType quantile(const complemented2_type, RealType>& c) { + BOOST_MATH_STD_USING + static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + kolmogorov_smirnov_distribution const& dist = c.dist; + RealType n = dist.number_of_observations(); + // Error check: + RealType error_result; + RealType p = c.param; + + if(false == detail::check_probability(function, p, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + RealType k = detail::kolmogorov_smirnov_quantile_guess(RealType(1-p)) / sqrt(n); + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t max_iter = policies::get_max_root_iterations(); // and max iterations. + + RealType result = tools::newton_raphson_iterate( + detail::kolmogorov_smirnov_complementary_quantile_functor(dist, p), + k, RealType(0), RealType(1), get_digits, max_iter); + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} // quantile (complemented) + +template +inline RealType mode(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::mode(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + std::pair r = boost::math::tools::brent_find_minima( + detail::kolmogorov_smirnov_negative_pdf_functor(), + static_cast(0), static_cast(1), policies::digits()); + return r.first / sqrt(n); +} + +// Mean and variance come directly from +// https://www.jstatsoft.org/article/view/v008i18 Section 3 +template +inline RealType mean(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::mean(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return constants::root_half_pi() * constants::ln_two() / sqrt(n); +} + +template +inline RealType variance(const kolmogorov_smirnov_distribution& dist) +{ + static const char* function = "boost::math::variance(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return (constants::pi_sqr_div_six() + - constants::pi() * constants::ln_two() * constants::ln_two()) / (2*n); +} + +// Skewness and kurtosis come from integrating the PDF +// The alternating series pops out a Dirichlet eta function which is related to the zeta function +template +inline RealType skewness(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::skewness(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + RealType ex3 = RealType(0.5625) * constants::root_half_pi() * constants::zeta_three() / n / sqrt(n); + RealType mean = boost::math::mean(dist); + RealType var = boost::math::variance(dist); + return (ex3 - 3 * mean * var - mean * mean * mean) / var / sqrt(var); +} + +template +inline RealType kurtosis(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::kurtosis(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + RealType ex4 = 7 * constants::pi_sqr_div_six() * constants::pi_sqr_div_six() / 20 / n / n; + RealType mean = boost::math::mean(dist); + RealType var = boost::math::variance(dist); + RealType skew = boost::math::skewness(dist); + return (ex4 - 4 * mean * skew * var * sqrt(var) - 6 * mean * mean * var - mean * mean * mean * mean) / var / var; +} + +template +inline RealType kurtosis_excess(const kolmogorov_smirnov_distribution& dist) +{ + static const char* function = "boost::math::kurtosis_excess(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return kurtosis(dist) - 3; +} +}} +#endif diff --git a/third-party/boost-math/include/boost/math/distributions/landau.hpp b/third-party/boost-math/include/boost/math/distributions/landau.hpp new file mode 100644 index 0000000000000..e8e9420be17d9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/landau.hpp @@ -0,0 +1,4642 @@ +// Copyright Takuma Yoshimura 2024. +// Copyright Matt Borland 2024 +// 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) + +#ifndef BOOST_STATS_LANDAU_HPP +#define BOOST_STATS_LANDAU_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#include +#endif + +namespace boost { namespace math { +template +class landau_distribution; + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 6.1179e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.62240126375351657026e-1), + static_cast(3.37943593381366824691e-1), + static_cast(1.53537606095123787618e-1), + static_cast(3.01423783265555668011e-2), + static_cast(2.66982581491576132363e-3), + static_cast(-1.57344124519315009970e-5), + static_cast(3.46237168332264544791e-7), + static_cast(2.54512306953704347532e-8), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.61596691542333069131e0), + static_cast(1.31560197919990191004e0), + static_cast(6.37865139714920275881e-1), + static_cast(1.99051021258743986875e-1), + static_cast(3.73788085017437528274e-2), + static_cast(3.72580876403774116752e-3), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if(x < 2){ + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 2.1560e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(1.63531240868022603476e-1), + static_cast(1.42818648212508067982e-1), + static_cast(4.95816076364679661943e-2), + static_cast(8.59234710489723831273e-3), + static_cast(5.76649181954629544285e-4), + static_cast(-5.66279925274108366994e-7), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.41478104966077351483e0), + static_cast(9.41180365857002724714e-1), + static_cast(3.65084346985789448244e-1), + static_cast(8.77396986274371571301e-2), + static_cast(1.24233749817860139205e-2), + static_cast(8.57476298543168142524e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 9.1732e-19 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(9.55242261334771588094e-2), + static_cast(6.66529732353979943139e-2), + static_cast(1.80958840194356287100e-2), + static_cast(2.34205449064047793618e-3), + static_cast(1.16859089123286557482e-4), + static_cast(-1.48761065213531458940e-7), + static_cast(4.37245276130361710865e-9), + static_cast(-8.10479404400603805292e-11), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.21670723402658089612e0), + static_cast(6.58224466688607822769e-1), + static_cast(2.00828142796698077403e-1), + static_cast(3.64962053761472303153e-2), + static_cast(3.76034152661165826061e-3), + static_cast(1.74723754509505656326e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 7.6621e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.83643820409470770350e-2), + static_cast(1.97555000044256883088e-2), + static_cast(3.71748668368617282698e-3), + static_cast(3.04022677703754827113e-4), + static_cast(8.76328889784070114569e-6), + static_cast(-3.34900379044743745961e-9), + static_cast(5.36581791174380716937e-11), + static_cast(-5.50656207669255770963e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(9.09290785092251223006e-1), + static_cast(3.49404120360701349529e-1), + static_cast(7.23730835206014275634e-2), + static_cast(8.47875744543245845354e-3), + static_cast(5.28021165718081084884e-4), + static_cast(1.33941126695887244822e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 6.6311e-19 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.12656323880287532947e-2), + static_cast(2.87311140580416132088e-3), + static_cast(2.61788674390925516376e-4), + static_cast(9.74096895307400300508e-6), + static_cast(1.19317564431052244154e-7), + static_cast(-6.99543778035110375565e-12), + static_cast(4.33383971045699197233e-14), + static_cast(-1.75185581239955717728e-16), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(4.94430267268436822392e-1), + static_cast(1.00370783567964448346e-1), + static_cast(1.05989564733662652696e-2), + static_cast(6.04942184472254239897e-4), + static_cast(1.72741008294864428917e-5), + static_cast(1.85398104367945191152e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 5.6459e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.83847488747490686627e-3), + static_cast(4.95641151588714788287e-4), + static_cast(2.79159792287747766415e-5), + static_cast(5.93951761884139733619e-7), + static_cast(3.89602689555407749477e-9), + static_cast(-4.86595415551823027835e-14), + static_cast(9.68524606019510324447e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.01847536766892219351e-1), + static_cast(3.63152433272831196527e-2), + static_cast(2.20938897517130866817e-3), + static_cast(7.05424834024833384294e-5), + static_cast(1.09010608366510938768e-6), + static_cast(6.08711307451776092405e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 6.5205e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(6.85767880395157523315e-4), + static_cast(4.08288098461672797376e-5), + static_cast(8.10640732723079320426e-7), + static_cast(6.10891161505083972565e-9), + static_cast(1.37951861368789813737e-11), + static_cast(-1.25906441382637535543e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.23722380864018634550e-1), + static_cast(6.05800403141772433527e-3), + static_cast(1.47809654123655473551e-4), + static_cast(1.84909364620926802201e-6), + static_cast(1.08158235309005492372e-8), + static_cast(2.16335841791921214702e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(x) < 8) { + RealType t = log2(ldexp(x, -6)); + + // Rational Approximation + // Maximum Relative Error: 3.5572e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(6.78613480244945294595e-1), + static_cast(9.61675759893298556080e-1), + static_cast(3.45159462006746978086e-1), + static_cast(6.32803373041761027814e-2), + static_cast(6.93646175256407852991e-3), + static_cast(4.69867700169714338273e-4), + static_cast(1.76219117171149694118e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.44693640094228656726e0), + static_cast(5.46298626321591162873e-1), + static_cast(1.01572892952421447864e-1), + static_cast(1.04982575345680980744e-2), + static_cast(7.65591730392359463367e-4), + static_cast(2.69383817793665674679e-5), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 16) { + RealType t = log2(ldexp(x, -8)); + + // Rational Approximation + // Maximum Relative Error: 5.7408e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.51438485661317103070e-1), + static_cast(2.67941671074735988081e-1), + static_cast(5.18564629295719783781e-2), + static_cast(6.18976337233135940231e-3), + static_cast(5.08042228681335953236e-4), + static_cast(2.97268230746003939324e-5), + static_cast(1.24283200336057908183e-6), + static_cast(3.35670921544537716055e-8), + static_cast(5.06987792821954864905e-10), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(4.23792506680780833665e-1), + static_cast(8.17040643791396371682e-2), + static_cast(9.63961713981621216197e-3), + static_cast(8.06584713485725204135e-4), + static_cast(4.62050471704120102023e-5), + static_cast(1.96919734048024406173e-6), + static_cast(5.23890369587103685278e-8), + static_cast(7.99399970089366802728e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 32) { + RealType t = log2(ldexp(x, -16)); + + // Rational Approximation + // Maximum Relative Error: 1.0195e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(6.36745544906925230102e-1), + static_cast(2.06319686601209029700e-1), + static_cast(3.27498059700133287053e-2), + static_cast(3.30913729536910108000e-3), + static_cast(2.34809665750270531592e-4), + static_cast(1.21234086846551635407e-5), + static_cast(4.55253563898240922019e-7), + static_cast(1.17544434819877511707e-8), + static_cast(1.76754192209232807941e-10), + static_cast(-2.78616504641875874275e-17), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(3.24145654925686670201e-1), + static_cast(5.14350019501887110402e-2), + static_cast(5.19867984016649969928e-3), + static_cast(3.68798608372265018587e-4), + static_cast(1.90449594112666257344e-5), + static_cast(7.15068261954120746192e-7), + static_cast(1.84646096630493837656e-8), + static_cast(2.77636277083994601941e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 64) { + RealType t = log2(ldexp(x, -32)); + + // Rational Approximation + // Maximum Relative Error: 8.0433e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.36619776379492082324e-1), + static_cast(2.68158440168597706495e-1), + static_cast(5.49040993767853738389e-2), + static_cast(7.23458585096723552751e-3), + static_cast(6.85438876301780090281e-4), + static_cast(4.84561891424380633578e-5), + static_cast(2.82092117716081590941e-6), + static_cast(9.57557353473514565245e-8), + static_cast(5.16773829224576217348e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(4.21222294324039934056e-1), + static_cast(8.62431574655015481812e-2), + static_cast(1.13640608906815986975e-2), + static_cast(1.07668486873466248474e-3), + static_cast(7.61148039258802068270e-5), + static_cast(4.43109262308946031382e-6), + static_cast(1.50412757354817481381e-7), + static_cast(8.11746432728995551732e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else{ + result = 2 / (constants::pi() * x * x); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 7.4629e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62240126375351657025589608183516471315e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94698530837122818345222883832757839888e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06728003509081587907620543204047536319e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.41256254272104786752190871391781331271e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34420233794664437979710204055323742199e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55021337841765667713712845735938627884e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90557752737535583908921594594761570259e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.89899202021818926241643215600800085123e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.19635143827754893815649685600837995626e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.90989458941330917626663002392683325107e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92038069341802550019371049232152823407e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.40251964644989324856906264776204142653e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.55873076454666680466531097660277995317e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.80771940886011613393622410616035955976e-13), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.35771004134750535117224809381897395331e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37002484862962406489509174332580745411e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.40833952846707180337506160933176158766e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.81709029902887471895588386777029652661e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98824705588020901032379932614151640505e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.83767868823957223030472664574235892682e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35718995485026064249286377096427165287e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37305148463792922843850823142976586205e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.06575764439154972544253668821920460826e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07663693811543002088092708395572161856e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09711221791106684926377106608027279057e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91302186546138009232520527964387543006e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 6.6684e-38 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63531240868022603475813051802104652763e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.17803013130262393286657457221415701909e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77780575692956605214628767143941600132e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44224824965135546671876867759691622832e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.93294212655117265065191070995706405837e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16021988737209938284910541133167243163e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89245591723934954825306673917695058577e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09614731993308746343064543583426077485e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48578173962833046113032690615443901556e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.91098199913613774034789276073191721350e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.46788618410999858374206722394998550706e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.14296339768511312584670061679121003569e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.52631422678659858574974085885146420544e-15), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.48481735580594347909096198787726314434e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91598585888012869317473155570063821216e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12672162924784178863164220170459406872e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06981909640884405591730537337036849744e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.89767326897694369071250285702215471082e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05098647402530640576816174680275844283e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.10454903166951593161839822697382452489e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08850649343579977859251275585834901546e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.21168773136767495960695426112972188729e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21420361560900449851206650427538430926e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.84456961344035545134425261150891935402e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46462389440125559723382692664970874255e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 6.3397e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.55242261334771588093967856464157010584e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48866040463435403672044647455806606078e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04241715667984551487882549843428953917e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.32030608366022483736940428739436921577e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17209924605508887793687609139940354371e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.16808856405217460367038406337257561698e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75466331296758720822164534334356742122e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35657250222166360635152712608912585973e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28870137478821561164537700376942753108e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07556331078347991810236646922418944687e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.18067019247793233704208913546277631267e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96745094401496364651919224112160111958e-12), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07735872062601280828576861757316683396e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00667909426245388114411629440735066799e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18840123665979969294228925712434860653e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79233661359264185181083948452464063323e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38221013998193410441723488211346327478e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91365002115280149925615665651486504495e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.50379182630668701710656913597366961277e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.03946139315999749917224356955071595508e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95417998434227083224840824790387887539e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05109028829536837163462811783445124876e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.33125282515685091345480270760501403655e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.58127838888839012133236453180928291822e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64781659622256824499981528095809140284e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 8.0238e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83643820409470770350079809236512802618e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.02996762669868036727057860510914079553e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88220267784864518806154823373656292346e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.12677705163934102871251710968247891123e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.96642570169484318623869835991454809217e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04358807405587072010621764865118316919e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09461879230275452416933096674703383719e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06823998699058163165831211561331795518e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24129479811279469256914665585439417704e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01799222004929573125167949870797564244e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27744716755834439008073010185921331093e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.64210356143729930758657624381557123115e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11666384975358223644665199669986358056e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.30202644697506464624965700043476935471e-22), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44479208003384373099160875893986831861e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.54290037675901616362332580709754113529e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79815821498858750185823401350096868195e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01076480676864621093034009679744852375e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88607467767854661547920709472888000469e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51572461182263866462295745828009170865e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39843444671402317250813055670653845815e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60546478324160472036295355872288494327e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.25462551353792877506974677628167909695e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05915328498722701961972258866550409117e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20632869761578411246344533841556350518e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99438347491752820345051091574883391217e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 3.2541e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12656323880287532946687856443190592955e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.31374972240605659239154788518240221417e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.10776910971729651587578902049263096117e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.53872632372452909103332647334935138324e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.81756147611150151751911596225474463602e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75302607308223110644722612796766590029e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33839913867469199941739467004997833889e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.32115127487193219555283158969582307620e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.90766547421015851413713511917307214275e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08939895797457378361211153362169024503e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.88597187949354708113046662952288249250e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62829447082637808482463811005771133942e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.65525705592205245661726488519562256000e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60698835222044786453848932477732972928e-26), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88605948104664828377228254521124685930e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.58594705700945215121673591119784576258e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.67113091918430152113322758216774649130e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39583889554372147091140765508385042797e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57139043074134496391251233307552940106e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26451960029396455805403758307828624817e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30400557427446929311350088728080667203e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.99617890540456503276038942480115937467e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.50232186816498003232143065883536003942e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59310652872918546431499274822722004981e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82203579442241682923277858553949327687e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10345359368438386945407402887625511801e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55225829972215033873365516486524181445e-17), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 4.1276e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83847488747490686627461184914507143000e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.61220392257287638364190361688188696363e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42217711448675893329072184826328300776e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20597728166467972373586650878478687059e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.46404433551447410467051774706080733051e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27909145305324391651548849043874549520e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.33564789388635859003082815215888382619e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.18456219811686603951886248687349029515e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.92730718471866912036453008101994816885e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.51773776414973336511129801645901922234e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32371094281803507447435352076735970857e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44775294242071078601023962869394690897e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.94920633206242554892676642458535141153e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.18030442958390399095902441284074544279e-31), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.65871972115253665568580046072625013145e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.74531522538358367003224536101724206626e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20716479628426451344205712137554469781e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.83247584368619500260722365812456197226e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.52931189426842216323461406426803698335e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19343566926626449933230814579037896037e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.16243058880148231471744235009435586353e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21344088555713979086041331387697053780e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63246599173435592817113618949498524238e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43426263963680589288791782556801934305e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.62386317351298917459659548443220451300e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13281535580097407374477446521496074453e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27187882784316306216858933778750811182e-21), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 1.8458e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.85767880395157523314894776472286059373e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07684379950498990874449661385130414967e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.29181715091139597455177955800910928786e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78745116935613858188145093313446961899e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.61522707085521545633529621526418843836e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00989556810424018339768632204186394735e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94136605359672888838088037894401904574e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.15203266224687619299892471650072720579e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.25349098945982074415471295859193558426e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.31874620165906020409111024866737082384e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19330888204484008667352280840160186671e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.89951131249530265518610784629981482444e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35979606245171162602352579985003194602e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.50946115943875327149319867495704969908e-36), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21212467547297045538111676107434471585e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17663841151156626845609176694801024524e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25478800461954401173897968683982253458e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.69831763649657690166671862562231448718e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19712058726935472913461138967922524612e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11423395018514913507624349385447326009e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.58664605420655866109404476637021322838e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15398721299264752103644541934654351463e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17567858878427250079920401604119982576e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.92808825029184923713064129493385469531e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.06007644624654848502783947087038305433e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.01246784499782934986619755015082182398e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(x) < 8) { + RealType t = log2(ldexp(x, -6)); + + // Rational Approximation + // Maximum Relative Error: 2.6634e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.78613480244945294594505480426643613242e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07362312709864018864207848733814857157e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.47727521897653923649758175033206259109e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04183129813120998456717217121703605830e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09978729224187570508825456585418357590e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98739784100617344335742510102186570437e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08596635852958074572320481325030046975e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34947456497875218771996878497766058580e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31766866003171430205401377671093088134e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29444683984117745298484117924452498776e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34885173277203843795065094551227568738e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30306828175920576070486704404727265760e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.05908347665846652276910544097430115068e-13), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07218191317166728296013167220324207427e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.38908532499742180532814291654329829544e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63676664387672566455490461784630320677e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31302647779056928216789214742790688980e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.69477260342662648574925942030720482689e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.82918424748192763052497731722563414651e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69244295675395948278971027618145225216e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08928780307959133484802547123672997757e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.11055350627948183551681634293425028439e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22066081452382450191191677443527136733e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78025987104169227624653323808131280009e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.93164997733174955208299290433803918816e-13), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 16) { + RealType t = log2(ldexp(x, -8)); + + // Rational Approximation + // Maximum Relative Error: 6.1919e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.51438485661317103069553924870169052838e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.29652867028564588922931020456447362877e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.90557738902930002845457640269863338815e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.47622170600415955276436226439948455362e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75198213226024095368607442455597948634e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73010116224706573149404022585502812698e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.33440551266376466187512220300943206212e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27556365758364667507686872656121131255e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.63395763346533783414747536236033733143e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75408632486279069728789506666930014630e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.74194099205847568739445023334735086627e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52462367172968216583968200390021647482e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75367408334713835736514158797013854282e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.62633983586253025227038002631010874719e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46717630077826649018810277799043037738e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00642537643332236333695338824014611799e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47351714774371338348451112020520067028e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15896012319823666881998903857141624070e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.62176014448801854863922778456328119208e-25), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.79042471052521112984740498925369905803e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.55058068535501327896327971200536085268e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33143443551335870264469963604049242325e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75325348141376361676246108294525717629e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.28871858542582365161221803267369985933e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.23702867786056336210872367019916245663e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.14513776996445072162386201808986222616e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13763070277828149031445006534179375988e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75529866599039195417128499359378019030e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53029524184341515115464886126119582515e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.10598685541492162454676538516969294049e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75587930183994618721688808612207567233e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.83150895141383746641924725237948860959e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30675015193353451939138512698571954110e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.71774361582156518394662911172142577047e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.03397072601182597002547703682673198965e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.52666999314026491934445577764441483687e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 32) { + RealType t = log2(ldexp(x, -16)); + + // Rational Approximation + // Maximum Relative Error: 1.2411e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36745544906925230101752563433306496000e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73688900814770369626527563956988302379e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.81718746296195151971617726268038570065e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.13663059680440438907042970413471861121e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.40004645275531255402942177790836798523e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.80059489775751412372432345156902685277e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47699576477278882708291693658669435536e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.45226121992756638990044029871581321461e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13406331882918393195342615955627442395e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46682598893946975917562485374893408094e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50450743907497671918301557074470352707e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.33121239192492785826422815650499088833e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05998176182038788839361491871608950696e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17857918044922309623941523489531919822e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.67865547879145051715131144371287619666e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.89654931108624296326740455618289840327e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.73017950634516660552375272495618707905e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68519137981001059472024985205381913202e-24), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.29948066505039082395951244410552705780e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.13730690908098361287472898564563217987e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27810872138103132689695155123062073221e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31948058845675193039732511839435290811e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06822729610151747708260147063757668707e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.03250522904270408071762059653475885811e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.85197262150009124871794386644476067020e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78139536405831228129042087771755615472e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.01642938314578533660138738069251610818e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36328724659833107203404258336776286146e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.80342430290059616305921915291683180697e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66502051110007556897014898713746069491e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42209715361911856322028597714105225748e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.77842582605458905635718323117222788078e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.69147628396460384758492682185049535079e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.43015110519230289924122344324563890953e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21788819753161690674882271896091269356e-24), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 64) { + RealType t = log2(ldexp(x, -32)); + + // Rational Approximation + // Maximum Relative Error: 2.0348e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619776379492082323649724050601750141e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29818158612993476124594583743266388964e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07736315744724186061845512973085067283e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72566458808745644851080213349673559756e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.01243670706840752914099834172565920736e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65306557791300593593488790517297048902e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41751291649776832705247036453540452119e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.26652535267657618112731521308564571490e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32742926765578976373764178875983383214e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.32948532312961882464151446137719196209e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96536595631611560703804402181953334762e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48463581600017734001916804890205661347e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.65588239861378749665334852913775575615e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39462290798829172203386678450961569536e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83049279786679854738508318703604392055e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87131679136229094080572090496960701828e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35977519905679446758726709186381481753e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.50639358104925465711435411537609380290e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.47593981758247424082096107205150226114e-40), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60997521267746350015610841742718472657e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.40470704349086277215167519790809981379e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.42305660178694704379572259575557934523e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30272082429322808188807034927827414359e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16742567294582284534194935923915261582e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22662407906450293978092195442686428843e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.84343501655116670387608730076359018869e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.65591734166216912475609790035240582537e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15131286290573570519912674341226377625e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08718962387679715644203327604824250850e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.04444946843492647477476784817227903589e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35966282749098189010715902284098451987e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19066854132814661112207991393498039851e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87533136296192957063599695937632598999e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93945754223094281767677343057286164777e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13592988790740273103099465658198617078e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.64942281110142621080966631872844557766e-26), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else if (ilogb(x) < 128) { + RealType t = log2(ldexp(x, -64)); + + // Rational Approximation + // Maximum Relative Error: 4.3963e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619772367581344984274685280416528592e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72417390936686577479751162141499390532e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74319117326966091295365258834959120634e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94269681742277805376258823511210253023e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09354876913180019634171748490068797632e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.46986612543101357465265079580805403382e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21726753043764920243710352514279216684e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29971756326232375757519588897328507962e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06770117983967828996891025614645348127e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27141668055392041978388268556174062945e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48383887723476619460217715361289178429e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49530301203157403427315504054500005836e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18668427867427341566476567665953082312e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73377083349017331494144334612902128610e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.32380647653444581710582396517056104063e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.29865827039123699411352876626634361936e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07464506614287925844993490382319608619e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60173555862875972119871402681133785088e-23), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27912237038396638341492536677313983747e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.02138359905285600768927677649467546192e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24763589856532154099789305018886222841e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27133166772875885088000073325642460162e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01628419446817660009223289575239926907e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.62446834592284424116329218260348474201e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61238790103816844895453935630752859272e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67714109140674398508739253084218270557e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70952563202454851902810005226033501692e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33080865791583428494353408816388908148e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.06120545912923145572220606396715398781e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86403930600680015325844027465766431761e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.29419718354538719350803683985104818654e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.36261565790718847159482447247645891176e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46062982552515416754702177333530968405e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68804852250549346018535616711418533423e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51600033199082754845231795160728350588e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x * x); + } + else { + result = 2 / (constants::pi() * x * x); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if(x >= -1){ + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 9.3928e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(2.21762208692280384264e-1), + static_cast(7.10041055270973473923e-1), + static_cast(8.66556480457430718380e-1), + static_cast(4.78718713740071686348e-1), + static_cast(1.03670563650247405820e-1), + static_cast(4.31699263023057628473e-3), + static_cast(1.72029926636215817416e-3), + static_cast(-2.76271972015177236271e-4), + static_cast(1.89483904652983701680e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(2.18155995697310361937e0), + static_cast(2.53173077603836285217e0), + static_cast(1.91802065831309251416e0), + static_cast(9.94481663032480077373e-1), + static_cast(3.72037148486473195054e-1), + static_cast(8.85828240211801048938e-2), + static_cast(1.41354784778520560313e-2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 2.4742e-18 + BOOST_MATH_STATIC const RealType P[11] = { + static_cast(6.50763682207511020789e-3), + static_cast(5.73790055136022120436e-2), + static_cast(2.22375662069496257066e-1), + static_cast(4.92288611166073916396e-1), + static_cast(6.74552077334695078716e-1), + static_cast(5.75057550963763663751e-1), + static_cast(2.85690710485234671432e-1), + static_cast(6.73776735655426117231e-2), + static_cast(3.80321995712675339999e-3), + static_cast(1.09503400950148681072e-3), + static_cast(-9.00045301380982997382e-5), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + static_cast(1), + static_cast(1.07919389927659014373e0), + static_cast(2.56142472873207168042e0), + static_cast(1.68357271228504881003e0), + static_cast(2.23924151033591770613e0), + static_cast(9.05629695159584880257e-1), + static_cast(8.94372028246671579022e-1), + static_cast(1.98616842716090037437e-1), + static_cast(1.70142519339469434183e-1), + static_cast(1.46288923980509020713e-2), + static_cast(1.26171654901120724762e-2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + const static RealType lambda_bias = static_cast(1.45158270528945486473); // (= log(pi/2)+1) + + RealType sigma = exp(-x * constants::pi() / 2 - lambda_bias); + RealType s = exp(-sigma) * sqrt(sigma); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 5.8685e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(6.31126317567898819465e-1), + static_cast(5.28493759149515726917e-1), + static_cast(3.28301410420682938866e-1), + static_cast(1.31682639578153092699e-1), + static_cast(3.86573798047656547423e-2), + static_cast(7.77797337463414935830e-3), + static_cast(9.97883658430364658707e-4), + static_cast(6.05131104440018116255e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(8.47781139548258655981e-1), + static_cast(5.21797290075642096762e-1), + static_cast(2.10939174293308469446e-1), + static_cast(6.14856955543769263502e-2), + static_cast(1.24427885618560158811e-2), + static_cast(1.58973907730896566627e-3), + static_cast(9.66647686344466292608e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -5.1328125) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 3.2532e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.26864481454444278646e-1), + static_cast(5.10647753508714204745e-1), + static_cast(1.98551443303285119497e-1), + static_cast(4.71644854289800143386e-2), + static_cast(7.71285919105951697285e-3), + static_cast(8.93551020612017939395e-4), + static_cast(6.97020145401946303751e-5), + static_cast(4.17249760274638104772e-6), + static_cast(7.73502439313710606153e-12), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(8.15124079722976906223e-1), + static_cast(3.16755852188961901369e-1), + static_cast(7.52819418000330690962e-2), + static_cast(1.23053506566779662890e-2), + static_cast(1.42615273721494498141e-3), + static_cast(1.11211928184477279204e-4), + static_cast(6.65899898061789485757e-6), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 1.2803e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21762208692280384264052188465103527015e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07121154108880017947709737976750200391e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34036993772851526455115746887751392080e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.06347688547967680654012636399459376006e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68662427153576049083876306225433068713e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67496398036468361727297056409545434117e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.69289909624425652939466055042210850769e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65649060232973461318206716040181929160e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.93006819232611588097575675157841312689e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34514211575975820725706925256381036061e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86184594939834946952489805173559003431e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66982890863184520310462776294335540260e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.28944885271022303878175622411438230193e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.47136245900831864668353768185407977846e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98034330388999615249606466662289782222e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.67931741921878993598048665757824165533e-12), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.81019852414657529520034272090632311645e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.51602582973416348091361820936922274106e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.87246706500788771729605610442552651673e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.55758863380051182011815572544985924963e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.16921634066377885762356020006515057786e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.28590978860106110644638308039189352463e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07182688002603587927920766666962846169e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.14413931232875917473403467095618397172e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59534588679183116305361784906322155131e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.62788361787003488572546802835677555151e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32291670834750583053201239125839728061e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97300476673137879475887158731166178829e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99801949382703479169010768105376163814e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09234481837537672361990844588166022791e-5), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 3.8590e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.50763682207511020788551990942118742910e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.35160148798611192350830963080055471564e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.85567614778755464918744664468938413626e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24395902843792338723377508551415399267e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75803588325237557939443967923337822799e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44751743702858358960016891543930028989e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.38771920793989989423514808134997891434e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.99899457801652012757624005300136548027e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.59668432891116320233415536189782241116e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02521376213276025040458141317737977692e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.00511857068867825025582508627038721402e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19031970665203475373248353773765801546e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.03203906044415590651592066934331209362e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01354553335348149914596284286907046333e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40077709279222086527834844446288408059e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07036291955272673946830858788691198641e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75229595324028909877518859428663744660e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.51522041748753421579496885726802106514e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.28554063325397021905295499768922434904e-10), + }; + BOOST_MATH_STATIC const RealType Q[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.55889733194498836168215560931863059152e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.45050534010127542130960211621894286688e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39437268390909980446225806216001154876e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85370557677145869100298813360909127310e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99358236671478050470186012149124879556e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82914467302553175692644992910876515874e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42426383410763382224410804289834740252e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.69477085497572590673874940261777949808e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.69832833104494997844651343499526754631e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95708391432781281454592429473451742972e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32541987059874996779040445020449508142e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.24889827757289516008834701298899804535e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76326709965329347689033555841964826234e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.19652942193884551681987290472603208296e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22987197033955835618810845653379470109e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51893290463268547258382709202599507274e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.43575882043846146581825453522967678538e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06683418138599962787868832158681391673e-5), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + const static RealType lambda_bias = BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.451582705289454864726195229894882143572); // (= log(pi/2)+1) + + RealType sigma = exp(-x * constants::pi() / 2 - lambda_bias); + RealType s = exp(-sigma) * sqrt(sigma); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 7.0019e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.31126317567898819464557840628449107915e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.31008645911415314700225107327351636697e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.60743397071713227215207831174512626190e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69243936604887410595461520921270733657e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93778117053417749769040328795824088196e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.04718815412035890861219665332918840537e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41914050146414549019258775115663029791e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17147074474397510167661838243237386450e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31006358624990533313832878493963971249e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.31424805670861981190416637260176493218e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71604447221961082506919140038819715820e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.01796816886825676412069047911936154422e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16975381608692872525287947181531051179e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47194712963929503930146780326366215579e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19469248860267489980690249379132289464e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22272545853285700254948346226514762534e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.05432616288832680241611577865488417904e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08723511461992818779941378551362882730e-14), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01021278581037282130358759075689669228e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.91783545335316986601746168681457332835e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.90025337163174587593060864843160047245e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09029833197792884728968597136867674585e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44295160726145715084515736090313329125e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46416375246465800703437031839310870287e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86521610039165178072099210670199368231e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29830357713744587265637686549132688965e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32187562202835921333177458294507064946e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75034541113922116856456794810138543224e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79216314818261657918748858010817570215e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.69179323869133503169292092727333289999e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.09019623876540244217038375274802731869e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13900582194674129200395213522524183495e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92590979457175565666605415984496551246e-9), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -6.875) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 6.4095e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.26864481454444278645937156746132802908e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35052316263030534355724898036735352905e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46701697626917441774916114124028252971e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03805679118924248671851611170709699862e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29457230118834515743802694404620370943e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04992992250026414994541561073467805333e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.21521951889983113700615967351903983850e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50611640491200231504944279876023072268e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96007721851412367657495076592244098807e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76876967456744990483799856564174838073e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.34285198828980523126745002596084187049e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.98811180672843179022928339476420108494e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36933707823930146448761204037985193905e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76515121042989743198432939393805252169e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87259915481622487665138935922067520210e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34703958446785695676542385299325713141e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53199672688507288037695102377982544434e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.97283413733676690377949556457649405210e-14), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15492787140203223641846510939273526038e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34095796298757853634036909432345998054e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65650140652391522296109869665871008634e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.44894089102275258806976831589022821974e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27121975866547045393504246592187721233e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.91803733484503004520983723890062644122e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40341451263971324381655967408519161854e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72360046810103129487529493828280649599e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.60986435254173073868329335245110986549e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01216966786091058959421242465309838187e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11514619470960373138100691463949937779e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01639426441970732201346798259534312372e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.60411422906070056043690129326288757143e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.58398956202137709744885774931524547894e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14956902064425256856583295469934064903e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23201118234279642321630988607491208515e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43185798646451225275728735761433082676e-13), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_imp_prec(const RealType& x, const boost::math::integral_constant &tag) { + if (x >= 0) { + return landau_pdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return landau_pdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_imp_prec(const RealType& x, const boost::math::integral_constant& tag) { + if (x >= 0) { + return landau_pdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return landau_pdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_pdf_imp(const landau_distribution& dist, const RealType& x) { + // + // This calculates the pdf of the Landau distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::pdf(landau<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + RealType bias = dist.bias(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale + bias; + + result = landau_pdf_imp_prec(u, tag_type()) / scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 2.7348e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(6.34761298487625202628e-1), + static_cast(7.86558857265845597915e-1), + static_cast(4.30220871807399303399e-1), + static_cast(1.26410946316538340541e-1), + static_cast(2.09346669713191648490e-2), + static_cast(1.48926177023501002834e-3), + static_cast(-5.93750588554108593271e-7), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(1.65227304522196452589e0), + static_cast(1.29276828719607419526e0), + static_cast(5.93815051307098615300e-1), + static_cast(1.69165968013666952456e-1), + static_cast(2.84272940328510367574e-2), + static_cast(2.28001970477820696422e-3), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 6.1487e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(4.22133240358047652363e-1), + static_cast(3.48421126689016131480e-1), + static_cast(1.15402429637790321091e-1), + static_cast(1.90374044978864005061e-2), + static_cast(1.26628667888851698698e-3), + static_cast(-5.75103242931559285281e-7), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(1.21277435324167238159e0), + static_cast(6.38324046905267845243e-1), + static_cast(1.81723381692749892660e-1), + static_cast(2.80457012073363245106e-2), + static_cast(1.93749385908189487538e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 3.2975e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(2.95892137955791216378e-1), + static_cast(2.29083899043580095868e-1), + static_cast(7.09374171394372356009e-2), + static_cast(1.08774274442674552229e-2), + static_cast(7.69674715320139398655e-4), + static_cast(1.63486840000680408991e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(1.09704883482087441931e0), + static_cast(5.10139057077147935327e-1), + static_cast(1.27055234007499238241e-1), + static_cast(1.74542139987310825683e-2), + static_cast(1.18944143641885993718e-3), + static_cast(2.55296292914537992309e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 2.6740e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.73159318667565938776e-1), + static_cast(6.95847424776057206679e-2), + static_cast(1.04513924567165899506e-2), + static_cast(6.35094718543965631442e-4), + static_cast(1.04166111154771164657e-5), + static_cast(1.43633490646363733467e-9), + static_cast(-4.55493341295654514558e-11), + static_cast(6.71119091495929467041e-13), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(6.23409270429130114247e-1), + static_cast(1.54791925441839372663e-1), + static_cast(1.85626981728559445893e-2), + static_cast(1.01414235673220405086e-3), + static_cast(1.63385654535791481980e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 7.6772e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(8.90469147411748292410e-2), + static_cast(2.76033447621178662228e-2), + static_cast(3.26577485081539607943e-3), + static_cast(1.77755752909150255339e-4), + static_cast(4.20716551767396206445e-6), + static_cast(3.19415703637929092564e-8), + static_cast(-1.79900915228302845362e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(4.36499987260915480890e-1), + static_cast(7.67544181756713372678e-2), + static_cast(6.83535263652329633233e-3), + static_cast(3.15983778969051850073e-4), + static_cast(6.84144567273078698399e-6), + static_cast(5.00300197147417963939e-8), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 1.5678e-20 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.35157264931262089762e-2), + static_cast(8.46833474333913742597e-3), + static_cast(6.43769318301002170686e-4), + static_cast(2.39440197089740502223e-5), + static_cast(4.45572968892675484685e-7), + static_cast(3.76071815793351687179e-9), + static_cast(1.04851094362145160445e-11), + static_cast(-8.50646541795105885254e-18), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(2.59832721225510968607e-1), + static_cast(2.75929030381330309762e-2), + static_cast(1.53115657043391090526e-3), + static_cast(4.70173086825204710446e-5), + static_cast(7.76185172490852556883e-7), + static_cast(6.10512879655564540102e-9), + static_cast(1.64522607881748812093e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 2.2534e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.11253031965493064317e-2), + static_cast(1.36656844320536022509e-3), + static_cast(2.99036224749763963099e-5), + static_cast(2.54538665523638998222e-7), + static_cast(6.79286608893558228264e-10), + static_cast(-6.92803349600061706079e-16), + static_cast(5.47233092767314029032e-19), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(9.71506209641408410168e-2), + static_cast(3.52744690483830496158e-3), + static_cast(5.85142319429623560735e-5), + static_cast(4.29686638196055795330e-7), + static_cast(1.06586221304077993137e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(x) < 8) { + RealType t = log2(ldexp(x, -6)); + + // Rational Approximation + // Maximum Relative Error: 3.8057e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(6.60754766433212615409e-1), + static_cast(2.47190065739055522599e-1), + static_cast(4.17560046901040308267e-2), + static_cast(3.71520821873148657971e-3), + static_cast(2.03659383008528656781e-4), + static_cast(2.52070598577347523483e-6), + static_cast(-1.63741595848354479992e-8), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(3.92836792184266080580e-1), + static_cast(6.64332913820571574875e-2), + static_cast(5.59456053716889879620e-3), + static_cast(3.44201583106671507027e-4), + static_cast(2.74554105716911980435e-6), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 16) { + RealType t = log2(ldexp(x, -8)); + + // Rational Approximation + // Maximum Relative Error: 1.5585e-18 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.44802371584831601817e-1), + static_cast(2.74177359656349204309e-1), + static_cast(5.53659240731871433983e-2), + static_cast(6.97653365560511851744e-3), + static_cast(6.17058143529799037402e-4), + static_cast(3.94979574476108021136e-5), + static_cast(1.88315864113369221822e-6), + static_cast(6.10941845734962836501e-8), + static_cast(1.39403332890347813312e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(4.32345127287830884682e-1), + static_cast(8.70500634789942065799e-2), + static_cast(1.09253956356393590470e-2), + static_cast(9.72576825490118007977e-4), + static_cast(6.18656322285414147985e-5), + static_cast(2.96375876501823390564e-6), + static_cast(9.58622809886777038970e-8), + static_cast(2.19059124630695181004e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 32) { + RealType t = log2(ldexp(x, -16)); + + // Rational Approximation + // Maximum Relative Error: 8.4773e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.36685748306554972132e-1), + static_cast(2.22217783148381285219e-1), + static_cast(3.79173960692559280353e-2), + static_cast(4.13394722917837684942e-3), + static_cast(3.18141233442663766089e-4), + static_cast(1.79745613243740552736e-5), + static_cast(7.47632665728046334131e-7), + static_cast(2.18258684729250152138e-8), + static_cast(3.93038365129320422968e-10), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(3.49087806008685701060e-1), + static_cast(5.95568283529034601477e-2), + static_cast(6.49386742119035055908e-3), + static_cast(4.99721374204563274865e-4), + static_cast(2.82348248031305043777e-5), + static_cast(1.17436903872210815656e-6), + static_cast(3.42841159307801319359e-8), + static_cast(6.17382517100568714012e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 64) { + RealType t = log2(ldexp(x, -32)); + + // Rational Approximation + // Maximum Relative Error: 4.1441e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.36619774420718062663e-1), + static_cast(2.68594096777677177874e-1), + static_cast(5.50713044649497737064e-2), + static_cast(7.26574134143434960446e-3), + static_cast(6.89173530168387629057e-4), + static_cast(4.87688310559244353811e-5), + static_cast(2.84218580121660744969e-6), + static_cast(9.65240367429172366675e-8), + static_cast(5.21722720068664704240e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(4.21906621389193043384e-1), + static_cast(8.65058026826346828750e-2), + static_cast(1.14129998157398060009e-2), + static_cast(1.08255124950652385121e-3), + static_cast(7.66059006900869004871e-5), + static_cast(4.46449501653114622960e-6), + static_cast(1.51619602364037777665e-7), + static_cast(8.19520132288940649002e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else { + result = 2 / (constants::pi() * x); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 2.6472e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.34761298487625202628055609797763667089e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67589195401255255724121983550745957195e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07502511824371206858547365520593277966e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58354381655514028012912292026393699991e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.26470588572701739953294573496059174764e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09494168186680012705692462031819276746e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.47385718073281027400744626077865581325e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69107567947502492044754464589464306928e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39641345689672620514703813504927833352e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27003930699448633502508661352994055898e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26124673422692247711088651516214728305e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.92103390710025598612731036700549416611e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.49572523814120679048097861755172556652e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.50719933268462244255954307285373705456e-13), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05332427324361912631483249892199461926e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46280417679002004953145547112352398783e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.10429833573651169023447466152999802738e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.63535585818618617796313647799029559407e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24103322502244219003850826414302390557e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.38359438431541204276767900393091886363e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16687583686405832820912406970664239423e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31451667102532056871497958974899742424e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31646175307279119467894327494418625431e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.22334681489114534492425036698050444462e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86326948577818727263376488455223120476e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53867591038308710930446815360572461884e-7), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 1.2387e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22133240358047652363270514524313049653e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.35860518549481281929441026718420080571e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.89900189271177970319691370395978805326e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84682995288088652145572170736339265315e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.10748045562955323875797887939420022326e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00246325517647746481631710824413702051e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02998394686245118431020407235000441722e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.06095284318730009040434594746639110387e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91754425158654496372516241124447726889e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.37288564874584819097890713305968351561e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.77487285800889132325390488044487626942e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.41654614425073025870130302460301244273e-13), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13058739144695658589427075788960660400e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11792528400843967390452475642793635419e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28794756779085737559146475126886069030e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29339015472607099189295465796550367819e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53434372685847620864540166752049026834e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.17610372643685730837081191600424913542e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64455304425865128680681864919048610730e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.62357689170951502920019033576939977973e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.89912258835489782923345357128779660633e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.76323449710934127736624596886862488066e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21524231900555452527639738371019517044e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.2281e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95892137955791216377776422765473500279e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.65957634570689820998348206103212047458e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.34657686985192350529330481818991619730e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43985500841002490334046057189458709493e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.09876223028004323158413173719329449720e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.04194660038290410425299531094974709019e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09780604136364125990393172827373829860e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02676079027875648517286351062161581740e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30298199082321832830328345832636435982e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33633965123855006982811143987691483957e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46384114966020719170903077536685621119e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07058773850795175564735754911699285828e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.76765053309825506619419451346428518606e-16), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89758965744489334954041814073547951925e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65985298582650601001220682594742473012e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.81017086203232617734714711306180675445e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14481301672800918591822984940714490526e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.90605450026850685321372623938646722657e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42447999818015246265718131846902731574e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83426770079526980292392341278413549820e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65073357441521690641768959521412898756e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.90437453546925074707222505750595530773e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.63458145595422196447107547750737429872e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.94457070577990681786301801930765271001e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80986568964737305842778359322566801845e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 5.3269e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73159318667565938775602634998889798568e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95149372103869634275319490207451722385e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.87504411659823400690797222216564651939e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94571385159717824767058200278511014560e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.71656210265434934399632978675652106638e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.51248899957476233641240573020681464290e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.74490600490886011190565727721143414249e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07537323853509621126318424069471060527e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59167561354023258538869598891502822922e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.72608361427131857269675430568328018022e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.54143016370650707528704927655983490119e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07936446902207128577031566135957311260e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.73506415766100115673754920344659223382e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66918494546396383814682000746818494148e-21), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34854858486201481385140426291984169791e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.25379978655428608198799717171321453517e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.01905621587554903438286661709763596137e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.31293339647901753103699339801273898688e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22793491714510746538048140924864505813e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45360205736839126407568005196865547577e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20918479556021574336548106785887700883e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.91450617548036413606169102407934734864e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59940586452863361281618661053014404930e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.93918243796178165623395356401173295690e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.14578198844767847381800490360878776998e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.25951924258762195043744665124187621023e-13), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 4.8719e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.90469147411748292410422813492550092930e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.20196598836093298098360769875443462143e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92579652651763461802771336515384878994e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.50439147419887323351995227585244144060e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13214742069751393867851080954754449610e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29648648382394801501422003194522139519e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80420399625810952886117129805960917210e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.73059844436212109742132138573157222143e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66835461298243901306176013397428732836e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61808423521250921041207160217989047728e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39300098366988229510997966682317724011e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09447823064238788960158765421669935819e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76962456941948786610101052244821659252e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.56004343709960620209823076030906442732e-25), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.22996422556023111037354479836605618488e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05244279198013248402385148537421114680e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72477335169177427114629223821992187549e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.76404568980852320252614006021707040788e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.79959793426748071158513573279263946303e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.93524788220877416643145672816678561612e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.46692111397574773931528693806744007042e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20764040991846422990601664181377937629e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84452460717254884659858711994943474216e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30317379590981344496250492107505244036e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83736710938966780518785861828424593249e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72943283576264035508862984899450025895e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77791087299927741360821362607419036797e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 5.3269e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35157264931262089761621934621402648954e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51407493866635569361305338029611888082e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30886132894858313459359493329266696766e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02488735053241778868198537544867092626e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12676055870976203566712705442945186614e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.14136757304740001515364737551021389293e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01514327671186735593984375829685709678e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63783530594707477852365258482782354261e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67623013776194044717097141295482922572e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01397549144502050693284434189497148608e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.16720246008161901837639496002941412533e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70776057051329137176494230292143483874e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.02838174509144355795908173352005717435e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.07343581702278433243268463675468320030e-30), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13166129191902183515154099741529804400e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.58587877615076239769720197025023333190e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.14619910799508944167306046977187889556e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.66671218029939293563302720748492945618e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67192565058098643223751044962155343554e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.68397391192695060767615969382391508636e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94009678375859797198831431154760916459e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91901267471125881702216121486397689200e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83697721782125852878533856266722593909e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65409094893730117412328297801448869154e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.04202174160401885595563150562438901685e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.82104711207466136473754349696286794448e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 1.0937e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11253031965493064317003259449214452745e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66886306590939856622089350675801752704e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77786526684921036345823450504680078696e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20343424607276252128027697088363135591e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29196073776799916444272401212341853981e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.92132293422644089278551376756604946339e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07465707745270914645735055945940815947e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.54424785613626844024154493717770471131e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74829439628215654062512023453584521531e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.03470347880592072854295353687395319489e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21113051919776165865529140783521696702e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.83719812218384126931626509884648891889e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.41009036423458926116066353864843586169e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04965807080681693416200699806159303323e-34), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06133417626680943824361625182288165823e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87991711814130682492211639336942588926e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.98342969282034680444232201546039059255e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41940454945139684365514171982891170420e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.90481418770909949109210069475433304086e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25451856391453896652473393039014954572e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36349120987010174609224867075354225138e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94716367816033715208164909918572061643e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.67466470065187852967064897686894407151e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31509787633232139845762764472649607555e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93147765040455324545205202900563337981e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07370974123835247210519262324524537634e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(x) < 8) { + RealType t = log2(ldexp(x, -6)); + + // Rational Approximation + // Maximum Relative Error: 3.1671e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60754766433212615408805486898847664740e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.76143516602438873568296501921670869526e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.25254763859315398784817302471631188095e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.58650277225655302085863010927524053686e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92227773746592457803942136197158658110e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77170481512334811333255898903061802339e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.97864282716826576471164657368231427231e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.44243747123065035356982629201975914275e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54592817957461998135980337838429682406e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.52110831321633404722419425039513444319e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75030698219998735693228347424295850790e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.08894662488905377548940479566994482806e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11472306961184868827300852021969296872e-12), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04202386226609593823214781180612848612e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.07648212684952405730772649955008739292e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50646784687432427178774105515508540021e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02521400964223268224629095722841793118e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35374201758795213489427690294679848997e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.67290684433876221744005507243460683585e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83834977086311601362115427826807705185e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43236252790815493406777552261402865674e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17693398496807851224497995174884274919e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34161978291568722756523120609497435933e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10819003833429876218381886615930538464e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75674945131892236663189757353419870796e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 16) { + RealType t = log2(ldexp(x, -8)); + + // Rational Approximation + // Maximum Relative Error: 6.8517e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.44802371584831601817146389426921705500e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.32962058761590152378007743852342151897e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93461601407042255925193793376118641680e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.55533612685775705468614711945893908392e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76358919439168503100357154639460097607e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74131615534562303144125602950691629908e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.34470363614899824502654995633001232079e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29020592733459891982428815398092077306e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65794017754267756566941255128608603072e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78550878208007836345763926019855723350e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00524022519953193863682806155339574713e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.75977976583947697667784048133959750133e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89287460618943500291479647438555099783e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.27647727947590174240069836749437647626e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70582660582766959108625375415057711766e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.68499175244574169768386088971844067765e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84493774639724473576782806157757824413e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.03526708437207438952843827018631758857e-20), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.88770963972332750838571146142568699263e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.60273143287476497658795203149608758815e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34393017137025732376113353720493995469e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77086140458900002000076127880391602253e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30613589576665986239534705717153313682e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.25355055770024448240128702278455001334e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.16820392686312531160900884133254461634e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.17518073757769640772428097588524967431e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80469112215756035261419102003591533407e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57898123952200478396366475124854317231e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.47675840885248141425130440389244781221e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.97339213584115778189141444065113447170e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.85845602624148484344802432304264064957e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67971825826765902713812866354682255811e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.78795543918651402032912195982033010270e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.18166403020940538730241286150437447698e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.47995312365747437038996228794650773820e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 32) { + RealType t = log2(ldexp(x, -16)); + + // Rational Approximation + // Maximum Relative Error: 6.5315e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36685748306554972131586673701426039950e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75892450098649456865500477195142009984e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.77167300709199375935767980419262418694e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76657987434662206916119089733639111866e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.55003354250569146980730594644539195376e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.64102805555049236216024194001407792885e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36247488122195469059567496833809879653e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63710218182036673197103906176200862606e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60629446465979003842091012679929186607e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22712292003775206105713577811447961965e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.28539646473359376707298867613704501434e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47893806904387088760579412952474847897e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.86809622035928392542821045232270554753e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47935154807866802001012566914901169147e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.40623855123515207599160827187101517978e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.60738876249485914019826585865464103800e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29257874466803586327275841282905821499e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.06781616867813418930916928811492801723e-31), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.33391038950576592915531240096703257292e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.06598147816889621749840662500099582486e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21997213397347849640608088189055469954e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18596259982438670449688554459343971428e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.86085649929528605647139297483281849158e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28178198640304770056854166079598253406e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57155234493390297220982397633114062827e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03771216318243964850930846579433365529e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.49837117625052865973189772546210716556e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.87302306206908338457432167186661027909e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32312467403555290915110093627622951484e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.50516769529388616534895145258103120804e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.03618834064000582669276279973634033592e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.49205787058220657972891114812453768100e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23730041323226753771240724078738146658e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60115971929371066362271909482282503973e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 64) { + RealType t = log2(ldexp(x, -32)); + + // Rational Approximation + // Maximum Relative Error: 1.0538e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619774420718062663274858007687066488e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30268560944740805268408378762250557522e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.09208091036436297425427953080968023835e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.74943166696408995577495065480328455423e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.03759498310898586326086395411203400316e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67261192787197720215143001944093963953e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42934578939412238889174695091726883834e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.32436794923711934610724023467723195718e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35077626369701051583611707128788137675e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.40836846523442062397035620402082560833e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98783806012035285862106614557391807137e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53869567415427145730376778932236900838e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.76521311340629419738016523643187305675e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41298928566351198899106243930173421965e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85552706372195482059144049293491755419e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89780987301820615664133438159710338126e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37965575161090804572561349091024723962e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.58944184323201470938493323680744408698e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35050162268451658064792430214910233545e-40), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61705010674524952791495931314010679992e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.42782564900556152436041716057503104160e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.46038982970912591009739894441944631471e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.34223936001873800295785537132905986678e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.19812900355867749521882613003222797586e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24521111398180921205229795007228494287e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.93429394949368809594897465724934596442e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69259071867341718986156650672535675726e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16370379759046264903196063336023488714e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.12248872253003553623419554868303473929e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12936649424676303532477421399492615666e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37683645610869385656713212194971883914e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21951837982136344238516771475869548147e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91465509588513270823718962232280739302e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98107277753797219142748868489983891831e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.16715818685246698314459625236675887448e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.77987471623502330881961633434056523159e-26), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else if (ilogb(x) < 128) { + RealType t = log2(ldexp(x, -64)); + + // Rational Approximation + // Maximum Relative Error: 2.2309e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619772367581344040890134127619524371e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72522424358877592972375801826826390634e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74749058021341871895402838175268752603e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.95136532385982168410320513292144834602e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.10500792867575154180588502397506694341e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.48101840822895419487033057691746982216e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22577211783918426674527460572438843266e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30499751609793470641331626931224574780e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07043764292750472900578756659402327450e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.28345765853059515246787820662932506931e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48838700086419232178247558529254516870e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.51015062047870581993810118835353083110e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19087584836023628483830612541904830502e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74405125338538967114280887107628943111e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.34493122865874905104884954420903910585e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.33794243240353561095702650271950891264e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07931799710240978706633227327649731325e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60935135769719557933955672887720342220e-23), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.28077223152164982690351137450174450926e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.02813709168750724641877726632095676090e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24899754437233214579860634420198464016e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27313166830073839667108783881090842820e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01803599095361490387188839658640162684e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.63782732057408167492988043000134055952e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.62068163155799642595981598061154626504e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68143951757351157612001096085234448512e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72843955600132743549395255544732133507e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33795283380674591910584657171640729449e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.08452802793967494363851669977089389376e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87062340827301546650149031133192913586e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.31034562935470222182311379138749593572e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.39579834094849668082821388907704276985e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46680056726416759571957577951115309094e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69538874529209016624246362786229032706e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52796320119313458991885552944744518437e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * x); + } + else { + result = 2 / (constants::pi() * x); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 4.8279e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(9.61609610406317335842e-2), + static_cast(3.91836314722738553695e-1), + static_cast(6.79862925205625107133e-1), + static_cast(6.52516594941817706368e-1), + static_cast(3.78594163612581127974e-1), + static_cast(1.37741592243008345389e-1), + static_cast(3.16100502353317199197e-2), + static_cast(3.94935603975622336575e-3), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(1.76863983252615276767e0), + static_cast(1.81486018095087241378e0), + static_cast(1.17295504548962999723e0), + static_cast(5.33998066342362562313e-1), + static_cast(1.66508320794082632235e-1), + static_cast(3.42192028846565504290e-2), + static_cast(3.94691613177524994796e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 2.3675e-17 + BOOST_MATH_STATIC const RealType P[11] = { + static_cast(7.07114056489178077423e-4), + static_cast(7.35277969197058909845e-3), + static_cast(3.45402694579204809691e-2), + static_cast(9.62849773112695332289e-2), + static_cast(1.75738736725818007992e-1), + static_cast(2.18309266582058485951e-1), + static_cast(1.85680388782727289455e-1), + static_cast(1.06177394398691169291e-1), + static_cast(3.94880388335722224211e-2), + static_cast(9.46543177731050647162e-3), + static_cast(1.50949646857411896396e-3), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + static_cast(1), + static_cast(1.19520021153535414164e0), + static_cast(2.24057032777744601624e0), + static_cast(1.63635577968560162720e0), + static_cast(1.58952087228427876880e0), + static_cast(7.63062254749311648018e-1), + static_cast(4.65805990343825931327e-1), + static_cast(1.45821531714775598887e-1), + static_cast(5.42393925507104531351e-2), + static_cast(9.84276292481407168381e-3), + static_cast(1.54787649925009672534e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + const static RealType lambda_bias = static_cast(1.45158270528945486473); // (= log(pi/2)+1) + + RealType sigma = exp(-x * constants::pi() / 2 - lambda_bias); + RealType s = exp(-sigma) / sqrt(sigma); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 6.6532e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(3.71658823632747235572e-1), + static_cast(2.81493346318174084721e-1), + static_cast(1.80052521696460721846e-1), + static_cast(7.65907659636944822120e-2), + static_cast(2.33352148213280934280e-2), + static_cast(5.02308701022480574067e-3), + static_cast(6.29239919421134075502e-4), + static_cast(8.36993181707604609065e-6), + static_cast(-8.38295154747385945293e-6), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(6.62107509936390708604e-1), + static_cast(4.72501892305147483696e-1), + static_cast(1.84446743813050604353e-1), + static_cast(5.99971792581573339487e-2), + static_cast(1.24751029844082800143e-2), + static_cast(1.56705297654475773870e-3), + static_cast(2.36392472352050487445e-5), + static_cast(-2.11667044716450080820e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -5.1328125) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 2.6331e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(3.97500903816385095134e-1), + static_cast(5.08559630146730380854e-1), + static_cast(2.99190443368166803486e-1), + static_cast(1.07339363365158174786e-1), + static_cast(2.61694301269384158162e-2), + static_cast(4.58386867966451237870e-3), + static_cast(5.80610284231484509069e-4), + static_cast(5.07249042503156949021e-5), + static_cast(2.91644292826084281875e-6), + static_cast(9.75453868235609527534e-12), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(1.27376091725485414303e0), + static_cast(7.49829208702328578188e-1), + static_cast(2.69157374996960976399e-1), + static_cast(6.55795320040378662663e-2), + static_cast(1.14912646428788757804e-2), + static_cast(1.45541420582309879973e-3), + static_cast(1.27135040794481871472e-4), + static_cast(7.31138551538712031061e-6), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 1.2055e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.61609610406317335842332400044553397267e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74152295981095898203847178356629061821e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58642905042588731020840168744866124345e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69370085525311304330141932309908104187e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14888713497930800611167630826754270499e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69123861559106636252620023643265102867e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74273532954853421626852458737661546439e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.73534665976007761924923962996725209700e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42543389723715037640714282663089570985e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05120903211852044362181935724880384488e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49586169587615171270941258051088627885e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46047939521303565932576405363107506886e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.68248726161641913236972878212857788320e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.60663638253775180681171554635861859625e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76463460016745893121574217030494989443e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.08380585744336744543979680558024295296e-12), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66458574743150749245922924142120646408e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.87010262350733534202724862784081296105e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.51107149980251214963849267707173045433e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.71158207369578457239679595370389431171e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37188705505573668092513124472448362633e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95647530096628718695081507038921183627e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30278895428001081342301218278371140110e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61322060563420594659487640090297303892e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30529729106312748824241317854740876915e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.90465740298431311519387111139787971960e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.92760416706194729215037805873466599319e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02070496615845146626690561655353212151e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72080705566714681586449384371609107346e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76433504120625478720883079263866245392e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 3.4133e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07114056489178077422539043012078031613e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.18006784954579394004360967455655021959e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.60309646092161147676756546417366564213e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13479499932401667065782086621368143322e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.68587439643060549883916236839613331692e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12366494749830793876926914920462629077e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70739124754664545339208363069646589169e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04073482998938337661285862393345731336e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94833709787596305918524943438549684109e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50214412821697972546222929550410139790e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.43105005523280337071698704765973602884e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.85396789833278250392015217207198739243e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05690359993570736607428746439280858381e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.17297815188944531843360083791153470475e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.03913601629627587800587620822216769010e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61963034255210565218722882961703473760e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.99502258440875586452963094474829571000e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.66563884565518965562535171848480872267e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.23954896921292896539048530795544784261e-6), + }; + BOOST_MATH_STATIC const RealType Q[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77934931846682015134812629288297137499e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.85052416252910403272283619201501701345e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45276747409453182009917448097687214033e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87717215449690275562288513806049961791e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96583424263422661540930513525639950307e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73001838976297286477856104855182595364e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29209801725936746054703603946844929105e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.31809396176316042818100839595926947461e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.62125101720695030847208519302530333864e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22912823173107974750307098204717046200e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.28404310708078592866397210871397836013e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.33433860799478110495440617696667578486e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01779942752411055394079990371203135494e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.60870827161929649807734240735205100749e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.43275518144078080917466090587075581039e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.80287554756375373913082969626543154342e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00697535360590561244468004025972321465e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.23883308105457761862174623664449205327e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + const static RealType lambda_bias = BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.451582705289454864726195229894882143572); // (= log(pi/2)+1) + + RealType sigma = exp(-x * constants::pi() / 2 - lambda_bias); + RealType s = exp(-sigma) / sqrt(sigma); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 9.2619e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.71658823632747235572391863987803415545e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20402452680758356732340074285765302037e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53870483364594487885882489517365212394e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.73525449564340671962525942038149851804e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.67339872142847248852186397385576389802e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.60644488744851390946293970736919678433e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33042051950636491987775324999025538357e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13846819893538329440033115143593487041e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41648498082970622389678372669789346515e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.74006867625631068946791714035394785978e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.12238896415831258936563475509362795783e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88070293465108791701905953972140154151e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.24813015654516014181209691083399092303e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64092873079064926551281731026589848877e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.09892207654972883190432072151353819511e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.86990125202059013860642688739159455800e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62986611607135348214220687891374676368e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07567013469555215514702758084138467446e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.84619752008414239602732630339626773669e-14), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.28669950018285475182750690468224641923e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12421557061005325313661189943328446480e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68376064122323574208976258468929505299e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22010354939562426718305463635398985290e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13795955314742199207524303721722785075e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90452274425830801819532524004271355513e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.38324283887272345859359008873739301544e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15232844484261129757743512155821350773e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.79562237779621711674853020864686436450e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64370777996591099856555782918006739330e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.02327782881305686529414731684464770990e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27181015755595543140221119020333695667e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01121287947061613072815935956604529157e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44038164966032378909755215752715620878e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.39138685106442954199109662617641745618e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.83317957765031605023198891326325990178e-10), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -6.875) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 4.9208e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[20] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97500903816385095134217223320239082420e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02058997410109156148729828665298333233e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30492992901887465108077581566548743407e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08695332228530157560495896731847709498e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.54469321766529692240388930552986490213e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00543201281990041935310905273146022998e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08633547932070289660163851972658637916e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15432691192536747268886307936712580254e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.46179071338871656505293487217938889935e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45295210106393905833273975344579255175e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34638105523514101671944454719592801562e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15786069528793080046638424661219527619e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.54781306296697568446848038567723598851e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31977279631544580423883461084970429143e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.56616743805004179430469197497030496870e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60913959062328670735884196858280987356e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.91123354712008822789348244888916948822e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82453513391091361890763400931018529659e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.12671859603774617133607658779709622453e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03211544596001317143519388487481133891e-20), + }; + BOOST_MATH_STATIC const RealType Q[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.56188463983858614833914386500628633184e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27273165410457713017446497319550252691e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72495122287308474449946195751088057230e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64049710819255633163836824600620426349e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.53329810455612298967902432399110414761e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72302144446588066369304547920758875106e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.90680157119357595265085115978578965640e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87039785683949322939618337154059874729e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64199530594973983893552925652598080310e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88147828823178863054226159776600116931e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.91569503818223078110818909039307983575e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.89289385694964650198403071737653842880e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.32154679053642509246603754078168127853e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.43239674842248090516375370051832849701e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.03349866320207008385913232167927124115e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98307302768178927108235662166752511325e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07996042577029996321821937863373306901e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53576500935979732855511826033727522138e-13), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? landau_cdf_plus_imp_prec(x, tag) : 1 - landau_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - landau_cdf_minus_imp_prec(x, tag) : landau_cdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? landau_cdf_plus_imp_prec(x, tag) : 1 - landau_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - landau_cdf_minus_imp_prec(x, tag) : landau_cdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_cdf_imp(const landau_distribution& dist, const RealType& x, bool complement) { + // + // This calculates the cdf of the Landau distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::cdf(landau<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + RealType bias = dist.bias(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale + bias; + + result = landau_cdf_imp_prec(u, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_lower_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.375) { + RealType t = p - static_cast < RealType>(0.375); + + // Rational Approximation + // Maximum Absolute Error: 3.0596e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(3.74557416577759554506e-2), + static_cast(3.87808262376545756299e0), + static_cast(4.03092288183382979104e0), + static_cast(-1.65221829710249468257e1), + static_cast(-6.99689838230114367276e0), + static_cast(1.51123479911771488314e1), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(4.37863773851525662884e-1), + static_cast(-6.35020262707816744534e0), + static_cast(3.07646508389502660442e-1), + static_cast(9.72566583784248877260e0), + static_cast(-2.72338088170674280735e0), + static_cast(-1.58608957980133006476e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - static_cast < RealType>(0.25); + + // Rational Approximation + // Maximum Absolute Error: 5.2780e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(-4.17764764050720190117e-1), + static_cast(1.27887601021900963655e0), + static_cast(1.80329928265996817279e1), + static_cast(2.35783605878556791719e1), + static_cast(-2.67160590411398800149e1), + static_cast(-2.36192101013335692266e1), + static_cast(8.30396110938939237358e0), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(5.37459525158081633669e0), + static_cast(2.35696607501498012129e0), + static_cast(-1.71117034150268575909e1), + static_cast(-6.72278235529877170403e0), + static_cast(1.27763043804603299034e1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast < RealType>(0.125); + + // Rational Approximation + // Maximum Absolute Error: 6.3254e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-8.77109518013577785811e-1), + static_cast(-1.03442936529923615496e1), + static_cast(-1.03389868296950570121e1), + static_cast(2.01575691867458616553e2), + static_cast(4.59115079925618829199e2), + static_cast(-3.38676271744958577802e2), + static_cast(-5.38213647878547918506e2), + static_cast(1.99214574934960143349e2), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(1.64177607733998839003e1), + static_cast(8.10042194014991761178e1), + static_cast(7.61952772645589839171e1), + static_cast(-2.52698871224510918595e2), + static_cast(-1.95365983250723202416e2), + static_cast(2.61928845964255538379e2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 3.5192e-18 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(-8.77109518013577852585e-1), + static_cast(-1.08703720146608358678e0), + static_cast(-4.34198537684719253325e-1), + static_cast(-6.97264194535092564620e-2), + static_cast(-4.20721933993302797971e-3), + static_cast(-6.27420063107527426396e-5), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(8.38688797993971740640e-1), + static_cast(2.47558526682310722526e-1), + static_cast(3.03952783355954712472e-2), + static_cast(1.39226078796010665644e-3), + static_cast(1.43993679246435688244e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 1.1196e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-1.16727296241754548410e0), + static_cast(-1.12325365855062172009e0), + static_cast(-3.96403456954867129566e-1), + static_cast(-6.50024588048629862189e-2), + static_cast(-5.08582387678609504048e-3), + static_cast(-1.71657051345258316598e-4), + static_cast(-1.81536405273085024830e-6), + static_cast(-9.65262938333207656548e-10), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(7.55271574611337871389e-1), + static_cast(2.16323131117540100488e-1), + static_cast(2.92693206540519768049e-2), + static_cast(1.89396907936678571916e-3), + static_cast(5.20017914327360594265e-5), + static_cast(4.18896774212993675707e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 1.0763e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-1.78348038398799868409e0), + static_cast(-7.74779087785346936524e-1), + static_cast(-1.27121601027522656374e-1), + static_cast(-9.86675785835385622362e-3), + static_cast(-3.69510132425310943600e-4), + static_cast(-6.00811940375633438805e-6), + static_cast(-3.06397799506512676163e-8), + static_cast(-7.34821360521886161256e-12), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(3.76606062137668223823e-1), + static_cast(5.37821995022686641494e-2), + static_cast(3.62736078766811383733e-3), + static_cast(1.16954398984720362997e-4), + static_cast(1.59917906784160311385e-6), + static_cast(6.41144889614705503307e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 9.9936e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-2.32474749499506229415e0), + static_cast(-4.81681429397597263092e-1), + static_cast(-3.79696253130015182335e-2), + static_cast(-1.42328672650093755545e-3), + static_cast(-2.58335052925986849305e-5), + static_cast(-2.03945574260603170161e-7), + static_cast(-5.04229972664978604816e-10), + static_cast(-5.49506755992282162712e-14), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(1.87186049570056737301e-1), + static_cast(1.32852903862611979806e-2), + static_cast(4.45262195863310928309e-4), + static_cast(7.13306978839226580931e-6), + static_cast(4.84555343060572391776e-8), + static_cast(9.65086092007764297450e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 9.2449e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-2.82318656228158372998e0), + static_cast(-2.84346379198027589453e-1), + static_cast(-1.09194719815749710073e-2), + static_cast(-1.99728160102967185378e-4), + static_cast(-1.77069359938827653381e-6), + static_cast(-6.82828539186572955883e-9), + static_cast(-8.22634582905944543176e-12), + static_cast(-4.10585514777842307175e-16), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(9.29910333991046040738e-2), + static_cast(3.27860300729204691815e-3), + static_cast(5.45852206475929614010e-5), + static_cast(4.34395271645812189497e-7), + static_cast(1.46600782366946777467e-9), + static_cast(1.45083131237841500574e-12), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 8.6453e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-3.29700011190686231229e0), + static_cast(-1.62920309130909343601e-1), + static_cast(-3.07152472866757852259e-3), + static_cast(-2.75922040607620211449e-5), + static_cast(-1.20144242264703283024e-7), + static_cast(-2.27410079849018964454e-10), + static_cast(-1.34109445298156050256e-13), + static_cast(-3.08843378675512185582e-18), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(4.62324092774919223927e-2), + static_cast(8.10410923007867515072e-4), + static_cast(6.70843016241177926470e-6), + static_cast(2.65459014339231700938e-8), + static_cast(4.45531791525831169724e-11), + static_cast(2.19324401673412172456e-14), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -256) { + RealType t = -log2(ldexp(p, 128)); + + // Rational Approximation + // Maximum Relative Error: 8.2028e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-3.75666995985336008568e0), + static_cast(-9.15751436135409108392e-2), + static_cast(-8.51745858385908954959e-4), + static_cast(-3.77453552696508401182e-6), + static_cast(-8.10504146884381804474e-9), + static_cast(-7.55871397276946580837e-12), + static_cast(-2.19023097542770265117e-15), + static_cast(-2.34270094396556916060e-20), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(2.30119177073875808729e-2), + static_cast(2.00787377759037971795e-4), + static_cast(8.27382543511838001513e-7), + static_cast(1.62997898759733931959e-9), + static_cast(1.36215810410261098317e-12), + static_cast(3.33957268115953023683e-16), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -512) { + RealType t = -log2(ldexp(p, 256)); + + // Rational Approximation + // Maximum Relative Error: 7.8900e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-4.20826069989721597050e0), + static_cast(-5.07864788729928381957e-2), + static_cast(-2.33825872475869133650e-4), + static_cast(-5.12795917403072758309e-7), + static_cast(-5.44657955194364350768e-10), + static_cast(-2.51001805474510910538e-13), + static_cast(-3.58448226638949307172e-17), + static_cast(-1.79092368272097571876e-22), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(1.14671758705641048135e-2), + static_cast(4.98614103841229871806e-5), + static_cast(1.02397186002860292625e-7), + static_cast(1.00544286633906421384e-10), + static_cast(4.18843275058038084849e-14), + static_cast(5.11960642868907665857e-18), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -1024) { + RealType t = -log2(ldexp(p, 512)); + + // Rational Approximation + // Maximum Relative Error: 7.6777e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-4.65527239540648658214e0), + static_cast(-2.78834161568280967534e-2), + static_cast(-6.37014695368461940922e-5), + static_cast(-6.92971221299243529202e-8), + static_cast(-3.64900562915285147191e-11), + static_cast(-8.32868843440595945586e-15), + static_cast(-5.87602374631705229119e-19), + static_cast(-1.37812578498484605190e-24), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(5.72000087046224585566e-3), + static_cast(1.24068329655043560901e-5), + static_cast(1.27105410419102416943e-8), + static_cast(6.22649556008196699310e-12), + static_cast(1.29416254332222127404e-15), + static_cast(7.89365027125866583275e-20), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else{ + result = -boost::math::numeric_limits::infinity(); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_lower_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.375) { + RealType t = p - 0.375; + + // Rational Approximation + // Maximum Absolute Error: 2.5723e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.74557416577759248536854968412794870581e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.04379368253541440583870397314012269006e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12622841210720956864564105821904588447e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.57744422491408570970393103737579322242e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.13509711945094517370264490591904074504e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.18322789179144512109337184576079775889e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21447613719864832622177316196592738866e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49076304733407444404640803736504398642e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.96654951892056950374719952752959986017e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.73083458872938872583408218098970368331e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.22584946471889320670122404162385347867e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98534922151507267157370682137856253991e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.09159286510191893522643172277831735606e0), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.86204686129323171601167115178777357431e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.43698274248278918649234376575855135232e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.75240332521434608696943994815649748669e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.31438891446345558658756610288653829009e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10716029191240549289948990305434475528e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.10878330779477313404660683539265890549e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.52360069933886703736010179403700697679e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.15864312939821257811853678185928982258e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.10341116017481903631605786613604619909e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29121822170912306719250697890270750964e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56489746112937744052098794310386515793e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - 0.25; + + // Rational Approximation + // Maximum Absolute Error: 6.1583e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.17764764050720242897742634974454113395e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.80044093802431965072543552425830082205e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23613318632011593171919848575560968064e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77438013844838858458786448973516177604e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.62569530523012138862025718052954558264e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.02005706260864894793795986187582916504e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.29383609355165614630538852833671831839e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.09367754001841471839736367284852087164e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45744413840415901080013900562654222567e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41920296534143581978760545125050148256e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.94857580745127596732818606388347624241e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.02847586753967876900858299686189155164e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.29953583375818707785500963989580066735e1), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27455303165341271216882778791555788609e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41762124591820618604790027888328605963e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.30845760165840203715852751405553821601e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.00827370048057599908445731563638383351e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.19621193929561206904250173267823637982e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.10514757798726932158537558200005910184e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.79738493761540403010052092523396617472e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.94101664430520833603032182296078344870e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.31586575577250608890806988616823861649e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93650751613703379272667745729529916084e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.52472388998113562780767055981852228229e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.01428305018551686265238906201345171425e0), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - 0.125; + + // Rational Approximation + // Maximum Absolute Error: 1.3135e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.77109518013577849065583862782160121458e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.05813204052660740589813216397258899528e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.19628607167020425528944673039894592264e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.67162644860799051148361885190022738759e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.05921446080443979618622123764941760355e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.26685085062411656483492973256809500654e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17117538916032273474332064444853786788e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.45059470468014721314631799845029715639e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28952226224720891553119529857430570919e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.98502296814963504284919407719496390478e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.10876326351879104392865586365509749012e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.70358021544406445036220918341411271912e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.49724346845064961378591039928633169443e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.23815021378788622035604969476085727123e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.17262073948257994617723369387261569086e4), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.94901665980514882602824575757494472790e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.54328910175180674300123471690771017388e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84847502738788846487698327848593567941e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98451502799612368808473649408471338893e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.13744760159877712051088928513298431905e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.20745061658519699732567732006176366700e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68622317228909264645937229979147883985e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.96020751551679746882793283955926871655e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88860541272346724142574740580038834720e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.73454107207588310809238143625482857512e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.23165643368613191971938741926948857263e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.94832163019509140191456686231012184524e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.26616234097287315007047356261933409072e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24686019847093806280148917466062407447e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 2.0498e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.77109518013577849065583862782160155093e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.77585398076895266354686007069850894777e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47522378123968853907102309276280187353e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.63343576432650242131602396758195296288e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.77801189859227220359806456829683498508e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.93221663334563259732178473649683953515e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.95272757466323942599253855146019408376e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.73624853556509653351605530630788087166e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.41317699770351712612969089634227647374e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.34187895701093934279414993393750297714e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.64090928155753225614302094820737249510e-10), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62401464973350962823995096121206419019e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11979822811128264831341485706314465894e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27257342406829987209876262928379300361e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.85505879705365729768944032174855501091e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40983451000610516082352700421098499905e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23459897865681009685618192649929504121e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.28925214684463186484928824536992032740e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67647262682850294124662856194944728023e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88173142080572819772032615169461689904e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.07756799117728455728056041053803769069e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 6.7643e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.16727296241754547290632950718657117630e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.97822895738734630842909028778257589627e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.45580723831325060656664869189975355503e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.13835678647158936819843386298690513648e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.64536831064884519168892017327822018961e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.93786616484143556451247457584976578832e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.55770899078184683328915310751857391073e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.91778173446401005072425460365992356304e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.59064619930808759325013814591048817325e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.54786673836080683521554567617693797315e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.15917340396537949894051711038346411232e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.29633344043292285568750868731529586549e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.27785620133198676852587951604694784533e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.89999814745618370028655821500875451178e-16), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48772690114094395052120751771215809418e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.72281013057830222881716429522080327421e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.67186370229687087768391373818683340542e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.86988148601521223503040043124617333773e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43321724586909919175166704060749343677e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57428821868404424742036582321713763151e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17165774858274087452172407067668213010e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.78674439389954997342198692571336875222e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82045374895858670592647375231115294575e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40152058277291349447734231472872126483e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.34789603687129472952627586273206671442e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38087376350052845654180435966624948994e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34945081364333330292720602508979680233e-16), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 6.4987e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.78348038398799867332294266481364810762e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.42913983922316889357725662957488617770e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.02077376277824482097703213549730657663e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.01799479940825547859103232846394236067e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.31954083060883245879038709103320778401e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.14437110578260816704498035546280169833e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.75434713435598124790021625988306358726e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.70722283097111675839403787383067403199e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.22792548204908895458622068271940298849e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.23652632092726261134927067083229843867e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.26848751206698811476021875382152874517e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.96683933776920842966962054618493551480e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.65547426464916480144982028081303670013e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.01788104318587272115031165074724363239e-19), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.43507070588695242714872431565299762416e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.42808541175677232789532731946043918868e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.58154336417481327293949514291626832622e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.52883128062761272825364005132296437324e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46220303655089035098911370014929809787e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.44776253795594076489612438705019750179e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.09607872267766585503592561222987444825e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24270418154050297788150584301311027023e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.52138350835458198482199500102799185922e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28330565098807415367837423320898722351e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61220858078610415609826514581165467762e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31680570822471881148008283775281806658e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61638868324981393463928986484698110415e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 6.4643e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.32474749499506228416012679106564727824e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.11125026189437033131539969177846635890e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56906722402983201196890012041528422765e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56242546565817333757522889497509484980e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.96189353402888611791301502740835972176e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.25518459970705638772495930203869523701e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.23831474024265607073689937590604367113e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.44925744847701733694636991148083680863e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.22891322042392818013643347840386719351e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.72860750698838897533843164259437533533e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.38276123679972197567738586890856461530e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.75010927807240165715236750369730131837e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.39435252454410259267870094713230289131e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.32672767938414655620839066142834241506e-23), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.71913035066927544877255131988977106466e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.07499674325721771035402891723823952963e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.73304002376509252638426379643927595435e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.45986195188119302051678426047947808068e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39631771214004792103186529415117786213e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.82972151546053891838685817022915476363e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.11484161875982352879422494936862579004e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.76886416872139526041488219568768973343e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.88160764330501845206576873052377420740e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20653899535657202009579871085255085820e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.86752135706343102514753706859178940399e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.08670633989984379551412930443791478495e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96869107941293302786688580824755244599e-24), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 6.2783e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.82318656228158372073367735499501003484e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.46261040951642110189344545942990712460e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.64741560190892266676648641695426188913e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.28753551974093682831398870653055328683e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.21312013770915263838500863217194379134e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.52436958859473873340733176333088176566e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.19550238139736009251193868269757013675e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.14964971787780037500173882363122301527e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.40304301938210548254468386306034204388e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.86982233973109416660769999752508002999e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47229710624085810190563630948355644978e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.97511060097659395674010001155696382091e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.14321784268659603072523892366718901165e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.69804409248161357472540739283978368871e-27), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85763741109198600677877934140774914793e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51555423561034635648725665049090572375e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.14334282485948451530639961260946534734e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15303265564789411158928907568898290494e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.33945229806307308687045028827126348382e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.94373901322371782367428404051188999662e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.51420073260465851038482922686870398511e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.39366317896256472225488167609473929757e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32986474655329330922243678847674164814e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09408217872473269288530036223761068322e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79051953285476930547217173280519421410e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94530899348454778842122895096072361105e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36452993460830805591166007621343447892e-28), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 6.0123e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.29700011190686230364493911161520668302e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.16175031776740080906111179721128106011e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.33343982195432985864570319341790342784e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.25414682801788504282484273374052405406e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.08812659343240279665150323243172015853e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.33251452861660571881208437468957953698e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.80894766863868081020089830941243893253e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.84955155823472122347227298177346716657e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.98637322645260158088125181176106901234e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.24174383760514163336627039277792172744e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.54369979866464292009398761404242103210e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.02572051048819721089874338860693952304e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.93656169061287808919601714139458074543e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.14930159772574816086864316805656403181e-31), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27154900915819978649344191118112870943e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77527908332591966425460814882436207182e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88097249712649070373643439940164263005e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33593973311650359460519742789132084170e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34383186845963127931313004467487408932e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.18631088001587612168708294926967112654e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25338215226314856456799568077385137286e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30644713290591280849926388043887647219e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55508263112797212356530850090635211577e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96694528841324480583957017533192805939e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81411886190142822899424539396403206677e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64683991040772975824276994623053932566e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81924597500766743545654858597960153152e-32), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -256) { + RealType t = -log2(ldexp(p, 128)); + + // Rational Approximation + // Maximum Relative Error: 5.7624e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.75666995985336007747791649448887723610e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.78960399079208663111712385988217075907e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.74942252057371678208959612011771010491e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.54567765510065203543937772001248399869e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.53093894540157655856029322335609764674e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.83833601054721321664219768559444646069e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.52281007055180941965172296953524749452e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.57322728543196345563534040700366511864e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.52881564741260266060082523971278782893e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.60440334652864372786302383583725866608e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.60691285483339296337794569661545125426e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.29567560587442907936295101146377006338e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.50976593324256906782731237116487284834e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.71308835356954147218854223581309967814e-35), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.62732785401286024270119905692156750540e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.40382961238668912455720345718267045656e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10406445824749289380797744206585266357e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.28896702052362503156922190248503561966e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16141168910009886089186579048301366151e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41978644147717141591105056152782456952e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28101353275172857831967521183323237520e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02996252940600644617348281599332256544e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.91006255647885778937252519693385130907e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84585864559619959844425689120130028450e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.68573963627097356380969264657086640713e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11059307697054035905630311480256015939e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36363494270701950295678466437393953964e-36), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -512) { + RealType t = -log2(ldexp(p, 256)); + + // Rational Approximation + // Maximum Relative Error: 5.5621e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.20826069989721596260510558511263035942e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.97440158261228371765435988840257904642e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.03971528248920108158059927256206438162e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.27123766722395421727031536104546382045e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.42341191105097202061646583288627536471e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.27644514375284202188806395834379509517e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.10772944192965679212172315655880689287e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.32875098791800400229370712119075696952e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.06204614360238210805757647764525929969e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.43745006810807466452260414216858795476e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.66712970893511330059273629445122037896e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.72840198778128683137250377883245540424e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.91906782399731224228792112460580813901e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.42769091263044979075875010403899574987e-39), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31008507886426704374911618340654350029e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34370110384866123378972324145883460422e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37370811166006065198348108499624387519e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.14880753458828334658200185014547794333e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29049942195929206183214601044522500821e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19814793427532184357255406261941946071e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53609759199568827596069048758012402352e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94113467521833827559558236675876398395e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.46066673213431758610437384053309779874e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73781952388557106045597803110890418919e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.17225106466605017267996611448679124342e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66384334839761400228111118435077786644e-35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.02877806111195383689496741738320318348e-40), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -1024) { + RealType t = -log2(ldexp(p, 512)); + + // Rational Approximation + // Maximum Relative Error: 5.4128e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.65527239540648657446629479052874029563e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.49609214609793557370425343404734771058e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.85355312961840000203681352424632999367e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.57243631623079865238801420669247289633e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.64978384343879316016184643597712973486e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.12776782513387823319217102727637716531e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.86985041780323969283076332449881856202e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.11665149267826038417038582618446201377e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.44259259232002496618805591961855219612e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.13186466395317710362065595347401054176e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.72627240737786709568584848420972570566e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.40450635670659803069555960816203368299e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.90550919589933206991152832258558972394e-38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.33785768143117121220383154455316199086e-43), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15365252334339030944695314405853064901e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84519641047962864523571386561993045416e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71097850431873211384168229175171958023e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20268329795802836663630276028274915013e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.00891848515558877833795613956071967566e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41031229424613259381704686657785733606e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96506914235910190020798805190634423572e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.51190756655665636680121123277286815188e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82855686000721415124702578998188630945e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64298533757673219241102013167519737553e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01176104624443909516274664414542493718e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.41571947895162847564926590304679876888e-39), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.84682590163505511580949151048092123923e-44), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -2048) { + RealType t = -log2(ldexp(p, 1024)); + + // Rational Approximation + // Maximum Relative Error: 5.3064e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.09971143249822249471944441552701756051e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.00154235169065403254826962372636417554e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.76859552294270710004718457715250134998e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.16331901379268792872208226779641113312e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.11590258438815173520561213981966313758e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.17278804462968109983985217400233347654e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.14112976645884560534267524918610371127e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.34652102658577790471066054415469309178e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.85242987373551062800089607781071064493e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.35051904844102317261572436130886083833e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.78478298776769981726834169566536801689e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.22532973433435489030532261530565473605e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.25433604872532935232490414753194993235e-41), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.49792182967344082832448065912949074241e-47), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.76316274347013095030195725596822418859e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45872499993438633169552184478587544165e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13309566903496793786045158442686362533e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99468690853840997883815075627545315449e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24734617022827960185483615293575601906e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.30099852343633243897084627428924039959e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52598626985708878790452436052924637029e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91432956461466900007096548587800675801e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.54421383015859327468201269268335476713e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55939743284103455997584863292829252782e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.73331214275752923691778067125447148395e-38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55089353084326800338273098565932598679e-42), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.85408276119483460035366338145310798737e-48), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4096) { + RealType t = -log2(ldexp(p, 2048)); + + // Rational Approximation + // Maximum Relative Error: 5.2337e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.54271778755494231572464179212263718102e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.62737121212473668543011440432166267791e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.10099492629239750693134803100262740506e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56925359477960645026399648793960646858e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.50756287005636861300081510456668184335e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.40657453971177017986596834420774251809e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.25518001919157628924245515302669097090e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.79618511101781942757791021761865762100e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.70242241511341924787722778791482800736e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.87078860748428154402226644449936091766e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.84256560347986567120140826597805016470e-35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.71419536977123330712095123316879755172e-40), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.20746149769511232987820552765701234564e-45), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.97544543671003989410397788518265345930e-51), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87980995989632171985079518382705421728e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64234691529227024725728122489224211774e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66149363392892604040036997518509803848e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24365427902918684575287447585802611012e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.88619663977804926166359181945671853793e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.25299846770395565237726328268659386749e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18720305257346902130922082357712771134e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13302092710568005396855019882472656722e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.88571994886818976015465466797965950164e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.48486836614948668196092864992423643733e-36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72247229252387482782783442901266890088e-41), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76046592638280288324495546006105696670e-46), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.09378739037162732758860377477607829024e-52), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8192) { + RealType t = -log2(ldexp(p, 4096)); + + // Rational Approximation + // Maximum Relative Error: 5.1864e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.98493298246627952401490656857159302716e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.76990949843357898517869703626917264559e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.65042794324685841303461715489845834903e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.10605446678026983843303253925148000808e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.02762962429283889606329831562937730874e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.04105882385534634676234513866095562877e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.76001901462155366759952792570076976049e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.48255362964603267691139956218580946011e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.19422119466925125740484046268759113569e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.00719439924828639148906078835399693640e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.89921842231783558951433534621837291030e-38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.90738353848476619269054038082927243972e-43), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.19893980415902021846066305054394089887e-49), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.85434486590981105149494168639321627061e-55), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43932168599456260558411716919165161381e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.09851997458503734167541584552305867433e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.32285843258966417340522520711168738158e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76041266755635729156773747720864677283e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21202253509959946958614664659473305613e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28647335562574024550800155417747339700e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.24953333571478743858014647649207040423e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.41206199962423704137133875822618501173e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34018702380092542910629787632780530080e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41732943566503750356718429150708698018e-39), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29626943299239081309470153019011607254e-44), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.13947437500822384369637881437951570653e-50), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.61766557173110449434575883392084129710e-56), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16384) { + RealType t = -log2(ldexp(p, 8192)); + + // Rational Approximation + // Maximum Relative Error: 5.1568e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.42671464308364892089984144203590292562e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.70165333325375920690660683988390032004e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.51230594210711745541592189387307516997e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.81387249912672866168782835177116953008e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.35308063526816559199325906123032162155e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.67672500455361049516022171111707553191e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.45533142942305626136621399056034449775e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.37422341389432268402917477004312957781e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.32123176403616347106899307416474970831e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.07816837508332884935917946618577512264e-36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.95418937882563343895280651308376855123e-41), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.78256110112636303941842779721479313701e-47), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.09423327107440352766843873264503717048e-52), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.12386630925835960782702757402676887380e-58), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.19477412398085422408065302795208098500e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27347517804649548179786994390985841531e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15042399607786347684366638940822746311e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.84537882580411074097888848210083177973e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.78283331111405789359863743531858801963e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00711555012725961640684514298170252743e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.21370151454170604715234671414141850094e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72008007024350635082914256163415892454e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61182095564217124712889821368695320635e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35498047010165964231841033788823033461e-42), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11828030216193307885831734256233140264e-47), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22499308298315468568520585583666049073e-53), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04877018522402283597555167651619229959e-59), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = -boost::math::numeric_limits::infinity(); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.375) { + RealType t = p - static_cast < RealType>(0.375); + + // Rational Approximation + // Maximum Relative Error: 5.1286e-20 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.31348919222343858178e0), + static_cast(-1.06646675961352786791e0), + static_cast(-1.80946160022120488884e1), + static_cast(-1.53457017598330440033e0), + static_cast(4.71260102173048370028e1), + static_cast(4.61048467818771410732e0), + static_cast(-2.80957284947853532418e1), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1), + static_cast(4.71007453129016317772e0), + static_cast(1.31946404969596908872e0), + static_cast(-1.70321827414586880227e1), + static_cast(-1.11253495615474018666e1), + static_cast(1.62659086449959446986e1), + static_cast(7.37109203295032098763e0), + static_cast(-2.43898047338699777337e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - static_cast < RealType>(0.25); + + // Rational Approximation + // Maximum Relative Error: 3.4934e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.55081568282045924981e0), + static_cast(5.38750533719526696218e0), + static_cast(-2.32797421725187349036e1), + static_cast(-3.96043566411306749784e1), + static_cast(3.80609941977115436545e1), + static_cast(3.35014421131920266346e1), + static_cast(-1.17490458743273503838e1), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(7.52439409918350484765e0), + static_cast(1.34784954182866689668e1), + static_cast(-9.21002543625052363446e0), + static_cast(-2.67378141317474265949e1), + static_cast(2.10158795079902783094e0), + static_cast(5.90098096212203282798e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast < RealType>(0.125); + + // Rational Approximation + // Maximum Relative Error: 4.0795e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(5.68160868054034111703e0), + static_cast(1.06098927525586705381e2), + static_cast(5.74509518025029027944e2), + static_cast(4.91117375866809056969e2), + static_cast(-2.92607000654635606895e3), + static_cast(-3.82912009541683403499e3), + static_cast(2.49195208452006100935e3), + static_cast(1.29413301335116683836e3), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1), + static_cast(2.69603865809599480308e1), + static_cast(2.63378422475372461819e2), + static_cast(1.09903493506098212946e3), + static_cast(1.60315072092792425370e3), + static_cast(-5.44710468198458322870e2), + static_cast(-1.76410218726878681387e3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 4.4618e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(7.10201085067542566037e-1), + static_cast(6.70042401812679849451e-1), + static_cast(2.42799404088685074098e-1), + static_cast(4.80613880364042262227e-2), + static_cast(6.04473313360581797461e-3), + static_cast(5.09172911021654842046e-4), + static_cast(-6.63145317984529265677e-6), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1), + static_cast(9.18649629646213969612e-1), + static_cast(3.66343989541898286306e-1), + static_cast(8.01010534748206001446e-2), + static_cast(1.00553335007168823115e-2), + static_cast(6.30966763237332075752e-4), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 5.8994e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(7.06147398566773538296e-1), + static_cast(4.26802162741800814387e-1), + static_cast(1.32254436707168800420e-1), + static_cast(2.86055054496737936396e-2), + static_cast(3.63373131686703931514e-3), + static_cast(3.84438945816411937013e-4), + static_cast(1.67768561420296743529e-5), + static_cast(8.76982374043363061978e-7), + static_cast(-1.99744396595921347207e-8), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(6.28190787856605587324e-1), + static_cast(2.10992746593815791546e-1), + static_cast(4.44397672327578790713e-2), + static_cast(6.02768341661155914525e-3), + static_cast(5.46578619531721658923e-4), + static_cast(3.11116573895074296750e-5), + static_cast(1.17729007979018602786e-6), + static_cast(-2.78441865351376040812e-8), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 8.8685e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.48209596014908359251e-1), + static_cast(2.52611824671691390768e-1), + static_cast(4.65114070477803399291e-2), + static_cast(5.23373513313686849909e-3), + static_cast(3.83113384161076881958e-4), + static_cast(1.96230077517629530809e-5), + static_cast(5.83117485120890819338e-7), + static_cast(6.92614450423703079737e-9), + static_cast(-3.89531123166658723619e-10), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(3.99413988076189200840e-1), + static_cast(7.32068638518417765776e-2), + static_cast(8.15517102642752348889e-3), + static_cast(6.09126071418098074914e-4), + static_cast(3.03794079468789962611e-5), + static_cast(9.32109079205017197662e-7), + static_cast(1.05435710482490499583e-8), + static_cast(-6.08748435983193979360e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 1.0253e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(6.36719010559816164896e-1), + static_cast(2.06504115804034148753e-1), + static_cast(3.28085429275407182582e-2), + static_cast(3.31676417519020335859e-3), + static_cast(2.35502578757551086372e-4), + static_cast(1.21652240566662139418e-5), + static_cast(4.57039495420392748658e-7), + static_cast(1.18090959236399583940e-8), + static_cast(1.77492646969597480221e-10), + static_cast(-2.19331267300885448673e-17), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(3.24422807416528490276e-1), + static_cast(5.15290129833049138552e-2), + static_cast(5.21051235888272287209e-3), + static_cast(3.69895399249472399625e-4), + static_cast(1.91103139437893226482e-5), + static_cast(7.17882574725373091636e-7), + static_cast(1.85502934977316481559e-8), + static_cast(2.78798057565507249164e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 8.1705e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(6.36619775525705206992e-1), + static_cast(2.68335698140634792041e-1), + static_cast(5.49803347535070103650e-2), + static_cast(7.25018344556356907109e-3), + static_cast(6.87753481255849254220e-4), + static_cast(4.86155006277788340253e-5), + static_cast(2.84604768310787862450e-6), + static_cast(9.56133960810049319917e-8), + static_cast(5.26850116571886385248e-9), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1), + static_cast(4.21500730173440590900e-1), + static_cast(8.63629077498258325752e-2), + static_cast(1.13885615328098640032e-2), + static_cast(1.08032064178130906887e-3), + static_cast(7.63650498196064792408e-5), + static_cast(4.47056124637379045275e-6), + static_cast(1.50189171357721423127e-7), + static_cast(8.27574227882033707932e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else { + result = 2 / (constants::pi() * p); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.4375) { + RealType t = p - 0.4375; + + // Rational Approximation + // Maximum Relative Error: 1.4465e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.08338732735341567163440035550389989556e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.27245731792290848390848202647311435023e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.29317169036386848462079766136373749420e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36342136825575317326816540539659955416e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31108700679715257074164180252148868348e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.81863611749256385875333154189074054367e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.11618233433781722149749739225688743102e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45241854625686954669050322459035410227e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.09780430233523239228350030812868983054e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.42232005306623465126477816911649683789e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.24816048952817367950452675590290535540e0), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80464069267458650284548842830642770344e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.28240205449280944407125436342013240876e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.94145088402407692372903806765594642452e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30062294376971843436236253827463203953e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47118047660686070998671803800237836970e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.00643263133479482753298910520340235765e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.79460803824650509439313928266686172255e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32647058691746306769699006355256099134e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.59208938705683333141038012302171324544e0), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.375) { + RealType t = p - 0.375; + + // Rational Approximation + // Maximum Relative Error: 5.1929e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31348919222343858173602105619413801018e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.02800226274700443079521563669609776285e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.02091675505570786434803291987263553778e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50141943970885120432710080552941486001e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.93099903417013423125762526465625227789e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.56412922160141953385088141936082249641e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47026602535072645589119440784669747242e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.01068960815396205074336853052832780888e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.86591619131639705495877493344047777421e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.26390836417639942474165178280649450755e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.18212484486162942333407102351878915285e0), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97802777458574322604171035748634755981e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.33277809211107726455308655998819166901e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.76555481647551088626503871996617234475e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.33146828123660043197526014404644087069e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65159900182434446550785415837526228592e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.32391192521438191878041140980983374411e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.12112886240590711980064990996002999330e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.93964809733838306198746831833843897743e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53948309965401603055162465663290204205e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - 0.25; + + // Rational Approximation + // Maximum Relative Error: 3.2765e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55081568282045925871949387822806890848e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21080883686702131458668798583937913025e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15083151599213113740932148510289036342e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.94190629930345397070104862391009053509e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.40768205403470729468297576291723141480e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00001008242667338579153437084294876585e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70900785394455368299616221471466320407e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48947677419760753410122194475234527150e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.01826174001050912355357867446431955195e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.55833657916143927452986099130671173511e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.32953617526068647169047596631564287934e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.32825234826729794599233825734928884074e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.47352171888649528242284500266830013906e1), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40793887011403443604922082103267036101e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.04348824299115035210088417095305744248e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19680004238557953382868629429538716069e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.31172263627566980203163658640597441741e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.07390429662527773449936608284938592773e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.94877589960261706923147291496752293313e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.94903802003585398809229608695623474341e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80417437710146805538675929521229778181e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.23364098614130091185959973343748897970e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.12975537807357019330268041620753617442e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.36592279898578127130605391750428961301e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18495624730372864715421146607185990918e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - 0.125; + + // Rational Approximation + // Maximum Relative Error: 1.8007e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.68160868054034088524891526884683014057e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85165791469635551063850795991424359350e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.42938802867742165917839659578485422534e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59273512668331194186228996665355137458e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.91680503091725091370507732042764517726e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85642348415580865994863513727308578556e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.90181935466760294413877600892013910183e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.89141276256233344773677083034724024215e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00250514074918631367419468760920281159e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28168216451109123143492880695546179794e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14996399533648172721538646235459709807e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.58122093722347315498230864294015130011e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.25168985723506298009849577846542992545e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01179759985059408785527092464505889999e5), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08766677593618443545489115711858395831e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.05163374816838964338807027995515659842e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.62582103160439981904537982068579322820e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.62170991799612186300694554812291085206e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11013837158432827711075385018851760313e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45458895395245243570930804678601511371e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.08336489932795411216528182314354971403e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.11314692423102333551299419575616734987e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.43287683964711678082430107025218057096e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.62052814931825182298493472041247278475e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91440920656902450957296030252809476245e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.54913345383745613446952578605023052270e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.76034827722473399290702590414091767416e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94027684838690965214346010602354223752e3), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 6.1905e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.10201085067542610656114408605853786551e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.04725580445598482170291458376577106746e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.35945839005443673797792325217359695272e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15894004364989372373490772246381545906e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.54550169514753150042231386414687368032e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50389998399729913427837945242228928632e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75018554725308784191307050896936055909e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95901705695908219804887362154169268380e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34386856794684798098717884587473860604e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.89025399683852111061217430321882178699e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19044156703773954109232310846984749672e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11932910013840927659486142481532276176e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64064398716881126082770692219937093427e-10), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24909572944428286558287313527068259394e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.70912720447370835699164559729287157119e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.21998644852982625437008410769048682388e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.95906385698373052547496572397097325447e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35344144061390771459100718852878517200e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34168669072527413734185948498168454149e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.24488907049996230177518311480230131257e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.92059624838630990024209986717533470508e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84464614954263838504154559314144088371e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.67874815200287308180777775077428545024e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65919857481420519138294080418011981524e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.31466713452016682217190521435479677133e-10), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 8.5157e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.06147398566773479301585022897491054494e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06137881154706023038556659418303323027e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.00274868819366386235164897614448662308e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.03481313941011533876096564688041226638e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50172569438851062169493372974287427240e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.33370725278950299189434839636002761850e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.97566905908106543054773229070602272718e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85701973515993932384374087677862623215e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81956143385351702288398705969037130205e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.49975572102999645354655667945479202048e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.54665400959860442558683245665801873530e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94292402413454232307556797758030774716e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98038791388715925556623187510676330309e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11242951548709169234296005470944661995e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.92636379295018831848234711132457626676e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77389296072621088586880199705598178518e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.57808410784300002747916947756919004207e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.93860773322862111592582321183379587624e-16), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52683694883265337797012770275040297516e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17837082293165509684677505408307814500e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06195236296471366891670923430225774487e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29459155224640682509948954218044556307e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.71350726081102446771887145938865551618e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55986063168260695680927535587363081713e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91996892322204645930710038043021675160e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.43907073162091303683795779882887569537e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.50034830055055263363497137448887884379e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.56615898355501904078935686679056442496e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61099855362387625880067378834775577974e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.12940315230564635808566630258463831421e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73572881409271303264226007333510301220e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.77786420070246087920941454352749186288e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77914406265766625938477137082940482898e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.19708585422668069396821478975324123588e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40406059898292960948942525697075698413e-15), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 7.6812e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.48209596014908270566135466727658374314e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02026332003132864886056710532156370366e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68941634461905013212266453851941196774e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.61650792370551069313309111250434438540e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52611930219013953260661961529732777539e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29488123972430683478601278003510200360e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68806175827491046693183596144172426378e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51806782259569842628995584152985951836e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92353868262961486571527005289554589652e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21494769586031703137329731447673056499e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.39837421784601055804920937629607771973e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82216155524308827738242486229625170158e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04275785296896148301798836366902456306e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19999929939765873468528448012634122362e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.03583326787146398902262502660879425573e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59755092249701477917281379650537907903e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32583227076029470589713734885690555562e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18237323554153660947807202150429686004e-20), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.38459552164692902984228821988876295376e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21584899508575302641780901222203752951e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19656836695824518143414401720590693544e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39821085943818944882332778361549212756e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60484296824768079700823824408428524933e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22173385695010329771921985088956556771e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95541259523416810836752584764202086573e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02184255281138028802991551275755427743e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90825805251143907045903671893185297007e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00501277755608081163250456177637280682e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.43387099521800224735155351696799358451e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63751106922299101655071906417624415019e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02796982349519589339629488980132546290e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26197249278457937947269910907701176956e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50981935956236238709523457678017928506e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.65309560070040982176772709693008187384e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42817828965851841104270899392956866435e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 2.8388e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36719010559816175149447242695581604280e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14714772485724956396126176973339095223e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.47792450677638612907408723539943311437e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14084804538576805298420530820092167411e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25784891219227004394312050838763762669e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06837168825575413225975778906503529455e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.26908306638706189702624634771158355088e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06396335535135452379658152785541731746e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89854018431899039966628599727721422261e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.48974049316978526855972339306215972434e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50886538662952684349385729585856778829e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.14095970401472469264258565259303801322e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71915162586912203234023473966563445362e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.46099196574734038609354417874908346873e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.69944075002490023348175340827135133316e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.37340205792165863440617831987825515203e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.87812199530402923085142356622707924805e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76810877067601573471489978907720495511e-24), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.94373217074550329856398644558576545146e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17462725343185049507839058445338783693e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79202779096887355136298419604918306868e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97583473532621831662838256679872014292e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67819154370257505016693473230060726722e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14182379349642191946237975301363902175e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.38367234191828732305257162934647076311e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98221340505887984555143894024281550376e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17648765147609962405833802498013198305e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.94091261341172666220769613477202626517e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12169979717068598708585414568018667622e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70043694579268983742161305612636042906e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.43651270200498902307944806310116446583e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.95266223996097470768947426604723764300e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15821111112681530432702452073811996961e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08041298058041360645934320138765284054e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.91893114159827950553463154758337724676e-24), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 1.8746e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619775525705288697351261475419832625e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29882145587771350744255724773409752285e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07952726597277085327360888304737411175e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72928496414816922167597110591366081416e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.01641163277458693633771532254570177776e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65627339211110756774878685166318417370e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41953343652571732907631074381749818724e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.27682202874503433884090203197149318368e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33177176779158737868498722222027162030e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.34485618544363735547395633416797591537e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96996761199233617188435782568975757378e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49631247632674130553464740647053162499e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.68090516971007163491968659797593218680e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39910262557283449853923535586722968539e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83704888007521886644896435914745476741e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87884425419276681417666064027484555860e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36600092466902449189685791563990733005e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.53604301472332155307661986064796109517e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65664588229982894587678197374867153136e-40), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61098031370834273919229478584740981117e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.40810642301361416278392589243623940154e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.42874346984605660407576451987840217534e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30896462654364903689199648803900475405e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.17246449391141576955714059812811712587e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22979790521806964047777145482613709395e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.85960899519336488582042102184331670230e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66273852553220863665584472398487539899e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15372731217983084923067673501176233172e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09441788794783860366430915309857085224e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.06279112323261126652767146380404236150e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36359339522621405197747209968637035618e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19770526521305519813109395521868217810e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.88562963284557433336083678206625018948e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95128165317597657325539450957778690578e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14570923483883184645242764315877865073e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.69599603258626408321886443187629340033e-26), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 3.9915e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619772367581344576326594951209529606e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72456363182667891167613558295097711432e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74486567435450138741058930951301644059e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94624522781897679952110594449134468564e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09848623985771449914778668831103210333e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.47493285141689711937343304940229517457e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22134975575390048261922652492143139174e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30240148387764167235466713023950979069e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06917824188001432265980161955665997666e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27834220508404489112697949450988070802e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48663447630051388468872352628795428134e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.50514504588736921389704370029090421684e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18965303814265217659151418619980209487e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74200654214326267651127117044008493519e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.34060054352573532839373386456991657111e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.34240516843783954067548886404044879120e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07803703545135964499326712080667886449e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61500479431085205124031101160332446432e-23), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27973454499231032893774072677004977154e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.02401389920613749641292661572240166038e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24819328156695252221821935845914708591e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27210724381675120281861717194783977895e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01708007392492681238863778030115281961e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.63088069045476088736355784718397594807e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61660379368211892821215228891806384883e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67946125503415200067055797463173521598e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72040422051759599096448422858046040086e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33519997465950200122152159780364149268e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07666528975810553712124845533861745455e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86870262247486708096341722190198527508e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30713380444621290817686989936029997572e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.38899571664905345700275460272815357978e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46750157220118157937510816924752429685e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69337661543585547694652989893297703060e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53684359865963395505791671817598669527e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * p); + } + else { + result = 2 / (constants::pi() * p); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) + { + return !complement ? landau_quantile_upper_imp_prec(1 - p, tag) : landau_quantile_lower_imp_prec(1 - p, tag); + } + + return complement ? landau_quantile_upper_imp_prec(p, tag) : landau_quantile_lower_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) + { + return !complement ? landau_quantile_upper_imp_prec(1 - p, tag) : landau_quantile_lower_imp_prec(1 - p, tag); + } + + return complement ? landau_quantile_upper_imp_prec(p, tag) : landau_quantile_lower_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_quantile_imp(const landau_distribution& dist, const RealType& p, bool complement) +{ + // This routine implements the quantile for the Landau distribution, + // the value p may be the probability, or its complement if complement=true. + + constexpr auto function = "boost::math::quantile(landau<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType bias = dist.bias(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * (landau_quantile_imp_prec(p, complement, tag_type()) - bias); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_mode_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(-0.42931452986133525017); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_mode_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, -0.42931452986133525016556463510885028346); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_mode_imp(const landau_distribution& dist) +{ + // This implements the mode for the Landau distribution, + + constexpr auto function = "boost::math::mode(landau<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType bias = dist.bias(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * (landau_mode_imp_prec(tag_type()) - bias); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_median_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(0.57563014394507821440); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_median_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, 0.57563014394507821439627930892257517269); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_median_imp(const landau_distribution& dist) +{ + // This implements the median for the Landau distribution, + + constexpr auto function = "boost::math::median(landau<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType bias = dist.bias(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * (landau_median_imp_prec(tag_type()) - bias); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_entropy_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(2.37263644000448182448); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_entropy_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.3726364400044818244844049010588577710); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType landau_entropy_imp(const landau_distribution& dist) +{ + // This implements the entropy for the Landau distribution, + + constexpr auto function = "boost::math::entropy(landau<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Landau distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = landau_entropy_imp_prec(tag_type()) + log(scale); + + return result; +} + +} // detail + +template > +class landau_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED landau_distribution(RealType l_location = 0, RealType l_scale = 1) + : mu(l_location), c(l_scale) + { + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::landau_distribution<%1%>::landau_distribution"; + RealType result = 0; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + + location_bias = -2 / constants::pi() * log(l_scale); + } // landau_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return mu; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return c; + } + BOOST_MATH_GPU_ENABLED RealType bias()const + { + return location_bias; + } + + private: + RealType mu; // The location parameter. + RealType c; // The scale parameter. + RealType location_bias; // = -2 / pi * log(c) +}; + +typedef landau_distribution landau; + +#ifdef __cpp_deduction_guides +template +landau_distribution(RealType) -> landau_distribution::type>; +template +landau_distribution(RealType, RealType) -> landau_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const landau_distribution&) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const landau_distribution&) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const landau_distribution& dist, const RealType& x) +{ + return detail::landau_pdf_imp(dist, x); +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const landau_distribution& dist, const RealType& x) +{ + return detail::landau_cdf_imp(dist, x, false); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const landau_distribution& dist, const RealType& p) +{ + return detail::landau_quantile_imp(dist, p, false); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::landau_cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::landau_quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const landau_distribution&) +{ // There is no mean: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Landau Distribution has no mean"); + + return policies::raise_domain_error( + "boost::math::mean(landau<%1%>&)", + "The Landau distribution does not have a mean: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const landau_distribution& /*dist*/) +{ + // There is no variance: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Landau Distribution has no variance"); + + return policies::raise_domain_error( + "boost::math::variance(landau<%1%>&)", + "The Landau distribution does not have a variance: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const landau_distribution& dist) +{ + return detail::landau_mode_imp(dist); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const landau_distribution& dist) +{ + return detail::landau_median_imp(dist); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const landau_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Landau Distribution has no skewness"); + + return policies::raise_domain_error( + "boost::math::skewness(landau<%1%>&)", + "The Landau distribution does not have a skewness: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const landau_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Landau Distribution has no kurtosis"); + + return policies::raise_domain_error( + "boost::math::kurtosis(landau<%1%>&)", + "The Landau distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const landau_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Landau Distribution has no kurtosis excess"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(landau<%1%>&)", + "The Landau distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const landau_distribution& dist) +{ + return detail::landau_entropy_imp(dist); +} + +}} // namespaces + + +#endif // BOOST_STATS_LANDAU_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/laplace.hpp b/third-party/boost-math/include/boost/math/distributions/laplace.hpp new file mode 100644 index 0000000000000..81a0abe1abda2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/laplace.hpp @@ -0,0 +1,494 @@ +// Copyright Thijs van den Berg, 2008. +// Copyright John Maddock 2008. +// Copyright Paul A. Bristow 2008, 2014. +// Copyright Matt Borland 2024. + +// 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) + +// This module implements the Laplace distribution. +// Weisstein, Eric W. "Laplace Distribution." From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/LaplaceDistribution.html +// http://en.wikipedia.org/wiki/Laplace_distribution +// +// Abramowitz and Stegun 1972, p 930 +// http://www.math.sfu.ca/~cbm/aands/page_930.htm + +#ifndef BOOST_STATS_LAPLACE_HPP +#define BOOST_STATS_LAPLACE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) // conditional expression is constant +#endif + +template > +class laplace_distribution +{ +public: + // ---------------------------------- + // public Types + // ---------------------------------- + using value_type = RealType; + using policy_type = Policy; + + // ---------------------------------- + // Constructor(s) + // ---------------------------------- + BOOST_MATH_GPU_ENABLED explicit laplace_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_location(l_location), m_scale(l_scale) + { + RealType result; + check_parameters("boost::math::laplace_distribution<%1%>::laplace_distribution()", &result); + } + + + // ---------------------------------- + // Public functions + // ---------------------------------- + + BOOST_MATH_GPU_ENABLED RealType location() const + { + return m_location; + } + + BOOST_MATH_GPU_ENABLED RealType scale() const + { + return m_scale; + } + + BOOST_MATH_GPU_ENABLED bool check_parameters(const char* function, RealType* result) const + { + if(false == detail::check_scale(function, m_scale, result, Policy())) return false; + if(false == detail::check_location(function, m_location, result, Policy())) return false; + return true; + } + +private: + RealType m_location; + RealType m_scale; +}; // class laplace_distribution + +// +// Convenient type synonym for double. +using laplace = laplace_distribution; + +#ifdef __cpp_deduction_guides +template +laplace_distribution(RealType)->laplace_distribution::type>; +template +laplace_distribution(RealType,RealType)->laplace_distribution::type>; +#endif + +// +// Non-member functions. +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const laplace_distribution&) +{ + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { // Can use infinity. + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max value. + } + +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const laplace_distribution&) +{ + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { // Can Use infinity. + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max value. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + constexpr auto function = "boost::math::pdf(const laplace_distribution<%1%>&, %1%))"; + + // Check scale and location. + if (false == dist.check_parameters(function, &result)) return result; + // Special pdf values. + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + if (false == detail::check_x(function, x, &result, Policy())) return result; + + // General case + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + RealType exponent = x - location; + if (exponent>0) exponent = -exponent; + exponent /= scale; + + result = exp(exponent); + result /= 2 * scale; + + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = -boost::math::numeric_limits::infinity(); + constexpr auto function = "boost::math::logpdf(const laplace_distribution<%1%>&, %1%))"; + + // Check scale and location. + if (false == dist.check_parameters(function, &result)) + { + return result; + } + // Special pdf values. + if((boost::math::isinf)(x)) + { + return result; // pdf + and - infinity is zero so logpdf is -INF + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType mu = dist.scale(); + const RealType b = dist.location(); + + // if b is 0 avoid divide by 0 error + if(abs(b) < boost::math::numeric_limits::epsilon()) + { + result = log(pdf(dist, x)); + } + else + { + // General case + const RealType log2 = boost::math::constants::ln_two(); + result = -abs(x-mu)/b - log(b) - log2; + } + + return result; +} // logpdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // For ADL of std functions. + + RealType result = 0; + // Checking function argument. + constexpr auto function = "boost::math::cdf(const laplace_distribution<%1%>&, %1%)"; + // Check scale and location. + if (false == dist.check_parameters(function, &result)) return result; + + // Special cdf values: + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity. + return 1; // + infinity. + } + if (false == detail::check_x(function, x, &result, Policy())) return result; + + // General cdf values + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + if (x < location) + { + result = exp( (x-location)/scale )/2; + } + else + { + result = 1 - exp( (location-x)/scale )/2; + } + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // For ADL of std functions. + + RealType result = 0; + // Checking function argument. + constexpr auto function = "boost::math::logcdf(const laplace_distribution<%1%>&, %1%)"; + // Check scale and location. + if (false == dist.check_parameters(function, &result)) + { + return result; + } + + // Special cdf values: + if((boost::math::isinf)(x)) + { + if(x < 0) + { + return 0; // -infinity. + } + return 1; // + infinity. + } + + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + // General cdf values + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + if (x < location) + { + result = ((x - location) / scale) - boost::math::constants::ln_two(); + } + else + { + result = log1p(-exp((location - x) / scale) / 2); + } + + return result; +} // logcdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const laplace_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + // Checking function argument + RealType result = 0; + constexpr auto function = "boost::math::quantile(const laplace_distribution<%1%>&, %1%)"; + if (false == dist.check_parameters(function, &result)) return result; + if(false == detail::check_probability(function, p, &result, Policy())) return result; + + // Extreme values of p: + if(p == 0) + { + result = policies::raise_overflow_error(function, + "probability parameter is 0, but must be > 0!", Policy()); + return -result; // -inf + } + + if(p == 1) + { + result = policies::raise_overflow_error(function, + "probability parameter is 1, but must be < 1!", Policy()); + return result; // inf + } + // Calculate Quantile + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + if (p - 0.5 < 0.0) + result = location + scale*log( static_cast(p*2) ); + else + result = location - scale*log( static_cast(-p*2 + 2) ); + + return result; +} // quantile + + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + // Calculate complement of cdf. + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + RealType x = c.param; + RealType result = 0; + + // Checking function argument. + constexpr auto function = "boost::math::cdf(const complemented2_type, %1%>&)"; + + // Check scale and location. + if (false == c.dist.check_parameters(function, &result)) return result; + + // Special cdf values. + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy()))return result; + + // Cdf interval value. + if (-x < -location) + { + result = exp( (-x+location)/scale )/2; + } + else + { + result = 1 - exp( (-location+x)/scale )/2; + } + return result; +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) +{ + // Calculate complement of logcdf. + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + RealType x = c.param; + RealType result = 0; + + // Checking function argument. + constexpr auto function = "boost::math::logcdf(const complemented2_type, %1%>&)"; + + // Check scale and location. + if (false == c.dist.check_parameters(function, &result)) return result; + + // Special cdf values. + if((boost::math::isinf)(x)) + { + if(x < 0) + { + return 1; // cdf complement -infinity is unity. + } + + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy()))return result; + + // Cdf interval value. + if (-x < -location) + { + result = (-x+location)/scale - boost::math::constants::ln_two(); + } + else + { + result = log1p(-exp( (-location+x)/scale )/2, Policy()); + } + return result; +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + // Calculate quantile. + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + RealType q = c.param; + RealType result = 0; + + // Checking function argument. + constexpr auto function = "quantile(const complemented2_type, %1%>&)"; + if (false == c.dist.check_parameters(function, &result)) return result; + + // Extreme values. + if(q == 0) + { + return boost::math::numeric_limits::infinity(); + } + if(q == 1) + { + return -boost::math::numeric_limits::infinity(); + } + if(false == detail::check_probability(function, q, &result, Policy())) return result; + + if (0.5 - q < 0.0) + result = location + scale*log( static_cast(-q*2 + 2) ); + else + result = location - scale*log( static_cast(q*2) ); + + + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const laplace_distribution& dist) +{ + return constants::root_two() * dist.scale(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const laplace_distribution& /*dist*/) +{ + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const laplace_distribution& /*dist*/) +{ + return 6; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const laplace_distribution& /*dist*/) +{ + return 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const laplace_distribution & dist) +{ + using std::log; + return log(2*dist.scale()*constants::e()); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_LAPLACE_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/logistic.hpp b/third-party/boost-math/include/boost/math/distributions/logistic.hpp new file mode 100644 index 0000000000000..56dc6e9f2f478 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/logistic.hpp @@ -0,0 +1,397 @@ +// Copyright 2008 Gautam Sewani +// Copyright 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_DISTRIBUTIONS_LOGISTIC +#define BOOST_MATH_DISTRIBUTIONS_LOGISTIC + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + + template > + class logistic_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED logistic_distribution(RealType l_location=0, RealType l_scale=1) // Constructor. + : m_location(l_location), m_scale(l_scale) + { + constexpr auto function = "boost::math::logistic_distribution<%1%>::logistic_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_location, &result, Policy()); + } + // Accessor functions. + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; + } + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return m_location; + } + private: + // Data members: + RealType m_location; // distribution location aka mu. + RealType m_scale; // distribution scale aka s. + }; // class logistic_distribution + + + typedef logistic_distribution logistic; + + #ifdef __cpp_deduction_guides + template + logistic_distribution(RealType)->logistic_distribution::type>; + template + logistic_distribution(RealType,RealType)->logistic_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const logistic_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair( + boost::math::numeric_limits::has_infinity ? -boost::math::numeric_limits::infinity() : -max_value(), + boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const logistic_distribution& /* dist */) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + infinity + } + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const logistic_distribution& dist, const RealType& x) + { + constexpr auto function = "boost::math::pdf(const logistic_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType result = 0; + + if(false == detail::check_scale(function, scale , &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + BOOST_MATH_STD_USING + RealType exp_term = (location - x) / scale; + if(fabs(exp_term) > tools::log_max_value()) + return 0; + exp_term = exp(exp_term); + if((exp_term * scale > 1) && (exp_term > tools::max_value() / (scale * exp_term))) + return 1 / (scale * exp_term); + return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const logistic_distribution& dist, const RealType& x) + { + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType result = 0; // of checks. + constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + BOOST_MATH_STD_USING + RealType power = (location - x) / scale; + if(power > tools::log_max_value()) + return 0; + if(power < -tools::log_max_value()) + return 1; + return 1 / (1 + exp(power)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const logistic_distribution& dist, const RealType& x) + { + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType result = 0; // of checks. + constexpr auto function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + + if((boost::math::isinf)(x)) + { + if(x < 0) + { + return 0; // -infinity + } + return 1; // + infinity + } + + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + BOOST_MATH_STD_USING + RealType power = (location - x) / scale; + if(power > tools::log_max_value()) + { + return 0; + } + if(power < -tools::log_max_value()) + { + return 1; + } + + return -log1p(exp(power)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const logistic_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING + RealType location = dist.location(); + RealType scale = dist.scale(); + + constexpr auto function = "boost::math::quantile(const logistic_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + { + return -policies::raise_overflow_error(function,"probability argument is 0, must be >0 and <1",Policy()); + } + if(p == 1) + { + return policies::raise_overflow_error(function,"probability argument is 1, must be >0 and <1",Policy()); + } + //Expressions to try + //return location+scale*log(p/(1-p)); + //return location+scale*log1p((2*p-1)/(1-p)); + + //return location - scale*log( (1-p)/p); + //return location - scale*log1p((1-2*p)/p); + + //return -scale*log(1/p-1) + location; + return location - scale * log((1 - p) / p); + } // RealType quantile(const logistic_distribution& dist, const RealType& p) + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING + RealType location = c.dist.location(); + RealType scale = c.dist.scale(); + RealType x = c.param; + constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + RealType power = (x - location) / scale; + if(power > tools::log_max_value()) + return 0; + if(power < -tools::log_max_value()) + return 1; + return 1 / (1 + exp(power)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING + RealType location = c.dist.location(); + RealType scale = c.dist.scale(); + RealType x = c.param; + constexpr auto function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + RealType power = (x - location) / scale; + if(power > tools::log_max_value()) + return 0; + if(power < -tools::log_max_value()) + return 1; + + return -log1p(exp(power)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + constexpr auto function = "boost::math::quantile(const complement(logistic_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + using boost::math::tools::max_value; + + if(q == 1) + { + return -policies::raise_overflow_error(function,"probability argument is 1, but must be >0 and <1",Policy()); + } + if(q == 0) + { + return policies::raise_overflow_error(function,"probability argument is 0, but must be >0 and <1",Policy()); + } + //Expressions to try + //return location+scale*log((1-q)/q); + return location + scale * log((1 - q) / q); + + //return location-scale*log(q/(1-q)); + //return location-scale*log1p((2*q-1)/(1-q)); + + //return location+scale*log(1/q-1); + //return location+scale*log1p(1/q-2); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const logistic_distribution& dist) + { + return dist.location(); + } // RealType mean(const logistic_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const logistic_distribution& dist) + { + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + return boost::math::constants::pi()*boost::math::constants::pi()*scale*scale/3; + } // RealType variance(const logistic_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const logistic_distribution& dist) + { + return dist.location(); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType median(const logistic_distribution& dist) + { + return dist.location(); + } + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const logistic_distribution& /*dist*/) + { + return 0; + } // RealType skewness(const logistic_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const logistic_distribution& /*dist*/) + { + return static_cast(6)/5; + } // RealType kurtosis_excess(const logistic_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const logistic_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } // RealType kurtosis_excess(const logistic_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType entropy(const logistic_distribution& dist) + { + using std::log; + return 2 + log(dist.scale()); + } + }} + + +// Must come at the end: +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_LOGISTIC diff --git a/third-party/boost-math/include/boost/math/distributions/lognormal.hpp b/third-party/boost-math/include/boost/math/distributions/lognormal.hpp new file mode 100644 index 0000000000000..dfc3e4b2a266b --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/lognormal.hpp @@ -0,0 +1,361 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_LOGNORMAL_HPP +#define BOOST_STATS_LOGNORMAL_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm +// http://mathworld.wolfram.com/LogNormalDistribution.html +// http://en.wikipedia.org/wiki/Lognormal_distribution + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ +namespace detail +{ + + template + BOOST_MATH_GPU_ENABLED inline bool check_lognormal_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; + } + +} // namespace detail + + +template > +class lognormal_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED lognormal_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_location(l_location), m_scale(l_scale) + { + RealType result; + detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_scale, &result, Policy()); + detail::check_location("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_location, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return m_location; + } + + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_location; // distribution location. + RealType m_scale; // distribution scale. +}; + +typedef lognormal_distribution lognormal; + +#ifdef __cpp_deduction_guides +template +lognormal_distribution(RealType)->lognormal_distribution::type>; +template +lognormal_distribution(RealType,RealType)->lognormal_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const lognormal_distribution& /*dist*/) +{ // Range of permissible values for random variable x is >0 to +infinity. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const lognormal_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED RealType pdf(const lognormal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + constexpr auto function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, sigma, &result, Policy())) + return result; + if(0 == detail::check_location(function, mu, &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, x, &result, Policy())) + return result; + + if(x == 0) + return 0; + + RealType exponent = log(x) - mu; + exponent *= -exponent; + exponent /= 2 * sigma * sigma; + + result = exp(exponent); + result /= sigma * sqrt(2 * constants::pi()) * x; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const lognormal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, dist.location(), &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, x, &result, Policy())) + return result; + + if(x == 0) + return 0; + + normal_distribution norm(dist.location(), dist.scale()); + return cdf(norm, log(x)); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const lognormal_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, dist.location(), &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return 0; + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + normal_distribution norm(dist.location(), dist.scale()); + return exp(quantile(norm, p)); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, c.dist.location(), &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, c.param, &result, Policy())) + return result; + + if(c.param == 0) + return 1; + + normal_distribution norm(c.dist.location(), c.dist.scale()); + return cdf(complement(norm, log(c.param))); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, c.dist.location(), &result, Policy())) + return result; + if(0 == detail::check_probability(function, c.param, &result, Policy())) + return result; + + if(c.param == 1) + return 0; + if(c.param == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + normal_distribution norm(c.dist.location(), c.dist.scale()); + return exp(quantile(complement(norm, c.param))); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return exp(mu + sigma * sigma / 2); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return exp(mu - sigma * sigma); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType mu = dist.location(); + return exp(mu); // e^mu +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + //RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType ss = sigma * sigma; + RealType ess = exp(ss); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return (ess + 2) * sqrt(boost::math::expm1(ss, Policy())); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + //RealType mu = dist.location(); + RealType sigma = dist.scale(); + RealType ss = sigma * sigma; + + RealType result = 0; + if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // RealType mu = dist.location(); + RealType sigma = dist.scale(); + RealType ss = sigma * sigma; + + RealType result = 0; + if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType mu = dist.location(); + RealType sigma = dist.scale(); + return mu + log(constants::two_pi()*constants::e()*sigma*sigma)/2; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_STUDENTS_T_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/mapairy.hpp b/third-party/boost-math/include/boost/math/distributions/mapairy.hpp new file mode 100644 index 0000000000000..8bf1f990c1923 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/mapairy.hpp @@ -0,0 +1,4220 @@ +// Copyright Takuma Yoshimura 2024. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_MAPAIRY_HPP +#define BOOST_STATS_MAPAIRY_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#endif + +namespace boost { namespace math { +template +class mapairy_distribution; + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 3.7591e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.97516171847191855610e-1), + static_cast(3.67488253628465083737e-2), + static_cast(-9.73242224038828612673e-4), + static_cast(2.32207514136635673061e-3), + static_cast(5.69067907423210669037e-5), + static_cast(-6.02637387141524535193e-5), + static_cast(1.04960324426666933327e-5), + static_cast(-6.58470237954242016920e-7), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(7.09464351647314165710e-1), + static_cast(3.66413036246461392316e-1), + static_cast(1.10947882302862241488e-1), + static_cast(2.65928486676817177159e-2), + static_cast(3.75507284977386290874e-3), + static_cast(4.03789594641339005785e-4), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 1.5996e-20 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.06251243013238748252e-1), + static_cast(1.38178831205785069108e-2), + static_cast(4.19280374368049006206e-3), + static_cast(8.54607219684690930289e-4), + static_cast(-7.46881084120928210702e-5), + static_cast(1.47110856483345063335e-5), + static_cast(-1.30090180307471994500e-6), + static_cast(5.24801123304330014713e-8), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(8.10853683888611687140e-1), + static_cast(3.89361261627717143905e-1), + static_cast(1.15124062681082170577e-1), + static_cast(2.38803416611949902468e-2), + static_cast(3.08616898814509065071e-3), + static_cast(2.43760043942846261876e-4), + static_cast(1.34538901435238836768e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.1592e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(5.33842514891989443409e-2), + static_cast(1.23301980674903270971e-2), + static_cast(3.45717831433988631923e-3), + static_cast(3.27034449923176875761e-4), + static_cast(1.20406794831890291348e-5), + static_cast(5.77489170397965604669e-7), + static_cast(-1.15255267205685159063e-7), + static_cast(9.15896323073109992939e-9), + static_cast(-3.14068002815368247985e-10), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(9.08772985520393226044e-1), + static_cast(4.26418573702560818267e-1), + static_cast(1.22033746594868893316e-1), + static_cast(2.27934009200310243172e-2), + static_cast(2.60658999011198623962e-3), + static_cast(1.54461660261435227768e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 9.2228e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.58950538583133457384e-2), + static_cast(7.47835440063141601948e-3), + static_cast(1.81137244353261478410e-3), + static_cast(2.26935565382135588558e-4), + static_cast(1.43877113825683795505e-5), + static_cast(2.08242747557417233626e-7), + static_cast(-1.54976465724771282989e-9), + static_cast(1.30762989300333026019e-11), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(9.95505437381674174441e-1), + static_cast(4.58882737262511297099e-1), + static_cast(1.25031310192148865496e-1), + static_cast(2.15727229249904102247e-2), + static_cast(2.33597081566665672569e-3), + static_cast(1.45198998318300328562e-4), + static_cast(3.87962234445835345676e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 1.0257e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.22517551525042172428e-3), + static_cast(1.12822806030796339659e-3), + static_cast(1.54489389961322571031e-4), + static_cast(9.28479992527909796427e-6), + static_cast(2.06168350199745832262e-7), + static_cast(9.05110751997021418539e-10), + static_cast(-2.15498112371756202097e-12), + static_cast(6.41838355699777435924e-15), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(6.53390465399680164234e-1), + static_cast(1.82759048270449018482e-1), + static_cast(2.80407546367978533849e-2), + static_cast(2.50853443923476718145e-3), + static_cast(1.27671852825846245421e-4), + static_cast(3.28380135691060279203e-6), + static_cast(3.06545317089055335742e-8), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 6.0510e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(5.82527663232857270992e-4), + static_cast(6.89502117025124630567e-5), + static_cast(2.24909795087265741433e-6), + static_cast(2.18576787334972903790e-8), + static_cast(3.39014723444178274435e-11), + static_cast(-9.74481309265612390297e-15), + static_cast(-1.13308546492906818388e-16), + static_cast(5.32472028720777735712e-19), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(2.74018883667663396766e-1), + static_cast(2.95901195665990089660e-2), + static_cast(1.57901733512147920251e-3), + static_cast(4.24965124147621236633e-5), + static_cast(5.17522027193205842016e-7), + static_cast(2.00522219276570039934e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 7.3294e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.03264853379349880039e-4), + static_cast(5.35256306644392405447e-6), + static_cast(9.00657716972118816692e-8), + static_cast(5.34913574042209793720e-10), + static_cast(6.70752605041678779380e-13), + static_cast(-5.30089923101856817552e-16), + static_cast(7.28133811621687143754e-19), + static_cast(-7.38047553655951666420e-22), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.29920843258164337377e-1), + static_cast(6.75018577147646502386e-3), + static_cast(1.77694968039695671819e-4), + static_cast(2.46428299911920942946e-6), + static_cast(1.67165053157990942546e-8), + static_cast(4.19496974141131087116e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x * x * x); + + // Rational Approximation + // Maximum Relative Error: 5.6693e-20 + BOOST_MATH_STATIC const RealType P[5] = { + static_cast(5.98413420602149016910e-1), + static_cast(3.14584075817417883086e-5), + static_cast(1.62977928311793051895e1), + static_cast(-4.12903117172994371875e-4), + static_cast(-1.06404478702135751872e2), + }; + BOOST_MATH_STATIC const RealType Q[3] = { + static_cast(1.), + static_cast(5.25696892802060720079e-5), + static_cast(4.03600055498020483920e1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 7.8308e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97516171847191855609649452292217911973e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17531822787252717270400174744562144891e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.85115358761409188259685286269086053296e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18029395189535552537870932989876189597e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77412874842522285996566741532939343827e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.77992070255086842672551073580133785334e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.54573264286260796576738952968288691782e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.94764012694602906119831079380500255557e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.97596258932025712802674070104281981323e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45466169112247379589927514614067756956e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.99760415118300349769641418430273526815e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43150486566834492207695241913522311930e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46130347604880355784938321408765318948e-13), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11845869711743584628289654085905424438e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.80391154854347711297249357734993136108e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75628443538173255184583966965162835227e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41016303833742742212624596040074202424e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.19142300833563644046500846364541891138e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02421707708633106515934651956262614532e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.03973732602338507411104824853671547615e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.35206168908201402570766383018708660819e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.38602606623008690327520130558254165564e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53740175911385378188372963739884519312e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27513004715414297729539702862351044344e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54510493017251997793679126704007098265e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 3.0723e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06251243013238748252181151646220197947e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.92438638323563234519452281479338921158e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83335793178622701784730867677919844599e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.84159075203218824591724451142550478306e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04213732090358859917896442076931334722e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.72388220651785798237487005913708387756e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.36099324022668533012286817710272936865e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74483270731217433628720245792741986795e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.56461597064783966758904403291149549559e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.28590608939674970691948223694855264817e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.81756745849477762773082030302943341729e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.65915115243311285178083515017249358853e-12), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33250387018216706082200927591739589024e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.71707718560216685629188467984384070512e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.81316277289673837399162302797006618384e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78475951599121894570443981591530879087e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.16167801098514576400689883575304687623e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19167794366424137722223009369062644830e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.20831082064982892777497773490792080382e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27196399162146247210036306870401328410e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79335434374966775903734846875100087590e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30825409557870847168672662674521614782e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97296173230649275943984471731360073540e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.48943057909563158917114503727080517958e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 4.0903e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.33842514891989443409465171800884519331e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53264053296761245408991932692426094424e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23210520807186629205810670362048049836e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.71104271443590027208545022968625306496e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98781446716778138729774954595209697813e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98895829308616657174932023565302947632e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.25993639218721804661037829873135732687e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.64669776700609853276056375742089715662e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.11846243382610611156151291892877027869e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.74830086064868141326053648144496072795e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07549997153431643849551871367000763445e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.10030596535721362628619523622308581344e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19376016170255697546854583591494809062e-13), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52686177278870816414637961315363468426e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19872083945442288336636376283295310445e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.26633866969676511944680471882188527224e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41261867539396133951024374504099977090e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.18852182132645783844766153200510014113e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70152126044106007357033814742158353948e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.23810508827493234517751339979902448944e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.96161313274648769113605163816403306967e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06693316156193327359541953619174255726e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.79366356086062616343285660797389238271e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.14585835815353770175366834099001313472e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05314631662369743547568064896403143693e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.90325380271096603676911761784650800378e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.36933359079566550212098911224675011839e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 6.5015e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58950538583133457383574346194006716984e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.25447644411503971725638816502617490834e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47605882774114100209665040117276675598e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.12224864838900383464124716266085521485e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79164249640537972514574059182421325541e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.89668438166714230032406615413991628135e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.44410389750700463263686630222653669837e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.14788978994687095829140113472609739982e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.79821680629333600844514042061772236495e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.49636960435731257154960798035854124639e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70554745768928821263556963261516872171e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.42293994855343109617040824208078534205e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37599287094703195312894833570340165019e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35248179978735448062307216459232932068e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.53569375838863862590910010617140120876e-18), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94337325681904859647161946168957959628e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77120402023938328899162557073347121463e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01644685191130734907530007424741314392e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.12479655123720440909164080517207084404e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25556010526357752360439314019567992245e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96143273204038192262150849394970544022e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.50612932318889495209230176354364299236e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.12160918304376427109905628326638480473e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.47696044292604039527013647985997661762e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.64067652576843720823459199100800335854e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.00745166063635113130434111509648306420e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05398901239421768403763864060147286105e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05698259572340563109985785513355912114e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19362835269415404005406782719825077472e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15444386779802728200716489787161419304e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02452666470008756043350040893761339083e-16), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 2.0995e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.22517551525042172427941302520759668293e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.86576974828476461442549217748945498966e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18419822818191546598384139622512477000e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98396184944524020019688823190946146641e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.06686400532599396487775148973665625687e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05680178109228687159829475615095925679e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.17554487015345146749705505971350254902e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14774751685364429557883242232797329274e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33266124509168360207594600356349282805e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76332756800842989348756910429214676252e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60639771339252642992277508068105926919e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.41859490403554144799385471141184829903e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77177795293424055655391515546880774987e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76106923344461402353501262620681801053e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68829978902134103249656805130103045021e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42496376687241918803028631991083570963e-26), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19213376162053391168605415200906099633e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65578261958732385181558047087365997878e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30046653564394292929001223763106276016e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.48388301731958697028701215596777178117e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.50873786049439122933188684993719288258e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23255654647151798865208394342856435797e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20861791399969402003082323686080041040e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.96882049090731653763684812243275884213e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.98669985741073085290012296575736698103e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.03383311816835346577432387682379226740e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.87320682938150375144724980774245810905e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13573468677076838075146150847170057373e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34526045003716422620879156626237175127e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35681579117696161282979297336282783473e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92944288060269290125987728528698476197e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 2.0937e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.82527663232857270992129793621400616909e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41696401156754081476312871174198295322e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.42036620449365724707919875710197564857e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.67076745288708619632303078677641380627e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14278954094278648593125010577441869646e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40092485054621853149602511539550254471e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.17755660009065973828053533035808718033e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.23871371557251644837598540542648782066e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04069998646037977439620128812310273053e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94055978349016208777803296823455779097e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29866428982892883091537921429389750973e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06056281963023929277728535486590256573e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57963857545037466186123981516026589992e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.81390322233700529779563477285232205886e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52190981930441828041102818178755246228e-31), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.70564782441895707961338319466546005093e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47770566490107388849474183308889339231e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29364672385303439788399215507370006639e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.37279274083988250795581105436675097881e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72124151284421794872333348562536468054e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.96970247774973902625712414297788402746e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.38395055453444011915661055983937917120e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.19605460410208704830882138883730331113e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76945301389475508747530234950023648137e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33624384932503964160642677987886086890e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01155130710615988897664213446593907596e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03959317021567084067518847978890548086e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78213669817351488671519066803835958715e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75492332026736176991870807903277324902e-22), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 1.5856e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03264853379349880038687006045193401399e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79539964604630527636184900467871907171e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34840369549460790638336121351837912308e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.73087351972154879439617719914590729748e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51775493325347153520115736204545037264e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.60104651860674451546102708885530128768e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.90233449697112559539826150932808197444e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06978852724410115655105118663137681992e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.00399855296672416041126220131900937128e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18139748830278263202087699889457673035e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43070756487288399784700274808326343543e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70126687893706466023887757573369648552e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.29405234560873665664952418690159194840e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.69069082510020066864633718082941688708e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.33468198065176301137949068264633336529e-37), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51951069241510130465691156908893803280e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84647597299970149588010858770320631739e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90239396588176334117512714878489376365e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35551585337774834346900776840459179841e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53375746264539501168763602838029023222e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.42421935941736734247914078641324315900e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.23835501607741697737129504173606231513e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.79603272375172813955236187874231935324e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.44624821303153251954931367754173356213e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.10635081308984534416704147448323126303e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.14627867347129520510628554651739571006e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43792928765659831045040802615903432044e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.79856365207259871336606847582889916798e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x * x * x); + + // Rational Approximation + // Maximum Relative Error: 3.5081e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[8] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.98413420602149016909919089901572802714e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30303835860684077803651094768293625633e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.89097726237252419724261295392691855545e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.12696604472230480273239741428914666511e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84517621403071494824886152940942995151e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.67577378292168927009421205756730205227e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.16343347002845084264982358165052437094e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.59558963351172885545760841064831356701e3), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.51965956124978480521462518750569617550e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61700833299761977287211297600922591853e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.94988298508869748383898344668918510537e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.52494213749069142804725453333400335525e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20093079283917759611690534481918040882e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.82564796242972192725215815897475246715e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 3.7525e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.76859868856746781256e-1), + static_cast(1.10489814676299003241e-1), + static_cast(-6.25690643488236678667e-3), + static_cast(-1.17905420222527577236e-3), + static_cast(1.27188963720084274122e-3), + static_cast(-7.20575105181207907889e-5), + static_cast(-2.22575633858411851032e-5), + static_cast(2.94270091008508492304e-6), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(4.98673671503410894284e-1), + static_cast(3.15907666864554716291e-1), + static_cast(8.34463558393629855977e-2), + static_cast(2.71804643993972494173e-2), + static_cast(3.52187050938036578406e-3), + static_cast(7.03072974279509263844e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 4.0995e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.14483832832989822788e-1), + static_cast(3.72789690317712876663e-1), + static_cast(1.86473650057086284496e-1), + static_cast(1.31182724166379598907e-2), + static_cast(-9.00695064809774432392e-3), + static_cast(3.46884420664996747052e-4), + static_cast(4.88651392754189961173e-4), + static_cast(-6.13516242712196835055e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(1.06478618107122200489e0), + static_cast(4.08809060854459518663e-1), + static_cast(2.66617598099501800866e-1), + static_cast(4.53526315786051807494e-2), + static_cast(2.44078693689626940834e-2), + static_cast(1.52822572478697831870e-3), + static_cast(8.69480001029742502197e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType s = exp(2 * x * x * x / 27) * sqrt(-x); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 2.4768e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.74308494787955998605e-1), + static_cast(4.87765991440983416392e-1), + static_cast(3.84524365110270427617e-1), + static_cast(1.77409497505926097339e-1), + static_cast(5.25612864287310961520e-2), + static_cast(1.01528615034079765421e-2), + static_cast(1.20417225696161842090e-3), + static_cast(6.97462693097107007719e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(1.81256903248465876424e0), + static_cast(1.43959302060852067876e0), + static_cast(6.65882284117861804351e-1), + static_cast(1.97537712781845593211e-1), + static_cast(3.81732970028510912201e-2), + static_cast(4.52767489928026542226e-3), + static_cast(2.62240194911920120003e-4), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -8) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 1.5741e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.67391547707456587286e-1), + static_cast(3.39319035621314371924e-1), + static_cast(1.85434799940724207230e-1), + static_cast(5.63667456320679857693e-2), + static_cast(1.01231164548944177474e-2), + static_cast(1.02501575174439362864e-3), + static_cast(4.60769537123286016400e-5), + static_cast(-4.92754650783224582641e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.27271216837333318516e0), + static_cast(6.96551952883867277759e-1), + static_cast(2.11871363524516350422e-1), + static_cast(3.80622887806509632537e-2), + static_cast(3.85400280812991562328e-3), + static_cast(1.73246593953823694311e-4), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -16) { + RealType t = -x - 8; + + // Rational Approximation + // Maximum Relative Error: 4.6579e-17 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(2.66153901932100301337e-1), + static_cast(1.65767350677458230714e-1), + static_cast(4.19801402197670061146e-2), + static_cast(5.39337995172784579558e-3), + static_cast(3.50811247702301287586e-4), + static_cast(9.21758454778883157515e-6), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(6.23092941554668369107e-1), + static_cast(1.57829914506366827914e-1), + static_cast(2.02787979758160988615e-2), + static_cast(1.31903008994475216511e-3), + static_cast(3.46575870637847438219e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -32) { + RealType t = -x - 16; + + // Rational Approximation + // Maximum Relative Error: 5.2014e-17 + BOOST_MATH_STATIC const RealType P[5] = { + static_cast(2.65985830928929730672e-1), + static_cast(7.19655029633308583205e-2), + static_cast(7.26293125679558421946e-3), + static_cast(3.24276402295343802262e-4), + static_cast(5.40508013573989841127e-6), + }; + BOOST_MATH_STATIC const RealType Q[5] = { + static_cast(1.), + static_cast(2.70578525590448009961e-1), + static_cast(2.73082032706004833847e-2), + static_cast(1.21926059813954504560e-3), + static_cast(2.03227900426552177849e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 5.2870e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76859868856746781256050397658493368372e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13037642242224438972685982606987140111e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.93206268361082760254653961897373271146e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12844418906916902333116398594921450782e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36889326770180267250286619759335338794e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.95272615884641416804001553871108995422e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.53808638264746233799776679481568171506e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.92177790427881393122479399837010657693e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93492737815019893169693306410980499366e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.87510085148730083683110532987841223544e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.28469424017979299382094276157986775969e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83693904015623816528442886551032709693e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.77632857558257155545506847333166147492e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00448215148716947837105979735199471601e-11), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.69069814466926608209872727645156315374e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.89657828158127300370734997707096744077e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62713433978940724622996782534485162816e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.91600878366366974062522408704458777166e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.89144035500328704769924414014440238441e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.35263616916053275381069097012458200491e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49136684724986851824746531490006769036e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65912003138912073317982729161392623277e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.65931144405541620572732754508534372034e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40193555853535182510951061797573338442e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.43625211359756249232841566256877823039e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33207781577559817130740123609636060998e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 1.1977e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14483832832989822788477500521594411868e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75657192307644021285091474845448102656e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40437358470633234235031852091608646844e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66609942512054705023295445270747546208e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.54563774151184610728476161049657676321e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51479057544157089574005315379453615537e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.59853789372610909788599341307719626846e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76919062715142378209907670793921883406e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.58572738466179822770103948740437237476e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.66618046393835590932491510543557226290e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.26253044828460469263564567571249315188e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11130363073235247786909976446790746902e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.49023728251751416730708805268921994420e-10), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.11919889346080886194925406930280687022e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.99082771425048574611745923487528183522e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99525320878512488641033584061027063035e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.20775109959302182467696345673111724657e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67505804311611026128557007926613964162e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.77854913919309273628222660024596583623e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91661599559554233157812211199256222756e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.83924945472605861063053622956144354568e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.84286353909650034923710426843028632590e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57737060659799463556626420070111210218e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76047305116625604109657617040360402976e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.86975509621224474718728318687795215895e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71646204381423826495116781730719271111e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30359141441663007574346497273327240071e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType s = exp(2 * x * x * x / 27) * sqrt(-x); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 5.4547e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74308494787955998605105974174143750745e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.56767876568276519015214709629156760546e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23402577465454790961498400214198520261e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09577559351834952074671208183548972395e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.76209118910349927892265971592071407626e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.09368637728788364895148841703533651597e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09003822946777310058789032386408519829e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02362804210869367995322279203786166303e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.67210045349462046966360849113168808620e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17170437120510484976042000272825166724e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62068279517157268391045945672600042900e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72238125522303876741011786930129571553e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33906175951716762094473406744654874848e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.88118741063309731598638313174835288433e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78908322579081615215057968216358892954e-9), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15777668058369565739250784347385217839e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.58275582332060589146223977924181161908e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08890987062755381429904193744273374370e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53062680969750921573862970262146744660e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15983695707064161504470525373678920004e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.09120624447001177857109399158887656977e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13566107440776375294261717406754395407e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50716565210262652091950832287627406780e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40417354541359829249609883808591989082e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.09285589734746898623782466689035549135e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.47580156629757526370271002425784456931e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.03479533688660179064728081632921439825e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.58728676819719406366664644282113323077e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72685000369623096389026353785111272994e-9), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -8) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 1.8813e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67391547707456587286086623414017962238e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.69944730920904699720804320295067934914e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.80384452804523880914883464295008532437e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.74832028145199140240423863864148009059e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71728522451977382202061046054643165624e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.91023495084678296967637417245526177858e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57730498044529764612538979048001166775e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31940820074475947691746555183209863058e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.54175805821840981842505041345112198286e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.31350452337838677820161124238784043790e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.52175993144502511705213771924810467309e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.85684239411667243910736588216628677445e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27124210379062272403030391492854565008e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17645475312219452046348851569796494059e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06306499345515479193219487228315566344e-11), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13521398369589479131299586715604029947e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17680254721938920978999949995837883884e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40693619288419980101309080614788657638e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.44930162913500531579305526795523256972e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22044272115074113804712893993125987243e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.92745159832354238503828226333417152767e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24766164774700476810039401793119553409e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08325637569571782180723187639357833929e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74954547353553788519997212700557196088e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82800744682204649977844278025855329390e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.20210992299988298543034791887173754015e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22996819257926038785424888617824130286e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.42340212199922656577943251139931264313e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.75700556749505163188370496864513941614e-11), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -16) { + RealType t = -x - 8; + + // Rational Approximation + // Maximum Relative Error: 3.7501e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66153901932100301337118653561328446399e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.52542079386371212946566450189144670788e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.17560936304516198261138159102435548430e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.26792904240601626330507068992045446428e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15418212265160879313643948347460896640e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.05247220687656529725024232836519908641e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.64228534097787946289779529645800775231e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.85634097697132464418223150629017524118e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49585420710073223183176764488210189671e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.48871040740917898530270248991342594461e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.42577266655992039477272273926475476183e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19214263302271253341410568192952269518e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36635313919771528255819112450043338510e-12), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32484755553196872705775494679365596205e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.17714315014480774542066462899317631393e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.10789882607024692577764888497624620277e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09821963157449764169644456445120769215e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52354198870000121894280965999352991441e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12133327236256081067100384182795121111e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.20187894923874357333806454001674518211e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69039238999927049119096278882765161803e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.35737444680219098802811205475695127060e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.54403624143647064402264521374546365073e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.24233005893817070145949404296998119469e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.89735152971223120087721392400123727326e-12), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -32) { + RealType t = -x - 16; + + // Rational Approximation + // Maximum Relative Error: 9.2696e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65985830928929730672052407058361701971e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80409998734303497641108024806388734755e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.49286120625421787109350223436127409819e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.89160491404149422833016337592047445082e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16725811789351893632348469796802834008e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.43438517439595919021069131504449842238e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.29058184637190638359623120253986595623e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.03288592271246432030980385908922413497e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.12286831076824535034975676306286388291e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.64563161552001551475186730009447111173e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13183856815615371136129883169639301710e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.02405342795439598418033139109649640085e-35), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.78286317363568496229516074305435186276e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06519013547074134846431611115576250187e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.71907733798006110542919988654989891098e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.38874744033460851257697736304200953873e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.54724289412996188575775800547576856966e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98922099980447626797646560786207812928e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.64352676367403443733555974471752023206e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92616898324742524009679754162620171773e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87471345773127482399498877510153906820e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92954174836731254818376396170511443820e-12), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -64) { + RealType t = -x - 32; + + // Rational Approximation + // Maximum Relative Error: 2.3524e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65964563346442080104568381680822923977e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.77958685324702990033291591478515962894e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.56419338083136866686699803771820491401e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.82465178504003399087279098324316458608e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92402911374159755476910533154145918079e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.91224450962405933321548581824712789516e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.84063939469145970625490205194192347630e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.15300528698702940691774461674788639801e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.85553643603397817535280932672322232325e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.46207029637607033398822620480584537642e-38), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54906717312241693103173902792310528801e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84408124581401290943345932332007045483e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81403744024723164669745491417804917709e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23423244618880845765135047598258754409e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.84697524433421334697753031272973192290e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94803525968789587050040294764458613062e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68948879514200831687856703804327184420e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07366525547027105672618224029122809899e-12), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_imp_prec(const RealType& x, const boost::math::integral_constant &tag) { + if (x >= 0) { + return mapairy_pdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return mapairy_pdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_imp_prec(const RealType& x, const boost::math::integral_constant& tag) { + if (x >= 0) { + return mapairy_pdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return mapairy_pdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_pdf_imp(const mapairy_distribution& dist, const RealType& x) { + // + // This calculates the pdf of the Map-Airy distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::pdf(mapairy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = mapairy_pdf_imp_prec(u, tag_type()) / scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 2.9194e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(3.33333333333333333333e-1), + static_cast(7.49532137610545010591e-2), + static_cast(9.25326921848155048716e-3), + static_cast(6.59133092365796208900e-3), + static_cast(-5.21942678326323374113e-4), + static_cast(8.22766804917461941348e-5), + static_cast(-3.97941251650023182117e-6), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(8.17408156824742736411e-1), + static_cast(3.57041011418415988268e-1), + static_cast(1.04580353775369716002e-1), + static_cast(1.87521616934129432292e-2), + static_cast(2.33232161135637085535e-3), + static_cast(7.31285352607895467310e-5), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 3.1531e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.84196970581015939888e-1), + static_cast(-1.19398028299089933853e-3), + static_cast(1.21954054797949597854e-2), + static_cast(-9.37912675685073154845e-4), + static_cast(1.66651954077980453212e-4), + static_cast(-1.33271812303025233648e-5), + static_cast(5.35982226125013888796e-7), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(5.70352826101668448273e-1), + static_cast(1.98852010141232271304e-1), + static_cast(3.64864882318453496161e-2), + static_cast(4.22173125405065522298e-3), + static_cast(1.20079284386796600356e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.8348e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.07409273397524124098e-1), + static_cast(3.83900318969331880402e-2), + static_cast(1.17926652359826576790e-2), + static_cast(1.52181625871479030046e-3), + static_cast(1.50703424417132565662e-4), + static_cast(2.10117959279448106308e-6), + static_cast(1.97360985832285866640e-8), + static_cast(-1.06076300080048408251e-9), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(8.54435380513870673497e-1), + static_cast(3.66021233157880878411e-1), + static_cast(9.42985570806905160687e-2), + static_cast(1.54122343653998564507e-2), + static_cast(1.49849056258932455548e-3), + static_cast(6.94290406268856211707e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 2.6624e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.70720199535228802538e-2), + static_cast(2.67200763833749070079e-2), + static_cast(7.37400551855064729769e-3), + static_cast(1.10592441765001623699e-3), + static_cast(9.15846028547400212588e-5), + static_cast(3.17801522553862136789e-6), + static_cast(2.03102753319827713542e-8), + static_cast(-5.16172854149066643529e-11), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(9.05317644829451086870e-1), + static_cast(3.73713496637025562492e-1), + static_cast(8.94434672792094976627e-2), + static_cast(1.31846542255347106087e-2), + static_cast(1.16680596342421447100e-3), + static_cast(5.44719256441278863300e-5), + static_cast(8.73131209154185067287e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 2.6243e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.74847564444513000450e-2), + static_cast(6.00209162595027323742e-3), + static_cast(7.86550260761375576075e-4), + static_cast(4.46682547335758521734e-5), + static_cast(9.51329761417139273391e-7), + static_cast(4.10313065114362712333e-9), + static_cast(-9.81286503831545640189e-12), + static_cast(2.98763969872672156104e-14), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(5.27732094554221674504e-1), + static_cast(1.14330643482604301178e-1), + static_cast(1.27722341942374066265e-2), + static_cast(7.54563340152441778517e-4), + static_cast(2.13377039814057925832e-5), + static_cast(2.09670987094350618690e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 5.4684e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(6.22684103170563193015e-3), + static_cast(1.34714356588780958096e-3), + static_cast(9.51289465377874891896e-5), + static_cast(2.64918464474843134081e-6), + static_cast(2.66703857491046795285e-8), + static_cast(5.42037888457985833156e-11), + static_cast(-6.18017115447736427379e-14), + static_cast(9.11626234402148561268e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.09895694991285975774e-1), + static_cast(3.69874670435930773471e-2), + static_cast(2.15708854325146400153e-3), + static_cast(6.35345408451056881884e-5), + static_cast(8.65722805575670770555e-7), + static_cast(4.03153189557220023202e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 6.5947e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.20357145727036120652e-3), + static_cast(1.45412555771401325111e-4), + static_cast(3.27819006009093198652e-6), + static_cast(2.96786786716623870006e-8), + static_cast(9.54192199129339742308e-11), + static_cast(5.71421706870777687254e-14), + static_cast(-1.48321866072033823195e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.12851983233980279746e-1), + static_cast(4.94650928817638043712e-3), + static_cast(1.05447405092956497114e-4), + static_cast(1.11578464291338271178e-6), + static_cast(5.27522295397347842625e-9), + static_cast(7.95786524903707645399e-12), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType x_cube = x * x * x; + RealType t = static_cast((boost::math::isnormal)(x_cube) ? 1 / sqrt(x_cube) : 1 / pow(sqrt(x), 3)); + + // Rational Approximation + // Maximum Relative Error: 6.2709e-17 + BOOST_MATH_STATIC const RealType P[4] = { + static_cast(3.98942280401432677940e-1), + static_cast(2.89752186412133782995e-2), + static_cast(4.67360459917040710474e0), + static_cast(-1.26770824563800250704e-1), + }; + BOOST_MATH_STATIC const RealType Q[3] = { + static_cast(1.), + static_cast(7.26301023103568827709e-2), + static_cast(1.60899894281099149848e1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 1) { + // Rational Approximation + // Maximum Relative Error: 4.7720e-37 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.33333333333333333333333333333333333333e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38519736580901276671338330967060054188e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.07012342772403725079487012557507575976e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70163612228825567572185033570526547856e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16393313438726572630782132625753922397e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.92141312947853945617138019222992750592e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16513062047959961711747864068554379374e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08850391017085844154857927364247623649e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07060872491334153829857156707699441084e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.56961733740920438026573722084839596926e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.93626747947476815631021107726714283086e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32967164823609209711923411113824666288e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.23420723211833268177898025846064230665e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13807083548358335699029971528179486964e-13), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00810772528427939684296334977783425582e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.24383652800043768524894854013745098654e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64696616559657052516796844068580626381e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.62288747679271039067363492752820355369e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19311779292286492714550084942827207241e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48436879303839576521077892946281025894e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.28665316157256311138787387605249076674e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.36350302380845433472593647100484547496e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.05835458213330488018147374864403662878e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.13919959493955187399856105325181806876e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30960533107704070411766556906543316310e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 1.6297e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.84196970581015939887507434989936103587e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23864910443500344832158256856064580005e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.72066675347648126090497588433854314742e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81712740200456564860442639192891089515e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.39091197181834765859741334477680768031e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.03759464781707198959689175957603165395e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15298069568149410830642785868857309358e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18910514301176322829267019223946392192e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.16851691488007921400221017970691227149e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.82031940093536875619655849638573432722e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30042143299959913519747484877532997335e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.19848671456872291336347012756651759817e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00479393063394570750334218362674723065e-13), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24929390929112144560152115661603117364e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.34853762543033883106055186520573363290e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.73783624941936412984356492130276742707e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23224734370942016023173307854505597524e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.11116448823067697039703254343621931158e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.12490054037308798338231679733816982120e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.38701607014856856812627276285445001885e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10075199231657382435402462616587005087e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.43662615015322880941108094510531477066e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37981396630189761210639158952200945512e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55820444854396304928946970937054949160e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 2.8103e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07409273397524124098315500450332255837e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.98373054365213259465522536994638631699e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.30851284606709136235419547406278197945e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92686617543233900289721448026065555990e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.18056394312484073294780140350522772329e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07058343449035366484618967963264380933e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71636108080692802684712497501670425230e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13155853034615230731719317488499751231e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.00070273388376168880473457782396672044e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35528857373910910704625837069445190727e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.99897218751541535347315078577172104436e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35092090729912631973050415647154137571e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72220647682193638971237255396233171508e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.45008884108655511268690849420714428764e-15), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42652074703683973183213296310906006173e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03479786698331153607905223548719296572e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.95556520914240562719970700900964416000e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73127917601685318803655745157828471269e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.63007065833918179119250623000791647836e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.70652732923091039268400927316918354628e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60880782675229297981880241245777122866e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09979261868403910549978204036056659380e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12085610111710889118562321318284539217e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59811533082647193392924345081953134304e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37211668706684650035086116219257276925e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62479830409039340826066305367893543134e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.22039803134898937546371285610102850458e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 7.5930e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.70720199535228802537946089633331273434e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.85220706158476482443562698303252970927e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55090221054465759649629178911450010833e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.70398047783095186291450019612979853708e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11846661331973171721224034349719801691e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83195024406409870789088752469490824640e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.23908312140480103249294791529383548724e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.40765128885655152415228193255890859830e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.14294523267278070539100529759317560119e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.26815059429007745850376987481747435820e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.28142945635159623618312928455133399240e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77079683180868753715374495747422819326e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73710011278079325323578951018770847628e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.70140037580287364298206334732060874507e-16), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36848014038411798213992770858203510748e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.15373052017549822413011375404872359177e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.92705544967513282963463451395766172671e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19899290805598090502434290420047460406e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74002906913724742582773116667380578990e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80632456977494447641985312297971970632e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.53381530665983535467406445749348183915e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.86606180756179817016240556949228031340e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.49594666942152749850479792402078560469e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.25231012522695972983928740617341887334e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34987086926725472733984045599487947378e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.58286136970918021841189712851698747417e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.12238357666199366902936267515573231037e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82464168044335183356132979380360583444e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40073718480172265670072434562833527076e-17), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 7.3609e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74847564444513000450056174922427854591e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56842503159303803254436983444304764079e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.48504629497687889354406208309334148575e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62327083507366120871877936416427790391e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72062210557023828776202679230979309963e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19153025667221102770398900522196418041e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66248482185063262034022017727375829162e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57390218395059632327421809878050974588e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.45520328522839835737631604118833792570e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76327978880339919462910339138428389322e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.99700625463451418394515481232159889297e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82943476668680389338853032002472541164e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19415284760817575957617090798914089413e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17080879333540200065368097274334363537e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.09912208206107606750610288716869139753e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.98451733054622166748935243139556132704e-26), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08148065380582488495702136465010348576e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.42385352331252779422725444021027377277e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66510412535270623169792008730183916611e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.47952712144801508762945315513819636452e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.20703092334999244212988997416711617790e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.71658889250345012472529115544710926154e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.63905601023452497974798277091285373919e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76730409484335386334980429532443217982e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19139408077753398896224794522985050607e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.58025872548387600940275201648443410419e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.11369336267349152895272975096509109414e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.56182954522937999103610817174373785571e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.35452907177197742692545044913125982311e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23587924912460218189929226092439805175e-17), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 9.7192e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.22684103170563193014558918295924551173e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55222688816852408105912768186300290291e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.60747505331765587662432023547517953629e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80463770266821887100086895337451846880e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.19190824169154471000496746227725070963e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40646301571395681364881852739555404287e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15408836734496798091749932018121879724e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.13676779930022341958128426888835497781e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02435098103190516418351075792372986932e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.82018920071479061978244972592746216377e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.26435061215428679536159320644587957335e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05298407883178633891153989998582851270e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61156860101928352010449210760843428372e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.02156808288545876198121127510075217184e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65549196385656698597261688277898043367e-30), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.03426141030409708635168766288764563749e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13808987755928828118915442251025992769e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52253239792170999949444502938290297674e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33720936468171204432499390745432338841e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.08713980159883984886576124842631646880e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.43652846144339754840998823540656399165e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02849693617024492825330133490278326951e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14110017452008167954262319462808192536e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.01462578814695350559338360744897649915e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73495817568046489613308117490508832084e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47445372925844096612021093857581987132e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08200002287534174751275097848899176785e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15305756373406702253187385797525419287e-21), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 9.7799e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.20357145727036120652264700679701054983e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95712324967981162396595365933255312698e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08619492652809635942960438372427086939e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37140224583881547818087260161723208444e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83073777522092069988595553041062506001e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.00473542739040742110568810201412321512e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.47447289601822506789553624164171452120e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70913574957198131397471307249294758738e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36538119628489354953085829178695645929e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00763343664814257170332492241110173166e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62297585950798764290583627210836077239e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15780217054514513493147192853488153246e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31961589164397397724611386366339562789e-28), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.26440207646105117747875545474828367516e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27872879091838733280518786463281413334e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34256572873114675776148923422025029494e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13595637397535037957995766856628205747e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33745879863685053883024090247009549434e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41792226523670940279016788831933559977e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.03966147662273388060545199475024100492e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62177951640260313354050335795080248910e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50650165210517365082118441264513277196e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.48413283257020741389298806290302772976e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16439276222123152748426700489921412654e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24969602890963356175782126478237865639e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.08681155203261739689727004641345513984e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28282024196484688479115133027874255367e-30), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType x_cube = x * x * x; + RealType t = (boost::math::isnormal)(x_cube) ? 1 / sqrt(x_cube) : 1 / pow(sqrt(x), 3); + + // Rational Approximation + // Maximum Relative Error: 3.5865e-37 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[8] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98942280401432677939946059934381868476e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12426566605292130233061857505057433291e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.91574528280329492283287073127040983832e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69914217884224943794012165979483573091e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30178902028403564086640591437738216288e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96515490341559353794378324810127583810e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44343825578434751356083230369361399507e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.07224810408790092272497403739984510394e2), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.32474438135610721926278423612948794250e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27594461167587027771303292526448542806e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49207539478843628626934249487055017677e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75094412095634602055738687636893575929e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.51642534474780515366628648516673270623e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05977615003758056284424652420774587813e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 1.6964e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.23238998449671083670e-1), + static_cast(4.95353582976475183891e-1), + static_cast(2.45823281826037784270e-1), + static_cast(7.29726507468813920788e-2), + static_cast(1.63332856186819713346e-2), + static_cast(2.82514634871307516142e-3), + static_cast(2.66220579589280704089e-4), + static_cast(3.09442180091323751049e-6), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(5.16241922223786900600e-1), + static_cast(2.75690727171711638879e-1), + static_cast(7.18707184893542884080e-2), + static_cast(1.87136800286819336797e-2), + static_cast(2.38383441176345054929e-3), + static_cast(3.23509126477812051983e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 5.8303e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.62598955251978523175e-1), + static_cast(2.30154661502402196205e-1), + static_cast(1.29233975368291684522e-1), + static_cast(3.80919553916980965587e-2), + static_cast(8.17724414618808505948e-3), + static_cast(1.95816800210481122544e-3), + static_cast(3.35259917978421935141e-4), + static_cast(1.22071311320012805777e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(9.63771793313770952352e-2), + static_cast(2.23602260938227310054e-1), + static_cast(9.21944797677283179038e-3), + static_cast(1.82181136341939651516e-2), + static_cast(1.11216849284965970458e-4), + static_cast(5.57446347676836375810e-4), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType s = exp(2 * x * x * x / 27) / sqrt(-x * x * x); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 3.6017e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(8.31806744221966404520e-1), + static_cast(1.34481067378012055850e0), + static_cast(9.12139427469494995264e-1), + static_cast(3.59706159222491124928e-1), + static_cast(9.48836332725688279299e-2), + static_cast(1.68259594978853951234e-2), + static_cast(1.89700733471520162946e-3), + static_cast(1.13854052826846329787e-4), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(1.29694286517571741097e0), + static_cast(7.99686735441213882518e-1), + static_cast(3.08198207583883597188e-1), + static_cast(7.97230139795658588972e-2), + static_cast(1.40742142048849462162e-2), + static_cast(1.58411440546277691506e-3), + static_cast(9.51560785730564046338e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -8) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 1.3504e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.10294551528734705946e0), + static_cast(1.26696377028973554615e0), + static_cast(6.63115985833429688941e-1), + static_cast(2.06289793717379095832e-1), + static_cast(4.11977615717846276227e-2), + static_cast(5.28620928618550859827e-3), + static_cast(4.04328442334023561279e-4), + static_cast(1.42364413902075896503e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(1.09709853682665798542e0), + static_cast(5.63687797989627787500e-1), + static_cast(1.73604358560002859604e-1), + static_cast(3.44985744385890794044e-2), + static_cast(4.41683993064797272821e-3), + static_cast(3.37834206192286709492e-4), + static_cast(1.18951465786445720729e-5), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -16) { + RealType t = -x - 8; + + // Rational Approximation + // Maximum Relative Error: 8.8272e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.18246847255744057280e0), + static_cast(8.41320657699741240497e-1), + static_cast(2.55093097377551881478e-1), + static_cast(4.21261576802732715976e-2), + static_cast(3.98805044659990523312e-3), + static_cast(2.04688276265993954527e-4), + static_cast(4.43354791268634655473e-6), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(7.07103973315808077783e-1), + static_cast(2.13664682181055450396e-1), + static_cast(3.52218225168465984709e-2), + static_cast(3.33218664347896435919e-3), + static_cast(1.71025807471868853268e-4), + static_cast(3.70441884597642042665e-6), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -32) { + RealType t = -x - 16; + + // Rational Approximation + // Maximum Relative Error: 2.6236e-18 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(1.19497306481411168356e0), + static_cast(3.90497195765498241356e-1), + static_cast(5.13120330037626853257e-2), + static_cast(3.38574023921119491471e-3), + static_cast(1.12075935888344736993e-4), + static_cast(1.48743616420183584738e-6), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(3.26493785348088598123e-1), + static_cast(4.28813205161574223713e-2), + static_cast(2.82893073845390254969e-3), + static_cast(9.36442365966638579335e-5), + static_cast(1.24281651532469125315e-6), + }; + + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_minus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x >= -1) { + RealType t = x + 1; + + // Rational Approximation + // Maximum Relative Error: 1.0688e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.23238998449671083670041452413316011920e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.14900991369455846775267187236501987891e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.19132787054572299485638029221977944555e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87295743700300806662745209398368996653e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.41994520703802035725356673887766112213e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78782099629586443747968633412271291734e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.05200546520666366552864974572901349343e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.51453477916196630939702866688348310208e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15461354910584918402088506199099270742e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43371674256124419899137414410592359185e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35849788347057186916350200082990102088e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.50359296597872967493549820191745700442e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21838020977580479741299141050400953125e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.46723648594704078875476888175530463986e-12), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.98700317671474659677458220091101276158e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.00405631175818416028878082789095587658e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04189939150805562128632256692765842568e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.03621065280443734565418469521814125946e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85722257874304617269018116436650330070e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.24191409213079401989695901900760076094e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.64269032641964601932953114106294883156e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19289631274036494326058240677240511431e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41389309719775603006897751176159931569e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42000309062533491486426399210996541477e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.02436961569668743353755318268149636644e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.50130875023154569442119099173406269991e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -2) { + RealType t = x + 2; + + // Rational Approximation + // Maximum Relative Error: 5.1815e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62598955251978523174755901843430986522e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08127698872954954678270473317137288772e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70144997468767751317246482211703706086e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49486603823046766249106014234315835102e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.07186495389828596786579668258622667573e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98334953533562948674335281457057445421e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.44119017374895211020429143034854620303e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27080759819117162456137826659721634882e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53892796920597912362370019918933112349e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30530442651657077016130554430933607143e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.04837779538527662990102489150650534390e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.94354615171320374997141684442120888127e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30746545799073289786965697800049892311e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41870129065056783732691371215602982173e-9), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.75919235734607601884356783586727272494e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.57656678936617227532275100649989944452e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72617552401870454676736869003112018648e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.59238104942208254162102314312757621047e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06040513359343987972917295603514840777e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.26922840063034349024167652148593396307e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25628506630180107357627955876231943531e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81600387497542714853225329159728694926e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08210973846891324886779444820838563800e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.68632477858150229792523037059221563861e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.43542789104866782087701759971538600076e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70594730517167328271953424328890849790e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30162314557860623869079601905904538470e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType s = exp(2 * x * x * x / 27) / sqrt(-x * x * x); + + if (x >= -4) { + RealType t = -x - 2; + + // Rational Approximation + // Maximum Relative Error: 6.4678e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.31806744221966404520449104514474066823e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50292887071777664663197915067642779665e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.45140067157601150721516139901304901854e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93227973605511286112712730820664209900e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74259108933048973391560053531348126900e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.77677252890665602191818487592154553094e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71843197238558832510595724454548089268e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.62811778285151415483649897138119310816e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74127763877120261698596916683136227034e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.24832552591462216226478550702845438540e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.93381036027487259940171548523889481080e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02261328789519398745019578211081412570e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.75409238451885381267277435341417474231e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.09526311389365895099871581844304449319e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96371756262605118060185816854433322493e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.88472819535099746216179119978362211227e-10), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.68923525157720774962908922391133419863e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40714902096062779527207435671907059131e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73120596883364361220343183559076165363e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56331267512666685349409906638266569733e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.80956276267438042306216894159447642323e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34213468750936211385520570062547991332e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.50081600968590616549654807511166706919e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47297208240850928379158677132220746750e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.73392976579560287571141938466202325901e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13858821123741335782695407397784840241e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.04103497389656828224053882850778186433e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.81040189127998139689091455192659191796e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42176283104790992634826374270801565123e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64077137545614380065714904794220228239e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08139724991616322332901357866680220241e-10), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -8) { + RealType t = -x - 4; + + // Rational Approximation + // Maximum Relative Error: 3.5975e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10294551528734705945662709421382590676e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.26135857114883288617323671166863478751e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23504465936865651893193560109437792738e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41598983788870071301270649341678962009e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.43871304031224174103636568402522086316e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22745720458050596514499383658714367529e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05976431838299244997805790000128175545e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32087500190238014890030606301748111874e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32754445514451500968404092049839985196e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31866016448921762610690552586049011375e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.80197257671079297305525087998125408939e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.44212088947602969374978384512149432847e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.38857170416924025226203571589937286465e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20239999218390467567339789443070294182e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93965060142992479149039624149602039394e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36407983918582149239548869529460234702e-12), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99867960957804580209868321228347067213e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.94236623527818880544030470097296139679e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21644866845440678050425616384656052588e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.48653919287388803523090727546630060490e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88696531788490258477870877792341909659e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.11157356307921406032115084386689196255e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11071149696069503480091810333521267753e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95274844731679437274609760294652465905e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.77971280158253322431071249000491659536e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.18092258028773913076132483326275839950e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87773088535057996947643657676843842076e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99609277781492599950063871899582711550e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00465660598924300723542908245498229301e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.29174652982710100418474261697035968379e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31746082236506935340972706820707017875e-12), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -16) { + RealType t = -x - 8; + + // Rational Approximation + // Maximum Relative Error: 2.6792e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18246847255744057280356900905660312795e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77955886026107125189834586992142580148e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24948425302263641813107623611637262126e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.42593662659560333324287312162818766556e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62714138002904073145045478360748042164e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.56008984285541289474850396553042124777e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84858048549330525583286373950733005244e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30578460156038467943968005946143934751e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.93974868941529258700281962314167648967e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.95086664204515648622431580749060079100e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57811968176644056830002158465591081929e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27814751838906948007289825582251221538e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06762893426725920159998333647896590440e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15388861641344998301210173677051088515e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83956842740198388242245209024484381888e-29), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50056124032615852703112365430040751173e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05112559537845833793684655693572118348e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.55609497026127521043140534271852131858e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36430652394614121156238070755223942728e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98167215021940993097697777547641188697e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.89418831310297071347013983522734394061e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.10980717618462843498917526227524790487e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.80119618735773019675212434416594954984e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13748676086657187580746476165248613583e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15424395860921826755718081823964568760e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.75228896859720124469916340725146705309e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72759238269315282789451836388878919387e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79966603543593799412565926418879689461e-12), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -32) { + RealType t = -x - 16; + + // Rational Approximation + // Maximum Relative Error: 2.1744e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19497306481411168355692832231058399132e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.15593166681833539521403250736661720488e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54020260738207743315755235213180652303e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76467972857585566189917087631621063058e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.97922795572348613358915532172847895070e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.26998967192207380100354278434037095729e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.32827180395699855050424881575240362199e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50587178182571637802022891868380669565e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.78252548290929962236994183546354358888e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01519297007773622283120166415145520855e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29602226691665918537895803270497291716e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.53666531487585211574942518181922132884e-14), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.82230649578130958108098853863277631065e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12412482738973738235656376802445565005e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98320116955422615960870363549721494683e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.99756654189000467678223166815845628725e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40414942475279981724792023159180203408e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78118445466942812088955228016254912391e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25827002637577602812624580692342616301e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.99604467789028963216078448884632489822e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.48237134334492289420105516726562561260e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08288201960155447241423587030002372229e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.29720612489952110448407063201146274502e-14), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x >= -64) { + RealType t = -x - 32; + + // Rational Approximation + // Maximum Relative Error: 3.4699e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19659414007358083585943280640656311534e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36969140730640253987817932335415532846e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21946928005759888612066397569236165853e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08341720579009422518863704766395201498e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44908614491286780138818989614277172709e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.54172482866925057749338312942859761961e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.49281630950104861570255344237175124548e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27586759709416364899010676712546639820e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00054716479138657682306851175059678989e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.48798342894235412426464893852098239746e-14), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.81588658109851219975949691772676519853e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.52583331848892383968186924120872369151e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57644670426430994363913234422346706991e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21080164634428298820141591419770346977e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79484074949580980980061103238709314326e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.93167250146504946763386377338487557826e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06604193118724797924138056151582242604e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35999937789324222934257460080153249173e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.91435929481043135336094426837156247599e-14), + }; + // LCOV_EXCL_STOP + result = s * tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = 0; + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? mapairy_cdf_plus_imp_prec(x, tag) : 1 - mapairy_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - mapairy_cdf_minus_imp_prec(x, tag) : mapairy_cdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? mapairy_cdf_plus_imp_prec(x, tag) : 1 - mapairy_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - mapairy_cdf_minus_imp_prec(x, tag) : mapairy_cdf_minus_imp_prec(x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_cdf_imp(const mapairy_distribution& dist, const RealType& x, bool complement) { + // + // This calculates the cdf of the Map-Airy distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::cdf(mapairy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = mapairy_cdf_imp_prec(u, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_lower_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.375) { + RealType t = p - static_cast (0.375); + + // Rational Approximation + // Maximum Relative Error: 1.5488e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(-1.17326074020471664075e0), + static_cast(1.51461298154568349598e0), + static_cast(1.19979368094343490487e1), + static_cast(-5.94882121521324108164e0), + static_cast(-2.20619749774447254528e1), + static_cast(7.17766543775229176131e0), + static_cast(4.79284243496552841508e0), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.76268072706610602584e0), + static_cast(-4.88492535243404839734e0), + static_cast(-5.67524172432687656881e0), + static_cast(6.83327389947131710596e0), + static_cast(2.91338085774159042709e0), + static_cast(-1.41108918944159283950e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 7.5181e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(-1.63281240925531302762e0), + static_cast(-4.92351310795930780147e0), + static_cast(1.43448529253101759409e1), + static_cast(3.33182629948094299473e1), + static_cast(-3.06679026539368582747e1), + static_cast(-2.87298447423841965301e1), + static_cast(1.31575930750093554120e1), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(5.38761652244702318296e0), + static_cast(2.40932080746189543284e0), + static_cast(-1.69465870062123632126e1), + static_cast(-6.39998944283654848809e0), + static_cast(1.27168434054332272391e1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 2.3028e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-2.18765177572396469657e0), + static_cast(-3.65752788934974426531e1), + static_cast(-1.81144810822028903904e2), + static_cast(-1.22434531262312950288e2), + static_cast(8.99451018491165823831e2), + static_cast(9.11333307522308410858e2), + static_cast(-8.76285742384616909177e2), + static_cast(-2.33786726970025938837e2), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(1.91797638291395345792e1), + static_cast(1.24293724082506952768e2), + static_cast(2.82393116012902543276e2), + static_cast(-1.80472369158936285558e1), + static_cast(-5.31764390192922827093e2), + static_cast(-5.60586018315854885788e1), + static_cast(1.21284324755968033098e2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 6.1147e-18 + BOOST_MATH_STATIC const RealType P[6] = { + static_cast(-2.18765177572396470773e0), + static_cast(-2.19887766409334094428e0), + static_cast(-7.77080107207360785208e-1), + static_cast(-1.15551765136654549650e-1), + static_cast(-6.64711321022529990367e-3), + static_cast(-9.74212491048543799073e-5), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(7.91919722132624625590e-1), + static_cast(2.17415447268626558639e-1), + static_cast(2.41474762519410575392e-2), + static_cast(9.41084107182696904714e-4), + static_cast(6.65754108797614202364e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 2.0508e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-2.59822399410385085335e0), + static_cast(-2.24306757759003016244e0), + static_cast(-7.36208578161752060979e-1), + static_cast(-1.15130762650287391576e-1), + static_cast(-8.77652386123688618995e-3), + static_cast(-2.96358888256575251437e-4), + static_cast(-3.33661282483762192446e-6), + static_cast(-4.19292241201527861927e-9), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(7.23065798041556418844e-1), + static_cast(1.96731305131315877264e-1), + static_cast(2.49952034298034383781e-2), + static_cast(1.49149568322111062242e-3), + static_cast(3.66010398525593921460e-5), + static_cast(2.46857713549279930857e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 2.1997e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-3.67354365380697580447e0), + static_cast(-1.52181685844845957618e0), + static_cast(-2.40883948836320845233e-1), + static_cast(-1.82424079258401987512e-2), + static_cast(-6.75844978572417703979e-4), + static_cast(-1.11273358356809152121e-5), + static_cast(-6.12797605223700996671e-8), + static_cast(-3.78061321691170114390e-11), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.57770840766081587688e-1), + static_cast(4.81290550545412209056e-2), + static_cast(3.02079969075162071807e-3), + static_cast(8.89589626547135423615e-5), + static_cast(1.07618717290978464257e-6), + static_cast(3.57383804712249921193e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 2.4331e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-4.92187819510636697128e0), + static_cast(-9.94924018698264727979e-1), + static_cast(-7.69914962772717316098e-2), + static_cast(-2.85558010159310978248e-3), + static_cast(-5.19022578720207406789e-5), + static_cast(-4.19975546950263453259e-7), + static_cast(-1.13886013623971006760e-9), + static_cast(-3.46758191090170732580e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.77270673840643360017e-1), + static_cast(1.18099604045834575786e-2), + static_cast(3.66889581757166584963e-4), + static_cast(5.34484782554469770841e-6), + static_cast(3.19694601727035291809e-8), + static_cast(5.24649233511937214948e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 2.7742e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-6.41443550638291133784e0), + static_cast(-6.38369359780748328332e-1), + static_cast(-2.43420704406734621618e-2), + static_cast(-4.45274771094277987075e-4), + static_cast(-3.99529078051262843241e-6), + static_cast(-1.59758677464731620413e-8), + static_cast(-2.14338367751477432622e-11), + static_cast(-3.23343844538964435927e-15), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(8.79845511272943785289e-2), + static_cast(2.90839059356197474893e-3), + static_cast(4.48172838083912540123e-5), + static_cast(3.23770691025690100895e-7), + static_cast(9.60156044379859908674e-10), + static_cast(7.81134095049301988435e-13), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 3.2451e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-8.23500806363233610938e0), + static_cast(-4.05652655284908839003e-1), + static_cast(-7.65978833819859622912e-3), + static_cast(-6.94194676058731901672e-5), + static_cast(-3.08771646223818451436e-7), + static_cast(-6.12443207313641110962e-10), + static_cast(-4.07882839359528825925e-13), + static_cast(-3.05720104049292610799e-17), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(4.37395212065018405474e-2), + static_cast(7.18654254114820140590e-4), + static_cast(5.50371158026951899491e-6), + static_cast(1.97583864365011234715e-8), + static_cast(2.91169706068202431036e-11), + static_cast(1.17716830382540977039e-14), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -256) { + RealType t = -log2(ldexp(p, 128)); + + // Rational Approximation + // Maximum Relative Error: 3.8732e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-1.04845570631944023913e1), + static_cast(-2.56502856165700644836e-1), + static_cast(-2.40615394566347412600e-3), + static_cast(-1.08364601171893250764e-5), + static_cast(-2.39603255140022514289e-8), + static_cast(-2.36344017673944676435e-11), + static_cast(-7.83146284114485675414e-15), + static_cast(-2.92218240202835807955e-19), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(2.17740414929742679904e-2), + static_cast(1.78084231709097280884e-4), + static_cast(6.78870668961146609668e-7), + static_cast(1.21313439060489363960e-9), + static_cast(8.89917934953781122884e-13), + static_cast(1.79115540847944524599e-16), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -512) { + RealType t = -log2(ldexp(p, 256)); + + // Rational Approximation + // Maximum Relative Error: 4.6946e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-1.32865827226175698181e1), + static_cast(-1.61802434199627472010e-1), + static_cast(-7.55642602577784211259e-4), + static_cast(-1.69457608092375302291e-6), + static_cast(-1.86612389867293722402e-9), + static_cast(-9.17015770142364635163e-13), + static_cast(-1.51422473889348610974e-16), + static_cast(-2.81661279271583206526e-21), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.08518414679241420227e-2), + static_cast(4.42335224797004486239e-5), + static_cast(8.40387821972524402121e-8), + static_cast(7.48486746424527560620e-11), + static_cast(2.73676810622938942041e-14), + static_cast(2.74588200481263214866e-18), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -1024) { + RealType t = -log2(ldexp(p, 512)); + + // Rational Approximation + // Maximum Relative Error: 5.7586e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(-1.67937186583822375593e1), + static_cast(-1.01958138247797604098e-1), + static_cast(-2.37409774265951876695e-4), + static_cast(-2.65483321307104128810e-7), + static_cast(-1.45803536947907216594e-10), + static_cast(-3.57375116523338994342e-14), + static_cast(-2.94401318006358820268e-18), + static_cast(-2.73260616170245224789e-23), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(5.41357843707822974161e-3), + static_cast(1.10082540037527566536e-5), + static_cast(1.04338126042963003178e-8), + static_cast(4.63619608458569600346e-12), + static_cast(8.45781310395535984099e-16), + static_cast(4.23432554226506409568e-20), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = -boost::math::numeric_limits::infinity(); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_lower_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.4375) { + RealType t = p - static_cast (0.4375); + + // Rational Approximation + // Maximum Relative Error: 4.2901e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.48344198262277235851026749871350753173e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.18249834490570496537675012473572546187e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20191368895639224466285643454767208281e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.88388953372157636908236843798588258539e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.59477796311326067051769635858472572709e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88799146700484120781026039104654730797e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.15708831983930955608517858269193800412e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.01389336086567891484877690859385409842e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.16683694881010716925933071465043323946e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.04356966421177683585461937085598186805e1), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.75444066345435020043849341970820565274e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.95105673975812427406540024601734210826e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.20381124524894051002242766595737443257e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.48370658634610329590305283520183480026e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.52213602242009530270284305006282822794e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.91028722773916006242187843372209197705e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.76130245344411748356977700519731978720e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30834721900169773543149860814908904224e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.37863084758381651884340710544840951679e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.46880981703613838666108664771931239970e0), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.375) { + RealType t = p - static_cast (0.375); + + // Rational Approximation + // Maximum Relative Error: 2.8433e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.17326074020471664204142312429732771661e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.23412560010002723970559712941124583385e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83665111310407767293290698145068379130e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.38459476870110655357485107373883403534e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.28751995328228442619291346921055105808e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.31663592034507247231393516167247241037e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13629333446941271397790762651183997586e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.80674058829101054663235662701823250421e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.53226182094253065852552393446365315319e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.14713948941614711932063053969010219677e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.62979741122708118776725634304028246971e0), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.10550060286464202595779024353437346419e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.15893254630199957990897452211066782021e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.58964066823516762861256609311733069353e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.73352515261971291505497909338586980605e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.64737859211974163695241658186141083513e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.79137714768236053008878088337762178011e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.71851514659301019977259792564627124877e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.37210093190088984630526671624779422232e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06793750951779308425209267821815264457e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 5.9072e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.63281240925531315038207673147576291783e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.72733898245766165408685147762489513406e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.48666841594842113608962500631836790675e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.38711336213357101067420572773139678571e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.19536066931882831915715343914510496760e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70911330354860558400876197129777829223e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.46138758869321272507090399082047865434e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.42653825421465476333482312795245170700e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68040069633027903153088221686431049116e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.63017854949929226947577854802720988740e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.57362168966659376351959631576588023516e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.48386631313725080746815524770260451090e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.03293129698111279047104766073456412318e1), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29511778027351594854005887702013466376e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.66155745848864270109281703659789474448e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.25628362783798417463294553777015370203e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.93162726153946899828589402901015679821e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.51582398149308841534372162372276623400e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55512400116480727630652657714109740448e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.11949742749256615588470329024257669470e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28090154738508864776480712360731968283e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.44307717248171941824014971579691790721e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.33595130666758203099507440236958725924e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.76156378002782668186592725145930755636e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.70446647862725980215630194019740606935e0), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 9.9092e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.18765177572396470161180571018467019660e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.16991481696416567893311341049825218287e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.25497491118598918048058751362064598010e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.00259915194411316966036757165146681474e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.20350803730836873687692010728689867756e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.75441278117456011071671644613599089820e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18844967505497310645091822621081741562e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.84771867850847121528386231811667556346e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.78112436422992766542256241612018834150e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.82617957794395420193751983521804760378e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.77260227244465268981198741998181334875e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.61918290776044518321561351472048170874e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.10309368217936941851272359946015001037e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68917274690585744147547352309416731690e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.96914697182030973966321601422851730384e4), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98063872144867195074924232601423646991e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65911346382127464683324945513128779971e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02451223307009464199634546540152067898e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.12662676019712475980273334769644047369e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.77637305574675655673572303462430608857e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.65900204382557635710258095712789133767e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.61649498173261886264315880770449636676e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.29867325788870863753779283018061152414e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.31375646045453788071216808289409712455e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.91053361331987954531162452163243245571e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.30917504462260061766689326034981496723e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.95779171217851232246427282884386844906e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.07234815204245866330282860014624832711e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21353269292094971546479026200435095695e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 3.9653e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.18765177572396470161180571018467025793e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.94718878144788678915739777385667044494e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.01760622104142726407095836139719210570e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.27585388152893587017559610649258643106e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.26494992809545184138230791849722703452e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.19962820888633928632710264415572027960e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.10249328404135065767844288193594496173e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.94733898567966142295343935527193851633e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.10350856810280579594619259121755788797e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.23852908701349250480831167491889740823e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.61008160195204632725691076288641221707e-10), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59109221235949005113322202980300291082e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07119192591092503378838510797916225920e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97313678065269932508447079892684333156e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.85743007214453288049750256975889151838e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21504290861269099964963866156493713716e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00880286431998922077891394903879512720e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.78806057460269900288838437267359072282e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15390284861815831078443996558014864171e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09877166004503937701692216421704042881e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.01544823753120969225271131241177003165e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 6.7872e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.59822399410385083283727681965013517187e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.30676107401101401386206170152508285083e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.14999782004905950712290914501961213222e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.33941786334132569296061539102765384372e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.67220197146826865151515598496049341734e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.80553562310354708419148501358813792297e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.69365728863553037992854715314245847166e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.66571611322125393586164383361858996769e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.60112572827002965346926427208336150737e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.82368436189138780270310776927920829805e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.53112953085778860983110669544602606343e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.47363651755817041383574210879856850108e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.56959356177318833325064543662295824581e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.16259632533790175212174199386945953139e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.51102540845397821195190063256442894688e-18), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51733661576324699382035973518172469602e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01435607980568082538278883569729476204e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93274478117803447229185270863587786287e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.79695020433868416640781960667235896490e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64179255575983014759473815411232853821e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88411076775875459504324039642698874213e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47924359965537384942568979646011627522e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.80915944234873904741224397674033111178e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67530059257263142305079790717032648103e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.59778634436027309520742387952911132163e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.45772841855129835242992919296397034883e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40356170422999016176996652783329671363e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31127037096552892520323998665757802862e-16), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 7.6679e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.67354365380697578246790709817724831418e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.98681625368564496421038758088088788795e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.07310677200866436332040539417232353673e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.24429836496456823308103613923194387860e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.02985399190977938381625172095575017346e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.76782196972948240235456454778537838123e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.74449002785643398012450514191731166637e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.59599894044461264694825875303563328822e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.25326249969126313897827328136779597159e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.41714701672521323699602179629851858792e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.43197925999694667433180053594831915164e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.84385683045691486021670951412023644809e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34484740544060627138216383389282372695e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.69717198111130468014375331439613690658e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.54464319402577486444841981479085908190e-22), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.56568169258142086426383908572004868200e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52144703581828715720555168887427064424e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.87268567039210776554113754014224005739e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.04907480436107533324385788289629535047e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05063218951887755000006493061952858632e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.88707869862323507236241669797692957827e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12876335369047582931728838551780783006e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96657547014655679104867167083078285517e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05799908632250375607393338998205481867e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.26543514080500125624753383852230043206e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02102501711063497529014782040893679505e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.91577723105757841509716090936343311518e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.13824283239122976911704652025193325941e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 8.6323e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.92187819510636694694450607724165689649e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.97763858433958798529675258052376253402e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.51315096979196319830162238831654165509e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.63462872759639470195664268077372442947e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.42843455093529447002457295994721102683e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.09839699044798405685726233251577671229e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.42918585783783247934440868680748693033e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.39927851612709063686969934343256912856e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.08811978806833318962489621493456773153e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.05790315329766847040100971840989677130e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.45479905512618918078640786598987515012e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.26725031195260767541308143946590024995e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.93921283405116349017396651678347306610e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.46989755992471397407520449698676945629e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.84098833615882764168840211033822541979e-26), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76933186134913044021577076301874622292e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.25794095712489484166470336696962749356e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.02367257449622569623375613790000874499e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.72422948147678152291655497515112236849e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54841786738844966378222670550160421679e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40690766057741905625149753730480294357e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.57722740290698689456097239435447030950e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12202417878861628530322715231540006386e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.52053248659561670052645118655279630611e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.93156242508301535729374373870786335203e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40767922796889118151219837068812449420e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83472702205100162081157644960354192597e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.07575352729625387198150555665307193572e-24), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 9.8799e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.41443550638291131009585191506467028820e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.27887396494095561461365753577189254063e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.12752633002089885479040650194288302309e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.79073355729340068320968150408320521772e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.92104558368762745368896313096467732214e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.31521786147036353766882145733055166296e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.69209485282228501578601478546441260206e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.17440286764020598209076590905417295956e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.24323354132100896221825450145208350291e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.53395893728239001663242998169841168859e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.68737623513761169307963299679882178852e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34293243065056704017609034428511365032e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.16077944943653158589001897848048630079e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.62195354664281744711336666974567406606e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34400562353945663460416286570988365992e-30), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87838171063584994806998206766890809367e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55395225505766120991458653457272783334e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.45282436421694718640472363162421055686e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29570159526914149727970023744213510609e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.75502365627517415214497786524319814617e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.74140267916464056408693097635546173776e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.53554952415602030474322188152855226456e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25818606585833092910042975933757268581e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79945579370700383986587672831350689541e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64188969985517050219881299229805701044e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.59811800080967790439078895802795103852e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.28225402720788909349967839966304553864e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.22313199865592821923485268860178384308e-28), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 1.1548e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.23500806363233607692361021471929016922e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.16747938711332885952564885548768072606e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.58252672740225210061031286151136185818e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.15477223656783400505701577048140375949e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.51130817987857130928725357067032472382e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68955185187558206711296837951129048907e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.30418343536824247801373327173028702308e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.96029044368524575193330776540736319950e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.53259926294848786440686413056632823519e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.09476918795964320022985872737468492126e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.20864569882477440934325776445799604204e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.01321468510611172635388570487951907905e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.45079221107904118975166347269173516170e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.36559452694774774399884349254686988041e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.92396730553947142987611521115040472261e-35), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.36599681872296382199486815169747516110e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.86330544720458446620644055149504593514e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.23793435123936109978741252388806998743e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41867848381419339587560909646887411175e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46493580168298395584601073832432583371e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03537470107933172406224278121518518287e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.00375884189083338846655326801486182158e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62515041281615938158455493618149216047e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42337949780187570810208014464208536484e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40196890950995648233637422892711654146e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.11894256193449973803773962108906527772e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00900961462911160554915139090711911885e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.65825716532665817972751320034032284421e-32), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -256) { + RealType t = -log2(ldexp(p, 128)); + + // Rational Approximation + // Maximum Relative Error: 1.3756e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.04845570631944023525776899386112795330e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.18146685146173151383718092529868406030e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.13255476532916847606354932879190731233e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.44228173780288838603949849889291143631e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.18663599891768480607165516401619315227e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.61193813386433438633008774630150180359e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.54402603714659392010463991032389692959e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.76816632514967325885563032378775486543e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.22774672528068516513970610441705738842e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.47312348271366325243169398780745416279e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.10984325972747808970318612951079014854e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.81620524028936785168005732104270722618e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.03443227423068771484783389914203726108e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.02313300749670214384591200940841254958e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.40321396496046206171642334628524367374e-39), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.67292043485384876322219919215413286868e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.61652550158809553935603664087740554258e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14722810796821047167211543031044501921e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.78954660078305461714050086730116257387e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52794892087101750452585357544956835504e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59652255206657812422503741672829368618e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.84914442937017449248597857220675602148e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.23662183613814475007146598734598810102e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.55388618781592901470236982277678753407e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.20418178834057564300014964843066904024e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48606639104883413456676877330419513129e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39845313960416564778273486179935754019e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14538443937605324316706211070799970095e-35), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -512) { + RealType t = -log2(ldexp(p, 256)); + + // Rational Approximation + // Maximum Relative Error: 1.6639e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.32865827226175697711590794217590458484e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.27551166309670994513910580518431041518e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.57161482253140058637495100797888501265e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.26908727392152312216118985392395130974e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.31391169101865809627389212651592902649e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.58926174475498352884244229017384309804e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.97074898765380614681225071978849430802e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.59852103341093122669197704225736036199e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.97287954178083606552531325613580819555e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.57634773176875526612407357244997035312e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.34467233210713881817055138794482883359e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.91236170873875898506577053309622472122e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.12220990075567880730037575497818287435e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.20881889651487527801970182542596258873e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.56848486878078288956741060120464349537e-43), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33267370502089423930888060969568705647e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39632352029900752622967578086289898150e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42703739831525305516280300008439396218e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45767617531685380458878368024246654652e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40344962756110545138002101382437142038e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.47015258371290492450093115369080460499e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.97280918936580227687603348219414768787e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40441024286579579491205384492088325576e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26130000914236204012152918399995098882e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.03893990417552709151955156348527062863e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12687002255767114781771099969545907763e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74218645918961186861014420578277888513e-35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36897549168687040570349702061165281706e-39), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -1024) { + RealType t = -log2(ldexp(p, 512)); + + // Rational Approximation + // Maximum Relative Error: 2.0360e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.67937186583822375017526293948703697225e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.06681764321003187068904973985967908140e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.12508887240195683379004033347903251977e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.56847823157999127998977939588643284176e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.31281869105767454049413701029676766275e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.01498951390503036399081209706853095793e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.72866867304007090391517734634589972858e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.44819806993104486828983054294866921869e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.91441365806306460165885645136864045231e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.71364347097027340365042558634044496149e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.63601648491144929836375956218857970640e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.76948956673676441236280803645598939735e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.47367651137203634311843318915161504046e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.83187517541957887917067558455828915184e-41), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.21480186561579326423946788448005430367e-47), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16494591376838053609854716130343599036e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.97651667629616309497454026431358820357e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77741398674456235952879526959641925087e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.39478109667902532743651043316724748827e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35965905056304225411108295866332882930e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83206524996481183422082802793852630990e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30320324476590103123012385840054658401e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.30322948189714718819437477682869360798e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43729790298535728717477691270336818161e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.89788697114251966298674871919685298106e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.43510901856942238937717065880365530871e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38232043389918216652459244727737381677e-38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64599465785019268214108345671361994702e-43), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -2048) { + RealType t = -log2(ldexp(p, 1024)); + + // Rational Approximation + // Maximum Relative Error: 2.5130e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.11959316095291435774375635827672517008e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.30292575371366023255165927527306483022e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.54260157439166096303943109715675142318e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.61232819199170639867079290977704351939e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.74481972848503486840161528924694379655e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.98283577906243441829434029827766571263e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.90691715740583828769850056130458574520e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.31354728925505346732804698899977180508e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.42545288372836698650371589645832759416e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.12901629676328680681102537492164204387e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.99690040253176100731314099573187027309e-31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.07899506956133955785140496937520311210e-35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.88607240095256436460507438213387199067e-40), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.78815984551154095621830792130401294111e-45), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.20516030880916148179297554212609531432e-51), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.81973541224235020744673910266545976833e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49156990107280109344880219729275939242e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21606730563542176411852745162267260946e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11449329529433741944366607648360521674e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35659138507940819452801802756409587220e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.95708516718550485872934856595725983907e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78871290972777009292563576533612002908e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60955318960542258732596447917271198307e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72437581728117963125690670426402194936e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77473938855958487119889840032590783232e-33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66198494713809467076392278745811981500e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.34142897042941614778352280692901008538e-42), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98791658647635156162347063765388728959e-47), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4096) { + RealType t = -log2(ldexp(p, 2048)); + + // Rational Approximation + // Maximum Relative Error: 3.1220e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.67307564006689676593687414536012112755e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.21005690250741024744367516466433711478e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.11537345869365655126739041291119096558e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.82910297156061391001507891422501792453e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.51574933516708249049824513935386420692e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56433757960363802088718489136097249753e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.74248235865301086829849817739500215149e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.19151506367084295119369434315371762091e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.98518959000360170320183116510466814569e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.21330422702314763225472001861559380186e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.44346922987964428874014866468161821471e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.59773305152191273570416120169527607421e-39), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.81894412321532723356954669501665983316e-44), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.25766346856943928908756472385992861288e-49), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.44601448994095786447982489957909713982e-55), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.90814053669730896497462224007523900520e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.72450689508305973756255440356759005330e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76517273086984384225845151573287252506e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31844251885317815627707511621078762352e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.22689324865113257769413663010725436393e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27524826460469866934006001123700331335e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39172850948322201614266822896191911031e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40343613937272428197414545004329993769e-27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.17936773028976355507339458927541970545e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66512598049860260933817550698863263184e-36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.06432209670481882442649684139775366719e-41), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.10247886333916820534393624270217678968e-46), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40899321122058714028548211810431871877e-51), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -8192) { + RealType t = -log2(ldexp(p, 4096)); + + // Rational Approximation + // Maximum Relative Error: 3.8974e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.36960987939726803544369406181770745475e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.17239311695985070524235502979761682692e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.51192208811996535244435318068035492922e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.38938553034896173195617671475670860841e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.55156910900732478717648524688116855303e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.14905040433940475292279950923000597280e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -7.35237464492052939771487320880614968639e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.07937000518607459141766382199896010484e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.42797358100745086706362563988598447929e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.27871637324128856529004325499921407260e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.99553669724530906250814559570819049401e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.04272644552406682186928100080598582627e-42), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.70093315570856725077212325128817808000e-47), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.51767319872105260145583037426067406953e-53), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.87159268409640967747617639113346310759e-59), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45350026842128595165328480395513258721e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.30398532102631290226106936127181928207e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.45242264812189519858570105609209495630e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.22745462510042159972414219082495434039e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31834645038348794443252730265421155969e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44590392528760847619123404904356730177e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08436623062305193311891193246627599030e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46542554766048266351202730449796918707e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78672067064478133389628198943161640913e-34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.56573050761582685018467077197376031818e-39), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.92145137276530136848088270840255715047e-44), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96933863894082533505471662180541379922e-49), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.92661972206232945959915223259585457082e-55), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -16384) { + RealType t = -log2(ldexp(p, 8192)); + + // Rational Approximation + // Maximum Relative Error: 4.8819e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.24662793339079714510108682543625432532e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.25841960642102016210295419419373971750e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.10589156998251704634852108689102850747e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.18697614924486382142056819421294206504e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.79445222262445726654186491785652765635e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.41847338407338901513049755299049551186e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.44550500540299259432401029904726959214e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.97463434518480676079167684683604645092e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68404349202062958045327516688040625516e-30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.14018837476359778654965300153810397742e-35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.67726222606571327724434861967972555751e-40), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.48082398191886705229604237754446294033e-45), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.28534456209055262678153908192583037946e-51), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.99466700145428173772768099494881455874e-57), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.43473066278196981345209422626769148425e-63), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.26570199429958856038191879713341034013e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32484776300757286079244074394356908390e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.31234182027812869096733088981702059020e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13711443044675425837293030288097468867e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.11480036828082409994688474687120865023e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.25592803132287127389756949487347562847e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.45726006695535760451195102271978072855e-28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13082170504731110487003517418453709982e-32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.48217827031663836930337143509338210426e-37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.47389053144555736191304002865419453269e-42), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90980968229123572201281013063229644814e-47), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79448544326289688123648457587797649323e-53), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.56179793347045575604935927245529360950e-59), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + result = -boost::math::numeric_limits::infinity(); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.25) { + RealType t = p - static_cast (0.25); + + // Rational Approximation + // Maximum Absolute Error: 1.8559e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.81512108276093785320e-1), + static_cast(-2.74296316128959647914e0), + static_cast(-3.29973875964825685757e1), + static_cast(-4.87536980816224603581e1), + static_cast(8.22233203036734027999e1), + static_cast(1.21654607908452130093e2), + static_cast(-6.66681853240657307279e1), + static_cast(-4.28101952511581488588e1), + }; + BOOST_MATH_STATIC const RealType Q[10] = { + static_cast(1.), + static_cast(8.20189490825315245036e0), + static_cast(1.63469912146101848441e1), + static_cast(-1.52740920318273920072e1), + static_cast(-5.41684560257839409762e1), + static_cast(6.51733677169299416471e0), + static_cast(3.93092001388102589237e1), + static_cast(-9.59983666140749481195e-1), + static_cast(-9.95648827557655863699e-1), + static_cast(-1.32007124426778083829e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast (0.125); + + // Rational Approximation + // Maximum Absolute Error: 4.6019e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.70276979914029733585e0), + static_cast(2.09991992116646276165e1), + static_cast(2.26775403775298867998e1), + static_cast(-4.85384304722129472833e2), + static_cast(-1.47107146466495573999e3), + static_cast(-7.08748473959943943929e1), + static_cast(1.54245210917147215257e3), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(2.13092357122115486375e1), + static_cast(1.57318281834689144053e2), + static_cast(4.42261730187813035957e2), + static_cast(2.10814431586717588454e2), + static_cast(-6.36700983439599552504e2), + static_cast(-2.82923881266630617596e2), + static_cast(1.36613971025062750340e2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 1.2193e-19 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(4.25692449785074345588e-1), + static_cast(3.10963501706596356267e-1), + static_cast(2.91357806215297069863e-2), + static_cast(2.34716342676849303244e-2), + static_cast(5.83137296293361915583e-3), + static_cast(3.71792415497884868748e-4), + static_cast(1.59538372221030642757e-4), + static_cast(4.74040834029330213692e-6), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(4.14801234415100707213e-1), + static_cast(1.04693730144480856638e-1), + static_cast(3.81581484862997435076e-2), + static_cast(8.95334009127358617362e-3), + static_cast(1.43316686981760147226e-3), + static_cast(1.81367766024620080990e-4), + static_cast(1.54779999748286671973e-5), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 4.4418e-17 + BOOST_MATH_STATIC const RealType P[11] = { + static_cast(5.07341098045260541890e-1), + static_cast(3.11771145411143166935e-1), + static_cast(1.74515601081894060888e-1), + static_cast(8.46576990174024231338e-2), + static_cast(2.57510090204322149315e-2), + static_cast(8.26605326867021684811e-3), + static_cast(1.73081423934722046819e-3), + static_cast(3.36314161099011673569e-4), + static_cast(4.50990441180388912803e-5), + static_cast(4.53513191985642134268e-6), + static_cast(2.62304611053075404923e-7), + }; + BOOST_MATH_STATIC const RealType Q[11] = { + static_cast(1.), + static_cast(5.28225379952156944029e-1), + static_cast(3.49662079845715371907e-1), + static_cast(1.45408903426879603625e-1), + static_cast(5.06773501409016231879e-2), + static_cast(1.45385556714043243731e-2), + static_cast(3.31235831325018043744e-3), + static_cast(6.06977554525543056050e-4), + static_cast(8.42406730405209749492e-5), + static_cast(8.32337989541696717905e-6), + static_cast(4.84923196546857128337e-7), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 5.7932e-17 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(5.41774626094491510395e-1), + static_cast(4.11060141334529017898e-1), + static_cast(1.48195601801946264526e-1), + static_cast(3.33881552814492855873e-2), + static_cast(5.20893974732203890418e-3), + static_cast(5.84734765774178832854e-4), + static_cast(4.71028150898133935445e-5), + static_cast(2.59185739450631464618e-6), + static_cast(7.77428184258777394627e-8), + static_cast(2.51255632629650930196e-14), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(7.58341767924960527280e-1), + static_cast(2.73511775500642961539e-1), + static_cast(6.16011987856129890130e-2), + static_cast(9.61296002312356116021e-3), + static_cast(1.07890675777726076554e-3), + static_cast(8.69223632953458271977e-5), + static_cast(4.78248875031756169279e-6), + static_cast(1.43460852065144859304e-7), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 9.0396e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(5.41926067826974905066e-1), + static_cast(4.86926556246548518715e-1), + static_cast(2.11963908288176005856e-1), + static_cast(5.92200639925655576883e-2), + static_cast(1.18859816815542567438e-2), + static_cast(1.76833662992855443754e-3), + static_cast(2.21226152157950219596e-4), + static_cast(1.50444847316426133872e-5), + static_cast(1.87458213915373906356e-6), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(8.98511036742503939380e-1), + static_cast(3.91130673008184655152e-1), + static_cast(1.09277016228474605069e-1), + static_cast(2.19328471889880028208e-2), + static_cast(3.26305879571349016107e-3), + static_cast(4.08222014684743492069e-4), + static_cast(2.77611385768697969181e-5), + static_cast(3.45911046256304795257e-6), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else { + RealType p_square = p * p; + + if ((boost::math::isnormal)(p_square)) { + result = 1 / cbrt(p_square * constants::two_pi()); + } + else if (p > 0) { + result = 1 / (cbrt(p) * cbrt(p) * cbrt(constants::two_pi())); + } + else { + result = boost::math::numeric_limits::infinity(); + } + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (p >= 0.375) { + RealType t = p - static_cast (0.375); + + // Rational Approximation + // Maximum Absolute Error: 4.0835e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.00474815142578902619056852805926666121e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.56422290947427848191079775267512708223e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.70103710180837859003070678080056933649e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.08521918131449191445864593768320217287e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29340655781369686013042530147130581054e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.24198237124638368989049118891909723118e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.43382878809828906953609389440800537385e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.45564809127564867825118566276365267035e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75881247317499884393790698530115428373e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.55845932095942777602241134226597158364e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.41328261385867825781522154621962338450e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06758225510372847658316203115073730186e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.10895417312529385966062255102265009972e0), + }; + BOOST_MATH_STATIC const RealType Q[12] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.88252553879196710256650370298744093367e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.54875259600848880869571364891152935969e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.78589587338618424770295921221996471887e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.15356831947775532414727361010652423453e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12951532118504570745988981200579372124e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48163841544376327168780999614703092433e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.56786609618056303930232548304847911521e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.25610739352108840474197350343978451729e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27063786175330237448255839666252978603e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.11941093895004369510720986032269722254e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.51487618026728514833542002963603231101e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.25) { + RealType t = p - static_cast (0.25); + + // Rational Approximation + // Maximum Absolute Error: 5.7633e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.81512108276093787175849069715334402323e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24417080443497141096829831516758083481e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.67006165991083501886186268944009973084e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.74402382755828993223083868408545308340e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.49182541725192134610277727922493871787e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.67273564707254788337557775618297381267e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.73476432616329813096120568871900178919e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31235376166262024838125198332476698090e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.59379285677781413393733801325840617522e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.38151434050794836595564739176884302539e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33534676810383673962443893459127818078e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.38110822236764293910895765875742805411e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.42750073722992463087082849671338957023e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.54255748148299874514839812717054396793e2), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64823387375875361292425741663822893626e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02973633484731117050245517938177308809e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71288209768693917630236009171518272534e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23837527610546426062625864735895938014e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.05056816585729983223036277071927165555e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.48087477651935811184913947280572029967e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04631058325147527913398256133791276127e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69813394441679590721342220435891453447e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.92323371456465893290687995174952942311e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.68542430563281320943284015587559056621e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.17969051793607842221356465819951568080e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82773308760283383020168853159163391394e2), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (p >= 0.125) { + RealType t = p - static_cast (0.125); + + // Rational Approximation + // Maximum Absolute Error: 2.1140e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70276979914029738186601698003670175907e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.63126762626382548478172664328434577553e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04190225271045202674546813475341133174e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.93523974140998850492859698545966806498e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19814006186501010136822066747124777014e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.55931423620290859807616748030589502039e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.78874021192395317496507459296221703565e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.03860533237347587977439662522389465152e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.77882648875352690605815508748162607271e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05498612167816258406694194925933958145e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05326361485692298778330190198630232666e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.85827791876754731187453265804790139032e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.93719378006868242377955041137674308589e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.56839957539576784391036362196229047625e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95604329277359828898502487252547842378e6), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79208640567193066236912382037923299779e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94775812217734059201656828286490832145e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16467934643564936346029555887148320030e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35525720248600096849901920839060920346e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69760913594243328874861534307039589127e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.32330501005950982838953061458838040612e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.79610639577090112327353399739315606205e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.43314292923292828425630915931385776182e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.97538885038058371436244702169375622661e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.48431896958634429210349441846613832681e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93459449030820736960297236799012798749e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.67200014823529787381847745962773726408e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.37035571075060153491151970623824940994e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.22682822001329636071591164177026394518e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09781406768816062486819491582960840983e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 3)); + + // Rational Approximation + // Maximum Relative Error: 1.1409e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25692449785074345466504245009175450649e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75679137667345136118441108839649360362e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06171803174020856964914440692439080669e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.87798066278592051163038122952593080648e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20070543183347459409303407166630392077e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13457391270614708627745403376469848816e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06743974464224003715510181633693539914e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16870984737226212814217822779976770316e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21845093091651861426944931268861694026e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.85357146081877929591916782097540632519e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.19085800299127898508052519062782284785e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41985644250494046067095909812634573318e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30857042700765443668305406695750760693e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.10466412567107519640190849286913680449e-10), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31914248618040435028023418981527961171e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.73578090645412656850163531828709850171e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.57329813782272411333511950903192234311e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62736127875896578315177123764520823372e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76809643836078823237530990091078867553e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32026948719622983920194944841520771986e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.45051018027743807545734050620973716634e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.58281707210621813556068724127478674938e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.63884527227517358294732620995363921547e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15973602356223075515067915930205826229e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.35069439950884795002182517078104942615e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15454119109586223908613596754794988609e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.55273685376557721039847456564342945576e-10), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 1.2521e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[23] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.07341098045260497471001948654506267614e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16518383383878659278973043343250842753e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.10029094208424121908983949243560936013e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.04771840726172284780129819470963100749e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34173170868011689830672637082451998700e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41990262178664512140746911398264330173e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.06779488545758366708787010705581103705e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41892665233583725631482443019441608726e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.20692306716979208762785454648538891867e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.11097906809673639231336894729060830995e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37476591232600886363441107536706973169e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02659053066396720145189153810309784416e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02209877191642023279303996697953314344e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.56663781532392665205516573323950583901e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95655734237060800145227277584749429063e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.06357695252098035545383649954315685077e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.78759045059235560356343893064681290047e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.95881339136963512103591745337914059651e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70156441275519927563064848389865812060e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.99745225746277063516394774908346367811e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.45718440382347867317547921045052714102e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.39027665085346558512961348663034579801e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05739751797738770096482688062542436470e-15), + }; + BOOST_MATH_STATIC const RealType Q[23] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43370372582239919321785765900615222895e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52872159582703775260145036441128318159e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28243735290178057451806192890274584778e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.93375398009812888642212045868197435998e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.73364866677217419593129631900708646445e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53645928499107852437053167521160449434e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74280939589407863107682593092148442428e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80095449855178765594835180574448729793e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.65924845456946706158946250220103271334e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52170861715436344002253767944763106994e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.87246437551620484806338690322735878649e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.88631873230311653853089809596759382095e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.84478812152918182782333415475103623486e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.47998768403859674841488325856607782853e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.82364683269852480160620586102339743788e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.65854316058742127585142691993199177898e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11358340340462071552670838135645042498e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22818744671190957896035448856159685984e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11038729491846772238262374112315536796e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.21355801166652957655438257794658921155e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.41278271853370874105923461404291742454e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95100373579692323015092323646110838623e-15), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 2.0703e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[21] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41774626094491452462664949805613444094e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.96383089261273022706449773421031102175e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.16315295073029174376617863024082371446e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.65377894193914426949840018839915119410e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33210993830236821503160637845009556016e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69315463529653886947182738378630780083e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09869947341518160436616160018702590834e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44331691052908906654005398143769791881e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13131413925652085071882765653750661678e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.64441840437413591336927030249538399459e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78393581596372725434038621824715039765e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.50239319821178575427758224587858938204e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92619647697287767235953207451871137149e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26901081456833267780600560830367533351e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12151768312254597726918329997945574766e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36907507996686107513673694597817437197e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31699373909892506279113260845246144240e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.11230682511893290562864133995544214588e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.44627067257461788044784631155226503036e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39869585157420474301450400944478312794e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.82128612844034824876694595066123093042e-27), + }; + BOOST_MATH_STATIC const RealType Q[20] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65414405277042133067228113526697909557e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32179221250476209346757936207079534440e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.74217392682100275524983756207618144313e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.45810448055940046896534973720645113799e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.81487408603233765436807980794697048675e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49442843848941402948883852684502731460e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66330842256792791665907478718489013963e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93285292223845804061941359223505045576e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.87966347754794288681626114849829710697e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13711644429711675111080150193733607164e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61758862007482013187806625777101452737e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.55435556106272558989915248980090731639e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34166571320580242213843747025082914011e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31411360099525131959755145015018410429e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.21684839228785650625270026640716752452e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.43021096301255274530428188746599779008e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.58831290247776456235908211620983180005e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74309280855806399632683315923592902203e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.58097100528573186098159133443927182780e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 3.4124e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[19] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41926067826974814669251179264786585885e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.21141529920003643675474888047093566280e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59964592861304582755436075901659426485e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.95135112971576806260593571877646426022e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12322024725362032809787183337883163254e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.96758465518847580191799508363466893068e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12389553946694902774213055563291192175e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04599236076217479033545023949602272721e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.16143771174487665823565565218797804931e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.38966874413947625866830582082846088427e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02590325514935982607907975481732376204e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44376747400143802055827426602151525955e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.82088624006657184426589019067893704020e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95757210706845964048697237729100056232e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.36096213291559182424937062842308387702e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14362780521873256616533770657488533993e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73571098395815275003552523759665474105e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47286214854389274681661944885238913581e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.73701196181204039400706651811524874455e-34), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.77119890916406072259446489508263892540e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95177888809731859578167185583119074026e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.29131027214559081111011582466619105016e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31442657037887347262737789825299661237e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83928863984637222329515960387531101267e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07389089078167127136964851949662391744e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93013847797006474150589676891548600820e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50600573851533884594030683413819219915e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94539484213971921794449107859541806317e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.58360895032645281635534287874266252341e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66414102108217999886628042310332365446e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07411076181287950822375436854492998754e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61224937285582228022463072515935601355e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.89242339209389981530783624934733098598e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11030225010379194015550512905872992373e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20285566539355859922818448335043495666e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71782855576364068752705740544460766362e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 2.1680e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.41926070139289008206183757488364846894e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.78434820569480998586988738136492447574e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07939171933509333571821660328723436210e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.92438439347811482522082798370060349739e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24288918322433485413615362874371441367e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04437759300344740815274986587186340509e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74063952231188399929705762263485071234e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07228849610363181194047955109059900544e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93120850707001212714821992328252707694e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40911049607879914351205073608184243057e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71898232013947717725198847649536278438e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06963706982203753050300400912657068823e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.79849166632277658631839126599110199710e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.74682085785152276503345630444792840850e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09650236336641219916377836114077389212e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97326394822836529817663710792553753811e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.26635728806398747570910072594323836441e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.96470010392255781222480229189380065951e-18), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.82841492468725267177870050157374330523e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83703946702662950408034486958999188355e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09320896703777230915306208582393356690e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29346630787642344947323515884281464979e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77242894492599243245354774839232776944e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05722029871614922850936250945431594997e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.66920224988248720006255827987385374411e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.40887155754772190509572243444386095560e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44545968319921473942351968892623238920e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.17198676140022989760684932594389017027e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97376935482567419865730773801543995320e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06997835790265899882151030367297786861e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.06862653266619706928282319356971834957e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02334307903766790059473763725329176667e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.33174535634931487079630169746402085699e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70989324903345102377898775620363767855e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.47067260145014475572799216996976703615e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * cbrt(p * p)); + } + else { + RealType p_square = p * p; + + if ((boost::math::isnormal)(p_square)) { + result = 1 / cbrt(p_square * constants::two_pi()); + } + else if (p > 0) { + result = 1 / (cbrt(p) * cbrt(p) * cbrt(constants::two_pi())); + } + else { + result = boost::math::numeric_limits::infinity(); + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? mapairy_quantile_upper_imp_prec(1 - p, tag) : mapairy_quantile_lower_imp_prec(1 - p, tag); + } + + return complement ? mapairy_quantile_upper_imp_prec(p, tag) : mapairy_quantile_lower_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? mapairy_quantile_upper_imp_prec(1 - p, tag) : mapairy_quantile_lower_imp_prec(1 - p, tag); + } + + return complement ? mapairy_quantile_upper_imp_prec(p, tag) : mapairy_quantile_lower_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_quantile_imp(const mapairy_distribution& dist, const RealType& p, bool complement) +{ + // This routine implements the quantile for the Map-Airy distribution, + // the value p may be the probability, or its complement if complement=true. + + constexpr auto function = "boost::math::quantile(mapairy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * mapairy_quantile_imp_prec(p, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_mode_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(-1.16158727113597068525); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_mode_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.1615872711359706852500000803029112987); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_mode_imp(const mapairy_distribution& dist) +{ + // This implements the mode for the Map-Airy distribution, + + constexpr auto function = "boost::math::mode(mapairy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * mapairy_mode_imp_prec(tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_median_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(-0.71671068545502205332); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_median_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, -0.71671068545502205331700196278067230944440); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_median_imp(const mapairy_distribution& dist) +{ + // This implements the median for the Map-Airy distribution, + + constexpr auto function = "boost::math::median(mapairy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * mapairy_median_imp_prec(tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_entropy_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(2.00727681841065634600); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_entropy_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.0072768184106563460003025875575283708); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mapairy_entropy_imp(const mapairy_distribution& dist) +{ + // This implements the entropy for the Map-Airy distribution, + + constexpr auto function = "boost::math::entropy(mapairy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The Map-Airy distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = mapairy_entropy_imp_prec(tag_type()) + log(scale); + + return result; +} + +} // detail + +template > +class mapairy_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED mapairy_distribution(RealType l_location = 0, RealType l_scale = 1) + : mu(l_location), c(l_scale) + { + constexpr auto function = "boost::math::mapairy_distribution<%1%>::mapairy_distribution"; + RealType result = 0; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + } // mapairy_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return mu; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return c; + } + + private: + RealType mu; // The location parameter. + RealType c; // The scale parameter. +}; + +typedef mapairy_distribution mapairy; + +#ifdef __cpp_deduction_guides +template +mapairy_distribution(RealType) -> mapairy_distribution::type>; +template +mapairy_distribution(RealType, RealType) -> mapairy_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const mapairy_distribution&) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const mapairy_distribution&) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const mapairy_distribution& dist, const RealType& x) +{ + return detail::mapairy_pdf_imp(dist, x); +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const mapairy_distribution& dist, const RealType& x) +{ + return detail::mapairy_cdf_imp(dist, x, false); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const mapairy_distribution& dist, const RealType& p) +{ + return detail::mapairy_quantile_imp(dist, p, false); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::mapairy_cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::mapairy_quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const mapairy_distribution &dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const mapairy_distribution& /*dist*/) +{ + return boost::math::numeric_limits::infinity(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const mapairy_distribution& dist) +{ + return detail::mapairy_mode_imp(dist); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const mapairy_distribution& dist) +{ + return detail::mapairy_median_imp(dist); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const mapairy_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Map-Airy Distribution has no skewness"); + + return policies::raise_domain_error( + "boost::math::skewness(mapairy<%1%>&)", + "The Map-Airy distribution does not have a skewness: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const mapairy_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Map-Airy Distribution has no kurtosis"); + + return policies::raise_domain_error( + "boost::math::kurtosis(mapairy<%1%>&)", + "The Map-Airy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const mapairy_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Map-Airy Distribution has no kurtosis excess"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(mapairy<%1%>&)", + "The Map-Airy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const mapairy_distribution& dist) +{ + return detail::mapairy_entropy_imp(dist); +} + +}} // namespaces + + +#endif // BOOST_STATS_MAPAIRY_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/negative_binomial.hpp b/third-party/boost-math/include/boost/math/distributions/negative_binomial.hpp new file mode 100644 index 0000000000000..f520c94803900 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/negative_binomial.hpp @@ -0,0 +1,609 @@ +// boost\math\special_functions\negative_binomial.hpp + +// Copyright Paul A. Bristow 2007. +// Copyright John Maddock 2007. + +// 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) + +// http://en.wikipedia.org/wiki/negative_binomial_distribution +// http://mathworld.wolfram.com/NegativeBinomialDistribution.html +// http://documents.wolfram.com/teachersedition/Teacher/Statistics/DiscreteDistributions.html + +// The negative binomial distribution NegativeBinomialDistribution[n, p] +// is the distribution of the number (k) of failures that occur in a sequence of trials before +// r successes have occurred, where the probability of success in each trial is p. + +// In a sequence of Bernoulli trials or events +// (independent, yes or no, succeed or fail) with success_fraction probability p, +// negative_binomial is the probability that k or fewer failures +// precede the r th trial's success. +// random variable k is the number of failures (NOT the probability). + +// Negative_binomial distribution is a discrete probability distribution. +// But note that the negative binomial distribution +// (like others including the binomial, Poisson & Bernoulli) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. + +// However, by default the policy is to use discrete_quantile_policy. + +// To enforce the strict mathematical model, users should use conversion +// on k outside this function to ensure that k is integral. + +// MATHCAD cumulative negative binomial pnbinom(k, n, p) + +// Implementation note: much greater speed, and perhaps greater accuracy, +// might be achieved for extreme values by using a normal approximation. +// This is NOT been tested or implemented. + +#ifndef BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP +#define BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP + +#include +#include +#include +#include +#include +#include // for ibeta(a, b, x) == Ix(a, b). +#include // complement. +#include // error checks domain_error & logic_error. +#include // isnan. +#include // for root finding. +#include +#include + +#if defined (BOOST_MSVC) +# pragma warning(push) +// This believed not now necessary, so commented out. +//# pragma warning(disable: 4702) // unreachable code. +// in domain_error_imp in error_handling. +#endif + +namespace boost +{ + namespace math + { + namespace negative_binomial_detail + { + // Common error checking routines for negative binomial distribution functions: + template + BOOST_MATH_GPU_ENABLED inline bool check_successes(const char* function, const RealType& r, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(r) || (r <= 0) ) + { + *result = policies::raise_domain_error( + function, + "Number of successes argument is %1%, but must be > 0 !", r, pol); + return false; + } + return true; + } + template + BOOST_MATH_GPU_ENABLED inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) ) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& r, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction(function, p, result, pol) + && check_successes(function, r, result, pol); + } + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_k(const char* function, const RealType& r, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, r, p, result, pol) == false) + { + return false; + } + if( !(boost::math::isfinite)(k) || (k < 0) ) + { // Check k failures. + *result = policies::raise_domain_error( + function, + "Number of failures argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // Check_dist_and_k + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + { + return false; + } + return true; + } // check_dist_and_prob + } // namespace negative_binomial_detail + + template > + class negative_binomial_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED negative_binomial_distribution(RealType r, RealType p) : m_r(r), m_p(p) + { // Constructor. + RealType result; + negative_binomial_detail::check_dist( + "negative_binomial_distribution<%1%>::negative_binomial_distribution", + m_r, // Check successes r > 0. + m_p, // Check success_fraction 0 <= p <= 1. + &result, Policy()); + } // negative_binomial_distribution constructor. + + // Private data getter class member functions. + BOOST_MATH_GPU_ENABLED RealType success_fraction() const + { // Probability of success as fraction in range 0 to 1. + return m_p; + } + BOOST_MATH_GPU_ENABLED RealType successes() const + { // Total number of successes r. + return m_r; + } + + BOOST_MATH_GPU_ENABLED static RealType find_lower_bound_on_p( + RealType trials, + RealType successes, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + constexpr auto function = "boost::math::negative_binomial<%1%>::find_lower_bound_on_p"; + RealType result = 0; // of error checks. + RealType failures = trials - successes; + if(false == detail::check_probability(function, alpha, &result, Policy()) + && negative_binomial_detail::check_dist_and_k( + function, successes, RealType(0), failures, &result, Policy())) + { + return result; + } + // Use complement ibeta_inv function for lower bound. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibeta_inv(successes, failures + 1, alpha, static_cast(nullptr), Policy()); + } // find_lower_bound_on_p + + BOOST_MATH_GPU_ENABLED static RealType find_upper_bound_on_p( + RealType trials, + RealType successes, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + constexpr auto function = "boost::math::negative_binomial<%1%>::find_upper_bound_on_p"; + RealType result = 0; // of error checks. + RealType failures = trials - successes; + if(false == negative_binomial_detail::check_dist_and_k( + function, successes, RealType(0), failures, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + if(failures == 0) + return 1; + // Use complement ibetac_inv function for upper bound. + // Note adjusted failures value: *not* failures+1 as usual. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibetac_inv(successes, failures, alpha, static_cast(nullptr), Policy()); + } // find_upper_bound_on_p + + // Estimate number of trials : + // "How many trials do I need to be P% sure of seeing k or fewer failures?" + + BOOST_MATH_GPU_ENABLED static RealType find_minimum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + constexpr auto function = "boost::math::negative_binomial<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, RealType(1), p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { return result; } + + result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_failures + + BOOST_MATH_GPU_ENABLED static RealType find_maximum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + constexpr auto function = "boost::math::negative_binomial<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, RealType(1), p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { return result; } + + result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_trials complemented + + private: + RealType m_r; // successes. + RealType m_p; // success_fraction + }; // template class negative_binomial_distribution + + typedef negative_binomial_distribution negative_binomial; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + negative_binomial_distribution(RealType,RealType)->negative_binomial_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const negative_binomial_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // max_integer? + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const negative_binomial_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // max_integer? + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const negative_binomial_distribution& dist) + { // Mean of Negative Binomial distribution = r(1-p)/p. + return dist.successes() * (1 - dist.success_fraction() ) / dist.success_fraction(); + } // mean + + //template + //inline RealType median(const negative_binomial_distribution& dist) + //{ // Median of negative_binomial_distribution is not defined. + // return policies::raise_domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + // Now implemented via quantile(half) in derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const negative_binomial_distribution& dist) + { // Mode of Negative Binomial distribution = floor[(r-1) * (1 - p)/p] + BOOST_MATH_STD_USING // ADL of std functions. + return floor((dist.successes() -1) * (1 - dist.success_fraction()) / dist.success_fraction()); + } // mode + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const negative_binomial_distribution& dist) + { // skewness of Negative Binomial distribution = 2-p / (sqrt(r(1-p)) + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + + return (2 - p) / + sqrt(r * (1 - p)); + } // skewness + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const negative_binomial_distribution& dist) + { // kurtosis of Negative Binomial distribution + // http://en.wikipedia.org/wiki/Negative_binomial is kurtosis_excess so add 3 + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + return 3 + (6 / r) + ((p * p) / (r * (1 - p))); + } // kurtosis + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const negative_binomial_distribution& dist) + { // kurtosis excess of Negative Binomial distribution + // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + return (6 - p * (6-p)) / (r * (1-p)); + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const negative_binomial_distribution& dist) + { // Variance of Binomial distribution = r (1-p) / p^2. + return dist.successes() * (1 - dist.success_fraction()) + / (dist.success_fraction() * dist.success_fraction()); + } // variance + + // RealType standard_deviation(const negative_binomial_distribution& dist) + // standard_deviation provided by derived accessors. + // RealType hazard(const negative_binomial_distribution& dist) + // hazard of Negative Binomial distribution provided by derived accessors. + // RealType chf(const negative_binomial_distribution& dist) + // chf of Negative Binomial distribution provided by derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const negative_binomial_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + constexpr auto function = "boost::math::pdf(const negative_binomial_distribution<%1%>&, %1%)"; + + RealType r = dist.successes(); + RealType p = dist.success_fraction(); + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + result = (p/(r + k)) * ibeta_derivative(r, static_cast(k+1), p, Policy()); + // Equivalent to: + // return exp(lgamma(r + k) - lgamma(r) - lgamma(k+1)) * pow(p, r) * pow((1-p), k); + return result; + } // negative_binomial_pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const negative_binomial_distribution& dist, const RealType& k) + { // Cumulative Distribution Function of Negative Binomial. + constexpr auto function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)"; + using boost::math::ibeta; // Regularized incomplete beta function. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Error check: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + RealType probability = ibeta(r, static_cast(k+1), p, Policy()); + // Ip(r, k+1) = ibeta(r, k+1, p) + return probability; + } // cdf Cumulative Distribution Function Negative Binomial. + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Negative Binomial. + + constexpr auto function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)"; + using boost::math::ibetac; // Regularized incomplete beta function complement. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType const& k = c.param; + negative_binomial_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Error check: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + p, + k, + &result, Policy())) + { + return result; + } + // Calculate cdf negative binomial using the incomplete beta function. + // Use of ibeta here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // Ip(k+1, r) = ibetac(r, k+1, p) + // constrain_probability here? + RealType probability = ibetac(r, static_cast(k+1), p, Policy()); + // Numerical errors might cause probability to be slightly outside the range < 0 or > 1. + // This might cause trouble downstream, so warn, possibly throw exception, but constrain to the limits. + return probability; + } // cdf Cumulative Distribution Function Negative Binomial. + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const negative_binomial_distribution& dist, const RealType& P) + { // Quantile, percentile/100 or Percent Point Negative Binomial function. + // Return the number of expected failures k for a given probability p. + + // Inverse cumulative Distribution Function or Quantile (percentile / 100) of negative_binomial Probability. + // MAthCAD pnbinom return smallest k such that negative_binomial(k, n, p) >= probability. + // k argument may be integral, signed, or unsigned, or floating point. + // BUT Cephes/CodeCogs says: finds argument p (0 to 1) such that cdf(k, n, p) = y + constexpr auto function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING // ADL of std functions. + + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Check dist and P. + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_prob + (function, r, p, P, &result, Policy())) + { + return result; + } + + // Special cases. + if (P == 1) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument is 1, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (P == 0) + { // No failures are expected if P = 0. + return 0; // Total trials will be just dist.successes. + } + if (P <= pow(dist.success_fraction(), dist.successes())) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + if(p == 0) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Success fraction is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + /* + // Calculate quantile of negative_binomial using the inverse incomplete beta function. + using boost::math::ibeta_invb; + return ibeta_invb(r, p, P, Policy()) - 1; // + */ + RealType guess = 0; + RealType factor = 5; + if(r * r * r * P * p > 0.005) + guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), P, RealType(1-P), Policy()); + + if(guess < 10) + { + // + // Cornish-Fisher Negative binomial approximation not accurate in this area: + // + guess = BOOST_MATH_GPU_SAFE_MIN(RealType(r * 2), RealType(10)); + } + else + factor = (1-P < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + typedef typename Policy::discrete_quantile_type discrete_type; + return detail::inverse_discrete_quantile( + dist, + P, + false, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // RealType quantile(const negative_binomial_distribution dist, p) + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point Binomial function. + // Return the number of expected failures k for a given + // complement of the probability Q = 1 - P. + constexpr auto function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING + + // Error checks: + RealType Q = c.param; + const negative_binomial_distribution& dist = c.dist; + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_prob( + function, + r, + p, + Q, + &result, Policy())) + { + return result; + } + + // Special cases: + // + if(Q == 1) + { // There may actually be no answer to this question, + // since the probability of zero failures may be non-zero, + return 0; // but zero is the best we can do: + } + if(Q == 0) + { // Probability 1 - Q == 1 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument complement is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (-Q <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy())) + { // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 0; // + } + if(p == 0) + { // Success fraction is 0 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Success fraction is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + //return ibetac_invb(r, p, Q, Policy()) -1; + RealType guess = 0; + RealType factor = 5; + if(r * r * r * (1-Q) * p > 0.005) + guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), RealType(1-Q), Q, Policy()); + + if(guess < 10) + { + // + // Cornish-Fisher Negative binomial approximation not accurate in this area: + // + guess = BOOST_MATH_GPU_SAFE_MIN(RealType(r * 2), RealType(10)); + } + else + factor = (Q < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + typedef typename Policy::discrete_quantile_type discrete_type; + return detail::inverse_discrete_quantile( + dist, + Q, + true, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/non_central_beta.hpp b/third-party/boost-math/include/boost/math/distributions/non_central_beta.hpp new file mode 100644 index 0000000000000..f311f77737c17 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/non_central_beta.hpp @@ -0,0 +1,977 @@ +// boost\math\distributions\non_central_beta.hpp + +// Copyright John Maddock 2008. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP + +#include +#include +#include +#include +#include +#include // for incomplete gamma. gamma_q +#include // complements +#include // central distribution +#include +#include // error checks +#include // isnan. +#include +#include // for root finding. +#include +#include + +namespace boost +{ + namespace math + { + + template + class non_central_beta_distribution; + + namespace detail{ + + template + BOOST_MATH_GPU_ENABLED T non_central_beta_p(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0) + { + BOOST_MATH_STD_USING + using namespace boost::math; + // + // Variables come first: + // + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, + // note that unlike other similar code, we do not set + // k to zero, when l2 is small, as forward iteration + // is unstable: + // + long long k = lltrunc(l2); + if(k == 0) + k = 1; + // Starting Poisson weight: + T pois = gamma_p_derivative(T(k+1), l2, pol); + if(pois == 0) + return init_val; + // recurance term: + T xterm; + // Starting beta term: + T beta = x < y + ? detail::ibeta_imp(T(a + k), b, x, pol, false, true, &xterm) + : detail::ibeta_imp(b, T(a + k), y, pol, true, true, &xterm); + + while (fabs(beta * pois) < tools::min_value()) + { + if ((k == 0) || (pois == 0)) + return init_val; + k /= 2; + pois = gamma_p_derivative(T(k + 1), l2, pol); + beta = x < y + ? detail::ibeta_imp(T(a + k), b, x, pol, false, true, &xterm) + : detail::ibeta_imp(b, T(a + k), y, pol, true, true, &xterm); + } + + xterm *= y / (a + b + k - 1); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + + if((beta == 0) && (xterm == 0)) + return init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + T last_term = 0; + boost::math::uintmax_t count = k; + for(auto i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + if(((fabs(term/sum) < errtol) && (fabs(last_term) >= fabs(term))) || (term == 0)) + { + count = k - i; + break; + } + pois *= i / l2; + beta += xterm; + + if (a + b + i != 2) + { + xterm *= (a + i - 1) / (x * (a + b + i - 2)); + } + + last_term = term; + } + last_term = 0; + for(auto i = k + 1; ; ++i) + { + poisf *= l2 / i; + xtermf *= (x * (a + b + i - 2)) / (a + i - 1); + betaf -= xtermf; + + T term = poisf * betaf; + sum += term; + if(((fabs(term/sum) < errtol) && (fabs(last_term) >= fabs(term))) || (term == 0)) + { + break; + } + last_term = term; + if(static_cast(count + i - k) > max_iter) + { + return policies::raise_evaluation_error("cdf(non_central_beta_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + } + return sum; + } + + template + BOOST_MATH_GPU_ENABLED T non_central_beta_q(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0) + { + BOOST_MATH_STD_USING + using namespace boost::math; + // + // Variables come first: + // + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + long long k = lltrunc(l2); + T pois; + if(k <= 30) + { + // + // Might as well start at 0 since we'll likely have this number of terms anyway: + // + if(a + b > 1) + k = 0; + else if(k == 0) + k = 1; + } + if(k == 0) + { + // Starting Poisson weight: + pois = exp(-l2); + } + else + { + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), l2, pol); + } + if(pois == 0) + return init_val; + // recurance term: + T xterm; + // Starting beta term: + T beta = x < y + ? detail::ibeta_imp(T(a + k), b, x, pol, true, true, &xterm) + : detail::ibeta_imp(b, T(a + k), y, pol, false, true, &xterm); + + xterm *= y / (a + b + k - 1); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((beta == 0) && (xterm == 0)) + return init_val; + // + // Forwards recursion first, this is the stable + // direction for recursion, and the location + // of the bulk of the sum: + // + T last_term = 0; + boost::math::uintmax_t count = 0; + for(long long i = k + 1; ; ++i) + { + poisf *= l2 / i; + xtermf *= (x * (a + b + (i - 2))) / (a + (i - 1)); + betaf += xtermf; + + T term = poisf * betaf; + sum += term; + if((fabs(term/sum) < errtol) && (last_term >= term)) + { + count = i - k; + break; + } + if(static_cast(i - k) > max_iter) + { + return policies::raise_evaluation_error("cdf(non_central_beta_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + last_term = term; + } + for(auto i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + if(fabs(term/sum) < errtol) + { + break; + } + if(static_cast(count + k - i) > max_iter) + { + return policies::raise_evaluation_error("cdf(non_central_beta_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + pois *= i / l2; + beta -= xterm; + if (a + b + i - 2 != 0) + { + xterm *= (a + i - 1) / (x * (a + b + i - 2)); + } + } + return sum; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType non_central_beta_cdf(RealType x, RealType y, RealType a, RealType b, RealType l, bool invert, const Policy&) + { + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + + if(x == 0) + return invert ? 1.0f : 0.0f; + if(y == 0) + return invert ? 0.0f : 1.0f; + value_type result; + value_type c = a + b + l / 2; + value_type cross = 1 - (b / c) * (1 + l / (2 * c * c)); + if(l == 0) + result = cdf(boost::math::beta_distribution(a, b), x); + else if(x > cross) + { + // Complement is the smaller of the two: + result = detail::non_central_beta_q( + static_cast(a), + static_cast(b), + static_cast(l), + static_cast(x), + static_cast(y), + forwarding_policy(), + static_cast(invert ? 0 : -1)); + invert = !invert; + } + else + { + result = detail::non_central_beta_p( + static_cast(a), + static_cast(b), + static_cast(l), + static_cast(x), + static_cast(y), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + if(invert) + result = -result; + return policies::checked_narrowing_cast( + result, + "boost::math::non_central_beta_cdf<%1%>(%1%, %1%, %1%)"); + } + + template + struct nc_beta_quantile_functor + { + BOOST_MATH_GPU_ENABLED nc_beta_quantile_functor(const non_central_beta_distribution& d, T t, bool c) + : dist(d), target(t), comp(c) {} + + BOOST_MATH_GPU_ENABLED T operator()(const T& x) + { + return comp ? + T(target - cdf(complement(dist, x))) + : T(cdf(dist, x) - target); + } + + private: + non_central_beta_distribution dist; + T target; + bool comp; + }; + + // + // This is more or less a copy of bracket_and_solve_root, but + // modified to search only the interval [0,1] using similar + // heuristics. + // + template + BOOST_MATH_GPU_ENABLED boost::math::pair bracket_and_solve_root_01(F f, const T& guess, T factor, bool rising, Tol tol, boost::math::uintmax_t& max_iter, const Policy& pol) + { + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::tools::bracket_and_solve_root_01<%1%>"; + // + // Set up initial brackets: + // + T a = guess; + T b = a; + T fa = f(a); + T fb = fa; + // + // Set up invocation count: + // + boost::math::uintmax_t count = max_iter - 1; + + if((fa < 0) == (guess < 0 ? !rising : rising)) + { + // + // Zero is to the right of b, so walk upwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(count == 0) + { + b = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol); // LCOV_EXCL_LINE + return boost::math::make_pair(a, b); + } + // + // Heuristic: every 20 iterations we double the growth factor in case the + // initial guess was *really* bad ! + // + if((max_iter - count) % 20 == 0) + factor *= 2; + // + // Now go ahead and move are guess by "factor", + // we do this by reducing 1-guess by factor: + // + a = b; + fa = fb; + b = 1 - ((1 - b) / factor); + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return a > 0 ? boost::math::make_pair(T(0), T(a)) : boost::math::make_pair(T(a), T(0)); + } + if(count == 0) + { + a = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol); // LCOV_EXCL_LINE + return boost::math::make_pair(a, b); + } + // + // Heuristic: every 20 iterations we double the growth factor in case the + // initial guess was *really* bad ! + // + if((max_iter - count) % 20 == 0) + factor *= 2; + // + // Now go ahead and move are guess by "factor": + // + b = a; + fb = fa; + a /= factor; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + max_iter -= count; + max_iter += 1; + boost::math::pair r = toms748_solve( + f, + (a < 0 ? b : a), + (a < 0 ? a : b), + (a < 0 ? fb : fa), + (a < 0 ? fa : fb), + tol, + count, + pol); + max_iter += count; + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + return r; + } + + template + BOOST_MATH_GPU_ENABLED RealType nc_beta_quantile(const non_central_beta_distribution& dist, const RealType& p, bool comp) + { + constexpr auto function = "quantile(non_central_beta_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type a = dist.alpha(); + value_type b = dist.beta(); + value_type l = dist.non_centrality(); + value_type r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_probability( + function, + static_cast(p), + &r, + Policy())) + return static_cast(r); + // + // Special cases first: + // + if(p == 0) + return comp + ? 1.0f + : 0.0f; + if(p == 1) + return !comp + ? 1.0f + : 0.0f; + + value_type c = a + b + l / 2; + value_type mean = 1 - (b / c) * (1 + l / (2 * c * c)); + /* + // + // Calculate a normal approximation to the quantile, + // uses mean and variance approximations from: + // Algorithm AS 310: + // Computing the Non-Central Beta Distribution Function + // R. Chattamvelli; R. Shanmugam + // Applied Statistics, Vol. 46, No. 1. (1997), pp. 146-156. + // + // Unfortunately, when this is wrong it tends to be *very* + // wrong, so it's disabled for now, even though it often + // gets the initial guess quite close. Probably we could + // do much better by factoring in the skewness if only + // we could calculate it.... + // + value_type delta = l / 2; + value_type delta2 = delta * delta; + value_type delta3 = delta * delta2; + value_type delta4 = delta2 * delta2; + value_type G = c * (c + 1) + delta; + value_type alpha = a + b; + value_type alpha2 = alpha * alpha; + value_type eta = (2 * alpha + 1) * (2 * alpha + 1) + 1; + value_type H = 3 * alpha2 + 5 * alpha + 2; + value_type F = alpha2 * (alpha + 1) + H * delta + + (2 * alpha + 4) * delta2 + delta3; + value_type P = (3 * alpha + 1) * (9 * alpha + 17) + + 2 * alpha * (3 * alpha + 2) * (3 * alpha + 4) + 15; + value_type Q = 54 * alpha2 + 162 * alpha + 130; + value_type R = 6 * (6 * alpha + 11); + value_type D = delta + * (H * H + 2 * P * delta + Q * delta2 + R * delta3 + 9 * delta4); + value_type variance = (b / G) + * (1 + delta * (l * l + 3 * l + eta) / (G * G)) + - (b * b / F) * (1 + D / (F * F)); + value_type sd = sqrt(variance); + + value_type guess = comp + ? quantile(complement(normal_distribution(static_cast(mean), static_cast(sd)), p)) + : quantile(normal_distribution(static_cast(mean), static_cast(sd)), p); + + if(guess >= 1) + guess = mean; + if(guess <= tools::min_value()) + guess = mean; + */ + value_type guess = mean; + detail::nc_beta_quantile_functor + f(non_central_beta_distribution(a, b, l), p, comp); + tools::eps_tolerance tol(policies::digits()); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + + boost::math::pair ir + = bracket_and_solve_root_01( + f, guess, value_type(2.5), true, tol, + max_iter, Policy()); + value_type result = ir.first + (ir.second - ir.first) / 2; + + if(max_iter >= policies::get_max_root_iterations()) + { + // LCOV_EXCL_START + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " either there is no answer to quantile of the non central beta distribution" + " or the answer is infinite. Current best guess is %1%", + policies::checked_narrowing_cast( + result, + function), Policy()); + // LCOV_EXCL_STOP + } + return policies::checked_narrowing_cast( + result, + function); + } + + template + BOOST_MATH_GPU_ENABLED T non_central_beta_pdf(T a, T b, T lam, T x, T y, const Policy& pol) + { + BOOST_MATH_STD_USING + // + // Special cases: + // + if((x == 0) || (y == 0)) + return 0; + // + // Variables come first: + // + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + long long k = lltrunc(l2); + // Starting Poisson weight: + T pois = gamma_p_derivative(T(k+1), l2, pol); + // Starting beta term: + T beta = x < y ? + ibeta_derivative(a + k, b, x, pol) + : ibeta_derivative(b, a + k, y, pol); + + while (fabs(beta * pois) < tools::min_value()) + { + if ((k == 0) || (pois == 0)) + return 0; // Nothing else we can do! + // + // We only get here when a+k and b are large and x is small, + // in that case reduce k (bisect) until both terms are finite: + // + k /= 2; + pois = gamma_p_derivative(T(k + 1), l2, pol); + // Starting beta term: + beta = x < y ? + ibeta_derivative(a + k, b, x, pol) + : ibeta_derivative(b, a + k, y, pol); + } + + + T sum = 0; + T poisf(pois); + T betaf(beta); + + // + // Stable backwards recursion first: + // + boost::math::uintmax_t count = k; + T ratio = 0; + T old_ratio = 0; + for(auto i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + ratio = fabs(term / sum); + if(((ratio < errtol) && (ratio < old_ratio)) || (term == 0)) + { + count = k - i; + break; + } + ratio = old_ratio; + pois *= i / l2; + + if (a + b + i != 1) + { + beta *= (a + i - 1) / (x * (a + i + b - 1)); + } + } + old_ratio = 0; + for(auto i = k + 1; ; ++i) + { + poisf *= l2 / i; + betaf *= x * (a + b + i - 1) / (a + i - 1); + + T term = poisf * betaf; + sum += term; + ratio = fabs(term / sum); + if(((ratio < errtol) && (ratio < old_ratio)) || (term == 0)) + { + break; + } + old_ratio = ratio; + if(static_cast(count + i - k) > max_iter) + { + return policies::raise_evaluation_error("pdf(non_central_beta_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + } + return sum; + } + + template + BOOST_MATH_GPU_ENABLED RealType nc_beta_pdf(const non_central_beta_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING + constexpr auto function = "pdf(non_central_beta_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type a = dist.alpha(); + value_type b = dist.beta(); + value_type l = dist.non_centrality(); + value_type r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + static_cast(x), + &r, + Policy())) + return static_cast(r); + + if(l == 0) + return pdf(boost::math::beta_distribution(dist.alpha(), dist.beta()), x); + return policies::checked_narrowing_cast( + non_central_beta_pdf(a, b, l, static_cast(x), value_type(1 - static_cast(x)), forwarding_policy()), + "function"); + } + + template + struct hypergeometric_2F2_sum + { + typedef T result_type; + BOOST_MATH_GPU_ENABLED hypergeometric_2F2_sum(T a1_, T a2_, T b1_, T b2_, T z_) : a1(a1_), a2(a2_), b1(b1_), b2(b2_), z(z_), term(1), k(0) {} + BOOST_MATH_GPU_ENABLED T operator()() + { + T result = term; + term *= a1 * a2 / (b1 * b2); + a1 += 1; + a2 += 1; + b1 += 1; + b2 += 1; + k += 1; + term /= k; + term *= z; + return result; + } + T a1, a2, b1, b2, z, term, k; + }; + + template + BOOST_MATH_GPU_ENABLED T hypergeometric_2F2(T a1, T a2, T b1, T b2, T z, const Policy& pol) + { + typedef typename policies::evaluation::type value_type; + + const char* function = "boost::math::detail::hypergeometric_2F2<%1%>(%1%,%1%,%1%,%1%,%1%)"; + + hypergeometric_2F2_sum s(a1, a2, b1, b2, z); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + value_type result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return policies::checked_narrowing_cast(result, function); + } + + } // namespace detail + + template > + class non_central_beta_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED non_central_beta_distribution(RealType a_, RealType b_, RealType lambda) : a(a_), b(b_), ncp(lambda) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::non_central_beta_distribution(%1%,%1%)"; + RealType r; + beta_detail::check_alpha( + function, + a, &r, Policy()); + beta_detail::check_beta( + function, + b, &r, Policy()); + detail::check_non_centrality( + function, + lambda, + &r, + Policy()); + } // non_central_beta_distribution constructor. + + BOOST_MATH_GPU_ENABLED RealType alpha() const + { // Private data getter function. + return a; + } + BOOST_MATH_GPU_ENABLED RealType beta() const + { // Private data getter function. + return b; + } + BOOST_MATH_GPU_ENABLED RealType non_centrality() const + { // Private data getter function. + return ncp; + } + private: + // Data member, initialized by constructor. + RealType a; // alpha. + RealType b; // beta. + RealType ncp; // non-centrality parameter + }; // template class non_central_beta_distribution + + typedef non_central_beta_distribution non_central_beta; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_beta_distribution(RealType,RealType,RealType)->non_central_beta_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const non_central_beta_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const non_central_beta_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), static_cast(1)); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const non_central_beta_distribution& dist) + { // mode. + constexpr auto function = "mode(non_central_beta_distribution<%1%> const&)"; + + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + RealType c = a + b + l / 2; + RealType mean = 1 - (b / c) * (1 + l / (2 * c * c)); + return detail::generic_find_mode_01( + dist, + mean, + function); + } + + // + // We don't have the necessary information to implement + // these at present. These are just disabled for now, + // prototypes retained so we can fill in the blanks + // later: + // + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const non_central_beta_distribution& dist) + { + BOOST_MATH_STD_USING + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType d = dist.non_centrality(); + RealType apb = a + b; + return exp(-d / 2) * a * detail::hypergeometric_2F2(1 + a, apb, a, 1 + apb, d / 2, Policy()) / apb; + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const non_central_beta_distribution& dist) + { + // + // Relative error of this function may be arbitrarily large... absolute + // error will be small however... that's the best we can do for now. + // + BOOST_MATH_STD_USING + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType d = dist.non_centrality(); + RealType apb = a + b; + RealType result = detail::hypergeometric_2F2(RealType(1 + a), apb, a, RealType(1 + apb), RealType(d / 2), Policy()); + result *= result * -exp(-d) * a * a / (apb * apb); + result += exp(-d / 2) * a * (1 + a) * detail::hypergeometric_2F2(RealType(2 + a), apb, a, RealType(2 + apb), RealType(d / 2), Policy()) / (apb * (1 + apb)); + return result; + } + + // RealType standard_deviation(const non_central_beta_distribution& dist) + // standard_deviation provided by derived accessors. + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const non_central_beta_distribution& /*dist*/) + { // skewness = sqrt(l). + const char* function = "boost::math::non_central_beta_distribution<%1%>::skewness()"; + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Non Central Beta Distribution has no skewness."); + + return policies::raise_evaluation_error(function, "This function is not yet implemented, the only sensible result is %1%.", // LCOV_EXCL_LINE + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? LCOV_EXCL_LINE + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const non_central_beta_distribution& /*dist*/) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::kurtosis_excess()"; + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The Non Central Beta Distribution has no kurtosis excess."); + + return policies::raise_evaluation_error(function, "This function is not yet implemented, the only sensible result is %1%.", // LCOV_EXCL_LINE + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? LCOV_EXCL_LINE + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const non_central_beta_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const non_central_beta_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + return detail::nc_beta_pdf(dist, x); + } // pdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const non_central_beta_distribution& dist, const RealType& x) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)"; + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + x, + &r, + Policy())) + return static_cast(r); + + if(l == 0) + return cdf(beta_distribution(a, b), x); + + return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, false, Policy()); + } // cdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)"; + non_central_beta_distribution const& dist = c.dist; + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType x = c.param; + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + x, + &r, + Policy())) + return static_cast(r); + + if(l == 0) + return cdf(complement(beta_distribution(a, b), x)); + + return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, true, Policy()); + } // ccdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const non_central_beta_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + return detail::nc_beta_quantile(dist, p, false); + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + return detail::nc_beta_quantile(c.dist, c.param, true); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/non_central_chi_squared.hpp b/third-party/boost-math/include/boost/math/distributions/non_central_chi_squared.hpp new file mode 100644 index 0000000000000..5917b3732d864 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/non_central_chi_squared.hpp @@ -0,0 +1,998 @@ +// boost\math\distributions\non_central_chi_squared.hpp + +// Copyright John Maddock 2008. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP + +#include +#include +#include +#include +#include +#include // for incomplete gamma. gamma_q +#include // for cyl_bessel_i +#include // for llround +#include // complements +#include // central distribution +#include // error checks +#include // isnan. +#include // for root finding. +#include +#include +#include + +namespace boost +{ + namespace math + { + + template + class non_central_chi_squared_distribution; + + namespace detail{ + + template + BOOST_MATH_GPU_ENABLED T non_central_chi_square_q(T x, T f, T theta, const Policy& pol, T init_sum = 0) + { + // + // Computes the complement of the Non-Central Chi-Square + // Distribution CDF by summing a weighted sum of complements + // of the central-distributions. The weighting factor is + // a Poisson Distribution. + // + // This is an application of the technique described in: + // + // Computing discrete mixtures of continuous + // distributions: noncentral chisquare, noncentral t + // and the distribution of the square of the sample + // multiple correlation coefficient. + // D. Benton, K. Krishnamoorthy. + // Computational Statistics & Data Analysis 43 (2003) 249 - 267 + // + BOOST_MATH_STD_USING + + // Special case: + if(x == 0) + return 1; + + // + // Initialize the variables we'll be using: + // + T lambda = theta / 2; + T del = f / 2; + T y = x / 2; + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T sum = init_sum; + // + // k is the starting location for iteration, we'll + // move both forwards and backwards from this point. + // k is chosen as the peek of the Poisson weights, which + // will occur *before* the largest term. + // + long long k = llround(lambda, pol); + // Forwards and backwards Poisson weights: + T poisf = boost::math::gamma_p_derivative(static_cast(1 + k), lambda, pol); + T poisb = poisf * k / lambda; + // Initial forwards central chi squared term: + T gamf = boost::math::gamma_q(del + k, y, pol); + // Forwards and backwards recursion terms on the central chi squared: + T xtermf = boost::math::gamma_p_derivative(del + 1 + k, y, pol); + T xtermb = xtermf * (del + k) / y; + // Initial backwards central chi squared term: + T gamb = gamf - xtermb; + + // + // Forwards iteration first, this is the + // stable direction for the gamma function + // recurrences: + // + long long i; + for(i = k; static_cast(i-k) < max_iter; ++i) + { + T term = poisf * gamf; + sum += term; + poisf *= lambda / (i + 1); + gamf += xtermf; + xtermf *= y / (del + i + 1); + if(((sum == 0) || (fabs(term / sum) < errtol)) && (term >= poisf * gamf)) + break; + } + //Error check: + if(static_cast(i-k) >= max_iter) + return policies::raise_evaluation_error("cdf(non_central_chi_squared_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + // + // Now backwards iteration: the gamma + // function recurrences are unstable in this + // direction, we rely on the terms diminishing in size + // faster than we introduce cancellation errors. + // For this reason it's very important that we start + // *before* the largest term so that backwards iteration + // is strictly converging. + // + for(i = k - 1; i >= 0; --i) + { + T term = poisb * gamb; + sum += term; + poisb *= i / lambda; + xtermb *= (del + i) / y; + gamb -= xtermb; + if((sum == 0) || (fabs(term / sum) < errtol)) + break; + } + + return sum; + } + + template + BOOST_MATH_GPU_ENABLED T non_central_chi_square_p_ding(T x, T f, T theta, const Policy& pol, T init_sum = 0) + { + // + // This is an implementation of: + // + // Algorithm AS 275: + // Computing the Non-Central #2 Distribution Function + // Cherng G. Ding + // Applied Statistics, Vol. 41, No. 2. (1992), pp. 478-482. + // + // This uses a stable forward iteration to sum the + // CDF, unfortunately this can not be used for large + // values of the non-centrality parameter because: + // * The first term may underflow to zero. + // * We may need an extra-ordinary number of terms + // before we reach the first *significant* term. + // + BOOST_MATH_STD_USING + // Special case: + if(x == 0) + return 0; + T tk = boost::math::gamma_p_derivative(f/2 + 1, x/2, pol); + T lambda = theta / 2; + T vk = exp(-lambda); + T uk = vk; + T sum = init_sum + tk * vk; + if(sum == 0) + return sum; + + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + + int i; + T lterm(0), term(0); + for(i = 1; static_cast(i) < max_iter; ++i) + { + tk = tk * x / (f + 2 * i); + uk = uk * lambda / i; + vk = vk + uk; + lterm = term; + term = vk * tk; + sum += term; + if((fabs(term / sum) < errtol) && (term <= lterm)) + break; + } + //Error check: + if(static_cast(i) >= max_iter) + return policies::raise_evaluation_error("cdf(non_central_chi_squared_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + return sum; + } + + + template + BOOST_MATH_GPU_ENABLED T non_central_chi_square_p(T y, T n, T lambda, const Policy& pol, T init_sum) + { + // + // This is taken more or less directly from: + // + // Computing discrete mixtures of continuous + // distributions: noncentral chisquare, noncentral t + // and the distribution of the square of the sample + // multiple correlation coefficient. + // D. Benton, K. Krishnamoorthy. + // Computational Statistics & Data Analysis 43 (2003) 249 - 267 + // + // We're summing a Poisson weighting term multiplied by + // a central chi squared distribution. + // + BOOST_MATH_STD_USING + // Special case: + if(y == 0) + return 0; + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T errorf(0), errorb(0); + + T x = y / 2; + T del = lambda / 2; + // + // Starting location for the iteration, we'll iterate + // both forwards and backwards from this point. The + // location chosen is the maximum of the Poisson weight + // function, which ocurrs *after* the largest term in the + // sum. + // + long long k = llround(del, pol); + T a = n / 2 + k; + // Central chi squared term for forward iteration: + T gamkf = boost::math::gamma_p(a, x, pol); + + if(lambda == 0) + return gamkf; + // Central chi squared term for backward iteration: + T gamkb = gamkf; + // Forwards Poisson weight: + T poiskf = gamma_p_derivative(static_cast(k+1), del, pol); + // Backwards Poisson weight: + T poiskb = poiskf; + // Forwards gamma function recursion term: + T xtermf = boost::math::gamma_p_derivative(a, x, pol); + // Backwards gamma function recursion term: + T xtermb = xtermf * x / a; + T sum = init_sum + poiskf * gamkf; + if(sum == 0) + return sum; + int i = 1; + // + // Backwards recursion first, this is the stable + // direction for gamma function recurrences: + // + while(i <= k) + { + xtermb *= (a - i + 1) / x; + gamkb += xtermb; + poiskb = poiskb * (k - i + 1) / del; + errorf = errorb; + errorb = gamkb * poiskb; + sum += errorb; + if((fabs(errorb / sum) < errtol) && (errorb <= errorf)) + break; + ++i; + } + i = 1; + // + // Now forwards recursion, the gamma function + // recurrence relation is unstable in this direction, + // so we rely on the magnitude of successive terms + // decreasing faster than we introduce cancellation error. + // For this reason it's vital that k is chosen to be *after* + // the largest term, so that successive forward iterations + // are strictly (and rapidly) converging. + // + do + { + xtermf = xtermf * x / (a + i - 1); + gamkf = gamkf - xtermf; + poiskf = poiskf * del / (k + i); + errorf = poiskf * gamkf; + sum += errorf; + ++i; + }while((fabs(errorf / sum) > errtol) && (static_cast(i) < max_iter)); + + //Error check: + if(static_cast(i) >= max_iter) + return policies::raise_evaluation_error("cdf(non_central_chi_squared_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + + return sum; + } + + template + BOOST_MATH_GPU_ENABLED T non_central_chi_square_pdf(T x, T n, T lambda, const Policy& pol) + { + // + // As above but for the PDF: + // + BOOST_MATH_STD_USING + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T x2 = x / 2; + T n2 = n / 2; + T l2 = lambda / 2; + T sum = 0; + long long k = lltrunc(l2); + T pois = gamma_p_derivative(static_cast(k + 1), l2, pol) * gamma_p_derivative(static_cast(n2 + k), x2); + if(pois == 0) + return 0; + T poisb = pois; + for(long long i = k; ; ++i) + { + sum += pois; + if(pois / sum < errtol) + break; + if(static_cast(i - k) >= max_iter) + return policies::raise_evaluation_error("pdf(non_central_chi_squared_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + pois *= l2 * x2 / ((i + 1) * (n2 + i)); + } + for(long long i = k - 1; i >= 0; --i) + { + poisb *= (i + 1) * (n2 + i) / (l2 * x2); + sum += poisb; + if(poisb / sum < errtol) + break; + } + return sum / 2; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType non_central_chi_squared_cdf(RealType x, RealType k, RealType l, bool invert, const Policy&) + { + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + value_type result; + if(l == 0) + return invert == false ? cdf(boost::math::chi_squared_distribution(k), x) : cdf(complement(boost::math::chi_squared_distribution(k), x)); + else if(x > k + l) + { + // Complement is the smaller of the two: + result = detail::non_central_chi_square_q( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? 0 : -1)); + invert = !invert; + } + else if(l < 200) + { + // For small values of the non-centrality parameter + // we can use Ding's method: + result = detail::non_central_chi_square_p_ding( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + else + { + // For largers values of the non-centrality + // parameter Ding's method will consume an + // extra-ordinary number of terms, and worse + // may return zero when the result is in fact + // finite, use Krishnamoorthy's method instead: + result = detail::non_central_chi_square_p( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + if(invert) + result = -result; + return policies::checked_narrowing_cast( + result, + "boost::math::non_central_chi_squared_cdf<%1%>(%1%, %1%, %1%)"); + } + + template + struct nccs_quantile_functor + { + BOOST_MATH_GPU_ENABLED nccs_quantile_functor(const non_central_chi_squared_distribution& d, T t, bool c) + : dist(d), target(t), comp(c) {} + + BOOST_MATH_GPU_ENABLED T operator()(const T& x) + { + return comp ? + target - cdf(complement(dist, x)) + : cdf(dist, x) - target; + } + + private: + non_central_chi_squared_distribution dist; + T target; + bool comp; + }; + + template + BOOST_MATH_GPU_ENABLED RealType nccs_quantile(const non_central_chi_squared_distribution& dist, const RealType& p, bool comp) + { + BOOST_MATH_STD_USING + constexpr auto function = "quantile(non_central_chi_squared_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type k = dist.degrees_of_freedom(); + value_type l = dist.non_centrality(); + value_type r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_probability( + function, + static_cast(p), + &r, + Policy())) + return static_cast(r); + // + // Special cases get short-circuited first: + // + if(p == 0) + return comp ? policies::raise_overflow_error(function, 0, Policy()) : 0; + if(p == 1) + return comp ? 0 : policies::raise_overflow_error(function, 0, Policy()); + // + // This is Pearson's approximation to the quantile, see + // Pearson, E. S. (1959) "Note on an approximation to the distribution of + // noncentral chi squared", Biometrika 46: 364. + // See also: + // "A comparison of approximations to percentiles of the noncentral chi2-distribution", + // Hardeo Sahai and Mario Miguel Ojeda, Revista de Matematica: Teoria y Aplicaciones 2003 10(1-2) : 57-76. + // Note that the latter reference refers to an approximation of the CDF, when they really mean the quantile. + // + value_type b = -(l * l) / (k + 3 * l); + value_type c = (k + 3 * l) / (k + 2 * l); + value_type ff = (k + 2 * l) / (c * c); + value_type guess; + if(comp) + { + guess = b + c * quantile(complement(chi_squared_distribution(ff), p)); + } + else + { + guess = b + c * quantile(chi_squared_distribution(ff), p); + } + // + // Sometimes guess goes very small or negative, in that case we have + // to do something else for the initial guess, this approximation + // was provided in a private communication from Thomas Luu, PhD candidate, + // University College London. It's an asymptotic expansion for the + // quantile which usually gets us within an order of magnitude of the + // correct answer. + // Fast and accurate parallel computation of quantile functions for random number generation, + // Thomas LuuDoctorial Thesis 2016 + // http://discovery.ucl.ac.uk/1482128/ + // + if(guess < 0.005) + { + value_type pp = comp ? 1 - p : p; + //guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k, 2 / k); + guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k * boost::math::tgamma(k / 2, forwarding_policy()), (2 / k)); + if(guess == 0) + guess = tools::min_value(); + } + value_type result = detail::generic_quantile( + non_central_chi_squared_distribution(k, l), + p, + guess, + comp, + function); + + return policies::checked_narrowing_cast( + result, + function); + } + + template + BOOST_MATH_GPU_ENABLED RealType nccs_pdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING + constexpr auto function = "pdf(non_central_chi_squared_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type k = dist.degrees_of_freedom(); + value_type l = dist.non_centrality(); + value_type r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + (value_type)x, + &r, + Policy())) + return static_cast(r); + + if(l == 0) + return pdf(boost::math::chi_squared_distribution(dist.degrees_of_freedom()), x); + + // Special case: + if(x == 0) + return 0; + if(l > 50) + { + r = non_central_chi_square_pdf(static_cast(x), k, l, forwarding_policy()); + } + else + { + r = log(x / l) * (k / 4 - 0.5f) - (x + l) / 2; + if(fabs(r) >= tools::log_max_value() / 4) + { + r = non_central_chi_square_pdf(static_cast(x), k, l, forwarding_policy()); + } + else + { + r = exp(r); + r = 0.5f * r + * boost::math::cyl_bessel_i(k/2 - 1, sqrt(l * x), forwarding_policy()); + } + } + return policies::checked_narrowing_cast( + r, + function); + } + + template + struct degrees_of_freedom_finder + { + BOOST_MATH_GPU_ENABLED degrees_of_freedom_finder( + RealType lam_, RealType x_, RealType p_, bool c) + : lam(lam_), x(x_), p(p_), comp(c) {} + + BOOST_MATH_GPU_ENABLED RealType operator()(const RealType& v) + { + non_central_chi_squared_distribution d(v, lam); + return comp ? + RealType(p - cdf(complement(d, x))) + : RealType(cdf(d, x) - p); + } + private: + RealType lam; + RealType x; + RealType p; + bool comp; + }; + + template + BOOST_MATH_GPU_ENABLED inline RealType find_degrees_of_freedom( + RealType lam, RealType x, RealType p, RealType q, const Policy& pol) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + if((p == 0) || (q == 0)) + { + // + // Can't a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%", // LCOV_EXCL_LINE + RealType(boost::math::numeric_limits::quiet_NaN()), Policy()); // LCOV_EXCL_LINE + } + degrees_of_freedom_finder f(lam, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know will give us a probability + // right around 0.5. + // + RealType guess = x - lam; + if(guess < 1) + guess = 1; + boost::math::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " or there is no answer to problem. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } + + template + struct non_centrality_finder + { + BOOST_MATH_GPU_ENABLED non_centrality_finder( + RealType v_, RealType x_, RealType p_, bool c) + : v(v_), x(x_), p(p_), comp(c) {} + + BOOST_MATH_GPU_ENABLED RealType operator()(const RealType& lam) + { + non_central_chi_squared_distribution d(v, lam); + return comp ? + RealType(p - cdf(complement(d, x))) + : RealType(cdf(d, x) - p); + } + private: + RealType v; + RealType x; + RealType p; + bool comp; + }; + + template + BOOST_MATH_GPU_ENABLED inline RealType find_non_centrality( + RealType v, RealType x, RealType p, RealType q, const Policy& pol) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_non_centrality"; + if((p == 0) || (q == 0)) + { + // + // Can't do a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, "Can't find non centrality parameter when the probability is 0 or 1, only possible answer is %1%", // LCOV_EXCL_LINE + RealType(boost::math::numeric_limits::quiet_NaN()), Policy()); // LCOV_EXCL_LINE + } + non_centrality_finder f(v, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know will give us a probability + // right around 0.5. + // + RealType guess = x - v; + if(guess < 1) + guess = 1; + boost::math::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " or there is no answer to problem. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } + + } + + template > + class non_central_chi_squared_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED non_central_chi_squared_distribution(RealType df_, RealType lambda) : df(df_), ncp(lambda) + { + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::non_central_chi_squared_distribution(%1%,%1%)"; + RealType r; + detail::check_df( + function, + df, &r, Policy()); + detail::check_non_centrality( + function, + ncp, + &r, + Policy()); + } // non_central_chi_squared_distribution constructor. + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom() const + { // Private data getter function. + return df; + } + BOOST_MATH_GPU_ENABLED RealType non_centrality() const + { // Private data getter function. + return ncp; + } + BOOST_MATH_GPU_ENABLED static RealType find_degrees_of_freedom(RealType lam, RealType x, RealType p) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_degrees_of_freedom( + static_cast(lam), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + BOOST_MATH_GPU_ENABLED static RealType find_degrees_of_freedom(const complemented3_type& c) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_degrees_of_freedom( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + BOOST_MATH_GPU_ENABLED static RealType find_non_centrality(RealType v, RealType x, RealType p) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_non_centrality"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_non_centrality( + static_cast(v), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + BOOST_MATH_GPU_ENABLED static RealType find_non_centrality(const complemented3_type& c) + { + constexpr auto function = "non_central_chi_squared<%1%>::find_non_centrality"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_non_centrality( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + private: + // Data member, initialized by constructor. + RealType df; // degrees of freedom. + RealType ncp; // non-centrality parameter + }; // template class non_central_chi_squared_distribution + + typedef non_central_chi_squared_distribution non_central_chi_squared; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_chi_squared_distribution(RealType,RealType)->non_central_chi_squared_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const non_central_chi_squared_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // Max integer? + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const non_central_chi_squared_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const non_central_chi_squared_distribution& dist) + { // Mean of poisson distribution = lambda. + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::mean()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + return k + l; + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const non_central_chi_squared_distribution& dist) + { // mode. + constexpr auto function = "mode(non_central_chi_squared_distribution<%1%> const&)"; + + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + bool asymptotic_mode = k < l/4; + RealType starting_point = asymptotic_mode ? k + l - RealType(3) : RealType(1) + k; + return detail::generic_find_mode(dist, starting_point, function); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const non_central_chi_squared_distribution& dist) + { // variance. + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::variance()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + return 2 * (2 * l + k); + } + + // RealType standard_deviation(const non_central_chi_squared_distribution& dist) + // standard_deviation provided by derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const non_central_chi_squared_distribution& dist) + { // skewness = sqrt(l). + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::skewness()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + BOOST_MATH_STD_USING + return pow(2 / (k + 2 * l), RealType(3)/2) * (k + 3 * l); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const non_central_chi_squared_distribution& dist) + { + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::kurtosis_excess()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return static_cast(r); + return 12 * (k + 4 * l) / ((k + 2 * l) * (k + 2 * l)); + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const non_central_chi_squared_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + return detail::nccs_pdf(dist, x); + } // pdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + x, + &r, + Policy())) + return static_cast(r); + + return detail::non_central_chi_squared_cdf(x, k, l, false, Policy()); + } // cdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + constexpr auto function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)"; + non_central_chi_squared_distribution const& dist = c.dist; + RealType x = c.param; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + x, + &r, + Policy())) + return static_cast(r); + + return detail::non_central_chi_squared_cdf(x, k, l, true, Policy()); + } // ccdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const non_central_chi_squared_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + return detail::nccs_quantile(dist, p, false); + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + return detail::nccs_quantile(c.dist, c.param, true); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/non_central_f.hpp b/third-party/boost-math/include/boost/math/distributions/non_central_f.hpp new file mode 100644 index 0000000000000..dedd437144bd6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/non_central_f.hpp @@ -0,0 +1,419 @@ +// boost\math\distributions\non_central_f.hpp + +// Copyright John Maddock 2008. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace math + { + template > + class non_central_f_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED non_central_f_distribution(RealType v1_, RealType v2_, RealType lambda) : v1(v1_), v2(v2_), ncp(lambda) + { + constexpr auto function = "boost::math::non_central_f_distribution<%1%>::non_central_f_distribution(%1%,%1%)"; + RealType r; + detail::check_df( + function, + v1, &r, Policy()); + detail::check_df( + function, + v2, &r, Policy()); + detail::check_non_centrality( + function, + lambda, + &r, + Policy()); + } // non_central_f_distribution constructor. + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom1()const + { + return v1; + } + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom2()const + { + return v2; + } + BOOST_MATH_GPU_ENABLED RealType non_centrality() const + { // Private data getter function. + return ncp; + } + private: + // Data member, initialized by constructor. + RealType v1; // alpha. + RealType v2; // beta. + RealType ncp; // non-centrality parameter + }; // template class non_central_f_distribution + + typedef non_central_f_distribution non_central_f; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_f_distribution(RealType,RealType,RealType)->non_central_f_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const non_central_f_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const non_central_f_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const non_central_f_distribution& dist) + { + constexpr auto function = "mean(non_central_f_distribution<%1%> const&)"; + RealType v1 = dist.degrees_of_freedom1(); + RealType v2 = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + v1, &r, Policy()) + || + !detail::check_df( + function, + v2, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(v2 <= 2) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 2 !", + v2, Policy()); + return v2 * (v1 + l) / (v1 * (v2 - 2)); + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const non_central_f_distribution& dist) + { // mode. + constexpr auto function = "mode(non_central_chi_squared_distribution<%1%> const&)"; + + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + RealType guess = m > 2 ? RealType(m * (n + l) / (n * (m - 2))) : RealType(1); + return detail::generic_find_mode( + dist, + guess, + function); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const non_central_f_distribution& dist) + { // variance. + constexpr auto function = "variance(non_central_f_distribution<%1%> const&)"; + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 4) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 4 !", + m, Policy()); + RealType result = 2 * m * m * ((n + l) * (n + l) + + (m - 2) * (n + 2 * l)); + result /= (m - 4) * (m - 2) * (m - 2) * n * n; + return result; + } + + // RealType standard_deviation(const non_central_f_distribution& dist) + // standard_deviation provided by derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const non_central_f_distribution& dist) + { // skewness = sqrt(l). + constexpr auto function = "skewness(non_central_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 6) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 6 !", + m, Policy()); + RealType result = 2 * constants::root_two(); + result *= sqrt(m - 4); + result *= (n * (m + n - 2) *(m + 2 * n - 2) + + 3 * (m + n - 2) * (m + 2 * n - 2) * l + + 6 * (m + n - 2) * l * l + 2 * l * l * l); + result /= (m - 6) * pow(n * (m + n - 2) + 2 * (m + n - 2) * l + l * l, RealType(1.5f)); + return result; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const non_central_f_distribution& dist) + { + constexpr auto function = "kurtosis_excess(non_central_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 8) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 8 !", + m, Policy()); + RealType l2 = l * l; + RealType l3 = l2 * l; + RealType l4 = l2 * l2; + RealType result = (3 * (m - 4) * (n * (m + n - 2) + * (4 * (m - 2) * (m - 2) + + (m - 2) * (m + 10) * n + + (10 + m) * n * n) + + 4 * (m + n - 2) * (4 * (m - 2) * (m - 2) + + (m - 2) * (10 + m) * n + + (10 + m) * n * n) * l + 2 * (10 + m) + * (m + n - 2) * (2 * m + 3 * n - 4) * l2 + + 4 * (10 + m) * (-2 + m + n) * l3 + + (10 + m) * l4)) + / + ((-8 + m) * (-6 + m) * boost::math::pow<2>(n * (-2 + m + n) + + 2 * (-2 + m + n) * l + l2)); + return result; + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const non_central_f_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const non_central_f_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type alpha = dist.degrees_of_freedom1() / 2; + value_type beta = dist.degrees_of_freedom2() / 2; + value_type y = x * alpha / beta; + value_type r = pdf(boost::math::non_central_beta_distribution(alpha, beta, dist.non_centrality()), y / (1 + y)); + return policies::checked_narrowing_cast( + r * (dist.degrees_of_freedom1() / dist.degrees_of_freedom2()) / ((1 + y) * (1 + y)), + "pdf(non_central_f_distribution<%1%>, %1%)"); + } // pdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const non_central_f_distribution& dist, const RealType& x) + { + constexpr auto function = "cdf(const non_central_f_distribution<%1%>&, %1%)"; + RealType r; + if(!detail::check_df( + function, + dist.degrees_of_freedom1(), &r, Policy()) + || + !detail::check_df( + function, + dist.degrees_of_freedom2(), &r, Policy()) + || + !detail::check_non_centrality( + function, + dist.non_centrality(), + &r, + Policy())) + return r; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType alpha = dist.degrees_of_freedom1() / 2; + RealType beta = dist.degrees_of_freedom2() / 2; + RealType y = x * alpha / beta; + RealType c = y / (1 + y); + RealType cp = 1 / (1 + y); + // + // To ensure accuracy, we pass both x and 1-x to the + // non-central beta cdf routine, this ensures accuracy + // even when we compute x to be ~ 1: + // + r = detail::non_central_beta_cdf(c, cp, alpha, beta, + dist.non_centrality(), false, Policy()); + return r; + } // cdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + constexpr auto function = "cdf(complement(const non_central_f_distribution<%1%>&, %1%))"; + RealType r; + if(!detail::check_df( + function, + c.dist.degrees_of_freedom1(), &r, Policy()) + || + !detail::check_df( + function, + c.dist.degrees_of_freedom2(), &r, Policy()) + || + !detail::check_non_centrality( + function, + c.dist.non_centrality(), + &r, + Policy())) + return r; + + if((c.param < 0) || !(boost::math::isfinite)(c.param)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", c.param, Policy()); + } + + RealType alpha = c.dist.degrees_of_freedom1() / 2; + RealType beta = c.dist.degrees_of_freedom2() / 2; + RealType y = c.param * alpha / beta; + RealType x = y / (1 + y); + RealType cx = 1 / (1 + y); + // + // To ensure accuracy, we pass both x and 1-x to the + // non-central beta cdf routine, this ensures accuracy + // even when we compute x to be ~ 1: + // + r = detail::non_central_beta_cdf(x, cx, alpha, beta, + c.dist.non_centrality(), true, Policy()); + return r; + } // ccdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const non_central_f_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + RealType alpha = dist.degrees_of_freedom1() / 2; + RealType beta = dist.degrees_of_freedom2() / 2; + RealType x = quantile(boost::math::non_central_beta_distribution(alpha, beta, dist.non_centrality()), p); + if(x == 1) + return policies::raise_overflow_error( + "quantile(const non_central_f_distribution<%1%>&, %1%)", + "Result of non central F quantile is too large to represent.", + Policy()); + return (x / (1 - x)) * (dist.degrees_of_freedom2() / dist.degrees_of_freedom1()); + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + RealType alpha = c.dist.degrees_of_freedom1() / 2; + RealType beta = c.dist.degrees_of_freedom2() / 2; + RealType x = quantile(complement(boost::math::non_central_beta_distribution(alpha, beta, c.dist.non_centrality()), c.param)); + if(x == 1) + return policies::raise_overflow_error( + "quantile(complement(const non_central_f_distribution<%1%>&, %1%))", + "Result of non central F quantile is too large to represent.", + Policy()); + return (x / (1 - x)) * (c.dist.degrees_of_freedom2() / c.dist.degrees_of_freedom1()); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP + + + diff --git a/third-party/boost-math/include/boost/math/distributions/non_central_t.hpp b/third-party/boost-math/include/boost/math/distributions/non_central_t.hpp new file mode 100644 index 0000000000000..a6c988d758a8c --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/non_central_t.hpp @@ -0,0 +1,1325 @@ +// boost\math\distributions\non_central_t.hpp + +// Copyright John Maddock 2008. + +// 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) + +#ifndef BOOST_MATH_SPECIAL_NON_CENTRAL_T_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_T_HPP + +#include +#include // for nc beta +#include // for normal CDF and quantile +#include +#include // quantile +#include +#include +#include + +namespace boost +{ + namespace math + { + + template + class non_central_t_distribution; + + namespace detail{ + + template + T non_central_t2_p(T v, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, we don't + // ever allow k == 0 as this can lead to catastrophic + // cancellation errors later (test case is v = 1621286869049072.3 + // delta = 0.16212868690490723, x = 0.86987415482475994). + // + long long k = lltrunc(d2); + T pois; + if(k == 0) k = 1; + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + if(pois == 0) + return init_val; + T xterm, beta; + // Recurrence & starting beta terms: + beta = x < y + ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, false, true, &xterm) + : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, true, true, &xterm); + + while (fabs(beta * pois) < tools::min_value()) + { + if ((k == 0) || (pois == 0)) + return init_val; + k /= 2; + pois = gamma_p_derivative(T(k + 1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + beta = x < y + ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, false, true, &xterm) + : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, true, true, &xterm); + } + + xterm *= y / (v / 2 + k); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((xterm == 0) && (beta == 0)) + return init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + std::uintmax_t count = 0; + T last_term = 0; + for(auto i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + // Don't terminate on first term in case we "fixed" k above: + if(((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol) || (v == 2 && i == 0)) + break; + last_term = term; + pois *= (i + 0.5f) / d2; + beta += xterm; + xterm *= (i) / (x * (v / 2 + i - 1)); + ++count; + } + last_term = 0; + for(auto i = k + 1; ; ++i) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (v / 2 + i - 1)) / (i); + betaf -= xtermf; + T term = poisf * betaf; + sum += term; + if((fabs(last_term) >= fabs(term)) && (fabs(term/sum) < errtol)) + break; + last_term = term; + ++count; + if(count > max_iter) + { + return policies::raise_evaluation_error("cdf(non_central_t_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + } + return sum; + } + + template + T non_central_t2_q(T v, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, we don't allow + // k == 0 as this can cause catastrophic cancellation errors + // (test case is v = 561908036470413.25, delta = 0.056190803647041321, + // x = 1.6155232703966216): + // + long long k = lltrunc(d2); + if(k == 0) k = 1; + // Starting Poisson weight: + T pois; + if((k < static_cast(max_factorial::value)) && (d2 < tools::log_max_value()) && (log(d2) * k < tools::log_max_value())) + { + // + // For small k we can optimise this calculation by using + // a simpler reduced formula: + // + pois = exp(-d2); + pois *= pow(d2, static_cast(k)); + pois /= boost::math::tgamma(T(k + 1 + 0.5), pol); + pois *= delta / constants::root_two(); + } + else + { + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + } + if(pois == 0) + return init_val; + // Recurance term: + T xterm; + T beta; + // Starting beta term: + if(k != 0) + { + beta = x < y + ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, true, true, &xterm) + : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, false, true, &xterm); + + xterm *= y / (v / 2 + k); + } + else + { + beta = pow(y, v / 2); + xterm = beta; + } + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((xterm == 0) && (beta == 0)) + return init_val; + + // + // Fused forward and backwards recursion: + // + std::uintmax_t count = 0; + T last_term = 0; + for(auto i = k + 1, j = k; ; ++i, --j) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (v / 2 + i - 1)) / (i); + betaf += xtermf; + T term = poisf * betaf; + + if(j >= 0) + { + term += beta * pois; + pois *= (j + 0.5f) / d2; + beta -= xterm; + if(!(v == 2 && j == 0)) + xterm *= (j) / (x * (v / 2 + j - 1)); + } + + sum += term; + // Don't terminate on first term in case we "fixed" the value of k above: + if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol) + break; + last_term = term; + if(count > max_iter) + { + return policies::raise_evaluation_error("cdf(non_central_t_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + ++count; + } + return sum; + } + + template + T non_central_t_cdf(T v, T delta, T t, bool invert, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(delta, 1); + return cdf(n, t); + } + // + // Otherwise, for t < 0 we have to use the reflection formula: + if(t < 0) + { + t = -t; + delta = -delta; + invert = !invert; + } + if(fabs(delta / (4 * v)) < policies::get_epsilon()) + { + // Approximate with a Student's T centred on delta, + // the crossover point is based on eq 2.6 from + // "A Comparison of Approximations To Percentiles of the + // Noncentral t-Distribution". H. Sahai and M. M. Ojeda, + // Revista Investigacion Operacional Vol 21, No 2, 2000. + // Original sources referenced in the above are: + // "Some Approximations to the Percentage Points of the Noncentral + // t-Distribution". C. van Eeden. International Statistical Review, 29, 4-31. + // "Continuous Univariate Distributions". N.L. Johnson, S. Kotz and + // N. Balkrishnan. 1995. John Wiley and Sons New York. + T result = cdf(students_t_distribution(v), t - delta); + return invert ? 1 - result : result; + } + // + // x and y are the corresponding random + // variables for the noncentral beta distribution, + // with y = 1 - x: + // + T x = t * t / (v + t * t); + T y = v / (v + t * t); + T d2 = delta * delta; + T a = 0.5f; + T b = v / 2; + T c = a + b + d2 / 2; + // + // Crossover point for calculating p or q is the same + // as for the noncentral beta: + // + T cross = 1 - (b / c) * (1 + d2 / (2 * c * c)); + T result; + if(x < cross) + { + // + // Calculate p: + // + if(x != 0) + { + result = non_central_beta_p(a, b, d2, x, y, pol); + result = non_central_t2_p(v, delta, x, y, pol, result); + result /= 2; + } + else + result = 0; + if (invert) + { + result = cdf(complement(boost::math::normal_distribution(), -delta)) - result; + invert = false; + } + else + result += cdf(boost::math::normal_distribution(), -delta); + } + else + { + // + // Calculate q: + // + invert = !invert; + if(x != 0) + { + result = non_central_beta_q(a, b, d2, x, y, pol); + result = non_central_t2_q(v, delta, x, y, pol, result); + result /= 2; + } + else // x == 0 + result = cdf(complement(boost::math::normal_distribution(), -delta)); + } + if(invert) + result = 1 - result; + return result; + } + + template + T non_central_t_quantile(const char* function, T v, T delta, T p, T q, const Policy&) + { + BOOST_MATH_STD_USING + // static const char* function = "quantile(non_central_t_distribution<%1%>, %1%)"; + // now passed as function + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + T r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(delta * delta), + &r, + Policy()) + || + !detail::check_probability( + function, + p, + &r, + Policy())) + return r; + + + value_type guess = 0; + if ( ((boost::math::isinf)(v)) || (v > 1 / boost::math::tools::epsilon()) ) + { // Infinite or very large degrees of freedom, so use normal distribution located at delta. + normal_distribution n(delta, 1); + if (p < q) + { + return quantile(n, p); + } + else + { + return quantile(complement(n, q)); + } + } + else if(v > 3) + { // Use normal distribution to calculate guess. + value_type mean = (v > 1 / policies::get_epsilon()) ? delta : delta * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, T(0.5f)); + value_type var = (v > 1 / policies::get_epsilon()) ? value_type(1) : (((delta * delta + 1) * v) / (v - 2) - mean * mean); + if(p < q) + guess = quantile(normal_distribution(mean, var), p); + else + guess = quantile(complement(normal_distribution(mean, var), q)); + } + // + // We *must* get the sign of the initial guess correct, + // or our root-finder will fail, so double check it now: + // + value_type pzero = non_central_t_cdf( + static_cast(v), + static_cast(delta), + static_cast(0), + !(p < q), + forwarding_policy()); + int s; + if(p < q) + s = boost::math::sign(p - pzero); + else + s = boost::math::sign(pzero - q); + if(s != boost::math::sign(guess)) + { + guess = static_cast(s); + } + + value_type result = detail::generic_quantile( + non_central_t_distribution(v, delta), + (p < q ? p : q), + guess, + (p >= q), + function); + return policies::checked_narrowing_cast( + result, + function); + } + + template + T non_central_t_pdf_integral(T x, T v, T mu, const Policy& pol) + { + BOOST_MATH_STD_USING + boost::math::quadrature::exp_sinh integrator; + T integral = pow(v, v / 2) * exp(-v * mu * mu / (2 * (x * x + v))); + if (integral != 0) + { + integral *= integrator.integrate([&x, v, mu](T y) + { + T p; + if (v * log(y) < tools::log_max_value()) + p = pow(y, v) * exp(boost::math::pow<2>((y - mu * x / sqrt(x * x + v))) / -2); + else + p = exp(log(y) * v + boost::math::pow<2>((y - mu * x / sqrt(x * x + v))) / -2); + return p; + }); + } + integral /= boost::math::constants::root_pi() * boost::math::tgamma(v / 2, pol) * pow(T(2), (v - 1) / 2) * pow(x * x + v, (v + 1) / 2); + return integral; + } + + template + T non_central_t_pdf_hypergeometric(T x, T v, T mu, const Policy& pol) + { + BOOST_MATH_STD_USING + long long scale = 0; + const char* function = "non central T PDF"; + // + // We only call this routine when we know that the series form of 1F1 is cheap to evaluate, + // so no need to call the whole 1F1 function, just the series will do: + // + T Av = hypergeometric_1F1_generic_series(static_cast((v + 1) / 2), boost::math::constants::half(), static_cast(mu * mu * x * x / (2 * (x * x + v))), pol, scale, function); + Av = ldexp(Av, static_cast(scale)); + scale = 0; + T Bv = hypergeometric_1F1_generic_series(static_cast(v / 2 + T(1)), static_cast(T(3) / 2), static_cast(mu * mu * x * x / (2 * (x * x + v))), pol, scale, function); + Bv = ldexp(Bv, static_cast(scale)); + Bv *= boost::math::tgamma_delta_ratio(v / 2 + T(1), -constants::half(), pol); + Bv *= boost::math::constants::root_two() * mu * x / sqrt(x * x + v); + + T tolerance = tools::root_epsilon() * Av * 4; + Av += Bv; + + if (Av < tolerance) + { + // More than half the digits have cancelled, fall back to the integral method: + return non_central_t_pdf_integral(x, v, mu, pol); + } + + Av *= exp(-mu * mu / 2) * pow(1 + x * x / v, -(v + 1) / 2) * boost::math::tgamma_delta_ratio(v / 2 + constants::half(), -constants::half(), pol); + Av /= sqrt(v) * boost::math::constants::root_pi(); + return Av; + } + + template + T non_central_t2_pdf(T n, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + long long k = lltrunc(d2); + T pois, xterm; + if(k == 0) + k = 1; + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + BOOST_MATH_INSTRUMENT_VARIABLE(pois); + // Starting beta term: + xterm = x < y + ? ibeta_derivative(T(k + 1), n / 2, x, pol) + : ibeta_derivative(n / 2, T(k + 1), y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(xterm); + + while (fabs(xterm * pois) < tools::min_value()) + { + if (k == 0) + return init_val; + k /= 2; + pois = gamma_p_derivative(T(k + 1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + BOOST_MATH_INSTRUMENT_VARIABLE(pois); + // Starting beta term: + xterm = x < y + ? ibeta_derivative(T(k + 1), n / 2, x, pol) + : ibeta_derivative(n / 2, T(k + 1), y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(xterm); + } + + T poisf(pois), xtermf(xterm); + T sum = init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + std::uintmax_t count = 0; + T old_ratio = 1; // arbitrary "large" value + for(auto i = k; i >= 0; --i) + { + T term = xterm * pois; + sum += term; + BOOST_MATH_INSTRUMENT_VARIABLE(sum); + T ratio = fabs(term / sum); + if(((ratio < errtol) && (i != k) && (ratio < old_ratio)) || (term == 0)) + break; + old_ratio = ratio; + pois *= (i + 0.5f) / d2; + xterm *= (i) / (x * (n / 2 + i)); + ++count; + if(count > max_iter) + { + return policies::raise_evaluation_error("pdf(non_central_t_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(sum); + old_ratio = 0; + for(auto i = k + 1; ; ++i) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (n / 2 + i)) / (i); + T term = poisf * xtermf; + sum += term; + T ratio = fabs(term / sum); + if(((ratio < errtol) && (ratio < old_ratio)) || (term == 0)) + break; + ++count; + old_ratio = ratio; + if(count > max_iter) + { + return policies::raise_evaluation_error("pdf(non_central_t_distribution<%1%>, %1%)", "Series did not converge, closest value was %1%", sum, pol); // LCOV_EXCL_LINE + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(sum); + return sum; + } + + template + T non_central_t_pdf(T n, T delta, T t, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(n)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution norm(delta, 1); + return pdf(norm, t); + } + if(t * t < tools::epsilon()) + { + // + // Handle this as a special case, using the formula + // from Weisstein, Eric W. + // "Noncentral Student's t-Distribution." + // From MathWorld--A Wolfram Web Resource. + // http://mathworld.wolfram.com/NoncentralStudentst-Distribution.html + // + // The formula is simplified thanks to the relation + // 1F1(a,b,0) = 1. + // + return tgamma_delta_ratio(n / 2 + 0.5f, T(0.5f)) + * sqrt(n / constants::pi()) + * exp(-delta * delta / 2) / 2; + } + if(fabs(delta / (4 * n)) < policies::get_epsilon()) + { + // Approximate with a Student's T centred on delta, + // the crossover point is based on eq 2.6 from + // "A Comparison of Approximations To Percentiles of the + // Noncentral t-Distribution". H. Sahai and M. M. Ojeda, + // Revista Investigacion Operacional Vol 21, No 2, 2000. + // Original sources referenced in the above are: + // "Some Approximations to the Percentage Points of the Noncentral + // t-Distribution". C. van Eeden. International Statistical Review, 29, 4-31. + // "Continuous Univariate Distributions". N.L. Johnson, S. Kotz and + // N. Balkrishnan. 1995. John Wiley and Sons New York. + return pdf(students_t_distribution(n), t - delta); + } + // + // Figure out if the hypergeometric formula will be efficient or not, + // based on where the summit of the series. + // + T a = (n + 1) / 2; + T x = delta * delta * t * t / (2 * (t * t + n)); + T summit = (sqrt(x * (4 * a + x)) + x) / 2; + if (summit < 40) + return non_central_t_pdf_hypergeometric(t, n, delta, pol); + // + // Otherwise, for t < 0 we have to use the reflection formula: + // + if (t < 0) + { + t = -t; + delta = -delta; + } + // + // x and y are the corresponding random + // variables for the noncentral beta distribution, + // with y = 1 - x: + // + x = t * t / (n + t * t); + T y = n / (n + t * t); + a = 0.5f; + T b = n / 2; + T d2 = delta * delta; + // + // Calculate pdf: + // + T dt = n * t / (n * n + 2 * n * t * t + t * t * t * t); + BOOST_MATH_INSTRUMENT_VARIABLE(dt); + T result = non_central_beta_pdf(a, b, d2, x, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + T tol = tools::root_epsilon() * result; + result = non_central_t2_pdf(n, delta, x, y, pol, result); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result *= dt; + if (result <= tol) + { + // More than half the digits in the result have cancelled, + // Try direct integration... super slow but reliable as far as we can tell... + if (delta < 0) + { + // reflect back: + delta = -delta; + t = -t; + } + result = non_central_t_pdf_integral(t, n, delta, pol); + } + return result; + } + + template + T mean(T v, T delta, const Policy& pol) + { + if ((boost::math::isinf)(v)) + { + return delta; + } + BOOST_MATH_STD_USING + if (v > 1 / boost::math::tools::epsilon() ) + { + //normal_distribution n(delta, 1); + //return boost::math::mean(n); + return delta; + } + else + { + return delta * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, T(0.5f), pol); + } + // Other moments use mean so using normal distribution is propagated. + } + + template + T variance(T v, T delta, const Policy& pol) + { + if ((boost::math::isinf)(v)) + { + return 1; + } + if (delta == 0) + { // == Student's t + return v / (v - 2); + } + T result = ((delta * delta + 1) * v) / (v - 2); + T m = mean(v, delta, pol); + result -= m * m; + return result; + } + + template + T skewness(T v, T delta, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { + return 0; + } + if(delta == 0) + { // == Student's t + return 0; + } + T mean = boost::math::detail::mean(v, delta, pol); + T l2 = delta * delta; + T var = ((l2 + 1) * v) / (v - 2) - mean * mean; + T result = -2 * var; + result += v * (l2 + 2 * v - 3) / ((v - 3) * (v - 2)); + result *= mean; + result /= pow(var, T(1.5f)); + return result; + } + + template + T kurtosis_excess(T v, T delta, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { + return 1; + } + if (delta == 0) + { // == Student's t + return 1; + } + T mean = boost::math::detail::mean(v, delta, pol); + T l2 = delta * delta; + T var = ((l2 + 1) * v) / (v - 2) - mean * mean; + T result = -3 * var; + result += v * (l2 * (v + 1) + 3 * (3 * v - 5)) / ((v - 3) * (v - 2)); + result *= -mean * mean; + result += v * v * (l2 * l2 + 6 * l2 + 3) / ((v - 4) * (v - 2)); + result /= var * var; + result -= static_cast(3); + return result; + } + +#if 0 + // + // This code is disabled, since there can be multiple answers to the + // question, and it's not clear how to find the "right" one. + // + template + struct t_degrees_of_freedom_finder + { + t_degrees_of_freedom_finder( + RealType delta_, RealType x_, RealType p_, bool c) + : delta(delta_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& v) + { + non_central_t_distribution d(v, delta); + return comp ? + p - cdf(complement(d, x)) + : cdf(d, x) - p; + } + private: + RealType delta; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_t_degrees_of_freedom( + RealType delta, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + if((p == 0) || (q == 0)) + { + // + // Can't a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%", // LCOV_EXCL_LINE + RealType(std::numeric_limits::quiet_NaN()), Policy()); // LCOV_EXCL_LINE + } + t_degrees_of_freedom_finder f(delta, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess: + // + RealType guess = 200; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " or there is no answer to problem. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } + + template + struct t_non_centrality_finder + { + t_non_centrality_finder( + RealType v_, RealType x_, RealType p_, bool c) + : v(v_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& delta) + { + non_central_t_distribution d(v, delta); + return comp ? + p - cdf(complement(d, x)) + : cdf(d, x) - p; + } + private: + RealType v; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_t_non_centrality( + RealType v, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + if((p == 0) || (q == 0)) + { + // + // Can't do a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, "Can't find non-centrality parameter when the probability is 0 or 1, only possible answer is %1%", // LCOV_EXCL_LINE + RealType(std::numeric_limits::quiet_NaN()), Policy()); // LCOV_EXCL_LINE + } + t_non_centrality_finder f(v, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know is the right side of + // zero: + // + RealType guess; + if(f(0) < 0) + guess = 1; + else + guess = -1; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " or there is no answer to problem. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; + } +#endif + } // namespace detail ====================================================================== + + template > + class non_central_t_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + non_central_t_distribution(RealType v_, RealType lambda) : v(v_), ncp(lambda) + { + const char* function = "boost::math::non_central_t_distribution<%1%>::non_central_t_distribution(%1%,%1%)"; + RealType r; + detail::check_df_gt0_to_inf( + function, + v, &r, Policy()); + detail::check_non_centrality( + function, + static_cast(lambda * lambda), + &r, + Policy()); + } // non_central_t_distribution constructor. + + RealType degrees_of_freedom() const + { // Private data getter function. + return v; + } + RealType non_centrality() const + { // Private data getter function. + return ncp; + } +#if 0 + // + // This code is disabled, since there can be multiple answers to the + // question, and it's not clear how to find the "right" one. + // + static RealType find_degrees_of_freedom(RealType delta, RealType x, RealType p) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_degrees_of_freedom( + static_cast(delta), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_degrees_of_freedom(const complemented3_type& c) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_degrees_of_freedom( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + static RealType find_non_centrality(RealType v, RealType x, RealType p) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_non_centrality( + static_cast(v), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_non_centrality(const complemented3_type& c) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_non_centrality( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } +#endif + private: + // Data member, initialized by constructor. + RealType v; // degrees of freedom + RealType ncp; // non-centrality parameter + }; // template class non_central_t_distribution + + typedef non_central_t_distribution non_central_t; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_t_distribution(RealType,RealType)->non_central_t_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline const std::pair range(const non_central_t_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); + } + + template + inline const std::pair support(const non_central_t_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); + } + + template + inline RealType mode(const non_central_t_distribution& dist) + { // mode. + static const char* function = "mode(non_central_t_distribution<%1%> const&)"; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy())) + return static_cast(r); + + BOOST_MATH_STD_USING + + RealType m = v < 3 ? 0 : detail::mean(v, l, Policy()); + RealType var = v < 4 ? 1 : detail::variance(v, l, Policy()); + + return detail::generic_find_mode( + dist, + m, + function, + sqrt(var)); + } + + template + inline RealType mean(const non_central_t_distribution& dist) + { + BOOST_MATH_STD_USING + const char* function = "mean(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy())) + return static_cast(r); + if(v <= 1) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined mean for degrees of freedom <= 1: got v=%1%.", v, Policy()); + // return l * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, RealType(0.5f)); + return policies::checked_narrowing_cast( + detail::mean(static_cast(v), static_cast(l), forwarding_policy()), function); + + } // mean + + template + inline RealType variance(const non_central_t_distribution& dist) + { // variance. + const char* function = "variance(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + BOOST_MATH_STD_USING + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy())) + return static_cast(r); + if(v <= 2) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined variance for degrees of freedom <= 2: got v=%1%.", v, Policy()); + return policies::checked_narrowing_cast( + detail::variance(static_cast(v), static_cast(l), forwarding_policy()), function); + } + + // RealType standard_deviation(const non_central_t_distribution& dist) + // standard_deviation provided by derived accessors. + + template + inline RealType skewness(const non_central_t_distribution& dist) + { // skewness = sqrt(l). + const char* function = "skewness(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy())) + return static_cast(r); + if(v <= 3) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined skewness for degrees of freedom <= 3: got v=%1%.", v, Policy());; + return policies::checked_narrowing_cast( + detail::skewness(static_cast(v), static_cast(l), forwarding_policy()), function); + } + + template + inline RealType kurtosis_excess(const non_central_t_distribution& dist) + { + const char* function = "kurtosis_excess(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy())) + return static_cast(r); + if(v <= 4) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined kurtosis for degrees of freedom <= 4: got v=%1%.", v, Policy());; + return policies::checked_narrowing_cast( + detail::kurtosis_excess(static_cast(v), static_cast(l), forwarding_policy()), function); + } // kurtosis_excess + + template + inline RealType kurtosis(const non_central_t_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType pdf(const non_central_t_distribution& dist, const RealType& t) + { // Probability Density/Mass Function. + const char* function = "pdf(non_central_t_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), // we need l^2 to be countable. + &r, + Policy()) + || + !detail::check_x( + function, + t, + &r, + Policy())) + return static_cast(r); + return policies::checked_narrowing_cast( + detail::non_central_t_pdf(static_cast(v), + static_cast(l), + static_cast(t), + Policy()), + function); + } // pdf + + template + RealType cdf(const non_central_t_distribution& dist, const RealType& x) + { + const char* function = "boost::math::cdf(non_central_t_distribution<%1%>&, %1%)"; +// was const char* function = "boost::math::non_central_t_distribution<%1%>::cdf(%1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy()) + || + !detail::check_x( + function, + x, + &r, + Policy())) + return static_cast(r); + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(l, 1); + cdf(n, x); + //return cdf(normal_distribution(l, 1), x); + } + + if(l == 0) + { // NO non-centrality, so use Student's t instead. + return cdf(students_t_distribution(v), x); + } + return policies::checked_narrowing_cast( + detail::non_central_t_cdf( + static_cast(v), + static_cast(l), + static_cast(x), + false, Policy()), + function); + } // cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + // was const char* function = "boost::math::non_central_t_distribution<%1%>::cdf(%1%)"; + const char* function = "boost::math::cdf(const complement(non_central_t_distribution<%1%>&), %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + non_central_t_distribution const& dist = c.dist; + RealType x = c.param; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); // aka delta + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_non_centrality( + function, + static_cast(l * l), + &r, + Policy()) + || + !detail::check_x( + function, + x, + &r, + Policy())) + return static_cast(r); + + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(l, 1); + return cdf(complement(n, x)); + } + if(l == 0) + { // zero non-centrality so use Student's t distribution. + return cdf(complement(students_t_distribution(v), x)); + } + return policies::checked_narrowing_cast( + detail::non_central_t_cdf( + static_cast(v), + static_cast(l), + static_cast(x), + true, Policy()), + function); + } // ccdf + + template + inline RealType quantile(const non_central_t_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + static const char* function = "quantile(const non_central_t_distribution<%1%>, %1%)"; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + return detail::non_central_t_quantile(function, v, l, p, RealType(1-p), Policy()); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + static const char* function = "quantile(const complement(non_central_t_distribution<%1%>, %1%))"; + non_central_t_distribution const& dist = c.dist; + RealType q = c.param; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + return detail::non_central_t_quantile(function, v, l, RealType(1-q), q, Policy()); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_T_HPP + diff --git a/third-party/boost-math/include/boost/math/distributions/normal.hpp b/third-party/boost-math/include/boost/math/distributions/normal.hpp new file mode 100644 index 0000000000000..aa27c8feb1494 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/normal.hpp @@ -0,0 +1,368 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_NORMAL_HPP +#define BOOST_STATS_NORMAL_HPP + +// http://en.wikipedia.org/wiki/Normal_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Normal Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/NormalDistribution.html + +#include +#include +#include +#include +#include +#include // for erf/erfc. +#include +#include +#include +#include + +namespace boost{ namespace math{ + +template > +class normal_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit normal_distribution(RealType l_mean = 0, RealType sd = 1) + : m_mean(l_mean), m_sd(sd) + { // Default is a 'standard' normal distribution N01. + constexpr auto function = "boost::math::normal_distribution<%1%>::normal_distribution"; + + RealType result; + detail::check_scale(function, sd, &result, Policy()); + detail::check_location(function, l_mean, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType mean()const + { // alias for location. + return m_mean; + } + + BOOST_MATH_GPU_ENABLED RealType standard_deviation()const + { // alias for scale. + return m_sd; + } + + // Synonyms, provided to allow generic use of find_location and find_scale. + BOOST_MATH_GPU_ENABLED RealType location()const + { // location. + return m_mean; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { // scale. + return m_sd; + } + +private: + // + // Data members: + // + RealType m_mean; // distribution mean or location. + RealType m_sd; // distribution standard deviation or scale. +}; // class normal_distribution + +using normal = normal_distribution; + +// +// Deduction guides, note we don't check the +// value of __cpp_deduction_guides, just assume +// they work as advertised, even if this is pre-final C++17. +// +#ifdef __cpp_deduction_guides + +template +normal_distribution(RealType, RealType)->normal_distribution::type>; +template +normal_distribution(RealType)->normal_distribution::type>; + +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const normal_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max value. + } +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const normal_distribution& /*dist*/) +{ // This is range values for random variable x where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max value. + } +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + + constexpr auto function = "boost::math::pdf(const normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + RealType exponent = x - mean; + exponent *= -exponent; + exponent /= 2 * sd * sd; + + result = exp(exponent); + result /= sd * sqrt(2 * constants::pi()); + + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + const RealType sd = dist.standard_deviation(); + const RealType mean = dist.mean(); + + constexpr auto function = "boost::math::logpdf(const normal_distribution<%1%>&, %1%)"; + + RealType result = -boost::math::numeric_limits::infinity(); + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return result; // pdf + and - infinity is zero so logpdf is -inf + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType pi = boost::math::constants::pi(); + const RealType half = boost::math::constants::half(); + + result = -log(sd) - half*log(2*pi) - (x-mean)*(x-mean)/(2*sd*sd); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + constexpr auto function = "boost::math::cdf(const normal_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + RealType diff = (x - mean) / (sd * constants::root_two()); + result = boost::math::erfc(-diff, Policy()) / 2; + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const normal_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + constexpr auto function = "boost::math::quantile(const normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + result= boost::math::erfc_inv(2 * p, Policy()); + result = -result; + result *= sd * constants::root_two(); + result += mean; + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = c.dist.standard_deviation(); + RealType mean = c.dist.mean(); + RealType x = c.param; + constexpr auto function = "boost::math::cdf(const complement(normal_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero + } + if(false == detail::check_x(function, x, &result, Policy())) + return result; + + RealType diff = (x - mean) / (sd * constants::root_two()); + result = boost::math::erfc(diff, Policy()) / 2; + return result; +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = c.dist.standard_deviation(); + RealType mean = c.dist.mean(); + constexpr auto function = "boost::math::quantile(const complement(normal_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + result = boost::math::erfc_inv(2 * q, Policy()); + result *= sd * constants::root_two(); + result += mean; + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType standard_deviation(const normal_distribution& dist) +{ + return dist.standard_deviation(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const normal_distribution& /*dist*/) +{ + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const normal_distribution& /*dist*/) +{ + return 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const normal_distribution& /*dist*/) +{ + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const normal_distribution & dist) +{ + BOOST_MATH_STD_USING + RealType arg = constants::two_pi()*constants::e()*dist.standard_deviation()*dist.standard_deviation(); + return log(arg)/2; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_NORMAL_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/pareto.hpp b/third-party/boost-math/include/boost/math/distributions/pareto.hpp new file mode 100644 index 0000000000000..97cf8024a0b03 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/pareto.hpp @@ -0,0 +1,508 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007, 2009 +// Copyright Matt Borland 2023. +// 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) + +#ifndef BOOST_STATS_PARETO_HPP +#define BOOST_STATS_PARETO_HPP + +// http://en.wikipedia.org/wiki/Pareto_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Pareto Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/ParetoDistribution.html +// Handbook of Statistical Distributions with Applications, K Krishnamoorthy, ISBN 1-58488-635-8, Chapter 23, pp 257 - 267. +// Caution KK's a and b are the reverse of Mathworld! + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace math + { + namespace detail + { // Parameter checking. + template + BOOST_MATH_GPU_ENABLED inline bool check_pareto_scale( + const char* function, + RealType scale, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(scale)) + { // any > 0 finite value is OK. + if (scale > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be > 0!", scale, pol); + return false; + } + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be finite!", scale, pol); + return false; + } + } // bool check_pareto_scale + + template + BOOST_MATH_GPU_ENABLED inline bool check_pareto_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(shape)) + { // Any finite value > 0 is OK. + if (shape > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0!", shape, pol); + return false; + } + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be finite!", shape, pol); + return false; + } + } // bool check_pareto_shape( + + template + BOOST_MATH_GPU_ENABLED inline bool check_pareto_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // + if (x > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be > 0 !", x, pol); + return false; + } + } + else + { // Not finite.. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_pareto_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_pareto( // distribution parameters. + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) + { + return check_pareto_scale(function, scale, result, pol) + && check_pareto_shape(function, shape, result, pol); + } // bool check_pareto( + + } // namespace detail + + template > + class pareto_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED pareto_distribution(RealType l_scale = 1, RealType l_shape = 1) + : m_scale(l_scale), m_shape(l_shape) + { // Constructor. + RealType result = 0; + detail::check_pareto("boost::math::pareto_distribution<%1%>::pareto_distribution", l_scale, l_shape, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType scale()const + { // AKA Xm and Wolfram b and beta + return m_scale; + } + + BOOST_MATH_GPU_ENABLED RealType shape()const + { // AKA k and Wolfram a and alpha + return m_shape; + } + private: + // Data members: + RealType m_scale; // distribution scale (xm) or beta + RealType m_shape; // distribution shape (k) or alpha + }; + + typedef pareto_distribution pareto; // Convenience to allow pareto(2., 3.); + + #ifdef __cpp_deduction_guides + template + pareto_distribution(RealType)->pareto_distribution::type>; + template + pareto_distribution(RealType,RealType)->pareto_distribution::type>; + #endif + + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const pareto_distribution& /*dist*/) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // scale zero to + infinity. + } // range + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const pareto_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(dist.scale(), max_value() ); // scale to + infinity. + } // support + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const pareto_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + RealType result = 0; + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + if (x < scale) + { // regardless of shape, pdf is zero (or should be disallow x < scale and throw an exception?). + return 0; + } + result = shape * pow(scale, shape) / pow(x, shape+1); + return result; + } // pdf + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const pareto_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + RealType result = 0; + + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero. + return 0; + } + + // result = RealType(1) - pow((scale / x), shape); + result = -boost::math::powm1(scale/x, shape, Policy()); // should be more accurate. + return result; + } // cdf + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const pareto_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::logcdf(const pareto_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + RealType result = 0; + + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero. + return -boost::math::numeric_limits::infinity(); + } + + result = log1p(-pow(scale/x, shape), Policy()); + return result; + } // logcdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const pareto_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + if(false == (detail::check_probability(function, p, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + { + return result; + } + if (p == 0) + { + return scale; // x must be scale (or less). + } + if (p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); // x = + infinity. + } + result = scale / + (pow((1 - p), 1 / shape)); + // K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3 + return result; + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType x = c.param; + RealType scale = c.dist.scale(); + RealType shape = c.dist.shape(); + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero, and complement is unity. + return 1; + } + result = pow((scale/x), shape); + + return result; + } // cdf complement + + template + BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::logcdf(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType x = c.param; + RealType scale = c.dist.scale(); + RealType shape = c.dist.shape(); + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero, and complement is unity. + return 0; + } + result = log(pow((scale/x), shape)); + + return result; + } // logcdf complement + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + constexpr auto function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType q = c.param; + RealType scale = c.dist.scale(); + RealType shape = c.dist.shape(); + if(false == (detail::check_probability(function, q, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + { + return result; + } + if (q == 1) + { + return scale; // x must be scale (or less). + } + if (q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); // x = + infinity. + } + result = scale / (pow(q, 1 / shape)); + // K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3 + return result; + } // quantile complement + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const pareto_distribution& dist) + { + RealType result = 0; + constexpr auto function = "boost::math::mean(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy())) + { + return result; + } + if (dist.shape() > RealType(1)) + { + return dist.shape() * dist.scale() / (dist.shape() - 1); + } + else + { + using boost::math::tools::max_value; + return max_value(); // +infinity. + } + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const pareto_distribution& dist) + { + return dist.scale(); + } // mode + + template + BOOST_MATH_GPU_ENABLED inline RealType median(const pareto_distribution& dist) + { + RealType result = 0; + constexpr auto function = "boost::math::median(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy())) + { + return result; + } + BOOST_MATH_STD_USING + return dist.scale() * pow(RealType(2), (1/dist.shape())); + } // median + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const pareto_distribution& dist) + { + RealType result = 0; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + constexpr auto function = "boost::math::variance(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, scale, shape, &result, Policy())) + { + return result; + } + if (shape > 2) + { + result = (scale * scale * shape) / + ((shape - 1) * (shape - 1) * (shape - 2)); + } + else + { + result = policies::raise_domain_error( + function, + "variance is undefined for shape <= 2, but got %1%.", dist.shape(), Policy()); + } + return result; + } // variance + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const pareto_distribution& dist) + { + BOOST_MATH_STD_USING + RealType result = 0; + RealType shape = dist.shape(); + constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 3) + { + result = sqrt((shape - 2) / shape) * + 2 * (shape + 1) / + (shape - 3); + } + else + { + result = policies::raise_domain_error( + function, + "skewness is undefined for shape <= 3, but got %1%.", dist.shape(), Policy()); + } + return result; + } // skewness + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const pareto_distribution& dist) + { + RealType result = 0; + RealType shape = dist.shape(); + constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 4) + { + result = 3 * ((shape - 2) * (3 * shape * shape + shape + 2)) / + (shape * (shape - 3) * (shape - 4)); + } + else + { + result = policies::raise_domain_error( + function, + "kurtosis_excess is undefined for shape <= 4, but got %1%.", shape, Policy()); + } + return result; + } // kurtosis + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const pareto_distribution& dist) + { + RealType result = 0; + RealType shape = dist.shape(); + constexpr auto function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 4) + { + result = 6 * ((shape * shape * shape) + (shape * shape) - 6 * shape - 2) / + (shape * (shape - 3) * (shape - 4)); + } + else + { + result = policies::raise_domain_error( + function, + "kurtosis_excess is undefined for shape <= 4, but got %1%.", dist.shape(), Policy()); + } + return result; + } // kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType entropy(const pareto_distribution& dist) + { + BOOST_MATH_STD_USING + RealType xm = dist.scale(); + RealType alpha = dist.shape(); + return log(xm/alpha) + 1 + 1/alpha; + } + + } // namespace math + } // namespace boost + + // This include must be at the end, *after* the accessors + // for this distribution have been defined, in order to + // keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_PARETO_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/poisson.hpp b/third-party/boost-math/include/boost/math/distributions/poisson.hpp new file mode 100644 index 0000000000000..c2fad66be0260 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/poisson.hpp @@ -0,0 +1,563 @@ +// boost\math\distributions\poisson.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. +// Copyright Matt Borland 2024. + +// 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) + +// Poisson distribution is a discrete probability distribution. +// It expresses the probability of a number (k) of +// events, occurrences, failures or arrivals occurring in a fixed time, +// assuming these events occur with a known average or mean rate (lambda) +// and are independent of the time since the last event. +// The distribution was discovered by Simeon-Denis Poisson (1781-1840). + +// Parameter lambda is the mean number of events in the given time interval. +// The random variate k is the number of events, occurrences or arrivals. +// k argument may be integral, signed, or unsigned, or floating point. +// If necessary, it has already been promoted from an integral type. + +// Note that the Poisson distribution +// (like others including the binomial, negative binomial & Bernoulli) +// is strictly defined as a discrete function: +// only integral values of k are envisaged. +// However because the method of calculation uses a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +// See http://en.wikipedia.org/wiki/Poisson_distribution +// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html + +#ifndef BOOST_MATH_SPECIAL_POISSON_HPP +#define BOOST_MATH_SPECIAL_POISSON_HPP + +#include +#include +#include +#include +#include +#include // for incomplete gamma. gamma_q +#include // for incomplete gamma. gamma_q +#include // complements +#include // error checks +#include // isnan. +#include // factorials. +#include // for root finding. +#include + +namespace boost +{ + namespace math + { + namespace poisson_detail + { + // Common error checking routines for Poisson distribution functions. + // These are convoluted, & apparently redundant, to try to ensure that + // checks are always performed, even if exceptions are not enabled. + + template + BOOST_MATH_GPU_ENABLED inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(mean) || (mean < 0)) + { + *result = policies::raise_domain_error( + function, + "Mean argument is %1%, but must be >= 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean + + template + BOOST_MATH_GPU_ENABLED inline bool check_mean_NZ(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { // mean == 0 is considered an error. + if( !(boost::math::isfinite)(mean) || (mean <= 0)) + { + *result = policies::raise_domain_error( + function, + "Mean argument is %1%, but must be > 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean_NZ + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { // Only one check, so this is redundant really but should be optimized away. + return check_mean_NZ(function, mean, result, pol); + } // bool check_dist + + template + BOOST_MATH_GPU_ENABLED inline bool check_k(const char* function, const RealType& k, RealType* result, const Policy& pol) + { + if((k < 0) || !(boost::math::isfinite)(k)) + { + *result = policies::raise_domain_error( + function, + "Number of events k argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // bool check_k + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_k(const char* function, RealType mean, RealType k, RealType* result, const Policy& pol) + { + if((check_dist(function, mean, result, pol) == false) || + (check_k(function, k, result, pol) == false)) + { + return false; + } + return true; + } // bool check_dist_and_k + + template + BOOST_MATH_GPU_ENABLED inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { // Check 0 <= p <= 1 + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + BOOST_MATH_GPU_ENABLED inline bool check_dist_and_prob(const char* function, RealType mean, RealType p, RealType* result, const Policy& pol) + { + if((check_dist(function, mean, result, pol) == false) || + (check_prob(function, p, result, pol) == false)) + { + return false; + } + return true; + } // bool check_dist_and_prob + + } // namespace poisson_detail + + template > + class poisson_distribution + { + public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit poisson_distribution(RealType l_mean = 1) : m_l(l_mean) // mean (lambda). + { // Expected mean number of events that occur during the given interval. + RealType r; + poisson_detail::check_dist( + "boost::math::poisson_distribution<%1%>::poisson_distribution", + m_l, + &r, Policy()); + } // poisson_distribution constructor. + + BOOST_MATH_GPU_ENABLED RealType mean() const + { // Private data getter function. + return m_l; + } + private: + // Data member, initialized by constructor. + RealType m_l; // mean number of occurrences. + }; // template class poisson_distribution + + using poisson = poisson_distribution; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + poisson_distribution(RealType)->poisson_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const poisson_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); // Max integer? + } + + template + BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const poisson_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const poisson_distribution& dist) + { // Mean of poisson distribution = lambda. + return dist.mean(); + } // mean + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const poisson_distribution& dist) + { // mode. + BOOST_MATH_STD_USING // ADL of std functions. + return floor(dist.mean()); + } + + // Median now implemented via quantile(half) in derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const poisson_distribution& dist) + { // variance. + return dist.mean(); + } + + // standard_deviation provided by derived accessors. + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const poisson_distribution& dist) + { // skewness = sqrt(l). + BOOST_MATH_STD_USING // ADL of std functions. + return 1 / sqrt(dist.mean()); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const poisson_distribution& dist) + { // skewness = sqrt(l). + return 1 / dist.mean(); // kurtosis_excess 1/mean from Wiki & MathWorld eq 31. + // http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess + // is more convenient because the kurtosis excess of a normal distribution is zero + // whereas the true kurtosis is 3. + } // RealType kurtosis_excess + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const poisson_distribution& dist) + { // kurtosis is 4th moment about the mean = u4 / sd ^ 4 + // http://en.wikipedia.org/wiki/Kurtosis + // kurtosis can range from -2 (flat top) to +infinity (sharp peak & heavy tails). + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm + return 3 + 1 / dist.mean(); // NIST. + // http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess + // is more convenient because the kurtosis excess of a normal distribution is zero + // whereas the true kurtosis is 3. + } // RealType kurtosis + + template + BOOST_MATH_GPU_ENABLED RealType pdf(const poisson_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + // Probability that there are EXACTLY k occurrences (or arrivals). + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType mean = dist.mean(); + // Error check: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::pdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + + // Special case of mean zero, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is zero. + return 0; + } + if (k == 0) + { // mean ^ k = 1, and k! = 1, so can simplify. + return exp(-mean); + } + return boost::math::gamma_p_derivative(k+1, mean, Policy()); + } // pdf + + template + BOOST_MATH_GPU_ENABLED RealType logpdf(const poisson_distribution& dist, const RealType& k) + { + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions. + using boost::math::lgamma; + + RealType mean = dist.mean(); + // Error check: + RealType result = -boost::math::numeric_limits::infinity(); + if(false == poisson_detail::check_dist_and_k( + "boost::math::pdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + + // Special case of mean zero, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is zero. + return boost::math::numeric_limits::quiet_NaN(); + } + + // Special case where k and lambda are both positive + if(k > 0 && mean > 0) + { + return -lgamma(k+1) + k*log(mean) - mean; + } + + result = log(pdf(dist, k)); + return result; + } + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const poisson_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Poisson. + // The random variate k is the number of occurrences(or arrivals) + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + // Returns the sum of the terms 0 through k of the Poisson Probability Density or Mass (pdf). + + // But note that the Poisson distribution + // (like others including the binomial, negative binomial & Bernoulli) + // is strictly defined as a discrete function: only integral values of k are envisaged. + // However because of the method of calculation using a continuous gamma function, + // it is convenient to treat it as if it is a continuous function + // and permit non-integral values of k. + // To enforce the strict mathematical model, users should use floor or ceil functions + // outside this function to ensure that k is integral. + + // The terms are not summed directly (at least for larger k) + // instead the incomplete gamma integral is employed, + + BOOST_MATH_STD_USING // for ADL of std function exp. + + RealType mean = dist.mean(); + // Error checks: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::cdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + // Special cases: + if (mean == 0) + { // Probability for any k is zero. + return 0; + } + if (k == 0) + { + // mean (and k) have already been checked, + // so this avoids unnecessary repeated checks. + return exp(-mean); + } + // For small integral k could use a finite sum - + // it's cheaper than the gamma function. + // BUT this is now done efficiently by gamma_q function. + // Calculate poisson cdf using the gamma_q function. + return gamma_q(k+1, mean, Policy()); + } // binomial cdf + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Poisson + // The random variate k is the number of events, occurrences or arrivals. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + // But note that the Poisson distribution + // (like others including the binomial, negative binomial & Bernoulli) + // is strictly defined as a discrete function: only integral values of k are envisaged. + // However because of the method of calculation using a continuous gamma function, + // it is convenient to treat it as is it is a continuous function + // and permit non-integral values of k. + // To enforce the strict mathematical model, users should use floor or ceil functions + // outside this function to ensure that k is integral. + + // Returns the sum of the terms k+1 through inf of the Poisson Probability Density/Mass (pdf). + // The terms are not summed directly (at least for larger k) + // instead the incomplete gamma integral is employed, + + RealType const& k = c.param; + poisson_distribution const& dist = c.dist; + + RealType mean = dist.mean(); + + // Error checks: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::cdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + // Special case of mean, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is unity, complement of zero. + return 1; + } + if (k == 0) + { // Avoid repeated checks on k and mean in gamma_p. + return -boost::math::expm1(-mean, Policy()); + } + // Unlike un-complemented cdf (sum from 0 to k), + // can't use finite sum from k+1 to infinity for small integral k, + // anyway it is now done efficiently by gamma_p. + return gamma_p(k + 1, mean, Policy()); // Calculate Poisson cdf using the gamma_p function. + // CCDF = gamma_p(k+1, lambda) + } // poisson ccdf + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const poisson_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) Poisson function. + // Return the number of expected events k for a given probability p. + constexpr auto function = "boost::math::quantile(const poisson_distribution<%1%>&, %1%)"; + RealType result = 0; // of Argument checks: + if(false == poisson_detail::check_prob( + function, + p, + &result, Policy())) + { + return result; + } + // Special case: + if (dist.mean() == 0) + { // if mean = 0 then p = 0, so k can be anything? + if (false == poisson_detail::check_mean_NZ( + function, + dist.mean(), + &result, Policy())) + { + return result; + } + } + if(p == 0) + { + return 0; // Exact result regardless of discrete-quantile Policy + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + using discrete_type = typename Policy::discrete_quantile_type; + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + RealType guess; + RealType factor = 8; + RealType z = dist.mean(); + if(z < 1) + guess = z; + else + guess = boost::math::detail::inverse_poisson_cornish_fisher(z, p, RealType(1-p), Policy()); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + + return detail::inverse_discrete_quantile( + dist, + p, + false, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) of Poisson function. + // Return the number of expected events k for a given + // complement of the probability q. + // + // Error checks: + constexpr auto function = "boost::math::quantile(complement(const poisson_distribution<%1%>&, %1%))"; + RealType q = c.param; + const poisson_distribution& dist = c.dist; + RealType result = 0; // of argument checks. + if(false == poisson_detail::check_prob( + function, + q, + &result, Policy())) + { + return result; + } + // Special case: + if (dist.mean() == 0) + { // if mean = 0 then p = 0, so k can be anything? + if (false == poisson_detail::check_mean_NZ( + function, + dist.mean(), + &result, Policy())) + { + return result; + } + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(q == 1) + { + return 0; // Exact result regardless of discrete-quantile Policy + } + using discrete_type = typename Policy::discrete_quantile_type; + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + RealType guess; + RealType factor = 8; + RealType z = dist.mean(); + if(z < 1) + guess = z; + else + guess = boost::math::detail::inverse_poisson_cornish_fisher(z, RealType(1-q), q, Policy()); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + + return detail::inverse_discrete_quantile( + dist, + q, + true, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_POISSON_HPP + + + diff --git a/third-party/boost-math/include/boost/math/distributions/rayleigh.hpp b/third-party/boost-math/include/boost/math/distributions/rayleigh.hpp new file mode 100644 index 0000000000000..155525b5399c1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/rayleigh.hpp @@ -0,0 +1,381 @@ +// Copyright Paul A. Bristow 2007. +// Copyright Matt Borland 2023. +// 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) + +#ifndef BOOST_STATS_rayleigh_HPP +#define BOOST_STATS_rayleigh_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost{ namespace math{ + +namespace detail +{ // Error checks: + template + BOOST_MATH_GPU_ENABLED inline bool verify_sigma(const char* function, RealType sigma, RealType* presult, const Policy& pol) + { + if((sigma <= 0) || (!(boost::math::isfinite)(sigma))) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"sigma\" must be > 0 and finite, but was: %1%.", sigma, pol); + return false; + } + return true; + } // bool verify_sigma + + template + BOOST_MATH_GPU_ENABLED inline bool verify_rayleigh_x(const char* function, RealType x, RealType* presult, const Policy& pol) + { + if((x < 0) || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error( + function, + "The random variable must be >= 0, but was: %1%.", x, pol); + return false; + } + return true; + } // bool verify_rayleigh_x +} // namespace detail + +template > +class rayleigh_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit rayleigh_distribution(RealType l_sigma = 1) + : m_sigma(l_sigma) + { + RealType err; + detail::verify_sigma("boost::math::rayleigh_distribution<%1%>::rayleigh_distribution", l_sigma, &err, Policy()); + } // rayleigh_distribution + + BOOST_MATH_GPU_ENABLED RealType sigma()const + { // Accessor. + return m_sigma; + } + +private: + RealType m_sigma; +}; // class rayleigh_distribution + +using rayleigh = rayleigh_distribution; + +#ifdef __cpp_deduction_guides +template +rayleigh_distribution(RealType)->rayleigh_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const rayleigh_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const rayleigh_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + + RealType sigma = dist.sigma(); + RealType result = 0; + constexpr auto function = "boost::math::pdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; + } + RealType sigmasqr = sigma * sigma; + result = x * (exp(-(x * x) / ( 2 * sigmasqr))) / sigmasqr; + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + + const RealType sigma = dist.sigma(); + RealType result = -boost::math::numeric_limits::infinity(); + constexpr auto function = "boost::math::logpdf(const rayleigh_distribution<%1%>&, %1%)"; + + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return result; + } + + result = -(x*x)/(2*sigma*sigma) - 2*log(sigma) + log(x); + return result; +} // logpdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = dist.sigma(); + constexpr auto function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + result = -boost::math::expm1(-x * x / ( 2 * sigma * sigma), Policy()); + return result; +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = dist.sigma(); + constexpr auto function = "boost::math::logcdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + result = log1p(-exp(-x * x / ( 2 * sigma * sigma)), Policy()); + return result; +} // logcdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const rayleigh_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = dist.sigma(); + constexpr auto function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + { + return 0; + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = sqrt(-2 * sigma * sigma * boost::math::log1p(-p, Policy())); + return result; +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = c.dist.sigma(); + constexpr auto function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + RealType x = c.param; + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + RealType ea = x * x / (2 * sigma * sigma); + // Fix for VC11/12 x64 bug in exp(float): + if (ea >= tools::max_value()) + return 0; + result = exp(-ea); + return result; +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = c.dist.sigma(); + constexpr auto function = "boost::math::logcdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + RealType x = c.param; + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return -boost::math::numeric_limits::infinity(); + } + RealType ea = x * x / (2 * sigma * sigma); + // Fix for VC11/12 x64 bug in exp(float): + if (ea >= tools::max_value()) + return 0; + result = -ea; + return result; +} // logcdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions, log & sqrt. + + RealType result = 0; + RealType sigma = c.dist.sigma(); + constexpr auto function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + { + return result; + } + if(q == 1) + { + return 0; + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = sqrt(-2 * sigma * sigma * log(q)); + return result; +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const rayleigh_distribution& dist) +{ + RealType result = 0; + RealType sigma = dist.sigma(); + constexpr auto function = "boost::math::mean(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + using boost::math::constants::root_half_pi; + return sigma * root_half_pi(); +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const rayleigh_distribution& dist) +{ + RealType result = 0; + RealType sigma = dist.sigma(); + constexpr auto function = "boost::math::variance(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + using boost::math::constants::four_minus_pi; + return four_minus_pi() * sigma * sigma / 2; +} // variance + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const rayleigh_distribution& dist) +{ + return dist.sigma(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const rayleigh_distribution& dist) +{ + using boost::math::constants::root_ln_four; + return root_ln_four() * dist.sigma(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const rayleigh_distribution& /*dist*/) +{ + return static_cast(0.63111065781893713819189935154422777984404221106391L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // 2 * sqrt(pi) * (pi-3) / pow(4, 2/3) - pi +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const rayleigh_distribution& /*dist*/) +{ + return static_cast(3.2450893006876380628486604106197544154170667057995L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // 3 - (6*pi*pi - 24*pi + 16) / pow(4-pi, 2) +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + return static_cast(0.2450893006876380628486604106197544154170667057995L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // -(6*pi*pi - 24*pi + 16) / pow(4-pi,2) +} // kurtosis_excess + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const rayleigh_distribution& dist) +{ + BOOST_MATH_STD_USING + return 1 + log(dist.sigma()*constants::one_div_root_two()) + constants::euler()/2; +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_rayleigh_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/saspoint5.hpp b/third-party/boost-math/include/boost/math/distributions/saspoint5.hpp new file mode 100644 index 0000000000000..7846b99560f92 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/saspoint5.hpp @@ -0,0 +1,2796 @@ +// Copyright Takuma Yoshimura 2024. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_SASPOINT5_HPP +#define BOOST_STATS_SASPOINT5_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#endif + +namespace boost { namespace math { +template +class saspoint5_distribution; + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.125) { + // Rational Approximation + // Maximum Relative Error: 7.8747e-17 + BOOST_MATH_STATIC const RealType P[13] = { + static_cast(6.36619772367581343076e-1), + static_cast(2.17275699713513462507e2), + static_cast(3.49063163361344578910e4), + static_cast(3.40332906932698464252e6), + static_cast(2.19485577044357440949e8), + static_cast(9.66086435948730562464e9), + static_cast(2.90571833690383003932e11), + static_cast(5.83089315593106044683e12), + static_cast(7.37911022713775715766e13), + static_cast(5.26757196603002476852e14), + static_cast(1.75780353683063527570e15), + static_cast(1.85883041942144306222e15), + static_cast(4.19828222275972713819e14), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + static_cast(1.), + static_cast(3.41295871011779138155e2), + static_cast(5.48907134827349102297e4), + static_cast(5.36641455324410261980e6), + static_cast(3.48045461004960397915e8), + static_cast(1.54920747349701741537e10), + static_cast(4.76490595358644532404e11), + static_cast(1.00104823128402735005e13), + static_cast(1.39703522470411802507e14), + static_cast(1.23724881334160220266e15), + static_cast(6.47437580921138359461e15), + static_cast(1.77627318260037604066e16), + static_cast(2.04792815832538146160e16), + static_cast(7.45102534638640681964e15), + static_cast(3.68496090049571174527e14), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 0.25) { + RealType t = x - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 2.1471e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(4.35668401768623200524e-1), + static_cast(7.12477357389655327116e0), + static_cast(4.02466317948738993787e1), + static_cast(9.04888497628205955839e1), + static_cast(7.56175387288619211460e1), + static_cast(1.26950253999694502457e1), + static_cast(-6.59304802132933325219e-1), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.98623818041545101115e1), + static_cast(1.52856383017632616759e2), + static_cast(5.70706902111659740041e2), + static_cast(1.06454927680197927878e3), + static_cast(9.13160352749764887791e2), + static_cast(2.58872466837209126618e2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 0.5) { + RealType t = x - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 5.3265e-17 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.95645445681747568732e-1), + static_cast(2.23779537590791610124e0), + static_cast(5.01302198171248036052e0), + static_cast(2.76363131116340641935e0), + static_cast(1.18134858311074670327e-1), + static_cast(2.00287083462139382715e-2), + static_cast(-7.53979800555375661516e-3), + static_cast(1.37294648777729527395e-3), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(1.02879626214781666701e1), + static_cast(3.85125274509784615691e1), + static_cast(6.18474367367800231625e1), + static_cast(3.77100050087302476029e1), + static_cast(5.41866360740066443656e0), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 1) { + RealType t = x - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 2.7947e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.70762401725206223811e-1), + static_cast(8.43343631021918972436e-1), + static_cast(1.39703819152564365627e0), + static_cast(8.75843324574692085009e-1), + static_cast(1.86199552443747562584e-1), + static_cast(7.35858280181579907616e-3), + static_cast(-1.03693607694266081126e-4), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(6.73363440952557318819e0), + static_cast(1.74288966619209299976e1), + static_cast(2.15943268035083671893e1), + static_cast(1.29818726981381859879e1), + static_cast(3.40707211426946022041e0), + static_cast(2.80229012541729457678e-1), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 1.7051e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(8.61071469126041183247e-2), + static_cast(1.69689585946245345838e-1), + static_cast(1.09494833291892212033e-1), + static_cast(2.76619622453130604637e-2), + static_cast(2.44972748006913061509e-3), + static_cast(4.09853605772288438003e-5), + static_cast(-2.63561415158954865283e-7), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.04082856018856244947e0), + static_cast(3.52558663323956252986e0), + static_cast(1.94795523079701426332e0), + static_cast(5.23956733400745421623e-1), + static_cast(6.19453597593998871667e-2), + static_cast(2.31061984192347753499e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 2.9247e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(3.91428580496513429479e-2), + static_cast(4.07162484034780126757e-2), + static_cast(1.43342733342753081931e-2), + static_cast(2.01622178115394696215e-3), + static_cast(1.00648013467757737201e-4), + static_cast(9.51545046750892356441e-7), + static_cast(-3.56598940936439037087e-9), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.63904431617187026619e0), + static_cast(1.03812003196677309121e0), + static_cast(3.18144310790210668797e-1), + static_cast(4.81930155615666517263e-2), + static_cast(3.25435391589941361778e-3), + static_cast(7.01626957128181647457e-5), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 2.6547e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.65057384221262866484e-2), + static_cast(8.05429762031495873704e-3), + static_cast(1.35249234647852784985e-3), + static_cast(9.18685252682786794440e-5), + static_cast(2.23447790937806602674e-6), + static_cast(1.03176916111395079569e-8), + static_cast(-1.94913182592441292094e-11), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(8.10113554189626079232e-1), + static_cast(2.54175325409968367580e-1), + static_cast(3.87119072807894983910e-2), + static_cast(2.92520770162792443587e-3), + static_cast(9.89094130526684467420e-5), + static_cast(1.07148513311070719488e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 2.5484e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(6.60044810497290557553e-3), + static_cast(1.59342644994950292031e-3), + static_cast(1.32429706922966110874e-4), + static_cast(4.45378136978435909660e-6), + static_cast(5.36409958111394628239e-8), + static_cast(1.22293787679910067873e-10), + static_cast(-1.16300443044165216564e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(4.10446485803039594111e-1), + static_cast(6.51887342399859289520e-2), + static_cast(5.02151225308643905366e-3), + static_cast(1.91741179639551137839e-4), + static_cast(3.27316600311598190022e-6), + static_cast(1.78840301213102212857e-8), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 2.9866e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.54339461777955741686e-3), + static_cast(3.10069525357852579756e-4), + static_cast(1.30082682796085732756e-5), + static_cast(2.20715868479255585050e-7), + static_cast(1.33996659756026452288e-9), + static_cast(1.53505360463827994365e-12), + static_cast(-7.42649416356965421308e-16), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(2.09203384450859785642e-1), + static_cast(1.69422626897631306130e-2), + static_cast(6.65649059670689720386e-4), + static_cast(1.29654785666009849481e-5), + static_cast(1.12886139474560969619e-7), + static_cast(3.14420104899170413840e-10), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 3.3581e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(9.55085695067883584460e-4), + static_cast(5.86125496733202756668e-5), + static_cast(1.23753971325810931282e-6), + static_cast(1.05643819745933041408e-8), + static_cast(3.22502949410095015524e-11), + static_cast(1.85366144680157942079e-14), + static_cast(-4.53975807317403152058e-18), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.05980850386474826374e-1), + static_cast(4.34966042652000070674e-3), + static_cast(8.66341538387446465700e-5), + static_cast(8.55608082202236124363e-7), + static_cast(3.77719968378509293354e-9), + static_cast(5.33287361559571716670e-12), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x); + + // Rational Approximation + // Maximum Relative Error: 4.7450e-19 + BOOST_MATH_STATIC const RealType P[5] = { + static_cast(1.99471140200716338970e-1), + static_cast(-1.93310094131437487158e-2), + static_cast(-8.44282614309073196195e-3), + static_cast(3.47296024282356038069e-3), + static_cast(-4.05398011689821941383e-4), + }; + BOOST_MATH_STATIC const RealType Q[5] = { + static_cast(1.), + static_cast(7.00973251258577238892e-1), + static_cast(2.66969681258835723157e-1), + static_cast(5.51785147503612200456e-2), + static_cast(6.50130030979966274341e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_pdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.0625) { + // Rational Approximation + // Maximum Relative Error: 8.8841e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[27] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.36619772367581343075535053490057448138e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.57459506929453385798277946154823008327e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46717322844023441698710451505816706570e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71501459971530549476153273173061194095e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76700973495278431084530045707075552432e10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01328150775099946510145440412520620021e13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70028222513668830210058353057559790101e15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29641781943744384078006991488193839955e17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52611994112742436432957758588495082163e19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27833177267552931459542318826727288124e21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68946162731840551853993619351896931533e23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02965010233956763504899745874128908220e25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.14128569264874914146628076133997950655e26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09103580386900060922163883603492216942e28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.86778299087452621293332172137014749128e29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80029712249744334924217328667885673985e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70890080432228368476255091774238573277e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88600513999992354909078399482884993261e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.01189178534848836605739139176681647755e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06531475170803043941021113424602440078e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64956999370443524098457423629252855270e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44276098283517934229787916584447559248e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.45856704224433991524661028965741649584e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.47263237190968408624388275549716907309e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.66186300951901408251743228798832386260e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.48064966533519934186356663849904556319e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64877082086372991309408001661535573441e35), + }; + BOOST_MATH_STATIC const RealType Q[28] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18981461118065892086304195732751798634e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.01761929839041982958990681130944341399e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69465252239913021973760046507387620537e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.49221044103838155300076098325950584061e10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59327386289821190042576978177896481082e13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67528179803224728786405503232064643870e15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61672367849271591791062829736720884633e17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98395893917909208201801908435620016552e19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60025693881358827551113845076726845495e21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67730578745705562356709169493821118109e23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63843883526710042156562706339553092312e25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.23075214698024188140971761421762265880e26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.37775321923937393366376907114580842429e28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12444724625354796650300159037364355605e30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00860835602766063447009568106012449767e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.39614080159468893509273006948526469708e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06547095715472468415058181351212520255e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36755997709303811764051969789337337957e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32519530489892818585066019217287415587e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.45230390606834183602522256278256501404e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80344475131699029428900627020022801971e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66469314795307459840482483320814279444e38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70209065673736156218117594311801487932e38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.84490531246108754748100009460860427732e38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30215083398643966091721732133851539475e38), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.58032845332990262754766784625271262271e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.50461648438613634025964361513066059697e36), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 0.125) { + RealType t = x - static_cast (0.0625); + + // Rational Approximation + // Maximum Relative Error: 3.4585e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46416716200748206779925127900698754119e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.41771273526123373239570033672829787791e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56142610225585235535211648703534340871e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15655694129872563686497490176725921724e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.00791883661952751945853742455643714995e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30252591667828615354689186280704562254e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76168115448224677276551213052798322583e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.88534624532179841393387625270218172719e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14740447137831585842166880265350244623e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14904082614021239315925958812100948136e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.76866867279164114004579652405104553404e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53475339598769347326916978463911377965e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.88896160275915786487519266368539625326e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05543800791717482823610940401201712196e4), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.44407579416524903840331499438398472639e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15911780811299460009161345260146251462e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.88457596285725454686358792906273558406e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.66501639812506059997744549411633476528e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.12674134216028769532305433586266118000e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.87676063477990584593444083577765264392e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.56084282739608760299329382263598821653e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.34250986378665047914811630036201995871e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31288233106689286803200674021353188597e9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33621494302241474082474689597125896975e9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.63379428046258653791600947328520263412e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14558538557562267533922961110917101850e8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 0.25) { + RealType t = x - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 6.9278e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35668401768623200524372663239480799018e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30066509937988171489091367354416214000e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.05924026744937322690717755156090122074e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.12998524955326375684693500551926325112e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52237930808361186011042950178715609183e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.10734809597587633852077152938985998879e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.20796157836149826988172603622242119074e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12398478061053302537736799402801934778e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17841330491647012385157454335820786724e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.46281413765362795389526259057436151953e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52220357379402116641048490644093497829e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.51130316105543847380510577656570543736e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.32201781975497810173532067354797097401e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.96874547436310030183519174847668703774e0), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.63164311578114868477819520857286165076e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34964379844144961683927306966955217328e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82966031793809959278519002412667883288e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56215285850856046267451500310816276675e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.81046679663412610005501878092824281161e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.33868038251479411246071640628518434659e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.46262495881941625571640264458627940579e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.40052628730443097561652737049917920495e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44394803828297754346261138417756941544e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.56647617803506258343236509255155360957e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.53513095899009948733175317927025056561e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69130675750530663088963759279778748696e5), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 0.5) { + RealType t = x - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 6.9378e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95645445681747568731488283573032414811e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.83246437763964151893665752064650172391e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.85333417559435252576820440080930004674e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90974714199542064991001365628659054084e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39707205668285805800884524044738261436e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.24814598419826565698241508792385416075e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.95012897118808793886195172068123345314e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.87265743900139300849404272909665705025e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.98795164648056126707212245325405968413e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07012128790318535418330629467906917213e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99797198893523173981812955075412130913e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55029227544167913873724286459253168886e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54064889901609722583601330171719819660e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.72254289950537680833853394958874977464e-3), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.58291085070053442257438623486099473087e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95618461039379226195473938654286975682e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97427161745150579714266897556974326502e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.52730436681412535198281529590508861106e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49521185356761585062135933350225236726e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.03881178612341724262911142022761966061e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.02360046338629039644581819847209730553e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65580339066083507998465454599272345735e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.15462499626138125314518636645472893045e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61951767959774678843021179589300545717e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.60745557054877240279811529503888551492e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91061555870569579915258835459255406575e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43045229010040855016672246098687100063e1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 1) { + RealType t = x - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 6.4363e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70762401725206223811383500786268939645e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19353011456197635663058525904929358535e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22974648900600015961253465796487372402e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91951696059042324975935209295355569292e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.79039444119906169910281912009369164227e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00089963120992100860902142265631127046e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37108883429306700857182028809960789020e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.49586566873564432788366931251358248417e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49790521605774884174840168128255220471e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.90660338063979435668763608259382712726e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93409982383888149064797608605579930804e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22802459215932860445033185874876812040e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.07739227340181463034286653569468171767e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.02669738424010290973023004028523684766e-7), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46404480283267324138113869370306506431e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.54550184643308468933661600211579108422e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.63602410602063476726031476852965502123e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.94463479638213888403144706176973026333e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48607087483870766806529883069123352339e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69715692924508994524755312953665710218e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33237849965272853370191827043868842100e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.08460086451666825383009487734769646087e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.47365552394788536087148438788608689300e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.38010282703940184371247559455167674975e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.67219842525655806370702248122668214685e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.01852843874982199859775136086676841910e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.14767043526088185802569803397824432028e-3), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 9.1244e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.61071469126041183247373313827161939454e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.35837460186564880289965856498718321896e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.47783071967681246738651796742079530382e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16019502727107539284403003943433359877e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.80510046274709592896987229782879937271e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30456542768955299533391113704078540955e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36539167913428133313942008990965988621e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76450743657913389896743235938695682829e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42847090205575096649865021874905747106e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41380341540026027117735179862124402398e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.40549721587212773424211923602910622515e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09089653391032945883918434200567278139e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21403900721572475664926557233205232491e-10), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.13172035933794917563324458011617112124e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65687100738157412154132860910003018338e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59672433683883998168388916533196510994e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61469557815097583209668778301921207455e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.77070955301136405523492329700943077340e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.20825570431301943907348077675777546304e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.60136197167727810483751794121979805142e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.53723076053642006159503073104152703814e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.63397465217490984394478518334313362490e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.40577918603319523990542237990107206371e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94376458316662573143947719026985667328e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.09333568224541559157192543410988474886e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.59947287428695057506683902409023760438e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 8.1110e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91428580496513429479068747515164587814e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.69015019070193436467106672180804948494e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03147451266231819912643754579290008651e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.18825170881552297150779588545792258740e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30548850262278582401286533053286406505e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.54315108501815531776138839512564427279e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.66434584176931077662201101557716482514e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.66158632576958238392567355014249971287e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31365802206301246598393821671437863818e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85378389166807263837732376845556856416e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20375363151456683883984823721339648679e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06637401794693307359898089790558771957e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08663671047376684678494625068451888284e-14), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.07443397096591141329212291707948432414e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16665031056584124503224711639009530348e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27666060511630720485121299731204403783e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65646979169107732387032821262953301311e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.63594064986880863092994744424349361396e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31360114173642293100378020953197965181e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.09489929949457075237756409511944811481e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24574519309785870806550506199124944514e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56048486483867679310086683710523566607e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60417286783794818094722636906776809193e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53154117367296710469692755461431646999e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60041713691072903334637560080298818163e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.77381528950794767694352468734042252745e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 2.5228e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.65057384221262866484014802392420311075e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.92801687242885330588201777283015178448e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.65508815862861196424333614846876229064e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71545573465295958468808641544341412235e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72077718130407940498710469661947719216e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.26299620525538984108147098966692839348e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77971404992990847565880351976461271350e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71176235845517643695464740679643640241e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.64603919225244695533557520384631958897e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.85274347406803894317891882905083368489e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48564096627181435612831469651920186491e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.90886715044580341917806394089282500340e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -6.39396206221935864416563232680283312796e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37760675743046300528308203869876086823e-22), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49023284463742780238035958819642738891e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.76284367953836866133894756472541395734e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.69932155343422362573146811195224195135e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.97593541520549770519034085640975455763e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45862809001322359249894968573830094537e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.61348135835522976885804369721316193713e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21069949470458047530981551232427019037e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.03132437580490629136144285669590192597e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91030348024641585284338958059030520141e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.56320479309161046934628280237629402373e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.39524198476052364627683067034422502163e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18666081063885228839052386515073873844e-13), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 9.6732e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60044810497290557552736366450372523266e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27034183360438185616541260923634443241e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19813403884333707962156711479716066536e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91346554854771687970018076643044998737e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91975837766081548424458764226669789039e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26031304514411902758114277797443618334e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.47127194811140370123712253347211626753e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55248861254135821097921903190564312000e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78340847719683652633864722047250151066e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95888612422041337572422846394029849086e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66363005792960308636467394552324255493e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.93244800648299424751906591077496534948e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.95046217952146113063614290717113024410e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.46784746963816915795587433372284530785e-25), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.16012189991825507132967712656930682478e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95202772611563835130347051925062280272e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.23801477561401113332870463345197159418e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.54022665579711946784722766000062263305e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.94266182294627770206082679848878391116e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.11782839184878848480753630961211685630e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.28827067686094594197542725283923947812e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.00220719177374237332018587370837457299e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.42250513143925626748132661121749401409e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82007216963767723991309138907689681422e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34214834652884406013489167210936679359e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.85519293212465087373898447546710143008e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.96728437809303144188312623363453475831e-19), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 1.0113e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54339461777955741686401041938275102207e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.17747085249877439037826121862689145081e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14104576580586095462211756659036062930e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.06903778663262313120049231822412184382e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53115958954246158081703822428768781010e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48225007017630665357941682179157662142e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20810829523286181556951002345409843125e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.54070972719909957155251432996372246019e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06258623970363729581390609798632080752e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15603641527498625694677136504611545743e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05376970060354261667000502105893106009e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.14727542705613448694396750352455931731e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76883960167449461476228984331517762578e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.03558202009465610972808653993060437679e-29), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08809672969012756295937194823378109391e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.41148083436617376855422685448827300528e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.85101541143091590863368934606849033688e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.38984899982960112626157576750593711628e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51437845497783812562009857096371643785e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.12891276596072815764119699444334380521e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82412500887161687329929693518498698716e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80215715026891688444965605768621763721e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.85838684678780184082810752634454259831e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83675729736846176693608812315852523556e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.80347165008408134158968403924819637224e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23639219622240634094606955067799349447e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.63446235885036169537726818244420509024e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 9.7056e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.55085695067883584460317653567009454037e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52919532248638251721278667010429548877e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06266842295477991789450356745903177571e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.20671609948319334255323512011575892813e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04692714549374449244320605137676408001e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70605481454469287545965803970738264158e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83960996572005209177458712170004097587e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29732261733491885750067029092181853751e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.78385693918239619309147428897790440735e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52969197316398995616879018998891661712e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14063120299947677255281707434419044806e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25957675329657493245893497219459256248e-25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.55238112862817593053765898004447484717e-29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -8.93970406521541790658675747195982964585e-34), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04722757068068234153968603374387493579e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85854131835804458353300285777969427206e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.85809281481040288085436275150792074968e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.38860750164285700051427698379841626305e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.91463283601681120487987016215594255423e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28104952818420195583669572450494959042e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43912720109615655035554724090181888734e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10668954229813492117417896681856998595e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.65093571330749369067212003571435698558e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81758227619561958470583781325371429458e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.36970757752002915423191164330598255294e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.06487673393164724939989217811068656932e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.47121057452822097779067717258050172115e-27), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x); + + // Rational Approximation + // Maximum Relative Error: 7.1032e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[8] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99471140200716338969973029967190934238e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.82846732476244747063962056024672844211e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -3.69724475658159099827638225237895868258e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21259630917863228526439367416146293173e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.13469812721679130825429547254346177005e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.73237434182338329541631611908947123606e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72986150007117100707304201395140411630e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -2.53567129749337040254350979652515879881e-7), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.89815449697874475254942178935516387239e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.21223228867921988134838870379132038419e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79514417558927397512722128659468888701e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.43331254539687594239741585764730095049e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.99078779616201786316256750758748178864e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04590833634768023225748107112347131311e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.17497990182339853998751740288392648984e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53420609011698705803549938558385779137e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t / x; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_pdf_imp_prec(const RealType& x, const boost::math::integral_constant &tag) { + BOOST_MATH_STD_USING // for ADL of std functions + + return saspoint5_pdf_plus_imp_prec(abs(x), tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_pdf_imp_prec(const RealType& x, const boost::math::integral_constant& tag) { + BOOST_MATH_STD_USING // for ADL of std functions + + return saspoint5_pdf_plus_imp_prec(abs(x), tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_pdf_imp(const saspoint5_distribution& dist, const RealType& x) { + // + // This calculates the pdf of the Saspoint5 distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::pdf(saspoint5<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The SaS point5 distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = saspoint5_pdf_imp_prec(u, tag_type()) / scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.5) { + // Rational Approximation + // Maximum Relative Error: 2.6225e-17 + BOOST_MATH_STATIC const RealType P[16] = { + static_cast(5.0e-1), + static_cast(1.11530082549581486148e2), + static_cast(1.18564167533523512811e4), + static_cast(7.51503793077701705413e5), + static_cast(3.05648233678438482191e7), + static_cast(8.12176734530090957088e8), + static_cast(1.39533182836234507573e10), + static_cast(1.50394359286077974212e11), + static_cast(9.79057903542935575811e11), + static_cast(3.73800992855150140014e12), + static_cast(8.12697090329432868343e12), + static_cast(9.63154058643818290870e12), + static_cast(5.77714904017642642181e12), + static_cast(1.53321958252091815685e12), + static_cast(1.36220966258718212359e11), + static_cast(1.70766655065405022702e9), + }; + BOOST_MATH_STATIC const RealType Q[16] = { + static_cast(1.), + static_cast(2.24333404643898143947e2), + static_cast(2.39984636687021023600e4), + static_cast(1.53353791432086858132e6), + static_cast(6.30764952479861776476e7), + static_cast(1.70405769169309597488e9), + static_cast(3.00381227010195289341e10), + static_cast(3.37519046677507392667e11), + static_cast(2.35001610518109063314e12), + static_cast(9.90961948200767679416e12), + static_cast(2.47066673978544828258e13), + static_cast(3.51442593932882610556e13), + static_cast(2.68891431106117733130e13), + static_cast(9.99723484253582494535e12), + static_cast(1.49190229409236772612e12), + static_cast(5.68752980146893975323e10), + }; + + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 1) { + RealType t = x - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 9.2135e-19 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(3.31309550000758082456e-1), + static_cast(1.63012162307622129396e0), + static_cast(2.97763161467248770571e0), + static_cast(2.49277948739575294031e0), + static_cast(9.49619262302649586821e-1), + static_cast(1.38360148984087584165e-1), + static_cast(4.00812864075652334798e-3), + static_cast(-4.82051978765960490940e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(5.43565383128046471592e0), + static_cast(1.13265160672130133152e1), + static_cast(1.13352316246726435292e1), + static_cast(5.56671465170409694873e0), + static_cast(1.21011708389501479550e0), + static_cast(8.34618282872428849500e-2), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 6.4688e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.71280312689343248819e-1), + static_cast(7.44610837974139249205e-1), + static_cast(7.17844128359406982825e-1), + static_cast(2.98789060945288850507e-1), + static_cast(5.22747411439102272576e-2), + static_cast(3.06447984437786430265e-3), + static_cast(2.60407071021044908690e-5), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.06221257507188300824e0), + static_cast(3.44827372231472308047e0), + static_cast(1.78166113338930668519e0), + static_cast(4.25580478492907232687e-1), + static_cast(4.09983847731128510426e-2), + static_cast(1.04343172183467651240e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 8.2289e-18 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(2.13928162275383716645e-1), + static_cast(2.35139109235828185307e-1), + static_cast(9.35967515134932733243e-2), + static_cast(1.64310489592753858417e-2), + static_cast(1.23186728989215889119e-3), + static_cast(3.13500969261032539402e-5), + static_cast(1.17021346758965979212e-7), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.28212183177829510267e0), + static_cast(6.17321009406850420793e-1), + static_cast(1.38400318019319970893e-1), + static_cast(1.44994794535896837497e-2), + static_cast(6.17774446282546623636e-4), + static_cast(7.00521050169239269819e-6), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 3.7284e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.63772802979087193656e-1), + static_cast(9.69009603942214234119e-2), + static_cast(2.08261725719828138744e-2), + static_cast(1.97965182693146960970e-3), + static_cast(8.05499273532204276894e-5), + static_cast(1.11401971145777879684e-6), + static_cast(2.25932082770588727842e-9), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(6.92463563872865541733e-1), + static_cast(1.80720987166755982366e-1), + static_cast(2.20416647324531054557e-2), + static_cast(1.26052070140663063778e-3), + static_cast(2.93967534265875431639e-5), + static_cast(1.82706995042259549615e-7), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 4.9609e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(1.22610122564874280532e-1), + static_cast(3.70273222121572231593e-2), + static_cast(4.06083618461789591121e-3), + static_cast(1.96898134215932126299e-4), + static_cast(4.08421066512186972853e-6), + static_cast(2.87707419853226244584e-8), + static_cast(2.96850126180387702894e-11), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(3.55825191301363023576e-1), + static_cast(4.77251766176046719729e-2), + static_cast(2.99136605131226103925e-3), + static_cast(8.78895785432321899939e-5), + static_cast(1.05235770624006494709e-6), + static_cast(3.35423877769913468556e-9), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 5.6559e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(9.03056141356415077080e-2), + static_cast(1.37568904417652631821e-2), + static_cast(7.60947271383247418831e-4), + static_cast(1.86048302967560067128e-5), + static_cast(1.94537860496575427218e-7), + static_cast(6.90524093915996283104e-10), + static_cast(3.58808434477817122371e-13), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.80501347735272292079e-1), + static_cast(1.22807958286146936376e-2), + static_cast(3.90421541115275676253e-4), + static_cast(5.81669449234915057779e-6), + static_cast(3.53005415676201803667e-8), + static_cast(5.69883025435873921433e-11), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 6.0653e-17 + BOOST_MATH_STATIC const RealType P[7] = { + static_cast(6.57333571766941474226e-2), + static_cast(5.02795551798163084224e-3), + static_cast(1.39633616037997111325e-4), + static_cast(1.71386564634533872559e-6), + static_cast(8.99508156357247137439e-9), + static_cast(1.60229460572297160486e-11), + static_cast(4.17711709622960498456e-15), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(9.10198637347368265508e-2), + static_cast(3.12263472357578263712e-3), + static_cast(5.00524795130325614005e-5), + static_cast(3.75913188747149725195e-7), + static_cast(1.14970132098893394023e-9), + static_cast(9.34957119271300093120e-13), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x); + + // Rational Approximation + // Maximum Relative Error: 2.0104e-20 + BOOST_MATH_STATIC const RealType P[5] = { + static_cast(3.98942280401432677940e-1), + static_cast(8.12222388783621449146e-2), + static_cast(1.68515703707271703934e-2), + static_cast(2.19801627205374824460e-3), + static_cast(-5.63321705854968264807e-5), + }; + BOOST_MATH_STATIC const RealType Q[5] = { + static_cast(1.), + static_cast(6.02536240902768558315e-1), + static_cast(1.99284471400121092380e-1), + static_cast(3.48012577961755452113e-2), + static_cast(3.38545004473058881799e-3), + }; + + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_cdf_plus_imp_prec(const RealType& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (x < 0.125) { + // Rational Approximation + // Maximum Relative Error: 6.9340e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[30] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.0e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.25520067710293108163697513129883130648e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.70866020657515874782126804139443323023e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.00865235319309486225795793030882782077e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.15226363537737769449645357346965170790e10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90371247243851280277289046301838071764e12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.55124590509169425751300134399513503679e14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.31282020412787511681760982839078664474e16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.81134278666896523873256421982740565131e18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.36154530125229747305141034242362609073e20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.67793867640429875837167908549938345465e22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34584264816825205490037614178084070903e24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.52622279567059369718208827282730379468e25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.84678324511679577282571711018484545185e27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.99412564257799793932936828924325638617e28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.08467105431111959283045453636520222779e30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87466808926544728702827204697734995611e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55020252231174414164534905191762212055e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69582736077420504345389671165954321163e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18203860972249826626461130638196586188e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.32955733788770318392204091471121129386e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.97972270315674052071792562126668438695e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93941537398987201071027348577636994465e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40818708062034138095495206258366082481e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.76833406751769751643745383413977973530e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.67873467711368838525239991688791162617e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.94179310584115437584091984619858795365e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24348215908456320362232906012152922949e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71625432346533320597285660433110657670e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.54662474187354179772157464533408058525e33), + }; + BOOST_MATH_STATIC const RealType Q[31] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05231337496532137901354609636674085703e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.43071888317491317900094470796567113997e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80864482202910830302921131771345102044e8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.32755297215862998181755216820621285536e10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.86251123527611073428156549377791985741e12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.12025543961949466786297141758805461421e15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27681657695574252637426145112570596483e17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17850553865715973904162289375819555884e19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.87285897504702686250962844939736867339e20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46852796231948446334549476317560711795e22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76101689878844725930808096548998198853e24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14017776727845251567032313915953239178e26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83738954971390158348334918235614003163e27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04701345216121451992682705965658316871e29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29994190638467725374533751141434904865e30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.03334024242845994501493644478442360593e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.59094378123268840693978620156028975277e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05630254163426327113368743426054256780e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.06008195534030444387061989883493342898e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.21262490304347036689874956206774563906e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52353024633841796119920505314785365242e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28839143293381125956284415313626962263e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31074057704096457802547386358094338369e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24762412200364040971704861346921094354e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.55663903116458425420509083471048286114e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81839283802391753865642022579846918253e37), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.40026559327708207943879092058654410696e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48767474646810049293505781106444169229e36), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10591353097667671736865938428051885499e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26980708896893794012677171239610721832e33), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + } + else if (x < 0.25) { + RealType t = x - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 9.6106e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.31887921568009055676985827521151969069e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62791448964529380666250180886203090183e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.18238045199893937316918299064825702894e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.77274519306540522227493503092956314136e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.89424638466340765479970877448972418958e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.84027004420207996285174223581748706097e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.84633134142285937075423713704784530853e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76780579189423063605715733542379494552e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19812409802969581112716039533798357401e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60039008588877024309600768114757310858e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.10268260529501421009222937882726290612e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.72169594688819848498039471657587836720e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27181379647139697258984772894869505788e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.73617450590346508706222885401965820190e1), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.18558935411552146390814444666395959919e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49210559503096368944407109881023223654e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93959323596111340518285858313038058302e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53590607436758691037825792660167970938e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.82700985983018132572589829602100319330e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62137033935442506086127262036686905276e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.76014299715348555304267927238963139228e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.12336796972134088340556958396544477713e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.01952132024838508233050167059872220508e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.41846547214877387780832317250797043384e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.02083431572388097955901208994308271581e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.30401057171447074343957754855656724141e4), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 0.5) { + RealType t = x - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 3.1519e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.87119665000174806422420129219814467874e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.60769554551148293079169764245570645155e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.49181979810834706538329284478129952168e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15722765491675871778645250624425739489e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.65973147084701923411221710174830072860e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93709338011482232037110656459951914303e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.57393131299425403017769538642434714791e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.24110491141294379107651487490031694257e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23670394514211681515965192338544032862e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06141024932329394052395469123628405389e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.08599362073145455095790192415468286304e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.22746783794652085925801188098270888502e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.19652234873414609727168969049557770989e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -5.73529976407853894192156335785920329181e-4), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.04157569499592889296640733909653747983e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82248883130787159161541119440215325308e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.35191216924911901198168794737654512677e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05099314677808235578577204150229855903e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.61081069236463123032873733048661305746e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.65340645555368229718826047069323437201e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.44526681322128674428653420882660351679e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.03963804195353853550682049993122898950e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40399236835577953127465726826981753422e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.46764755170079991793106428011388637748e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.06384106042490712972156545051459068443e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.27614406724572981099586665536543423891e0), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 1) { + RealType t = x - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 7.1196e-37 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31309550000758082761278726632760756847e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.07242222531117199094690544171275415854e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18286763141875580859241637334381199648e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72102024869298528501604761974348686708e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.31748399999514540052066169132819656757e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.72168003284748405703923567644025252608e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52648991506052496046447777354251378257e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.16777263528764704804758173026143295383e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.66044453196259367950849328889468385159e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.35095952392355288307377427145581700484e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43011308494452327007589069222668324337e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16582092138863383294685790744721021189e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.02261914949200575965813000131964695720e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.93943913630044161720796150617166047233e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -9.76395009419307902351328300308365369814e-8), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28073115520716780203055949058270715651e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.20245752585870752942356137496087189194e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.34548337034735803039553186623067144497e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.90925817267776213429724248532378895039e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.92883822651628140083115301005227577059e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.72868136219107985834601503784789993218e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.50498744791568911029110559017896701095e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05178276667813671578581259848923964311e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.16880263792490095344135867620645018480e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16199396397514668672304602774610890666e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.25543193822942088303609988399416145281e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.62522294286034117189844614005500278984e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18342889744790118595835138444372660676e-3), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 2) { + RealType t = x - 1; + + // Rational Approximation + // Maximum Relative Error: 9.5605e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71280312689343266367958859259591541365e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49628636612698702680819948707479820292e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61090930375686902075245639803646265081e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.01191924051756106307211298794294657688e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.42496510376427957390465373165464672088e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59577769624139820954046058289100998534e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02664809521258420718170586857797408674e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72258711278476951299824066502536249701e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.72578941800687566921553416498339481887e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.12553368488232553360765667155702324159e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.20749770911901442251726681861858323649e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00621121212654384864006297569770703900e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18976033102817074104109472578202752346e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22093548539863254922531707899658394458e-10), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.83305694892673455436552817409325835774e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.49922543669955056754932640312490112609e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.23488972536322019584648241457582608908e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.14051527527038669918848981363974859889e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37891280136777182304388426277537358346e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.08058775103864815769223385606687612117e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83305488980337433132332401784292281716e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.71072208215804671719811563659227630554e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.86332040813989094594982937011005305263e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.87698178237970337664105782546771501188e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69113555019737313680732855691540088318e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.31888539972217875242352157306613891243e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85633766164682554126992822326956560433e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 4) { + RealType t = x - 2; + + // Rational Approximation + // Maximum Relative Error: 1.1494e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.13928162275383718405630406427822960090e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.90742307267701162395764574873947997211e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.13821826367941514387521090205756466068e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.96186879146063565484800486550739025293e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19438785955706463753454881511977831603e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.44969124820016994689518539612465708536e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27841835070651018079759230944461773079e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69952429132675045239242077293594666305e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47919853099168659881487026035933933068e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.04644774117864306055402364094681541437e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.52604718870921084048756263996119841957e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97610950633031564892821158058978809537e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35934159016861180185992558083703785765e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21044098237798939057079316997065892072e-14), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.94437702178976797218081686254875998984e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.82068837586514484653828718675654460991e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87606058269189306593797764456467061128e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39130528408903116343256483948950693356e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.52792074489091396425713962375223436022e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00892233011840867583848470677898363716e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.53717105060592851173320646706141911461e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57293857675930200001382624769341451561e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04219251796696135508847408131139677925e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.20053006131133304932740325113068767057e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.26384707028090985155079342718673255493e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.19146442700994823924806249608315505708e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59879298772002950043508762057850408213e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 8) { + RealType t = x - 4; + + // Rational Approximation + // Maximum Relative Error: 1.9710e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63772802979087199762340235165979751298e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31941534705372320785274994658709390116e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.43643960022585762678456016437621064500e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.11415302325466272779041471612529728187e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15767742459744253874067896740220951622e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.74049309186016489825053763513176160256e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.76349898574685150849080543168157785281e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19757202370729036627932327405149840205e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.32067727965321839898287320520750897894e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47636340015260789807543414080472136575e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36236727340568181129875213546468908164e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89379573960280486883733996547662506245e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.71832232038263988173042637335112603365e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.72380245500539326441037770757072641975e-18), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51702400281458104713682413542736419584e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01375164846907815766683647295932603968e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.92796007869834847612192314006582598557e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.77580441164023725582659445614058463183e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63592331843149724480258804892989851727e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.87334158717610115008450674967492650941e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46596056941432875244263245821845070102e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.69980051560936361597177347949112822752e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.61690034211585843423761830218320365457e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.40619773800285766355596852314940341504e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.10624533319804091814643828283820958419e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.10009654621246392691126133176423833259e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.48070591106986983088640496621926852293e-16), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 16) { + RealType t = x - 8; + + // Rational Approximation + // Maximum Relative Error: 5.2049e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22610122564874286614786819620499101143e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.30352481858382230273216195795534959290e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.45933050053542949214164590814846222512e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.18776888646200567321599584635465632591e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53421996228923143480455729204878676265e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.26075686557831306993734433164305349875e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58045762501721375879877727645933749122e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13469629033419341069106781092024950086e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09157226556088521407323375433512662525e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44961350323527660188267669752380722085e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11052101325523147964890915835024505324e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.26421404354976214191891992583151033361e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.17133505681224996657291059553060754343e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41010917905686427164414364663355769988e-22), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.31062773739451672808456319166347015167e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35386721434011881226168110614121649232e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.39357338312443465616015226804775178232e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.26630144036271792027494677957363535353e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.24340476859846183414651435036807677467e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.33917136421389571662908749253850939876e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.80972141456523767244381195690041498939e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22653625120465488656616983786525028119e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64072452032620505897896978124863889812e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.61842001579321492488462230987972104386e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96631619425501661980194304605724632777e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.80392324086028812772385536034034039168e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.34254502871215949266781048808984963366e-20), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 32) { + RealType t = x - 16; + + // Rational Approximation + // Maximum Relative Error: 1.7434e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.03056141356415128156562790092782153630e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.15331583242023443256381237551843296356e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.81847913073640285776566199343276995613e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.23578443960486030170636772457627141406e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36906354316016270165240908809929957836e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.80584421020238085239890207672296651219e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.20726437845755296397071540583729544203e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.71042563703818585243207722641746283288e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08307373360265947158569900625482137206e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.80776566500233755365518221977875432763e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11405351639704510305055492207286172753e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21575609293568296049921888011966327905e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66081982641748223969990279975752576675e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96483118060215455299182487430511998831e-26), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.77347004038951368607085827825968614455e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.27559305780716801070924630708599448466e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.05452382624230160738008550961679711827e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75369667590360521677018734348769796476e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56551290985905942229892419848093494661e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.46972102361871185271727958608184616388e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.72423917010499649257775199140781647069e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14337306905269302583746182007852069459e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.69949885309711859563395555285232232606e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.00318719634300754237920041312234711548e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41139664927184402637020651515172315287e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79013190225240505774959477465594797961e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.46536966503325413797061462062918707370e-24), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else if (x < 64) { + RealType t = x - 32; + + // Rational Approximation + // Maximum Relative Error: 2.0402e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.57333571766941514095434647381791040479e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15416685251021339933358981066948923001e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.86806753164417557035166075399588122481e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.91972616817770660098405128729991574724e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10225768760715861978198010761036882002e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.05986998674039047865566990469266534338e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.59572646670205456333051888086612875871e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19347294198055585461131949159508730257e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21328285448498841418774425071549974153e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.19331596847283822557042655221763459728e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.36128017817576942059191451016251062072e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.35600223942735523925477855247725326228e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.14658948592500290756690769268766876322e-26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.86984591055448991335081550609451649866e-30), + }; + BOOST_MATH_STATIC const RealType Q[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90112824856612652807095815199496602262e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59291524937386142936420775839969648652e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.74245361925275011235694006013677228467e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41828589449615478387532599798645159282e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.08088176420557205743676774127863572768e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30760429417424419297000535744450830697e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.18464910867914234357511605329900284981e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.74255540513281299503596269087176674333e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.02616028440371294233330747672966435921e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.26276597941744408946918920573146445795e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.47463109867603732992337779860914933775e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.77217411888267832243050973915295217582e-24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.67397425207383164084527830512920206074e-28), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t); + } + else { + RealType t = 1 / sqrt(x); + + // Rational Approximation + // Maximum Relative Error: 9.2612e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[9] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.98942280401432677939946059934381868476e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33908701314796522684603310107061150444e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.92120397142832495974006972404741124398e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.15463147603421962834297353867930971657e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44488751006069172847577645328482300099e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44057582804743599116332797864164802887e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.02968018188491417839349438941039867033e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -4.75092244933846337077999183310087492887e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35099582728548602389917143511323566818e-8), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.34601617336219074065534356705298927390e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.82954035780824611941899463895040327299e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.70929001162671283123255408612494541378e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.05508596604210030533747793197422815105e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02913299057943756875992272236063124608e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37824426836648736125759177846682556245e-5), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / tools::evaluate_polynomial(Q, t) * t; + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? saspoint5_cdf_plus_imp_prec(x, tag) : 1 - saspoint5_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - saspoint5_cdf_plus_imp_prec(-x, tag) : saspoint5_cdf_plus_imp_prec(-x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_cdf_imp_prec(const RealType& x, bool complement, const boost::math::integral_constant& tag) { + if (x >= 0) { + return complement ? saspoint5_cdf_plus_imp_prec(x, tag) : 1 - saspoint5_cdf_plus_imp_prec(x, tag); + } + else if (x <= 0) { + return complement ? 1 - saspoint5_cdf_plus_imp_prec(-x, tag) : saspoint5_cdf_plus_imp_prec(-x, tag); + } + else { + return boost::math::numeric_limits::quiet_NaN(); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_cdf_imp(const saspoint5_distribution& dist, const RealType& x, bool complement) { + // + // This calculates the cdf of the Saspoint5 distribution and/or its complement. + // + + BOOST_MATH_STD_USING // for ADL of std functions + constexpr auto function = "boost::math::cdf(saspoint5<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The SaS point5 distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + RealType u = (x - location) / scale; + + result = saspoint5_cdf_imp_prec(u, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (ilogb(p) >= -2) { + RealType u = -log2(ldexp(p, 1)); + + if (u < 0.125) { + // Rational Approximation + // Maximum Relative Error: 4.2616e-17 + BOOST_MATH_STATIC const RealType P[13] = { + static_cast(1.36099130643975127045e-1), + static_cast(2.19634434498311523885e1), + static_cast(1.70276954848343179287e3), + static_cast(8.02187341786354339306e4), + static_cast(2.48750112198456813443e6), + static_cast(5.20617858300443231437e7), + static_cast(7.31202030685167303439e8), + static_cast(6.66061403138355591915e9), + static_cast(3.65687892725590813998e10), + static_cast(1.06061776220305595494e11), + static_cast(1.23930642673461465346e11), + static_cast(1.49986408149520127078e10), + static_cast(-6.17325587219357123900e8), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + static_cast(1.), + static_cast(1.63111146753825227716e2), + static_cast(1.27864461509685444043e4), + static_cast(6.10371533241799228037e5), + static_cast(1.92422115963507708309e7), + static_cast(4.11544185502250709497e8), + static_cast(5.95343302992055062258e9), + static_cast(5.65615858889758369947e10), + static_cast(3.30833154992293143503e11), + static_cast(1.06032392136054207216e12), + static_cast(1.50071282012095447931e12), + static_cast(5.43552396263989180433e11), + static_cast(9.57434915768660935004e10), + }; + + result = u * tools::evaluate_polynomial(P, u) / (tools::evaluate_polynomial(Q, u) * (p * p)); + } + else if (u < 0.25) { + RealType t = u - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 2.3770e-19 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(1.46698650748920243698e-2), + static_cast(3.58380131788385557227e-1), + static_cast(3.39153750029553194566e0), + static_cast(1.55457424873957272207e1), + static_cast(3.44403897039657057261e1), + static_cast(3.01881531964962975320e1), + static_cast(2.77679052294606319767e0), + static_cast(-7.76665288232972435969e-2), + }; + BOOST_MATH_STATIC const RealType Q[7] = { + static_cast(1.), + static_cast(1.72584280323876188464e1), + static_cast(1.11983518800147654866e2), + static_cast(3.25969893054048132145e2), + static_cast(3.91978809680672051666e2), + static_cast(1.29874252720714897530e2), + static_cast(2.08740114519610102248e1), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (u < 0.5) { + RealType t = u - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 9.2445e-18 + BOOST_MATH_STATIC const RealType P[8] = { + static_cast(2.69627866689346445458e-2), + static_cast(3.23091180507445216811e-1), + static_cast(1.42164019533549860681e0), + static_cast(2.74613170828120023406e0), + static_cast(2.07865023346180997996e0), + static_cast(2.53267176863740856907e-1), + static_cast(-2.55816250186301841152e-2), + static_cast(3.02683750470398342224e-3), + }; + BOOST_MATH_STATIC const RealType Q[6] = { + static_cast(1.), + static_cast(8.55049920135376003042e0), + static_cast(2.48726119139047911316e1), + static_cast(2.79519589592198994574e1), + static_cast(9.88212916161823866098e0), + static_cast(1.39749417956251951564e0), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else { + RealType t = u - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 2.2918e-20 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(4.79518653373241051274e-2), + static_cast(3.81837125793765918564e-1), + static_cast(1.13370353708146321188e0), + static_cast(1.55218145762186846509e0), + static_cast(9.60938271141036509605e-1), + static_cast(2.11811755464425606950e-1), + static_cast(8.84533960603915742831e-3), + static_cast(1.73314614571009160225e-3), + static_cast(-3.63491208733876986098e-5), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(6.36954463000253710936e0), + static_cast(1.40601897306833147611e1), + static_cast(1.33838075106916667084e1), + static_cast(5.60958095533108032859e0), + static_cast(1.11796035623375210182e0), + static_cast(1.12508482637488861060e-1), + static_cast(5.18503975949799718538e-3), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 2)); + + // Rational Approximation + // Maximum Relative Error: 4.2057e-18 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(8.02395484493329835881e-2), + static_cast(2.46132933068351274622e-1), + static_cast(2.81820176867119231101e-1), + static_cast(1.47754061028371025893e-1), + static_cast(3.54638964490281023406e-2), + static_cast(3.99998730093393774294e-3), + static_cast(3.81581928434827040262e-4), + static_cast(1.82520920154354221101e-5), + static_cast(-2.06151396745690348445e-7), + static_cast(6.77986548138011345849e-9), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(2.39244329037830026691e0), + static_cast(2.12683465416376620896e0), + static_cast(9.02612272334554457823e-1), + static_cast(2.06667959191488815314e-1), + static_cast(2.79328968525257867541e-2), + static_cast(2.28216286216537879937e-3), + static_cast(1.04195690531437767679e-4), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 3.3944e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(1.39293493266195561875e-1), + static_cast(1.26741380938661691592e-1), + static_cast(4.31117040307200265931e-2), + static_cast(7.50528269269498076949e-3), + static_cast(8.63100497178570310436e-4), + static_cast(6.75686286034521991703e-5), + static_cast(3.11102625473120771882e-6), + static_cast(9.63513655399980075083e-8), + static_cast(-6.40223609013005302318e-11), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(8.11234548272888947555e-1), + static_cast(2.63525516991753831892e-1), + static_cast(4.77118226533147280522e-2), + static_cast(5.46090741266888954909e-3), + static_cast(4.15325425646862026425e-4), + static_cast(2.02377681998442384863e-5), + static_cast(5.79823311154876056655e-7), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 4.1544e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(1.57911660613037760235e-1), + static_cast(5.59740955695099219682e-2), + static_cast(8.92895854008560399142e-3), + static_cast(8.88795299273855801726e-4), + static_cast(5.66358335596607738071e-5), + static_cast(2.46733195253941569922e-6), + static_cast(6.44829870181825872501e-8), + static_cast(7.62193242864380357931e-10), + static_cast(-7.82035413331699873450e-14), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(3.49007782566002620811e-1), + static_cast(5.65303702876260444572e-2), + static_cast(5.54316442661801299351e-3), + static_cast(3.58498995501703237922e-4), + static_cast(1.53872913968336341278e-5), + static_cast(4.08512152326482573624e-7), + static_cast(4.72959615756470826429e-9), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 8.5877e-18 + BOOST_MATH_STATIC const RealType P[10] = { + static_cast(1.59150086070234563099e-1), + static_cast(6.07144002506911115092e-2), + static_cast(1.10026443723891740392e-2), + static_cast(1.24892739209332398698e-3), + static_cast(9.82922518655171276487e-5), + static_cast(5.58366837526347222893e-6), + static_cast(2.29005408647580194007e-7), + static_cast(6.44325718317518336404e-9), + static_cast(1.05110361316230054467e-10), + static_cast(1.48083450629432857655e-18), + }; + BOOST_MATH_STATIC const RealType Q[9] = { + static_cast(1.), + static_cast(3.81470315977341203351e-1), + static_cast(6.91330250512167919573e-2), + static_cast(7.84712209182587717077e-3), + static_cast(6.17595479676821181012e-4), + static_cast(3.50829361179041199953e-5), + static_cast(1.43889153071571504712e-6), + static_cast(4.04840254888235877998e-8), + static_cast(6.60429636407045050112e-10), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 8.7254e-17 + BOOST_MATH_STATIC const RealType P[9] = { + static_cast(1.59154943017783026201e-1), + static_cast(6.91506515614472069475e-2), + static_cast(1.44590186111155933843e-2), + static_cast(1.92616138327724025421e-3), + static_cast(1.79640147906775699469e-4), + static_cast(1.30852535070639833809e-5), + static_cast(5.55259657884038297268e-7), + static_cast(3.50107118687544980820e-8), + static_cast(-1.47102592933729597720e-22), + }; + BOOST_MATH_STATIC const RealType Q[8] = { + static_cast(1.), + static_cast(4.34486357752330500669e-1), + static_cast(9.08486933075320995164e-2), + static_cast(1.21024289017243304241e-2), + static_cast(1.12871233794777525784e-3), + static_cast(8.22170725751776749123e-5), + static_cast(3.48879932410650101194e-6), + static_cast(2.19978790407451988423e-7), + }; + + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else { + result = 1 / (p * p * constants::two_pi()); + } + + return result; +} + + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_quantile_upper_imp_prec(const RealType& p, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + RealType result; + + if (ilogb(p) >= -2) { + RealType u = -log2(ldexp(p, 1)); + + if (u < 0.125) { + // Rational Approximation + // Maximum Relative Error: 2.5675e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[31] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36099130643975133156293056139850872219e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.03940482189350763127508703926866548690e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00518276893354880480781640750482315271e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.55844903094077096941027360107304259099e6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04507684135310729583474324660276395831e9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28519957085041757616278379578781441623e11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26054173986187219679917530171252145632e13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00693075272502479915569708465960917906e15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.64153695410984136395853200311209462775e16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.64993034609287363745840801813540992383e18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68080300629977787949474098413155901197e20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.50632142671665246974634799849090331338e21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11943753054362349397013211631038480307e23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.80601829873419334580289886671478701625e24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33441650581633426542372642262736818512e26), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.56279427934163518272441555879970370340e27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.08899113985387092689705022477814364717e28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.37750989391907347952902900750138805007e29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.76961267256299304213687639380275530721e30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.98417586455955659885944915688130612888e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.40932923796679251232655132670811114351e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.80810239916688876216017180714744912573e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23907429566810200929293428832485038147e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11441754640405256305951569489818422227e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.30534222360394829628175800718529342304e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.73301799323855143458670230536670073483e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.53142592196246595846485130434777396548e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81719621726393542967303806360105998384e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00188544550531824809437206713326495544e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62706943144847786115732327787879709587e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32129438774563059735783287456769609571e31), + }; + BOOST_MATH_STATIC const RealType Q[32] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.65910866673514847742559406762379054364e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21954860438789969160116317316418373146e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.85684385746348850219351196129081986508e7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76131116920014625994371306210585646224e9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.57402411617965582839975369786525269977e11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.42213951996062253608905591667405322835e13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.55477693883842522631954327528060778834e15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.00397907346473927493255003955380711046e17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76305959503723486331556274939198109922e19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.27926540483498824808520492399128682366e21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.98253913105291675445666919447864520248e22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.63457445658532249936389003141915626894e24), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.51446616633910582673057455450707805902e25), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04744823698010333311911891992022528040e27), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.03400927415310540137351756981742318263e28), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.28761940359662123632247441327784689568e29), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.39016138777648624292953560568071708327e30), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79639567867465767764785448609833337532e31), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.23406781975678544311073661662680006588e32), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.97261483656310352862554580475760827374e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.62715040832592600542933595577003951697e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.77359945057399130202830211722221279906e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07842295432910751940058270741081867701e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.51739306780247334064265249344359460675e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.60574331076505049588401700048488577194e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.08286808700840316336961663635580879141e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.27661033115008662284071342245200272702e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00465576791024249023365007797010262700e35), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83311248273885136105510175099322638440e34), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96635220211386288597285960837372073054e33), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23849744128418288892902205619933047730e32), + }; + // LCOV_EXCL_STOP + result = u * tools::evaluate_polynomial(P, u) / (tools::evaluate_polynomial(Q, u) * (p * p)); + } + else if (u < 0.25) { + RealType t = u - static_cast (0.125); + + // Rational Approximation + // Maximum Relative Error: 9.0663e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.46698650748920243663487731226111319705e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.39021286045890143123252180276484388346e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21933242816562043224009451007344301143e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33741547463966207206741888477702151242e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.29556944160837955334643715180923663741e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.25261081330476435844217173674285740857e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28690563577245995896389783271544510833e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.51764495004238264050843085122188741180e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.00501773552098137637598813101153206656e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.93991776883375928647775429233323885440e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.13059418708769178567954713937745050279e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.41565791250614170744069436181282300453e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.35838723365672196069179944509778281549e1), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.63888803456697300467924455320638435538e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.74785179836182339383932806919167693991e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.15133301804008879476562749311747788645e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87361675398393057971764841741518474061e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.02992617475892211368309739891693879676e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36356854400440662641546588001882412251e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.35807552915245783626759227539698719908e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75959389290929178190646034566377062463e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18514088996371641206828142820042918681e5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54881978220293930450469794941944831047e4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83958740186543542804045767758191509433e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26637084978098507405883170227585648985e2), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (u < 0.5) { + RealType t = u - static_cast (0.25); + + // Rational Approximation + // Maximum Relative Error: 7.1265e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[14] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.69627866689346442965083437425920959525e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.28948812330446670380449765578224539665e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.38832694133021352110245148952631526683e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.70206624753427831733487031852769976576e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.34677850226082773550206949299306677736e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.18657422004942861459539366963056149110e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.90933843076824719761937043667767333536e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.78597771586582252472927601403235921029e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76489020985978559079198751910122765603e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.37662018494780327201390375334403954354e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11303058491765900888068268844399186476e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.38147649159947518976483710606042789880e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.81260575060831053615857196033574207714e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, -1.26783311530618626413866321968979725353e-3), + }; + BOOST_MATH_STATIC const RealType Q[13] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.98941943311823528497840052715295329781e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70142252619301982454969690308614487433e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.17472255695869018956165466705137979540e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.42016169942136311355803413981032780219e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.55874385736597452997483327962434131932e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45782883079400958761816030672202996788e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.05272877129840019671123017296056938361e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.79833037593794381103412381177370862105e3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.67388248713896792948592889733513376054e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.19952164110429183557842014635391021832e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.43813483967503071358907030110791934870e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.21327682641358836049127780506729428797e-1), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else { + RealType t = u - static_cast (0.5); + + // Rational Approximation + // Maximum Relative Error: 2.7048e-37 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.79518653373241051262822702930040975338e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.62230291299220868262265687829866364204e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.87315544620612697712513318458226575394e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.38993950875334507399211313740958438201e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54257654902026056547861805085572437922e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85673656862223617197701693270067722169e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47842193222521213922734312546590337064e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.76640627287007744941009407221495229316e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.71884893887802925773271837595143776207e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.87432154629995817972739015224205530101e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.44664933176248007092868241686074743562e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.32094739938150047092982705610586287965e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.18537678581395571564129512698022192316e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.99365265557355974918712592061740510276e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.66467016868206844419002547523627548705e-6), + }; + BOOST_MATH_STATIC const RealType Q[15] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01315080955831561204744043759079263546e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.43409077070585581955481063438385546913e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09863540097812452102765922256432103612e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.69971336507400724019217277303598318934e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.71444880426858110981683485927452024652e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15252748520663939799185721687082682973e2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.28399989835264172624148638350889215004e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.73464700365199500083227290575797895127e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.40421770918884020099427978511354197438e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.97023025282119988988976542004620759235e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38774609088015115009880504176630591783e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.52748138528630655371589047000668876440e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13088455793478303045390386135591069087e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.18220605549460262119565543089703387122e-5), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + } + else if (ilogb(p) >= -4) { + RealType t = -log2(ldexp(p, 2)); + + // Rational Approximation + // Maximum Relative Error: 3.8969e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.02395484493329839255216366819344305871e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.02703992140456336967688958960484716694e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.38779662796374026809611637926067177436e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.22326903547451397450399124548020897393e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.29321119874906326000117036864856138032e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60045794013093831332658415095234082115e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.75863216252160126657107771372004587438e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.65658718311497180532644775193008407069e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.53225259384404343896446164609240157391e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17876243295156782920260122855798305258e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59647007234516896762020830535717539733e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64519789656979327339865975091579252352e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29566724776730544346201080459027524931e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.40979492647851412567441418477263395917e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78894057948338305679452471174923939381e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.97064244496171921075006182915678263370e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13496588267213644899739513941375650458e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.75224691413667093006312591320754720811e-14), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.59000688626663121310675150262772434285e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37518060227321498297232252379976917550e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.96559443266702775026538144474892076437e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.81865210018244220041408788510705356696e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15188291931842064325756652570456168425e1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.16909307081950035111952362482113369939e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.68454509269150307761046136063890222011e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.06391236761753712424925832120306727169e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.35744804731044427608283991933125506859e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00655928177646208520006978937806043639e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04093230988242553633939757013466501271e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.07921031269974885975846184199640060403e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.61356596082773699708092475561216104426e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.83968520269928804453766899533464507543e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.44620973323561344735660659502096499899e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.84398925760354259350870730551452956164e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -8) { + RealType t = -log2(ldexp(p, 4)); + + // Rational Approximation + // Maximum Relative Error: 4.0176e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.39293493266195566603513288406748830312e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.75724665658983779947977436518056682748e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.42437549740894393207094008058345312893e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.26189619865771499663660627120168211026e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.38952430871711360962228087792821341859e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.09604487371653920602809626594722822237e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06215021409396534038209460967790566899e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.02245531075243838209245241246011523536e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.52822482024384335373072062232322682354e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.32527687997718638700761890588399465467e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.54799997015944073019842889902521208940e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59368565314052950335981455903474908073e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.09459594346367728583560281313278117879e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.30296867679720593932307487485758431355e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04594079707862644415224596859620253913e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40274507498190913768918372242285652373e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.48644117815971872777609922455371868747e-16), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88079839671202113888025645668230104601e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58898753182105924446845274197682915131e0), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.05418719178760837974322764299800701708e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.76439568495464423890950166804368135632e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.87661284201828717694596419805804620767e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29462021166220769918154388930589492957e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.89960014717788045459266868996575581278e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.21759236630028632465777310665839652757e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.08884467282860764261728614542418632608e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60098870889198704716300891829788260654e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.00120123451682223443624210304146589040e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.08868117923724451329261971335574401646e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.07346130275947166224129347124306950150e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.57848230665832873347797099944091265220e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.50841502849442327828534131901583916707e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.19165038770000448560339443014882434202e-15), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -16) { + RealType t = -log2(ldexp(p, 8)); + + // Rational Approximation + // Maximum Relative Error: 4.1682e-36 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.57911660613037766795694241662819364797e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.28799302413396670477035614399187456630e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.87488304496324715063356722168914018093e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.15106082041721012436439208357739139578e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91744691940169259573871742836817806248e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.40707390548486625606656777332664791183e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.37047148097688601398129659532643297674e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88039545021930711122085375901243257574e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22254460725736448552173288004145978774e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.58462349007293730244197837509157696852e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.95242372547984999431208546685672497090e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10113734998651793201123616276573169622e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.38963677413425618019569452771868834246e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.45242599273032563942546507899265865936e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.64855118157117311049698715635863670233e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.31679318790012894619592273346600264199e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.97289727214495789126072009268721022605e-20), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.10184661848812835285809771940181522329e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.06179300560230499194426573196970342618e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.23171547302923911058112454487643162794e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.20486436116678834807354529081908850425e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.51239574861351183874145649960640500707e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48939385253081273966380467344920741615e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18148716720470800170115047757600735127e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.68156131480770927662478944117713742978e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.13720275846166334505537351224097058812e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.85505701632948614345319635028225905820e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.91876669388212587242659571229471930880e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.12971661051277278610784329698988278013e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.31096179726750865531615367639563072055e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.03579138802970748888093188937926461893e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.45570688568663643410924100311054014175e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.23959804461200982866930072222355142173e-19), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -32) { + RealType t = -log2(ldexp(p, 16)); + + // Rational Approximation + // Maximum Relative Error: 6.2158e-37 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59150086070234561732507586188017224084e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.80849532387385837583114307010320459997e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.41158479406270598752210344238285334672e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88824037165656723581890282427897772492e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.82912940787568736176030025420621547622e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.36469458704261637785603215754389736108e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.13801486421774537025334682673091205328e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.97058432407176502984043208925327069250e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.60823277541385163663463406307766614689e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.45016369260792040947272022706860047646e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.54846457278644736871929319230398689553e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.67291749890916930953794688556299297735e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.18742803398417392282841454979723852423e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.13337431668170547244474715030235433597e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.37782648734897338547414800391203459036e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.17863064141234633971470839644872485483e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.58768205048500915346781559321978174829e-24), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.27782279546086824129750042200649907991e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.86934772625607907724733810228981095894e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.18640923531164938140838239032346416143e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14927915778694317602192656254187608215e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.57462121236985574785071163024761935943e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 5.11326475640883361512750692176665937785e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.49479333407835032831192117009600622344e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.01048164044583907219965175201239136609e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.42444147056333448589159611785359705792e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.72928365136507710372724683325279209464e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.30776323450676114149657959931149982200e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.51599272091669693373558919762006698549e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.12120236145539526122748260176385899774e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.65713807525694136400636427188839379484e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.40555520515542383952495965093730818381e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.51084407433793180162386990118245623958e-23), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -64) { + RealType t = -log2(ldexp(p, 32)); + + // Rational Approximation + // Maximum Relative Error: 9.8515e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59154943017783040087729009335921759322e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.35955784629344586058432079844665517425e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.24333525582177610783141409282489279582e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.58257137499954581519132407255793210808e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47191495695958634792434622715063010854e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06408464185207904662485396901099847317e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.20796977470988464880970001894205834196e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.99451680244976178843047944033382023574e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.21331607817814211329055723244764031561e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.16997758215752306644496702331954449485e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.22151810180865778439184946086488092970e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.05017329554372903197056366604190738772e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.45919279055502465343977575104142733356e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.14611865933281087898817644094411667861e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.66574579315129285098834562564888533591e-19), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.90098275536617376789480602467351545227e-21), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.56200324658873566425094389271790730206e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.35526648761411463124801128103381691418e-26), + }; + BOOST_MATH_STATIC const RealType Q[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.99582804063194774835771688139366152937e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.81210581320456331960539046132284190053e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.94358920922810097599951120081974275145e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.24831443209858422294319043037419780210e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.68584098673893150929178892200446909375e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.90058244779420124535106788512940199547e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.88151039746201934320258158884886191886e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.62348975553160355852344937226490493460e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.62007418751593938350474825754731470453e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.67502458979132962529935588245058477825e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.91648040348401277706598232576212305626e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.05843052379331618504561151714467880641e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.20127592059771206959014911028588129920e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.04661894930286305556240859086772458465e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.19442269177165740287568170417649762849e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.81435584873372180820418114652670864136e-23), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.62145023253666168339801687459484937001e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else if (ilogb(p) >= -128) { + RealType t = -log2(ldexp(p, 64)); + + // Rational Approximation + // Maximum Relative Error: 2.2157e-35 + // LCOV_EXCL_START + BOOST_MATH_STATIC const RealType P[18] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.59154943091895335751628149866310390641e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.91164927854420277537616294413463565970e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47557801928232619499125670863084398577e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.06172621625221091203249391660455847328e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.11720157411653968975956625234656001375e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.70086412127379161257840749700428137407e-5), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11069186177775505692019195793079552937e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.04581765901792649215653828121992908775e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.78996797234624395264657873201296117159e-9), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.10365978021268853654282661591051834468e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.76744621013787434243259445839624450867e-12), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.11110170303355425599446515240949433934e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.83669090335022069229153919882930282425e-15), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.09633460833089193733622172621696983652e-17), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.16200852052266861122422190933586966917e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.47795810090424252745150042033544310609e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.35722092370326505616747155207965300634e-22), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 8.98381676423023212724768510437325359364e-51), + }; + BOOST_MATH_STATIC const RealType Q[17] = { + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 4.34271731953273239691423485699928257808e-1), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.27133013035186849140772481980360839559e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.29542078693828543560388747333519393752e-2), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.33027698228265344561650492600955601983e-3), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.06868444562964057795387778972002636261e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.97868278672593071151212650783507879919e-6), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.79869926850283188785885503049178903204e-7), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.75298857713475428388051708713106549590e-8), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.93449891515741631942400181171061740767e-10), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 2.36715626731277089044713008494971829270e-11), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 6.98125789528264426960496891930942311971e-13), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.78234546049400950544724588355539821858e-14), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.83044000387150792693434128054414524740e-16), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 7.30111486296552039483196431122555524886e-18), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 9.28628462422858135083238952377446358986e-20), + BOOST_MATH_BIG_CONSTANT(RealType, 113, 1.48108558735886480298604270981393793162e-21), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, t) / (tools::evaluate_polynomial(Q, t) * (p * p)); + } + else { + result = 1 / (p * p * constants::two_pi()); + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? saspoint5_quantile_upper_imp_prec(1 - p, tag) : -saspoint5_quantile_upper_imp_prec(1 - p, tag); + } + + return complement ? saspoint5_quantile_upper_imp_prec(p, tag) : -saspoint5_quantile_upper_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_quantile_imp_prec(const RealType& p, bool complement, const boost::math::integral_constant& tag) +{ + if (p > 0.5) { + return !complement ? saspoint5_quantile_upper_imp_prec(1 - p, tag) : -saspoint5_quantile_upper_imp_prec(1 - p, tag); + } + + return complement ? saspoint5_quantile_upper_imp_prec(p, tag) : -saspoint5_quantile_upper_imp_prec(p, tag); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_quantile_imp(const saspoint5_distribution& dist, const RealType& p, bool complement) +{ + // This routine implements the quantile for the Saspoint5 distribution, + // the value p may be the probability, or its complement if complement=true. + + constexpr auto function = "boost::math::quantile(saspoint5<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + RealType location = dist.location(); + + if (false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if (false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The SaS point5 distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = location + scale * saspoint5_quantile_imp_prec(p, complement, tag_type()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_entropy_imp_prec(const boost::math::integral_constant&) +{ + return static_cast(3.63992444568030649573); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_entropy_imp_prec(const boost::math::integral_constant&) +{ + return BOOST_MATH_BIG_CONSTANT(RealType, 113, 3.6399244456803064957308496039071853510); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType saspoint5_entropy_imp(const saspoint5_distribution& dist) +{ + // This implements the entropy for the Saspoint5 distribution, + + constexpr auto function = "boost::math::entropy(saspoint5<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType scale = dist.scale(); + + if (false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + + typedef typename tools::promote_args::type result_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + static_assert(tag_type::value, "The SaS point5 distribution is only implemented for types with known precision, and 113 bits or fewer in the mantissa (ie 128 bit quad-floats"); + + result = saspoint5_entropy_imp_prec(tag_type()) + log(scale); + + return result; +} + +} // detail + +template > +class saspoint5_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED saspoint5_distribution(RealType l_location = 0, RealType l_scale = 1) + : mu(l_location), c(l_scale) + { + constexpr auto function = "boost::math::saspoint5_distribution<%1%>::saspoint5_distribution"; + RealType result = 0; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + } // saspoint5_distribution + + BOOST_MATH_GPU_ENABLED RealType location()const + { + return mu; + } + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return c; + } + + private: + RealType mu; // The location parameter. + RealType c; // The scale parameter. +}; + +typedef saspoint5_distribution saspoint5; + +#ifdef __cpp_deduction_guides +template +saspoint5_distribution(RealType) -> saspoint5_distribution::type>; +template +saspoint5_distribution(RealType, RealType) -> saspoint5_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const saspoint5_distribution&) +{ // Range of permissible values for random variable x. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const saspoint5_distribution&) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits::has_infinity) + { + return boost::math::pair(-boost::math::numeric_limits::infinity(), boost::math::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return boost::math::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const saspoint5_distribution& dist, const RealType& x) +{ + return detail::saspoint5_pdf_imp(dist, x); +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const saspoint5_distribution& dist, const RealType& x) +{ + return detail::saspoint5_cdf_imp(dist, x, false); +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const saspoint5_distribution& dist, const RealType& p) +{ + return detail::saspoint5_quantile_imp(dist, p, false); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::saspoint5_cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::saspoint5_quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const saspoint5_distribution &dist) +{ + // There is no mean: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The SaS point5 Distribution has no mean"); + + return policies::raise_domain_error( + "boost::math::mean(saspoint5<%1%>&)", + "The SaS point5 distribution does not have a mean: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const saspoint5_distribution& /*dist*/) +{ + // There is no variance: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The SaS point5 Distribution has no variance"); + + return policies::raise_domain_error( + "boost::math::variance(saspoint5<%1%>&)", + "The SaS point5 distribution does not have a variance: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const saspoint5_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const saspoint5_distribution& dist) +{ + return dist.location(); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const saspoint5_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The SaS point5 Distribution has no skewness"); + + return policies::raise_domain_error( + "boost::math::skewness(saspoint5<%1%>&)", + "The SaS point5 distribution does not have a skewness: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const saspoint5_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The SaS point5 Distribution has no kurtosis"); + + return policies::raise_domain_error( + "boost::math::kurtosis(saspoint5<%1%>&)", + "The SaS point5 distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const saspoint5_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "The SaS point5 Distribution has no kurtosis excess"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(saspoint5<%1%>&)", + "The SaS point5 distribution does not have a kurtosis: " + "the only possible return value is %1%.", + boost::math::numeric_limits::quiet_NaN(), Policy()); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const saspoint5_distribution& dist) +{ + return detail::saspoint5_entropy_imp(dist); +} + +}} // namespaces + + +#endif // BOOST_STATS_SASPOINT5_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/skew_normal.hpp b/third-party/boost-math/include/boost/math/distributions/skew_normal.hpp new file mode 100644 index 0000000000000..28595a9ee8ca9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/skew_normal.hpp @@ -0,0 +1,760 @@ +// Copyright Benjamin Sobotta 2012 + +// 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) + +#ifndef BOOST_STATS_SKEW_NORMAL_HPP +#define BOOST_STATS_SKEW_NORMAL_HPP + +// http://en.wikipedia.org/wiki/Skew_normal_distribution +// http://azzalini.stat.unipd.it/SN/ +// Also: +// Azzalini, A. (1985). "A class of distributions which includes the normal ones". +// Scand. J. Statist. 12: 171-178. + +#include +#include // Owen's T function +#include +#include +#include +#include +#include +#include // Newton-Raphson +#include +#include // pdf max finder. + +#include +#include // std::lower_bound, std::distance + +#ifdef BOOST_MATH_INSTRUMENT_SKEW_NORMAL_ITERATIONS +extern std::uintmax_t global_iter_count; +#endif + +namespace boost{ namespace math{ + + namespace detail + { + template + inline bool check_skew_normal_shape( + const char* function, + RealType shape, + RealType* result, + const Policy& pol) + { + if(!(boost::math::isfinite)(shape)) + { + *result = + policies::raise_domain_error(function, + "Shape parameter is %1%, but must be finite!", + shape, pol); + return false; + } + return true; + } + + } // namespace detail + + template > + class skew_normal_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + skew_normal_distribution(RealType l_location = 0, RealType l_scale = 1, RealType l_shape = 0) + : location_(l_location), scale_(l_scale), shape_(l_shape) + { // Default is a 'standard' normal distribution N01. (shape=0 results in the normal distribution with no skew) + static const char* function = "boost::math::skew_normal_distribution<%1%>::skew_normal_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_location, &result, Policy()); + detail::check_skew_normal_shape(function, l_shape, &result, Policy()); + } + + RealType location()const + { + return location_; + } + + RealType scale()const + { + return scale_; + } + + RealType shape()const + { + return shape_; + } + + + private: + // + // Data members: + // + RealType location_; // distribution location. + RealType scale_; // distribution scale. + RealType shape_; // distribution shape. + }; // class skew_normal_distribution + + typedef skew_normal_distribution skew_normal; + + #ifdef __cpp_deduction_guides + template + skew_normal_distribution(RealType)->skew_normal_distribution::type>; + template + skew_normal_distribution(RealType,RealType)->skew_normal_distribution::type>; + template + skew_normal_distribution(RealType,RealType,RealType)->skew_normal_distribution::type>; + #endif + + template + inline const std::pair range(const skew_normal_distribution& /*dist*/) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair( + std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -max_value(), + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : max_value()); // - to + max value. + } + + template + inline const std::pair support(const skew_normal_distribution& /*dist*/) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } + + template + inline RealType pdf(const skew_normal_distribution& dist, const RealType& x) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::pdf(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + // Below produces MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && abs(x) == std::numeric_limits::infinity()) + //{ // pdf + and - infinity is zero. + // return 0; + //} + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = pdf(std_normal, transformed_x) * cdf(std_normal, shape*transformed_x) * 2 / scale; + + return result; + } // pdf + + template + inline RealType cdf(const skew_normal_distribution& dist, const RealType& x) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::cdf(const skew_normal_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && x == std::numeric_limits::infinity()) + //{ // cdf +infinity is unity. + // return 1; + //} + //if(std::numeric_limits::has_infinity && x == -std::numeric_limits::infinity()) + //{ // cdf -infinity is zero. + // return 0; + //} + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = cdf(std_normal, transformed_x) - owens_t(transformed_x, shape)*static_cast(2); + + return result; + } // cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { + const RealType scale = c.dist.scale(); + const RealType location = c.dist.location(); + const RealType shape = c.dist.shape(); + const RealType x = c.param; + + static const char* function = "boost::math::cdf(const complement(skew_normal_distribution<%1%>&), %1%)"; + + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && x == std::numeric_limits::infinity()) + //{ // cdf complement +infinity is zero. + // return 0; + //} + //if(std::numeric_limits::has_infinity && x == -std::numeric_limits::infinity()) + //{ // cdf complement -infinity is unity. + // return 1; + //} + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + if(false == detail::check_x(function, x, &result, Policy())) + return result; + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = cdf(complement(std_normal, transformed_x)) + owens_t(transformed_x, shape)*static_cast(2); + return result; + } // cdf complement + + template + inline RealType location(const skew_normal_distribution& dist) + { + return dist.location(); + } + + template + inline RealType scale(const skew_normal_distribution& dist) + { + return dist.scale(); + } + + template + inline RealType shape(const skew_normal_distribution& dist) + { + return dist.shape(); + } + + template + inline RealType mean(const skew_normal_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + + using namespace boost::math::constants; + + //const RealType delta = dist.shape() / sqrt(static_cast(1)+dist.shape()*dist.shape()); + + //return dist.location() + dist.scale() * delta * root_two_div_pi(); + + return dist.location() + dist.scale() * dist.shape() / sqrt(pi()+pi()*dist.shape()*dist.shape()) * root_two(); + } + + template + inline RealType variance(const skew_normal_distribution& dist) + { + using namespace boost::math::constants; + + const RealType delta2 = dist.shape() != 0 ? static_cast(1) / (static_cast(1)+static_cast(1)/(dist.shape()*dist.shape())) : static_cast(0); + //const RealType inv_delta2 = static_cast(1)+static_cast(1)/(dist.shape()*dist.shape()); + + RealType variance = dist.scale()*dist.scale()*(static_cast(1)-two_div_pi()*delta2); + //RealType variance = dist.scale()*dist.scale()*(static_cast(1)-two_div_pi()/inv_delta2); + + return variance; + } + + namespace detail + { + /* + TODO No closed expression for mode, so use max of pdf. + */ + + template + inline RealType mode_fallback(const skew_normal_distribution& dist) + { // mode. + static const char* function = "mode(skew_normal_distribution<%1%> const&)"; + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + RealType result; + if(!detail::check_scale( + function, + scale, &result, Policy()) + || + !detail::check_skew_normal_shape( + function, + shape, + &result, + Policy())) + return result; + + if( shape == 0 ) + { + return location; + } + + if( shape < 0 ) + { + skew_normal_distribution D(0, 1, -shape); + result = mode_fallback(D); + result = location-scale*result; + return result; + } + + BOOST_MATH_STD_USING + + // 21 elements + static const RealType shapes[] = { + 0.0, + 1.000000000000000e-004, + 2.069138081114790e-004, + 4.281332398719396e-004, + 8.858667904100824e-004, + 1.832980710832436e-003, + 3.792690190732250e-003, + 7.847599703514606e-003, + 1.623776739188722e-002, + 3.359818286283781e-002, + 6.951927961775606e-002, + 1.438449888287663e-001, + 2.976351441631319e-001, + 6.158482110660261e-001, + 1.274274985703135e+000, + 2.636650898730361e+000, + 5.455594781168514e+000, + 1.128837891684688e+001, + 2.335721469090121e+001, + 4.832930238571753e+001, + 1.000000000000000e+002}; + + // 21 elements + static const RealType guess[] = { + 0.0, + 5.000050000525391e-005, + 1.500015000148736e-004, + 3.500035000350010e-004, + 7.500075000752560e-004, + 1.450014500145258e-003, + 3.050030500305390e-003, + 6.250062500624765e-003, + 1.295012950129504e-002, + 2.675026750267495e-002, + 5.525055250552491e-002, + 1.132511325113255e-001, + 2.249522495224952e-001, + 3.992539925399257e-001, + 5.353553535535358e-001, + 4.954549545495457e-001, + 3.524535245352451e-001, + 2.182521825218249e-001, + 1.256512565125654e-001, + 6.945069450694508e-002, + 3.735037350373460e-002 + }; + + const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape); + + typedef typename std::iterator_traits::difference_type diff_type; + + const diff_type d = std::distance(shapes, result_ptr); + + BOOST_MATH_ASSERT(d > static_cast(0)); + + // refine + if(d < static_cast(21)) // shape smaller 100 + { + result = guess[d-static_cast(1)] + + (guess[d]-guess[d-static_cast(1)])/(shapes[d]-shapes[d-static_cast(1)]) + * (shape-shapes[d-static_cast(1)]); + } + else // shape greater 100 + { + result = 1e-4; + } + + skew_normal_distribution helper(0, 1, shape); + + result = detail::generic_find_mode_01(helper, result, function); + + result = result*scale + location; + + return result; + } // mode_fallback + + + /* + * TODO No closed expression for mode, so use f'(x) = 0 + */ + template + struct skew_normal_mode_functor + { + skew_normal_mode_functor(const boost::math::skew_normal_distribution dist) + : distribution(dist) + { + } + + boost::math::tuple operator()(RealType const& x) + { + normal_distribution std_normal; + const RealType shape = distribution.shape(); + const RealType pdf_x = pdf(distribution, x); + const RealType normpdf_x = pdf(std_normal, x); + const RealType normpdf_ax = pdf(std_normal, x*shape); + RealType fx = static_cast(2)*shape*normpdf_ax*normpdf_x - x*pdf_x; + RealType dx = static_cast(2)*shape*x*normpdf_x*normpdf_ax*(static_cast(1) + shape*shape) + pdf_x + x*fx; + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, -dx); + } + private: + const boost::math::skew_normal_distribution distribution; + }; + + } // namespace detail + + template + inline RealType mode(const skew_normal_distribution& dist) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::mode(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + + if( shape == 0 ) + { + return location; + } + + if( shape < 0 ) + { + skew_normal_distribution D(0, 1, -shape); + result = mode(D); + result = location-scale*result; + return result; + } + + // 21 elements + static const RealType shapes[] = { + static_cast(0.0), + static_cast(1.000000000000000e-004), + static_cast(2.069138081114790e-004), + static_cast(4.281332398719396e-004), + static_cast(8.858667904100824e-004), + static_cast(1.832980710832436e-003), + static_cast(3.792690190732250e-003), + static_cast(7.847599703514606e-003), + static_cast(1.623776739188722e-002), + static_cast(3.359818286283781e-002), + static_cast(6.951927961775606e-002), + static_cast(1.438449888287663e-001), + static_cast(2.976351441631319e-001), + static_cast(6.158482110660261e-001), + static_cast(1.274274985703135e+000), + static_cast(2.636650898730361e+000), + static_cast(5.455594781168514e+000), + static_cast(1.128837891684688e+001), + static_cast(2.335721469090121e+001), + static_cast(4.832930238571753e+001), + static_cast(1.000000000000000e+002) + }; + + // 21 elements + static const RealType guess[] = { + static_cast(0.0), + static_cast(5.000050000525391e-005), + static_cast(1.500015000148736e-004), + static_cast(3.500035000350010e-004), + static_cast(7.500075000752560e-004), + static_cast(1.450014500145258e-003), + static_cast(3.050030500305390e-003), + static_cast(6.250062500624765e-003), + static_cast(1.295012950129504e-002), + static_cast(2.675026750267495e-002), + static_cast(5.525055250552491e-002), + static_cast(1.132511325113255e-001), + static_cast(2.249522495224952e-001), + static_cast(3.992539925399257e-001), + static_cast(5.353553535535358e-001), + static_cast(4.954549545495457e-001), + static_cast(3.524535245352451e-001), + static_cast(2.182521825218249e-001), + static_cast(1.256512565125654e-001), + static_cast(6.945069450694508e-002), + static_cast(3.735037350373460e-002) + }; + + const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape); + + typedef typename std::iterator_traits::difference_type diff_type; + + const diff_type d = std::distance(shapes, result_ptr); + + BOOST_MATH_ASSERT(d > static_cast(0)); + + // TODO: make the search bounds smarter, depending on the shape parameter + RealType search_min = 0; // below zero was caught above + RealType search_max = 0.55f; // will never go above 0.55 + + // refine + if(d < static_cast(21)) // shape smaller 100 + { + // it is safe to assume that d > 0, because shape==0.0 is caught earlier + result = guess[d-static_cast(1)] + + (guess[d]-guess[d-static_cast(1)])/(shapes[d]-shapes[d-static_cast(1)]) + * (shape-shapes[d-static_cast(1)]); + } + else // shape greater 100 + { + result = 1e-4f; + search_max = guess[19]; // set 19 instead of 20 to have a safety margin because the table may not be exact @ shape=100 + } + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t max_iter = policies::get_max_root_iterations(); // and max iterations. + + skew_normal_distribution helper(0, 1, shape); + + result = tools::newton_raphson_iterate(detail::skew_normal_mode_functor(helper), result, + search_min, search_max, get_digits, max_iter); + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer to quantile or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + + result = result*scale + location; + + return result; + } + + + + template + inline RealType skewness(const skew_normal_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + using namespace boost::math::constants; + + static const RealType factor = four_minus_pi()/static_cast(2); + const RealType delta = dist.shape() / sqrt(static_cast(1)+dist.shape()*dist.shape()); + + return static_cast(factor * pow(root_two_div_pi() * delta, 3) / + pow(static_cast(1)-two_div_pi()*delta*delta, static_cast(1.5))); + } + + template + inline RealType kurtosis(const skew_normal_distribution& dist) + { + return kurtosis_excess(dist)+static_cast(3); + } + + template + inline RealType kurtosis_excess(const skew_normal_distribution& dist) + { + using namespace boost::math::constants; + + static const RealType factor = pi_minus_three()*static_cast(2); + + const RealType delta2 = dist.shape() != 0 ? static_cast(1) / (static_cast(1)+static_cast(1)/(dist.shape()*dist.shape())) : static_cast(0); + + const RealType x = static_cast(1)-two_div_pi()*delta2; + const RealType y = two_div_pi() * delta2; + + return factor * y*y / (x*x); + } + + template + inline RealType quantile(const skew_normal_distribution& dist, const RealType& p) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::quantile(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + // Compute initial guess via Cornish-Fisher expansion. + RealType x = -boost::math::erfc_inv(2 * p, Policy()) * constants::root_two(); + + // Avoid unnecessary computations if there is no skew. + if(shape != 0) + { + const RealType skew = skewness(dist); + const RealType exk = kurtosis_excess(dist); + + x = x + (x*x-static_cast(1))*skew/static_cast(6) + + x*(x*x-static_cast(3))*exk/static_cast(24) + - x*(static_cast(2)*x*x-static_cast(5))*skew*skew/static_cast(36); + } // if(shape != 0) + + result = standard_deviation(dist)*x+mean(dist); + + // handle special case of non-skew normal distribution. + if(shape == 0) + return result; + + // refine the result by numerically searching the root of (p-cdf) + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t max_iter = policies::get_max_root_iterations(); // and max iterations. + + if (result == 0) + result = tools::min_value(); // we need to be one side of zero or the other for the root finder to work. + + auto fun = [&, dist, p](const RealType& x)->RealType { return cdf(dist, x) - p; }; + + RealType f_result = fun(result); + + if (f_result == 0) + return result; + + if (f_result * result > 0) + { + // If the root is in the direction of zero, we need to check that we're the correct side of it: + RealType f_zero = fun(static_cast(0)); + if (f_zero * f_result > 0) + { + // we're the wrong side of zero: + result = -result; + f_result = fun(result); + } + } + + RealType scaling_factor = 1.25; + if (f_result * result > 0) + { + // We're heading towards zero... it's a long way down so use a larger scaling factor: + scaling_factor = 16; + } + + auto p_result = tools::bracket_and_solve_root(fun, result, scaling_factor, true, tools::eps_tolerance(get_digits), max_iter, Policy()); + +#ifdef BOOST_MATH_INSTRUMENT_SKEW_NORMAL_ITERATIONS + global_iter_count += max_iter; +#endif + + result = (p_result.first + p_result.second) / 2; + + // + // Try one last Newton step, just to close up the interval: + // + RealType step = fun(result) / pdf(dist, result); + + if (result - step <= p_result.first) + result = p_result.first; + else if (result - step >= p_result.second) + result = p_result.second; + else + result -= step; + + if (max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time: either there is no answer to quantile" // LCOV_EXCL_LINE + " or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + + return result; + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + const RealType scale = c.dist.scale(); + const RealType location = c.dist.location(); + const RealType shape = c.dist.shape(); + + static const char* function = "boost::math::quantile(const complement(skew_normal_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + skew_normal_distribution D(-location, scale, -shape); + + result = -quantile(D, q); + + return result; + } // quantile + + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_SKEW_NORMAL_HPP + + diff --git a/third-party/boost-math/include/boost/math/distributions/students_t.hpp b/third-party/boost-math/include/boost/math/distributions/students_t.hpp new file mode 100644 index 0000000000000..39f20d6e4109c --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/students_t.hpp @@ -0,0 +1,512 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2006, 2012, 2017. +// Copyright Thomas Mang 2012. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_STUDENTS_T_HPP +#define BOOST_STATS_STUDENTS_T_HPP + +// http://en.wikipedia.org/wiki/Student%27s_t_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3664.htm + +#include +#include +#include +#include +#include +#include // for ibeta(a, b, x). +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost { namespace math { + +template > +class students_t_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED students_t_distribution(RealType df) : df_(df) + { // Constructor. + RealType result; + detail::check_df_gt0_to_inf( // Checks that df > 0 or df == inf. + "boost::math::students_t_distribution<%1%>::students_t_distribution", df_, &result, Policy()); + } // students_t_distribution + + BOOST_MATH_GPU_ENABLED RealType degrees_of_freedom()const + { + return df_; + } + + // Parameter estimation: + BOOST_MATH_GPU_ENABLED static RealType find_degrees_of_freedom( + RealType difference_from_mean, + RealType alpha, + RealType beta, + RealType sd, + RealType hint = 100); + +private: + // Data member: + RealType df_; // degrees of freedom is a real number > 0 or +infinity. +}; + +typedef students_t_distribution students_t; // Convenience typedef for double version. + +#ifdef __cpp_deduction_guides +template +students_t_distribution(RealType)->students_t_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const students_t_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + // Now including infinity. + using boost::math::tools::max_value; + //return boost::math::pair(-max_value(), max_value()); + return boost::math::pair(((::boost::math::numeric_limits::is_specialized & ::boost::math::numeric_limits::has_infinity) ? -boost::math::numeric_limits::infinity() : -max_value()), ((::boost::math::numeric_limits::is_specialized & ::boost::math::numeric_limits::has_infinity) ? +boost::math::numeric_limits::infinity() : +max_value())); +} + +template +BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const students_t_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // Now including infinity. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + //return boost::math::pair(-max_value(), max_value()); + return boost::math::pair(((::boost::math::numeric_limits::is_specialized & ::boost::math::numeric_limits::has_infinity) ? -boost::math::numeric_limits::infinity() : -max_value()), ((::boost::math::numeric_limits::is_specialized & ::boost::math::numeric_limits::has_infinity) ? +boost::math::numeric_limits::infinity() : +max_value())); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const students_t_distribution& dist, const RealType& x) +{ + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType error_result; + if(false == detail::check_x_not_NaN( + "boost::math::pdf(const students_t_distribution<%1%>&, %1%)", x, &error_result, Policy())) + return error_result; + RealType df = dist.degrees_of_freedom(); + if(false == detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + "boost::math::pdf(const students_t_distribution<%1%>&, %1%)", df, &error_result, Policy())) + return error_result; + + RealType result; + if ((boost::math::isinf)(x)) + { // - or +infinity. + result = static_cast(0); + return result; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps + // - use normal distribution which is much faster and more accurate. + normal_distribution n(0, 1); + result = pdf(n, x); + } + else + { // + RealType basem1 = x * x / df; + if(basem1 < 0.125) + { + result = exp(-boost::math::log1p(basem1, Policy()) * (1+df) / 2); + } + else + { + result = pow(1 / (1 + basem1), (df + 1) / 2); + } + result /= sqrt(df) * boost::math::beta(df / 2, RealType(0.5f), Policy()); + } + return result; +} // pdf + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const students_t_distribution& dist, const RealType& x) +{ + RealType error_result; + // degrees_of_freedom > 0 or infinity check: + RealType df = dist.degrees_of_freedom(); + if (false == detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + "boost::math::cdf(const students_t_distribution<%1%>&, %1%)", df, &error_result, Policy())) + { + return error_result; + } + // Check for bad x first. + if(false == detail::check_x_not_NaN( + "boost::math::cdf(const students_t_distribution<%1%>&, %1%)", x, &error_result, Policy())) + { + return error_result; + } + if (x == 0) + { // Special case with exact result. + return static_cast(0.5); + } + if ((boost::math::isinf)(x)) + { // x == - or + infinity, regardless of df. + return ((x < 0) ? static_cast(0) : static_cast(1)); + } + + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps (perhaps infinite?) + // - use normal distribution which is much faster and more accurate. + normal_distribution n(0, 1); + RealType result = cdf(n, x); + return result; + } + else + { // normal df case. + // + // Calculate probability of Student's t using the incomplete beta function. + // probability = ibeta(degrees_of_freedom / 2, 1/2, degrees_of_freedom / (degrees_of_freedom + t*t)) + // + // However when t is small compared to the degrees of freedom, that formula + // suffers from rounding error, use the identity formula to work around + // the problem: + // + // I[x](a,b) = 1 - I[1-x](b,a) + // + // and: + // + // x = df / (df + t^2) + // + // so: + // + // 1 - x = t^2 / (df + t^2) + // + RealType x2 = x * x; + RealType probability; + if(df > 2 * x2) + { + RealType z = x2 / (df + x2); + probability = ibetac(static_cast(0.5), df / 2, z, Policy()) / 2; + } + else + { + RealType z = df / (df + x2); + probability = ibeta(df / 2, static_cast(0.5), z, Policy()) / 2; + } + return (x > 0 ? 1 - probability : probability); + } +} // cdf + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const students_t_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + // + // Obtain parameters: + RealType probability = p; + + // Check for domain errors: + RealType df = dist.degrees_of_freedom(); + constexpr auto function = "boost::math::quantile(const students_t_distribution<%1%>&, %1%)"; + RealType error_result; + if(false == (detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + function, df, &error_result, Policy()) + && detail::check_probability(function, probability, &error_result, Policy()))) + return error_result; + // Special cases, regardless of degrees_of_freedom. + if (probability == 0) + return -policies::raise_overflow_error(function, 0, Policy()); + if (probability == 1) + return policies::raise_overflow_error(function, 0, Policy()); + if (probability == static_cast(0.5)) + return 0; // + // +#if 0 + // This next block is disabled in favour of a faster method than + // incomplete beta inverse, but code retained for future reference: + // + // Calculate quantile of Student's t using the incomplete beta function inverse: + probability = (probability > 0.5) ? 1 - probability : probability; + RealType t, x, y; + x = ibeta_inv(degrees_of_freedom / 2, RealType(0.5), 2 * probability, &y); + if(degrees_of_freedom * y > tools::max_value() * x) + t = tools::overflow_error(function); + else + t = sqrt(degrees_of_freedom * y / x); + // + // Figure out sign based on the size of p: + // + if(p < 0.5) + t = -t; + + return t; +#endif + // + // Depending on how many digits RealType has, this may forward + // to the incomplete beta inverse as above. Otherwise uses a + // faster method that is accurate to ~15 digits everywhere + // and a couple of epsilon at double precision and in the central + // region where most use cases will occur... + // + return boost::math::detail::fast_students_t_quantile(df, probability, Policy()); +} // quantile + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + return cdf(c.dist, -c.param); +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + return -quantile(c.dist, c.param); +} + +// +// Parameter estimation follows: +// +namespace detail{ +// +// Functors for finding degrees of freedom: +// +template +struct sample_size_func +{ + BOOST_MATH_GPU_ENABLED sample_size_func(RealType a, RealType b, RealType s, RealType d) + : alpha(a), beta(b), ratio(s*s/(d*d)) {} + + BOOST_MATH_GPU_ENABLED RealType operator()(const RealType& df) + { + if(df <= tools::min_value()) + { // + return 1; + } + students_t_distribution t(df); + RealType qa = quantile(complement(t, alpha)); + RealType qb = quantile(complement(t, beta)); + qa += qb; + qa *= qa; + qa *= ratio; + qa -= (df + 1); + return qa; + } + RealType alpha, beta, ratio; +}; + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED RealType students_t_distribution::find_degrees_of_freedom( + RealType difference_from_mean, + RealType alpha, + RealType beta, + RealType sd, + RealType hint) +{ + constexpr auto function = "boost::math::students_t_distribution<%1%>::find_degrees_of_freedom"; + // + // Check for domain errors: + // + RealType error_result; + if(false == detail::check_probability( + function, alpha, &error_result, Policy()) + && detail::check_probability(function, beta, &error_result, Policy())) + return error_result; + + if(hint <= 0) + hint = 1; + + detail::sample_size_func f(alpha, beta, sd, difference_from_mean); + tools::eps_tolerance tol(policies::digits()); + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + boost::math::pair r = tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy()); + RealType result = r.first + (r.second - r.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time: either there is no answer to how many degrees of freedom are required" // LCOV_EXCL_LINE + " or the answer is infinite. Current best guess is %1%", result, Policy()); // LCOV_EXCL_LINE + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const students_t_distribution& /*dist*/) +{ + // Assume no checks on degrees of freedom are useful (unlike mean). + return 0; // Always zero by definition. +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const students_t_distribution& /*dist*/) +{ + // Assume no checks on degrees of freedom are useful (unlike mean). + return 0; // Always zero by definition. +} + +// See section 5.1 on moments at http://en.wikipedia.org/wiki/Student%27s_t-distribution + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const students_t_distribution& dist) +{ // Revised for https://svn.boost.org/trac/boost/ticket/7177 + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 1) ) + { // mean is undefined for moment <= 1! + return policies::raise_domain_error( + "boost::math::mean(students_t_distribution<%1%> const&, %1%)", + "Mean is undefined for degrees of freedom < 1 but got %1%.", df, Policy()); + return boost::math::numeric_limits::quiet_NaN(); + } + return 0; +} // mean + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const students_t_distribution& dist) +{ // http://en.wikipedia.org/wiki/Student%27s_t-distribution + // Revised for https://svn.boost.org/trac/boost/ticket/7177 + RealType df = dist.degrees_of_freedom(); + if ((boost::math::isnan)(df) || (df <= 2)) + { // NaN or undefined for <= 2. + return policies::raise_domain_error( + "boost::math::variance(students_t_distribution<%1%> const&, %1%)", + "variance is undefined for degrees of freedom <= 2, but got %1%.", + df, Policy()); + return boost::math::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 1; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 1; + } + else + { + return df / (df - 2); + } +} // variance + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const students_t_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + if( ((boost::math::isnan)(df)) || (dist.degrees_of_freedom() <= 3)) + { // Undefined for moment k = 3. + return policies::raise_domain_error( + "boost::math::skewness(students_t_distribution<%1%> const&, %1%)", + "Skewness is undefined for degrees of freedom <= 3, but got %1%.", + dist.degrees_of_freedom(), Policy()); + return boost::math::numeric_limits::quiet_NaN(); + } + return 0; // For all valid df, including infinity. +} // skewness + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const students_t_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 4)) + { // Undefined or infinity for moment k = 4. + return policies::raise_domain_error( + "boost::math::kurtosis(students_t_distribution<%1%> const&, %1%)", + "Kurtosis is undefined for degrees of freedom <= 4, but got %1%.", + df, Policy()); + return boost::math::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 3; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 3; + } + else + { + //return 3 * (df - 2) / (df - 4); re-arranged to + return 6 / (df - 4) + 3; + } +} // kurtosis + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const students_t_distribution& dist) +{ + // see http://mathworld.wolfram.com/Kurtosis.html + + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 4)) + { // Undefined or infinity for moment k = 4. + return policies::raise_domain_error( + "boost::math::kurtosis_excess(students_t_distribution<%1%> const&, %1%)", + "Kurtosis_excess is undefined for degrees of freedom <= 4, but got %1%.", + df, Policy()); + return boost::math::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 0; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 0; + } + else + { + return 6 / (df - 4); + } +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const students_t_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType v = dist.degrees_of_freedom(); + RealType vp1 = (v+1)/2; + RealType vd2 = v/2; + + return vp1*(digamma(vp1) - digamma(vd2)) + log(sqrt(v)*beta(vd2, RealType(1)/RealType(2))); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_STUDENTS_T_HPP diff --git a/third-party/boost-math/include/boost/math/distributions/triangular.hpp b/third-party/boost-math/include/boost/math/distributions/triangular.hpp new file mode 100644 index 0000000000000..e14d3f84a5007 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/triangular.hpp @@ -0,0 +1,548 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007. +// 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) + +#ifndef BOOST_STATS_TRIANGULAR_HPP +#define BOOST_STATS_TRIANGULAR_HPP + +// http://mathworld.wolfram.com/TriangularDistribution.html +// Note that the 'constructors' defined by Wolfram are difference from those here, +// for example +// N[variance[triangulardistribution{1, +2}, 1.5], 50] computes +// 0.041666666666666666666666666666666666666666666666667 +// TriangularDistribution{1, +2}, 1.5 is the analog of triangular_distribution(1, 1.5, 2) + +// http://en.wikipedia.org/wiki/Triangular_distribution + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ + namespace detail + { + template + BOOST_MATH_GPU_ENABLED inline bool check_triangular_lower( + const char* function, + RealType lower, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(lower)) + { // Any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Lower parameter is %1%, but must be finite!", lower, pol); + return false; + } + } // bool check_triangular_lower( + + template + BOOST_MATH_GPU_ENABLED inline bool check_triangular_mode( + const char* function, + RealType mode, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(mode)) + { // any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Mode parameter is %1%, but must be finite!", mode, pol); + return false; + } + } // bool check_triangular_mode( + + template + BOOST_MATH_GPU_ENABLED inline bool check_triangular_upper( + const char* function, + RealType upper, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(upper)) + { // any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Upper parameter is %1%, but must be finite!", upper, pol); + return false; + } + } // bool check_triangular_upper( + + template + BOOST_MATH_GPU_ENABLED inline bool check_triangular_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // Any finite value is OK + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_triangular_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_triangular( + const char* function, + RealType lower, + RealType mode, + RealType upper, + RealType* result, const Policy& pol) + { + if ((check_triangular_lower(function, lower, result, pol) == false) + || (check_triangular_mode(function, mode, result, pol) == false) + || (check_triangular_upper(function, upper, result, pol) == false)) + { // Some parameter not finite. + return false; + } + else if (lower >= upper) // lower == upper NOT useful. + { // lower >= upper. + *result = policies::raise_domain_error( + function, + "lower parameter is %1%, but must be less than upper!", lower, pol); + return false; + } + else + { // Check lower <= mode <= upper. + if (mode < lower) + { + *result = policies::raise_domain_error( + function, + "mode parameter is %1%, but must be >= than lower!", lower, pol); + return false; + } + if (mode > upper) + { + *result = policies::raise_domain_error( + function, + "mode parameter is %1%, but must be <= than upper!", upper, pol); + return false; + } + return true; // All OK. + } + } // bool check_triangular + } // namespace detail + + template > + class triangular_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED triangular_distribution(RealType l_lower = -1, RealType l_mode = 0, RealType l_upper = 1) + : m_lower(l_lower), m_mode(l_mode), m_upper(l_upper) // Constructor. + { // Evans says 'standard triangular' is lower 0, mode 1/2, upper 1, + // has median sqrt(c/2) for c <=1/2 and 1 - sqrt(1-c)/2 for c >= 1/2 + // But this -1, 0, 1 is more useful in most applications to approximate normal distribution, + // where the central value is the most likely and deviations either side equally likely. + RealType result; + detail::check_triangular("boost::math::triangular_distribution<%1%>::triangular_distribution",l_lower, l_mode, l_upper, &result, Policy()); + } + // Accessor functions. + BOOST_MATH_GPU_ENABLED RealType lower()const + { + return m_lower; + } + BOOST_MATH_GPU_ENABLED RealType mode()const + { + return m_mode; + } + BOOST_MATH_GPU_ENABLED RealType upper()const + { + return m_upper; + } + private: + // Data members: + RealType m_lower; // distribution lower aka a + RealType m_mode; // distribution mode aka c + RealType m_upper; // distribution upper aka b + }; // class triangular_distribution + + typedef triangular_distribution triangular; + + #ifdef __cpp_deduction_guides + template + triangular_distribution(RealType)->triangular_distribution::type>; + template + triangular_distribution(RealType,RealType)->triangular_distribution::type>; + template + triangular_distribution(RealType,RealType,RealType)->triangular_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const triangular_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const triangular_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return boost::math::pair(dist.lower(), dist.upper()); + } + + template + BOOST_MATH_GPU_ENABLED RealType pdf(const triangular_distribution& dist, const RealType& x) + { + constexpr auto function = "boost::math::pdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if((x < lower) || (x > upper)) + { + return 0; + } + if (x == lower) + { // (mode - lower) == 0 which would lead to divide by zero! + return (mode == lower) ? 2 / (upper - lower) : RealType(0); + } + else if (x == upper) + { + return (mode == upper) ? 2 / (upper - lower) : RealType(0); + } + else if (x <= mode) + { + return 2 * (x - lower) / ((upper - lower) * (mode - lower)); + } + else + { // (x > mode) + return 2 * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType pdf(const triangular_distribution& dist, const RealType& x) + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const triangular_distribution& dist, const RealType& x) + { + constexpr auto function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if((x <= lower)) + { + return 0; + } + if (x >= upper) + { + return 1; + } + // else lower < x < upper + if (x <= mode) + { + return ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower)); + } + else + { + return 1 - (upper - x) * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType cdf(const triangular_distribution& dist, const RealType& x) + + template + BOOST_MATH_GPU_ENABLED RealType quantile(const triangular_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std functions (sqrt). + constexpr auto function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + if(p == 0) + { + return lower; + } + if(p == 1) + { + return upper; + } + RealType p0 = (mode - lower) / (upper - lower); + RealType q = 1 - p; + if (p < p0) + { + result = sqrt((upper - lower) * (mode - lower) * p) + lower; + } + else if (p == p0) + { + result = mode; + } + else // p > p0 + { + result = upper - sqrt((upper - lower) * (upper - mode) * q); + } + return result; + + } // RealType quantile(const triangular_distribution& dist, const RealType& q) + + template + BOOST_MATH_GPU_ENABLED RealType cdf(const complemented2_type, RealType>& c) + { + constexpr auto function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = c.dist.lower(); + RealType mode = c.dist.mode(); + RealType upper = c.dist.upper(); + RealType x = c.param; + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if (x <= lower) + { + return 1; + } + if (x >= upper) + { + return 0; + } + if (x <= mode) + { + return 1 - ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower)); + } + else + { + return (upper - x) * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType cdf(const complemented2_type, RealType>& c) + + template + BOOST_MATH_GPU_ENABLED RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // Aid ADL for sqrt. + constexpr auto function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)"; + RealType l = c.dist.lower(); + RealType m = c.dist.mode(); + RealType u = c.dist.upper(); + RealType q = c.param; // probability 0 to 1. + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, l, m, u, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, q, &result, Policy())) + { + return result; + } + if(q == 0) + { + return u; + } + if(q == 1) + { + return l; + } + RealType lower = c.dist.lower(); + RealType mode = c.dist.mode(); + RealType upper = c.dist.upper(); + + RealType p = 1 - q; + RealType p0 = (mode - lower) / (upper - lower); + if(p < p0) + { + RealType s = (upper - lower) * (mode - lower); + s *= p; + result = sqrt((upper - lower) * (mode - lower) * p) + lower; + } + else if (p == p0) + { + result = mode; + } + else // p > p0 + { + result = upper - sqrt((upper - lower) * (upper - mode) * q); + } + return result; + } // RealType quantile(const complemented2_type, RealType>& c) + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const triangular_distribution& dist) + { + constexpr auto function = "boost::math::mean(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + return (lower + upper + mode) / 3; + } // RealType mean(const triangular_distribution& dist) + + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const triangular_distribution& dist) + { + constexpr auto function = "boost::math::mean(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + return (lower * lower + upper * upper + mode * mode - lower * upper - lower * mode - upper * mode) / 18; + } // RealType variance(const triangular_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const triangular_distribution& dist) + { + constexpr auto function = "boost::math::mode(const triangular_distribution<%1%>&)"; + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular_mode(function, mode, &result, Policy())) + { // This should never happen! + return result; + } + return mode; + } // RealType mode + + template + BOOST_MATH_GPU_ENABLED inline RealType median(const triangular_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + constexpr auto function = "boost::math::median(const triangular_distribution<%1%>&)"; + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular_mode(function, mode, &result, Policy())) + { // This should never happen! + return result; + } + RealType lower = dist.lower(); + RealType upper = dist.upper(); + if (mode >= (upper + lower) / 2) + { + return lower + sqrt((upper - lower) * (mode - lower)) / constants::root_two(); + } + else + { + return upper - sqrt((upper - lower) * (upper - mode)) / constants::root_two(); + } + } // RealType mode + + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const triangular_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + using namespace boost::math::constants; // for root_two + constexpr auto function = "boost::math::skewness(const triangular_distribution<%1%>&)"; + + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == boost::math::detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return root_two() * (lower + upper - 2 * mode) * (2 * lower - upper - mode) * (lower - 2 * upper + mode) / + (5 * pow((lower * lower + upper * upper + mode * mode + - lower * upper - lower * mode - upper * mode), RealType(3)/RealType(2))); + // #11768: Skewness formula for triangular distribution is incorrect - corrected 29 Oct 2015 for release 1.61. + } // RealType skewness(const triangular_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const triangular_distribution& dist) + { // These checks may be belt and braces as should have been checked on construction? + constexpr auto function = "boost::math::kurtosis(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return static_cast(12)/5; // 12/5 = 2.4; + } // RealType kurtosis_excess(const triangular_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const triangular_distribution& dist) + { // These checks may be belt and braces as should have been checked on construction? + constexpr auto function = "boost::math::kurtosis_excess(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return static_cast(-3)/5; // - 3/5 = -0.6 + // Assuming mathworld really means kurtosis excess? Wikipedia now corrected to match this. + } + + template + BOOST_MATH_GPU_ENABLED inline RealType entropy(const triangular_distribution& dist) + { + BOOST_MATH_STD_USING + return constants::half() + log((dist.upper() - dist.lower())/2); + } + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_TRIANGULAR_HPP + + + diff --git a/third-party/boost-math/include/boost/math/distributions/uniform.hpp b/third-party/boost-math/include/boost/math/distributions/uniform.hpp new file mode 100644 index 0000000000000..08472f95e1200 --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/uniform.hpp @@ -0,0 +1,398 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2006. +// Copyright Matt Borland 2024. +// 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) + +// TODO deal with infinity as special better - or remove. +// + +#ifndef BOOST_STATS_UNIFORM_HPP +#define BOOST_STATS_UNIFORM_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm +// http://mathworld.wolfram.com/UniformDistribution.html +// http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/UniformDistribution.html +// http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29 + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ + namespace detail + { + template + BOOST_MATH_GPU_ENABLED inline bool check_uniform_lower( + const char* function, + RealType lower, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(lower)) + { // any finite value is OK. + return true; + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Lower parameter is %1%, but must be finite!", lower, pol); + return false; + } + } // bool check_uniform_lower( + + template + BOOST_MATH_GPU_ENABLED inline bool check_uniform_upper( + const char* function, + RealType upper, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(upper)) + { // Any finite value is OK. + return true; + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Upper parameter is %1%, but must be finite!", upper, pol); + return false; + } + } // bool check_uniform_upper( + + template + BOOST_MATH_GPU_ENABLED inline bool check_uniform_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // Any finite value is OK + return true; + } + else + { // Not finite.. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_uniform_x + + template + BOOST_MATH_GPU_ENABLED inline bool check_uniform( + const char* function, + RealType lower, + RealType upper, + RealType* result, const Policy& pol) + { + if((check_uniform_lower(function, lower, result, pol) == false) + || (check_uniform_upper(function, upper, result, pol) == false)) + { + return false; + } + else if (lower >= upper) // If lower == upper then 1 / (upper-lower) = 1/0 = +infinity! + { // upper and lower have been checked before, so must be lower >= upper. + *result = policies::raise_domain_error( + function, + "lower parameter is %1%, but must be less than upper!", lower, pol); + return false; + } + else + { // All OK, + return true; + } + } // bool check_uniform( + + } // namespace detail + + template > + class uniform_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + BOOST_MATH_GPU_ENABLED uniform_distribution(RealType l_lower = 0, RealType l_upper = 1) // Constructor. + : m_lower(l_lower), m_upper(l_upper) // Default is standard uniform distribution. + { + RealType result; + detail::check_uniform("boost::math::uniform_distribution<%1%>::uniform_distribution", l_lower, l_upper, &result, Policy()); + } + // Accessor functions. + BOOST_MATH_GPU_ENABLED RealType lower()const + { + return m_lower; + } + + BOOST_MATH_GPU_ENABLED RealType upper()const + { + return m_upper; + } + private: + // Data members: + RealType m_lower; // distribution lower aka a. + RealType m_upper; // distribution upper aka b. + }; // class uniform_distribution + + typedef uniform_distribution uniform; + + #ifdef __cpp_deduction_guides + template + uniform_distribution(RealType)->uniform_distribution::type>; + template + uniform_distribution(RealType,RealType)->uniform_distribution::type>; + #endif + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair range(const uniform_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(-max_value(), max_value()); // - to + 'infinity'. + // Note RealType infinity is NOT permitted, only max_value. + } + + template + BOOST_MATH_GPU_ENABLED inline const boost::math::pair support(const uniform_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return boost::math::pair(dist.lower(), dist.upper()); + } + + template + BOOST_MATH_GPU_ENABLED inline RealType pdf(const uniform_distribution& dist, const RealType& x) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + + if((x < lower) || (x > upper) ) + { + return 0; + } + else + { + return 1 / (upper - lower); + } + } // RealType pdf(const uniform_distribution& dist, const RealType& x) + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const uniform_distribution& dist, const RealType& x) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + if (x < lower) + { + return 0; + } + if (x > upper) + { + return 1; + } + return (x - lower) / (upper - lower); // lower <= x <= upper + } // RealType cdf(const uniform_distribution& dist, const RealType& x) + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const uniform_distribution& dist, const RealType& p) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks + if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", p, &result, Policy())) + { + return result; + } + if(p == 0) + { + return lower; + } + if(p == 1) + { + return upper; + } + return p * (upper - lower) + lower; + } // RealType quantile(const uniform_distribution& dist, const RealType& p) + + template + BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) + { + RealType lower = c.dist.lower(); + RealType upper = c.dist.upper(); + RealType x = c.param; + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + if (x < lower) + { + return 1; + } + if (x > upper) + { + return 0; + } + return (upper - x) / (upper - lower); + } // RealType cdf(const complemented2_type, RealType>& c) + + template + BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) + { + RealType lower = c.dist.lower(); + RealType upper = c.dist.upper(); + RealType q = c.param; + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy())) + { + return result; + } + if(q == 0) + { + return upper; + } + if(q == 1) + { + return lower; + } + return -q * (upper - lower) + upper; + } // RealType quantile(const complemented2_type, RealType>& c) + + template + BOOST_MATH_GPU_ENABLED inline RealType mean(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::mean(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (lower + upper ) / 2; + } // RealType mean(const uniform_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType variance(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::variance(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (upper - lower) * ( upper - lower) / 12; + // for standard uniform = 0.833333333333333333333333333333333333333333; + } // RealType variance(const uniform_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType mode(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::mode(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + result = lower; // Any value [lower, upper] but arbitrarily choose lower. + return result; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType median(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::median(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (lower + upper) / 2; // + } + template + BOOST_MATH_GPU_ENABLED inline RealType skewness(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::skewness(const uniform_distribution<%1%>&)",lower, upper, &result, Policy())) + { + return result; + } + return 0; + } // RealType skewness(const uniform_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::kurtosis_excess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return static_cast(-6)/5; // -6/5 = -1.2; + } // RealType kurtosis_excess(const uniform_distribution& dist) + + template + BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const uniform_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + BOOST_MATH_GPU_ENABLED inline RealType entropy(const uniform_distribution& dist) + { + BOOST_MATH_STD_USING + return log(dist.upper() - dist.lower()); + } + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_UNIFORM_HPP + + + diff --git a/third-party/boost-math/include/boost/math/distributions/weibull.hpp b/third-party/boost-math/include/boost/math/distributions/weibull.hpp new file mode 100644 index 0000000000000..eb4de106c8d6e --- /dev/null +++ b/third-party/boost-math/include/boost/math/distributions/weibull.hpp @@ -0,0 +1,487 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_STATS_WEIBULL_HPP +#define BOOST_STATS_WEIBULL_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm +// http://mathworld.wolfram.com/WeibullDistribution.html + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline bool check_weibull_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) +{ + if((shape <= 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0 !", shape, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_weibull_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +BOOST_MATH_GPU_ENABLED inline bool check_weibull( + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) && check_weibull_shape(function, shape, result, pol); +} + +} // namespace detail + +template > +class weibull_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + BOOST_MATH_GPU_ENABLED explicit weibull_distribution(RealType l_shape, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_weibull("boost::math::weibull_distribution<%1%>::weibull_distribution", l_scale, l_shape, &result, Policy()); + } + + BOOST_MATH_GPU_ENABLED RealType shape()const + { + return m_shape; + } + + BOOST_MATH_GPU_ENABLED RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +using weibull = weibull_distribution; + +#ifdef __cpp_deduction_guides +template +weibull_distribution(RealType)->weibull_distribution::type>; +template +weibull_distribution(RealType,RealType)->weibull_distribution::type>; +#endif + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair range(const weibull_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return boost::math::pair(static_cast(0), max_value()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair support(const weibull_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return boost::math::pair(min_value(), max_value()); + // A discontinuity at x == 0, so only support down to min_value. +} + +template +BOOST_MATH_GPU_ENABLED inline RealType pdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::pdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + if(shape == 1) + { + return 1 / scale; + } + if(shape > 1) + { + return 0; + } + return policies::raise_overflow_error(function, 0, Policy()); + } + result = exp(-pow(x / scale, shape)); + result *= pow(x / scale, shape - 1) * shape / scale; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType logpdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logpdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + if(shape == 1) + { + return log(1 / scale); + } + if(shape > 1) + { + return 0; + } + return policies::raise_overflow_error(function, 0, Policy()); + } + + result = log(shape) - shape * log(scale) + log(x) * (shape - 1) - pow(x / scale, shape); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + result = -boost::math::expm1(-pow(x / scale, shape), Policy()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + result = log1p(-exp(-pow(x / scale, shape)), Policy()); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const weibull_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = scale * pow(-boost::math::log1p(-p, Policy()), 1 / shape); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, c.param, &result, Policy())) + return result; + + result = exp(-pow(c.param / scale, shape)); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType logcdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::logcdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, c.param, &result, Policy())) + return result; + + result = -pow(c.param / scale, shape); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = scale * pow(-log(q), 1 / shape); + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mean(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::mean(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + + result = scale * boost::math::tgamma(1 + 1 / shape, Policy()); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType variance(const weibull_distribution& dist) +{ + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + constexpr auto function = "boost::math::variance(const weibull_distribution<%1%>)"; + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + result = boost::math::tgamma(1 + 1 / shape, Policy()); + result *= -result; + result += boost::math::tgamma(1 + 2 / shape, Policy()); + result *= scale * scale; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType mode(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std function pow. + + constexpr auto function = "boost::math::mode(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + if(shape <= 1) + return 0; + result = scale * pow((shape - 1) / shape, 1 / shape); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType median(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std function pow. + + constexpr auto function = "boost::math::median(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); // Wikipedia k + RealType scale = dist.scale(); // Wikipedia lambda + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + using boost::math::constants::ln_two; + result = scale * pow(ln_two(), 1 / shape); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType skewness(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::skewness(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + + RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy()); + RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy()); + RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy()); + RealType d = pow(g2 - g1 * g1, RealType(1.5)); + + result = (2 * g1 * g1 * g1 - 3 * g1 * g2 + g3) / d; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + constexpr auto function = "boost::math::kurtosis_excess(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + + RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy()); + RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy()); + RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy()); + RealType g4 = boost::math::tgamma(1 + 4 / shape, Policy()); + RealType g1_2 = g1 * g1; + RealType g1_4 = g1_2 * g1_2; + RealType d = g2 - g1_2; + d *= d; + + result = -6 * g1_4 + 12 * g1_2 * g2 - 3 * g2 * g2 - 4 * g1 * g3 + g4; + result /= d; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const weibull_distribution& dist) +{ + return kurtosis_excess(dist) + 3; +} + +template +BOOST_MATH_GPU_ENABLED inline RealType entropy(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType k = dist.shape(); + RealType lambda = dist.scale(); + return constants::euler()*(1-1/k) + log(lambda/k) + 1; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_WEIBULL_HPP + + diff --git a/third-party/boost-math/include/boost/math/filters/daubechies.hpp b/third-party/boost-math/include/boost/math/filters/daubechies.hpp new file mode 100644 index 0000000000000..0655be37938c2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/filters/daubechies.hpp @@ -0,0 +1,99 @@ +/* + * Copyright Nick Thompson, John Maddock 2020 + * 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) + */ +#ifndef BOOST_MATH_FILTERS_DAUBECHIES_HPP +#define BOOST_MATH_FILTERS_DAUBECHIES_HPP +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math::filters { + +template +constexpr std::array daubechies_scaling_filter() +{ + static_assert(p < 20, "Filter coefficients only implemented up to 19."); + if constexpr (p == 1) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.70710678118654752440084436210484903928483593768847403658833986899536623923), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.70710678118654752440084436210484903928483593768847403658833986899536623923) }; + } + if constexpr (p == 2) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.48296291314453414337487159986444868381695241950420227520117153815521160699), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.83651630373780790557529378091687320345937038834843929349534147265289472661), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.22414386804201338102597276224040035546788351818427176138716833084015463224), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12940952255126038117444941881202416417453445065996525690700160365752848737) }; + } + if constexpr (p == 3) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.33267055295008261599851158913900563001292339924506835970847057855179372371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.80689150931109257649449360408871349051929739499482361816509206360348683533), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.45987750211849157009515194214761672080811017743149230664338678024864033563), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.135011020010254588696389906699374480562219845223781191975686255357062768), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.085441273882026661692819169181773311536197638988086629763517489805067820106), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.035226291885709536602740664715510029327758387917431610398934060748942171898) }; + } + if constexpr (p == 4) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.23037781330889650086329118304407085000161524824830929779109684402827164374), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.71484657055291564708992195527399260370760840109930817584501100344262504653), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63088076792985890788171633830061522020322292267719511740574732848435336141), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.027983769416859854211413747180075385411987320224491752840033582653363093001), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.18703481171909308407957067278908141958454417437458009120577708759399258629), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.030841381835560763627219362534959050170314821720034033418212190936063233775), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.032883011666885199735407513549244388664541941137549712597272784076733820371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.01059740178506903210488320852402722918109996490637641983484974272995894807) }; + } + if constexpr (p == 5) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16010239797419291448072374802042073365054412462505783277256992020754721449), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60382926979718967054011930652506210750742216310169869879692833603686283702), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.72430852843777292772807124410221864076875621823200737257673350480409279922), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13842814590132073150539714633902469731410579117395610226946522108855217638), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.24229488706638203186257137947461636199149080806261859839137269134106547424), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.032244869584638374648479755062134928313564984163798472254342681319811609232), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.077571493840045713523130489388601819806230994520125279832101462389556715934), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0062414902127982742741905191129201929707635571656876073234174353259085160535), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012580751999081999468509739931775792949204591626097850201692327064765016178), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0033357252854737712779981834158173557476365247423053150997064285156713511141) }; + } + if constexpr (p == 6) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.11154074335010946362132391724092343904253959198442167590823604579765159644), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4946238903984530856772041768778555886377863828962743623531834526188698465), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.75113390802109535067893449843973168558025478333826120097304206594799266889), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31525035170919762908598965481092639664951992351729452444041638160625244927), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22626469396543982007631450066090346567054015397289699401434877917897027718), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12976686756726193556228960587658546084523374922358147015993106558172041337), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.097501605587323049102343552538125342339830747495255142798931931211277981638), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027522865530305728625540839504193213657387587830434543214942028790000299266), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.031582039317486029565079080699848669057479532373148423375114649352606045848), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00055384220116149613925191839804650122061102627738649642954765245675247527348), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0047772575109455106396359752468207070502305012165814342975932545700203152873), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0010773010853084795648526216095872000352352336093344196898185808947884177076) }; + } + if constexpr (p == 7) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.077852054085009179019963521957893748379183052927955684387029371799629765558), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3965393194819173065390003909368428563587151149333287401110499620754878153), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.72913209084623511991694307033928205171796606119013637826977157495535702874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4697822874051931224715911609744517386817913056787359532392529141008369217), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.14390600392856497540506836221304600179527357054990848344017530142299184121), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22403618499387498263814042023325096447578308967732465526650953072415165804), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.071309219266830264750876570501129048227113274514123146595751132202029061555), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.080612609151083071912922480359381905858238209656294890581392184772265275649), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.038029936935014413579592061601858035854461969384678698982831227165741061737), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.016574541630666880654107674891702654792045043948207137052392725487143490786), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.012550998556099840612989886034187779572894740460487100384118183441674102341), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00042957797292136652113212912281973222282353503969424097429463669354494184942), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0018016407040474909152682629127395509625856514696410906253238648145908160214), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00035371379997452024844629583630642543109590600595200400125242756452643355644) }; + } + if constexpr (p == 8) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.054415842243104009955009405202999355035995542947330503977292808677193622648), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31287159091429997065916237550571772194973197403702291856987124211531149794), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.67563073629728980680780076704718314998691159063363642277667598381172874696), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.58535468365420671277126552004509819443032666780533690557071753488957052267), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.015829105256349305667380547876466304157744711545028265597353359560312661545), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.28401554296154692651620313237416473246843501248714517935992048090937585953), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00047248457391328277036059000982589498619480112887700746440840960229954465856), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.12874742662047845885702928750970838430226015755564887955770001654977066319), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.017369301001807546169616148868095983114130865294883943169773153885119747929), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.044088253930794751506763723238963501897518391901109964727503919854754335188), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013981027917398281648722930572633451442395595329343471691463681144262938301), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0087460940474057767163827432464756401804021470811406767426867470261177584378), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0048703529934515743104221815571098240166349785121570037647362085321921707468), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00039174037337694704629808035732377626752293500738904937244926946775919522535), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00067544940645056936636954757387929912184896300135584321036170773750596688963), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00011747678412476953373062823169889094440866939503115039276200135351481307347) }; + } + if constexpr (p == 9) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.038077947363878346588697658879551184487717144962784174766471924848268047975), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.24383467461259035373204158164928441552636110856092313614290881035764194652), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60482312369011111190307686743423617089595627118961175653337135326621948137), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.6572880780513005380782126390451732140305858669245918854436034065588449216), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13319738582500757619095494589979555369217807684336611361543468378391202935), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.29327378327917490880640319524219873104389616285899068257251128264977749451), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.096840783222976460513508133537696602248254581045990996794712676084296381974), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14854074933810638013507271750604230247912585772806030607716493946005155866), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.03072568147933337921231740072037882714105805024670744781503060505807447087), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.067632829061329973675642274829719015925787908713537399007483312098453778674), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00025094711483145195758718974998855433151762719937096333218341646914339924457), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0223616621236790972053737827026909524185564668830885375472181623365153339), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0047232047577513972779257078482424654057295149126279380187585268565784573968), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0042815036824634298344967950023145318764811818114632883748604550376910299936), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0018476468830562264766191294911256770511210813596003181607325150457467472311), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00023038576352319596720521639282454216929406620524637119722600068668037624505), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00025196318894271013697498868428786066072821815434780282141342653512309743183), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.934732031627159948068988306589150707782477055517013507359938155440548714e-05) }; + } + if constexpr (p == 10) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026670057900555553586617448771308582771924982908512899327799757762165073565), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1881768000776914890208929736790939942702546758640393484348595444098866088), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.52720118893172558648174482795950819249814026808402234453185494714513982787), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.68845903945360356574187178254923585397713640424073395372796811583990344659), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.28117234366057746074872699844558928762438888590261504138315439518337480745), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.24984642432731537941610189792077910005646697371320737150131215971067630043), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.1959462743773770435042992543190981318766776476382778474396781876838561782), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.12736934033579326008267723320140097707861774804222459955630975237390670344), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.093057364603572351160352289835452732269429179989469258680639741022454756675), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.071394147166397087145336093076050647672926119837021509175237563479658240953), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.029457536821875812858283237601418391993882005160649487797696542831849016741), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.033212674059341001739763653182159128979783374132670960433233512708331299782), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0036065535669561696554232914171334032995173505186189947627306122912865631829), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.01073317548333057504431811410651364448111548781143923213370333937093436962), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0013953517470529011657893184479577075676605428556885524267211177234294314032), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0019924052951850561171587422426406432117625553655141052800679364782486446064), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00068585669495971162656137098192657141966250433367869205162119035617579793186), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00011646685512928545095148097102589918915274618543475973628192350744688585366), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 9.3588670320069591334050130342228543996884562152972764435218739396771960302e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.3264202894521244812436675312266833057492409606058297564006746194667132319e-05) }; + } + if constexpr (p == 11) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.018694297761471084025435729395619757289677744559219585432866920854463984821), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1440670211506245127951915849361001143023718967556239604318852482176121098), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4498997643560453347688940373853603677806895378648933474599655795863440433), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.68568677491620051112093863169630979359402049645677034950515890174507509031), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.41196436894790746292593964857106673074304004101878453156972425113333086269), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.16227524502749036224058272699855115407442643242121302096496674298183214991), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.27423084681794696120210094528352666286480895217751782219057783900502396695), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.066043588196683191900614578881263026567531421689407915411134572260157270027), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14981201246637849640665626170441932985882724202674846537969095942150753335), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.046479955116684187271617225890237445772232609668482607474503209875958431693), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.06643878569502520527899215536971203191819566896079739622858574023360652697), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.031335090219046076030947984083031445363581056808800319649364455090954740139), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.020840904360181063022948112556564910151577618327347156911266922007670347371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.015364820906201599426198116099588227440143264957730001202058486279377738507), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0033408588730144456060908086179824061019306583594991908456567317772540817346), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0049284176560590411231707397417082736902855477299158024183974580101937664126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00030859285881514316517545907262789533071802166050784885819215622760236544448), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00089302325066626461339008246226486539898795198786207287931333582240853430266), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00024915252355282349887122168726668010882211993028554253819713924909320282452), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.4439074699368471673578568795768321919366785256007939780436889201682941436e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -3.4634984186984995541280851599740432145064880482334580359436013556794022457e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.4942742772365100954156482823101309164104979873837534605717417484340085911e-06) }; + } + if constexpr (p == 12) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013112257957229517506746090888933280656655106419313250077482807981375136912), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1095662728211851546057045050248905426075680503066774046383657434145947162), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.37735513521421265709282126048792061490109417060575263347058391156288509976), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.65719872257930708930276112866411698342502032899884121413942819500193920417), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.51588647842781560875603264805430327006776930870360900561276472986750316737), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.04476388565377462666762747311540166529284543631505924139071704101179655136), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.31617845375278553686480293534780310985088390325473643895742033716004955521), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.02377925725606972768399754609133225784553366558331741152482612716033502819), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.18247860592757967985404361161892417102947714480963026983290112608341065294), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0053595696743521503282762767297683322888626651841927058216363426180926941677), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.096432120096507082026503205343224841274308801430452205143464027486190605026), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.010849130255822184380890102377481521886616305676033346593225122643407774116), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.041546277495084440739270946819065748645135322213883748612870789941361661575), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012218649069748280719987982664715677129824660931165581753448110455020838418), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012840825198300683294660344718947284962061098323140976332752255734850878212), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0067114990087955091777670270682156724506481121858564567403794553368864243964), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.002248607240995237599950865211267234018343199786146177099262010279010074457), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0021795036186277604715989033795841711878400752918605712649809429870507326048), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.5451282125095955665004303993271107291117705688973566307145520074184844383e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00038865306282093144358972888377959817919174885734201775234360961313833182126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.8504109208204324208216459615537265987383221514719328080154430300199184715e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.4241545757030784029789153205317195804237783626642822393775322072922884523e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.2776952219379766587140463626166208873759609414394287560553539204265370227e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.529071758068510902712239164522901223197615439660340672602696416832185426e-06) }; + } + if constexpr (p == 13) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0092021335389623679729701634756441846675341719164165623860097030371191217305), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.082861243872902779644320271312304664052081133328901350725142774200948295461), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31199632216043806339607841122140496939466835289671803171603901730851565412), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.61105585115878765282119951367441805620736126760182394385265829401520403811), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.58888957043121890807103953473953339276659863828128360422355734065024957534), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.08698572617964723731023739838087494399231884076619701250882016643780541724), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.31497290771138863299816982559322825828768884506787890259503068186813077354), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12457673075081525894138083360212601807927392951736347195720693207526097203), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.17947607942933984323484500723393690135819662562441333930428814546967642382), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.072948933656777163809028306104776619833259290268798735536279632846163669865), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.10580761818793432645096673041964648494788607548012366582323605107782068188), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.026488406475343694639639122480347857264196048442976970162642241213351984244), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.05613947710028342886214501998387331119988378792543100244737056253966757901), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0023799722540590788114651709585542083580943946120519348684751392707093052796), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.023831420710323649032064030677577391342529227176362262740772986334105772526), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0039239414487974162433163702208155265588247466234514040439184072878721741534), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0072555894016175661945183933005026988989735296796466836952698286726005062515), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0027619112346568621780145762660984459953500933305018180249663164832661496432), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0013156739118922989366138353705936433760604125926536523072381245947457012192), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00093232613086726338622265178025485141009180882998019523079915692711270149142), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.9251525126289461921409573878665962101037782993888235008400944566113947075e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00016512898855650548946166877092380007558985482146597767033478014935998742089), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0678537579325493466494832285754762366004282172379005631282307485528301752e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.0441930571408137081707149910805969516707064362173281696414740684382080067e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.7004164793608683256501951650617713216503835829709585565680597113341224593e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.2200350984548646917364243548431769767470521552435570015319010534889500617e-07) }; + } + if constexpr (p == 14) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0064611534600879478181663974486228142723271594192011992181014041682131963958), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.062364758849398898327985667584348774283053336934076671646025188061380759653), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.25485026779262135366590778867782866861870424163671374437800842023823271874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.55430561794089383599268314498511548440782698309516346096839977753222684278), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63118784910485677955766171353581723486239524565700172897888095924843364054), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21867068775890652149174759182175170517657743212704320590302732335253422232), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.27168855227874804141421924761811710946048824656833308143118966692384906639), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.21803352999327604475555588127023119119752406694706047527471270417978599672), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13839521386480659107399396900215737139899004632296861190591199023906568404), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13998901658446070124929431622711634403282215556143261813336838173012766117), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.086748411568169689045608220667277953829791495395175036574929644598228933263), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.071548955504046130735841451151738079909580696731295380999909130933544719175), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.055237126259216044116188340605334033979138336325116721576711076599596585739), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026981408307912916973990314032151933433757665958072742332843492806013139065), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.030185351540390635187148226234891375737815754066586526248837561937906600698), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0056150495303569591332183713676914986374572972039258103876986801691601779992), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.012789493266333408961573307057840792993749038615720583134815345194814152872), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0007462189892683849371817160739181780971958187988813302900435487508701832207), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.003849638868022187445786349316095551774096818508285700493058915725327777667), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0010616910856067618430325667493884111730339415821478308638939395615438824882), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00070802115423552785864429776976171289834718634641815953716700944226680311764), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00038683194731295448210766633980573144273289021078421653799014684260953603847), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.1777245770372597352679795398392589283897265901327301310543237300793962875e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.8755042526975096038734370216280316018903706876518752798827278989286730311e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.0337209184570773946614073425948145862692725094907448506914430590564776387e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.3897049017813941152540425613671698293230853608008257181510491943726938635e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.7249946753678127698857126927417985235878947098673565769107179471945464675e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.7871399683113590763341929384708393438829903099769594469940228456912731758e-07) }; + } + if constexpr (p == 15) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0045385373615788988814593949102116963466636712437887869979165135973061826537), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.046743394892766271891709693348435757765791517002149435131131973437721383622), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.20602386398699573153989150094763072193061385056419309027020472662490156122), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.49263177170813962360677570740299463726172215651309324021601600369752281377), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.64581314035742435817642091201069179964326082874940461810714894789553306679), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3390025354547315276912641143835773918756769491793554669336690115093975569), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.19320413960914542870639905343214717463040900391428638279377549215058972689), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.28888259656696564624841250098223329813114356304353425949712929625629348294), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.065282952848772816922831079198695748820391742855961441259651013056195336897), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.19014671400712298234848931165860205179595012581743366968781560605525428795), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.039666176555790944483843667518962006683817428206837368054497453529283868676), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.11112093603723169336567103246740586088586237621659141205056578840053963186), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.033877143923507686208548178444335237708647446874112653694631959912301278547), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.05478055058450761268913790312581879108609415997422768564244845364080300918), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.025767007328439962585945257542698263922036416348253401383968368254171628001), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.020810050169693081677884834246770001620546579513648990409961661727192610178), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.015083918027835902363292744601703227362448928233056277162339688903695078372), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0051010003604075431697088601855653147248010665273442220555266310691657585506), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0064877345603157449951816831492186908169558456393888264079289674694518478686), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00024175649076162428116672253263001796052299469958145352233294119288913115604), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0019433239803822115417649123325410874410114248655795314014523026178946534131), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00037348235413761699200980942136454146113876309680302566257402267355583112012), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00035956524436246881216496200759098088581942024540840903056274804667283876243), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00015589648992059974794716582412271088162555670596254959152286036304283062436), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.5792699155318936809258624176168559129440423687673407091601197370095004239e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.8133296266047813647553247770784786657914438762937889042672556207530238846e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.3629871817375798031248452104201774721348466558640781871863045015033003361e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.8112704079405770837685109122858411605770859253375078505902906808655395748e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.3168823258816644212015972995176576541661379151211955104166416260677217926e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.1333599133057520290562994602897886019891904508853965121738455950580467421e-08) }; + } + if constexpr (p == 16) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0031892209253477380297695475646459586870670867501314287678758781777869486255), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.034907714323673346410301472240230200092182414305039841461400546477376377996), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16506428348885311789912527305611348115848350023427232402135928290203409966), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.43031272284600381374039254243576846206339704780369867739246462911886492889), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63735633208378889863198524129960305364985959408141981259677515932255242966), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.44029025688635690003908691635716792885278030351352725787898843221650113068), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.089751089402489642857187180774425974306592474455826601496247184152268478657), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.32706331052791770464629056756891196417572289182288124281417235311673360956), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.027918208133028276682645195950268732043399712191747360415354797624368497971), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21119069394710428872096801632688379009284914261676794392510428265923934071), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027340263752716041364852457572016179654290278195071302202315002681181103625), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.13238830556381039045004741477564933750922878177060279787985490274221256881), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0062397227524748717656745033941200258654446563116787609907614580866382455691), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.075924236044276315821484987439414224615304059461009433519403139995132210368), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.007588974368857737638494890864636995796586975144990925400097160943671446065), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.036888397691730142333526663208945543147187484297067308310640687651290473968), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.010297659640955969411650005800766169005288562658036622088541473449733491006), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013993768859828731029504518736703297264098402917278689884901007836048645298), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0069900145634139166702842495365172883380578561996464690781157596750271110103), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0036442796214983899321690005409336293870553339733531086688412150466993897338), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0031280233812062688316612025598546787678214719061936081174503608103102062028), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00040789698084971283624174703234060957824319529723105467150713971109834118994), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00094102174935956758892664539536358754077547472167344805092502736794906570513), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00011424152003872239264402280995556629458396843449364726528770914231509741867), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00017478724522533818038017586376607468749860247286153998979719535958918304821), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.1035966214109358351623691505222128119572599819659191439617228139148512866e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.3945668988208893451990783119984019823252735691986753354087079704564463183e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.1336608661276258587588487628865369975194710682037536617578434288137908852e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.0435713423116065015254547372626154048874789306356764715460326802862590987e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -7.3636567854512055120996957197255636465854455458416633274335692328538306759e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.3087840868575458664054127329420061213063067358666555253725448647310885248e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.1093396301007430970005726236034899068362975845916053077453499495253372784e-08) }; + } + if constexpr (p == 17) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0022418070010373128535359626770744369140621918805603707332505311813341919259), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.025985393703606043389148645917207883154739445248782412943999482768766372542), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1312149033078244065775506231859069960144293609259978530067004394590336311), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.37035072415264115044925481907218864494770788768968038236504259357952962858), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.61099661568462281818866788676793720827370938933587262913717839049083529043), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.51831576405693783932545385280859680462168171977184164024399049868328890005), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027314970403293635004312507191475864803504698189645630036729428228327122309), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.32832074836396173609096653407250617675815976981515580246791305268967637817), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12659975221588270287446791109338255050539662601040861621037283235916492881), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.19731058956501099278540470447819301425514224141356469171222842260045667421), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.10113548917747027215096998564334348021966225454996648761094379629310502982), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12681569177828631109485711286623316803847921859150170657321374899495682695), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.057091419631676927289112394786513823241611608698453470539901446405938289849), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.081105986654160885079658857485554292010243641909544991940206782277507046299), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.022312336178103795953391360595348137562322421140936892440208691931826899684), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.04692243838926973733300897059211400507138768125498030602878439278261681888), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0032709555358192937816553602221774944520695259580616093928092757512244970215), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.022733676583946270318456162447884489699067137413383394980248641327563508924), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.003042989981354637068592482637907206078633395457225096588287881355853146664), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0086029215203228548317137064132436599179267362842717306119209867025723028123), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0029679966915260948728064850600080382699594638465483789950441950342910257421), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0023012052421535456243020598690384236042419766801894474760647649372848372532), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0014368453048029761262228904029803849035036745307299358095614347112123643258), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0003281325194098379713954444017520115075812402442728749700195651589580752544), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00043946542776864367783856775273178416322892493197388921794659107576228639092), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.561010956654845882729891210949920221664082061531909655178413745234158599e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.2048032024533918390954825762821898661362730496367643386895936421343224507e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.3186813798745950844820682057062775721066951740918953385307347893104278256e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.9906009850767512732045497008553786277627585859020579640274813805087794281e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.5059424772229881941022682063783121297135726007164999449184166870668358606e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.016549609994557415605207594879939763476168705217646897702706189847154081e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.9577009333168567549799052588161513678703456289243173073546394956952199848e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.4239484460026801787870712969228770684103109422227996225931334161777920896e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 7.2674929685616081108797674414090350341585817197897910888920464080702904824e-09) }; + } + if constexpr (p == 18) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0015763102184407604315407449299397777476707537109916603636844298618471400136), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.019288531724146377059213917158290524199546670252884975722367148333214257583), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.10358846582242359622419104919372535964706965552202416729762241846965639407), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3146789413370316990571998255652579931786706190489374509491307510367406906), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.57182680776660722348185893709006234193936737431309305612953240480326532941), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.5718016548886513352891119994065965025668047882818525060759395264214055574), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14722311196992814157509772710810723125578641073557013878016771358441101668), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.29365404073655874424790309949811507239357107290350532396617523080121257803), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.21648093400514297112376786256682714714379372356694924083886923936637850636), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14953397556537778935093017389136672088048166918937656102619430719129024846), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16708131276325740451493181399501347453242056463539880831522506333701390259), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.092331884150846280604293725586594597314318480001445696120745084674620649946), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.10675224665982848559322005816149848613852664046241120839177020546784793523), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.06488721621190544281947577955141911463129382116634147846137149845158777673), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.057051247738536884120907688464996222605962261204310385246006764232075504463), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.044526141902982324715561435597446534929714778914398335927550346682023149009), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.023733210395860001032752095826652161101975193307134902330715657901430091468), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026670705926470590299879086316720203432078959999360728133634715203759565359), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0062621679543057074852360931444978825019903252047450131902680523152575205897), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.013051480946612001772776364476008071697551910545075716666061335803862913986), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00011863003385811746573017415921618190845448994174523174051856157299661793944), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0049433436054667381306655295168029748342996383133664777652952032600306770112), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0011187326669924970728006588552386501823180604825849701455126871198522790015), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0013405962983361066295175672282515836098230445246859866403239426912072388874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00062846568296514571256194498854208382175510227963015828743496528807647838152), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0002135815619103406884039052814341926025873200325996466522543440510602714976), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00019864855231174794857982454163624895549277978802640178761396052157321846575), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.5359171235347246750697703358767171937004724270215132365872881022095732925e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.7412378807400381810922081380353939523042926157939850307313638513284983136e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.5206025374466952039192549116555230224375969562263765123059170652407353738e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -3.3326344788858218887824520333410368273115059077964984398293372795640596047e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.7687129836276154558763287307553751764125013591140588154531006192349912666e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -7.6916326898851761460001528785395984058173975881565251167699086518741626737e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.1760987670282316984509823565612925613475797776953969535281413678099558364e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0688358630451748009354782949339753724501797878945744929305701163444205366e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.5079344549485982671951731831471267318063171448682758199414032678582329327e-09) }; + } + if constexpr (p == 19) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0011086697631817105710991541952097151642452996777734359321354552903838392437), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.014281098450764397374398891529501992347456634421636659578707159911077107554), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.081278113265459550652963067849016248398449799710286203664977268640601914766), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.26438843174089678467481003802894268738623778072119207184173858147735135325), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.5244363774646549153360575975484064626044633641048072116393160236280782601), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60170454912753789488670771359218026205365656395859632933139314339208321996), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.26089495265103882928724566753105283241726731013019077399252138987658244676), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22809139421548264637463257760546372070937872370864259095348224177661957967), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.2858386317558262418545975695028984237217356095588335149922119373572946758), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.074652269708103266367634331118788190058658661497319096563653999513477365762), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21234974330627848880906085670598241970770742008788394484169086980366838817), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.033518541902302878681693884187857315069778450752389668198140325857348144255), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.14278569503873657497796027316261128129984977061524285086275624334185303587), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027584350625628668750147435201621986553744745969634230807628183098383677126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.086906755555812232488476454288084430347852080024681927596403529749277245343), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.026501236250123040899018358436763873610750680176867478081713456471923315261), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.045674226277230908056454442142957960179389357321156300508801097842329883502), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.021623767409585047130329842571723723543180970678587525425710208194990717941), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.019375549889176127646370943544579998144968850958758255464069637242167682526), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.013988388678535141632504012352486625219168138674530958368083666866969990669), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0058669222810121747265844934360543737738146083408087581773727651715064285159), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0070407473671052431530145112074006201094016898976653830782293980831623467743), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0007689543592575483559749139148673955163477947086039406129546422516486233949), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0026875518007015820039573638550703986365340389209824782901702671996059483895), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.000341808653458595776565165729046380813521421484881951725779403154942704075), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00073580252050543520702604819053972818751831757927799048581894949173298761722), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00026067613567862800573183151308975227903839393620735634086135475594271631675), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00012460079173415877534497844089016539903173414133419809047575920469834920407), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 8.7112704672199229654168623881911282684129338932820835177294434200975612019e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.105950487073886053049222809934231573687367992106282669389264164311557866e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.6640176297154944546206777198991986303336756088120181087391449229369242509e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0109643162965263396953344547259436326457989381624271688513825000813231431e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.5319314766911930639318323810866360312031230327234774636241410593622067271e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.862755657769142701883554613486732854452740752771392411758418826691795609e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.4470882987978445420782198632916154205516735740713678343161676502124977734e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.6369377757826042234308577282109488988717482910859622966493207002061571346e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.116402067035825816390504769142472586464975799284473682246076559584239149e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 8.6668488389976193503230135407821246272897421902730593191228406494140940156e-10) }; + } +} + +template +std::array daubechies_wavelet_filter() { + std::array g; + auto h = daubechies_scaling_filter(); + for (size_t i = 0; i < g.size(); i += 2) + { + g[i] = h[g.size() - i - 1]; + g[i+1] = -h[g.size() - i - 2]; + } + return g; +} + +} // namespaces +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/barycentric_rational.hpp b/third-party/boost-math/include/boost/math/interpolators/barycentric_rational.hpp new file mode 100644 index 0000000000000..c18e38dd745f7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/barycentric_rational.hpp @@ -0,0 +1,99 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + * + * Given N samples (t_i, y_i) which are irregularly spaced, this routine constructs an + * interpolant s which is constructed in O(N) time, occupies O(N) space, and can be evaluated in O(N) time. + * The interpolation is stable, unless one point is incredibly close to another, and the next point is incredibly far. + * The measure of this stability is the "local mesh ratio", which can be queried from the routine. + * Pictorially, the following t_i spacing is bad (has a high local mesh ratio) + * || | | | | + * and this t_i spacing is good (has a low local mesh ratio) + * | | | | | | | | | | + * + * + * If f is C^{d+2}, then the interpolant is O(h^(d+1)) accurate, where d is the interpolation order. + * A disadvantage of this interpolant is that it does not reproduce rational functions; for example, 1/(1+x^2) is not interpolated exactly. + * + * References: + * Floater, Michael S., and Kai Hormann. "Barycentric rational interpolation with no poles and high rates of approximation." +* Numerische Mathematik 107.2 (2007): 315-331. + * Press, William H., et al. "Numerical recipes third edition: the art of scientific computing." Cambridge University Press 32 (2007): 10013-2473. + */ + +#ifndef BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_HPP +#define BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_HPP + +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ + +template +class barycentric_rational +{ +public: + barycentric_rational(const Real* const x, const Real* const y, size_t n, size_t approximation_order = 3); + + barycentric_rational(std::vector&& x, std::vector&& y, size_t approximation_order = 3); + + template + barycentric_rational(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order = 3, typename std::enable_if::value>::type* = nullptr); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + std::vector&& return_x() + { + return m_imp->return_x(); + } + + std::vector&& return_y() + { + return m_imp->return_y(); + } + +private: + std::shared_ptr> m_imp; +}; + +template +barycentric_rational::barycentric_rational(const Real* const x, const Real* const y, size_t n, size_t approximation_order): + m_imp(std::make_shared>(x, x + n, y, approximation_order)) +{ + return; +} + +template +barycentric_rational::barycentric_rational(std::vector&& x, std::vector&& y, size_t approximation_order): + m_imp(std::make_shared>(std::move(x), std::move(y), approximation_order)) +{ + return; +} + + +template +template +barycentric_rational::barycentric_rational(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order, typename std::enable_if::value>::type*) + : m_imp(std::make_shared>(start_x, end_x, start_y, approximation_order)) +{ +} + +template +Real barycentric_rational::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real barycentric_rational::prime(Real x) const +{ + return m_imp->prime(x); +} + + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/bezier_polynomial.hpp b/third-party/boost-math/include/boost/math/interpolators/bezier_polynomial.hpp new file mode 100644 index 0000000000000..022d205c094f1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/bezier_polynomial.hpp @@ -0,0 +1,60 @@ +// Copyright Nick Thompson, 2021 +// 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) +#ifndef BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_HPP +#define BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_HPP +#include +#include + +#ifdef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES +#warning "Thread local storage support is necessary for the Bezier polynomial class to work." +#endif + +namespace boost::math::interpolators { + +template +class bezier_polynomial +{ +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Z = typename RandomAccessContainer::size_type; + + bezier_polynomial(RandomAccessContainer && control_points) + : m_imp(std::make_shared>(std::move(control_points))) + { + } + + inline Point operator()(Real t) const + { + return (*m_imp)(t); + } + + inline Point prime(Real t) const + { + return m_imp->prime(t); + } + + void edit_control_point(Point const & p, Z index) + { + m_imp->edit_control_point(p, index); + } + + RandomAccessContainer const & control_points() const + { + return m_imp->control_points(); + } + + friend std::ostream& operator<<(std::ostream& out, bezier_polynomial const & bp) { + out << *bp.m_imp; + return out; + } + +private: + std::shared_ptr> m_imp; +}; + +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/bilinear_uniform.hpp b/third-party/boost-math/include/boost/math/interpolators/bilinear_uniform.hpp new file mode 100644 index 0000000000000..555204a875c0a --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/bilinear_uniform.hpp @@ -0,0 +1,54 @@ +// Copyright Nick Thompson, 2021 +// 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) + +// This implements bilinear interpolation on a uniform grid. +// If dx and dy are both positive, then the (x,y) = (x0, y0) is associated with data index 0 (herein referred to as f[0]) +// The point (x0 + dx, y0) is associated with f[1], and (x0 + i*dx, y0) is associated with f[i], +// i.e., we are assuming traditional C row major order. +// The y coordinate increases *downward*, as is traditional in 2D computer graphics. +// This is *not* how people generally think in numerical analysis (although it *is* how they lay out matrices). +// Providing the capability of a grid rotation is too expensive and not ergonomic; you'll need to perform any rotations at the call level. + +// For clarity, the value f(x0 + i*dx, y0 + j*dy) must be stored in the f[j*cols + i] position. + +#ifndef BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_HPP +#define BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_HPP + +#include +#include +#include + +namespace boost::math::interpolators { + +template +class bilinear_uniform +{ +public: + using Real = typename RandomAccessContainer::value_type; + using Z = typename RandomAccessContainer::size_type; + + bilinear_uniform(RandomAccessContainer && fieldData, Z rows, Z cols, Real dx = 1, Real dy = 1, Real x0 = 0, Real y0 = 0) + : m_imp(std::make_shared>(std::move(fieldData), rows, cols, dx, dy, x0, y0)) + { + } + + Real operator()(Real x, Real y) const + { + return m_imp->operator()(x,y); + } + + + friend std::ostream& operator<<(std::ostream& out, bilinear_uniform const & bu) { + out << *bu.m_imp; + return out; + } + +private: + std::shared_ptr> m_imp; +}; + +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cardinal_cubic_b_spline.hpp b/third-party/boost-math/include/boost/math/interpolators/cardinal_cubic_b_spline.hpp new file mode 100644 index 0000000000000..1a38caebae2c3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cardinal_cubic_b_spline.hpp @@ -0,0 +1,87 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This implements the compactly supported cubic b spline algorithm described in +// Kress, Rainer. "Numerical analysis, volume 181 of Graduate Texts in Mathematics." (1998). +// Splines of compact support are faster to evaluate and are better conditioned than classical cubic splines. + +// Let f be the function we are trying to interpolate, and s be the interpolating spline. +// The routine constructs the interpolant in O(N) time, and evaluating s at a point takes constant time. +// The order of accuracy depends on the regularity of the f, however, assuming f is +// four-times continuously differentiable, the error is of O(h^4). +// In addition, we can differentiate the spline and obtain a good interpolant for f'. +// The main restriction of this method is that the samples of f must be evenly spaced. +// Look for barycentric rational interpolation for non-evenly sampled data. +// Properties: +// - s(x_j) = f(x_j) +// - All cubic polynomials interpolated exactly + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_HPP + +#include + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_cubic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cardinal_cubic_b_spline(const BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + cardinal_cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + cardinal_cubic_b_spline() = default; + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::shared_ptr> m_imp; +}; + +template +cardinal_cubic_b_spline::cardinal_cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, f + length, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +template +cardinal_cubic_b_spline::cardinal_cubic_b_spline(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, end_p, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +Real cardinal_cubic_b_spline::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real cardinal_cubic_b_spline::prime(Real x) const +{ + return m_imp->prime(x); +} + +template +Real cardinal_cubic_b_spline::double_prime(Real x) const +{ + return m_imp->double_prime(x); +} + + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cardinal_quadratic_b_spline.hpp b/third-party/boost-math/include/boost/math/interpolators/cardinal_quadratic_b_spline.hpp new file mode 100644 index 0000000000000..a5b150f2f1686 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cardinal_quadratic_b_spline.hpp @@ -0,0 +1,57 @@ +// Copyright Nick Thompson, 2019 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_HPP +#include +#include + + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_quadratic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n - 1] = y(b), step_size = (b - a)/(n -1). + cardinal_quadratic_b_spline(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + : impl_(std::make_shared>(y, n, t0, h, left_endpoint_derivative, right_endpoint_derivative)) + {} + + // Oh the bizarre error messages if we template this on a RandomAccessContainer: + cardinal_quadratic_b_spline(std::vector const & y, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + : impl_(std::make_shared>(y.data(), y.size(), t0, h, left_endpoint_derivative, right_endpoint_derivative)) + {} + + + Real operator()(Real t) const { + return impl_->operator()(t); + } + + Real prime(Real t) const { + return impl_->prime(t); + } + + Real t_max() const { + return impl_->t_max(); + } + +private: + std::shared_ptr> impl_; +}; + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cardinal_quintic_b_spline.hpp b/third-party/boost-math/include/boost/math/interpolators/cardinal_quintic_b_spline.hpp new file mode 100644 index 0000000000000..3d72865d933a0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cardinal_quintic_b_spline.hpp @@ -0,0 +1,62 @@ +// Copyright Nick Thompson, 2019 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_HPP +#include +#include +#include + + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_quintic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n - 1] = y(b), step_size = (b - a)/(n -1). + cardinal_quintic_b_spline(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, + std::pair right_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}) + : impl_(std::make_shared>(y, n, t0, h, left_endpoint_derivatives, right_endpoint_derivatives)) + {} + + // Oh the bizarre error messages if we template this on a RandomAccessContainer: + cardinal_quintic_b_spline(std::vector const & y, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, + std::pair right_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}) + : impl_(std::make_shared>(y.data(), y.size(), t0, h, left_endpoint_derivatives, right_endpoint_derivatives)) + {} + + + Real operator()(Real t) const { + return impl_->operator()(t); + } + + Real prime(Real t) const { + return impl_->prime(t); + } + + Real double_prime(Real t) const { + return impl_->double_prime(t); + } + + Real t_max() const { + return impl_->t_max(); + } + +private: + std::shared_ptr> impl_; +}; + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cardinal_trigonometric.hpp b/third-party/boost-math/include/boost/math/interpolators/cardinal_trigonometric.hpp new file mode 100644 index 0000000000000..28a58c8b28616 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cardinal_trigonometric.hpp @@ -0,0 +1,58 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_TRIGONOMETRIC_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_TRIGONOMETRIC_HPP +#include +#include + +namespace boost { namespace math { namespace interpolators { + +template +class cardinal_trigonometric +{ +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_trigonometric(RandomAccessContainer const & v, Real t0, Real h) + { + m_impl = std::make_shared>(v.data(), v.size(), t0, h); + } + + Real operator()(Real t) const + { + return m_impl->operator()(t); + } + + Real prime(Real t) const + { + return m_impl->prime(t); + } + + Real double_prime(Real t) const + { + return m_impl->double_prime(t); + } + + Real period() const + { + return m_impl->period(); + } + + Real integrate() const + { + return m_impl->integrate(); + } + + Real squared_l2() const + { + return m_impl->squared_l2(); + } + +private: + std::shared_ptr> m_impl; +}; + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/catmull_rom.hpp b/third-party/boost-math/include/boost/math/interpolators/catmull_rom.hpp new file mode 100644 index 0000000000000..cf8e3cb3b884e --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/catmull_rom.hpp @@ -0,0 +1,310 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This computes the Catmull-Rom spline from a list of points. + +#ifndef BOOST_MATH_INTERPOLATORS_CATMULL_ROM +#define BOOST_MATH_INTERPOLATORS_CATMULL_ROM + +#include +#include +#include +#include +#include +#include + +namespace std_workaround { + +#if defined(__cpp_lib_nonmember_container_access) || (defined(_MSC_VER) && (_MSC_VER >= 1900)) + using std::size; +#else + template + inline constexpr std::size_t size(const C& c) + { + return c.size(); + } + template + inline constexpr std::size_t size(const T(&array)[N]) noexcept + { + return N; + } +#endif +} + +namespace boost{ namespace math{ + + namespace detail + { + template + typename Point::value_type alpha_distance(Point const & p1, Point const & p2, typename Point::value_type alpha) + { + using std::pow; + using std_workaround::size; + typename Point::value_type dsq = 0; + for (size_t i = 0; i < size(p1); ++i) + { + typename Point::value_type dx = p1[i] - p2[i]; + dsq += dx*dx; + } + return pow(dsq, alpha/2); + } + } + +template > +class catmull_rom +{ + typedef typename Point::value_type value_type; +public: + + catmull_rom(RandomAccessContainer&& points, bool closed = false, value_type alpha = (value_type) 1/ (value_type) 2); + + catmull_rom(std::initializer_list l, bool closed = false, value_type alpha = (value_type) 1/ (value_type) 2) : catmull_rom(RandomAccessContainer(l), closed, alpha) {} + + value_type max_parameter() const + { + return m_max_s; + } + + value_type parameter_at_point(size_t i) const + { + return m_s[i+1]; + } + + Point operator()(const value_type s) const; + + Point prime(const value_type s) const; + + RandomAccessContainer&& get_points() + { + return std::move(m_pnts); + } + +private: + RandomAccessContainer m_pnts; + std::vector m_s; + value_type m_max_s; +}; + +template +catmull_rom::catmull_rom(RandomAccessContainer&& points, bool closed, typename Point::value_type alpha) : m_pnts(std::move(points)) +{ + std::size_t num_pnts = m_pnts.size(); + //std::cout << "Number of points = " << num_pnts << "\n"; + if (num_pnts < 4) + { + throw std::domain_error("The Catmull-Rom curve requires at least 4 points."); + } + if (alpha < 0 || alpha > 1) + { + throw std::domain_error("The parametrization alpha must be in the range [0,1]."); + } + + using std::abs; + m_s.resize(num_pnts+3); + m_pnts.resize(num_pnts+3); + //std::cout << "Number of points now = " << m_pnts.size() << "\n"; + + m_pnts[num_pnts+1] = m_pnts[0]; + m_pnts[num_pnts+2] = m_pnts[1]; + + auto tmp = m_pnts[num_pnts-1]; + for (auto i = num_pnts; i > 0; --i) + { + m_pnts[i] = m_pnts[i - 1]; + } + m_pnts[0] = tmp; + + m_s[0] = -detail::alpha_distance(m_pnts[0], m_pnts[1], alpha); + if (abs(m_s[0]) < std::numeric_limits::epsilon()) + { + throw std::domain_error("The first and last point should not be the same.\n"); + } + m_s[1] = 0; + for (size_t i = 2; i < m_s.size(); ++i) + { + typename Point::value_type d = detail::alpha_distance(m_pnts[i], m_pnts[i-1], alpha); + if (abs(d) < std::numeric_limits::epsilon()) + { + throw std::domain_error("The control points of the Catmull-Rom curve are too close together; this will lead to ill-conditioning.\n"); + } + m_s[i] = m_s[i-1] + d; + } + if(closed) + { + m_max_s = m_s[num_pnts+1]; + } + else + { + m_max_s = m_s[num_pnts]; + } +} + + +template +Point catmull_rom::operator()(const typename Point::value_type s) const +{ + using std_workaround::size; + if (s < 0 || s > m_max_s) + { + throw std::domain_error("Parameter outside bounds."); + } + auto it = std::upper_bound(m_s.begin(), m_s.end(), s); + //Now *it >= s. We want the index such that m_s[i] <= s < m_s[i+1]: + size_t i = std::distance(m_s.begin(), it - 1); + + // Only denom21 is used twice: + typename Point::value_type denom21 = 1/(m_s[i+1] - m_s[i]); + typename Point::value_type s0s = m_s[i-1] - s; + typename Point::value_type s1s = m_s[i] - s; + typename Point::value_type s2s = m_s[i+1] - s; + size_t ip2 = i + 2; + // When the curve is closed and we evaluate at the end, the endpoint is in fact the startpoint. + if (ip2 == m_s.size()) { + ip2 = 0; + } + typename Point::value_type s3s = m_s[ip2] - s; + + Point A1_or_A3; + typename Point::value_type denom = 1/(m_s[i] - m_s[i-1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1_or_A3[j] = denom*(s1s*m_pnts[i-1][j] - s0s*m_pnts[i][j]); + } + + Point A2_or_B2; + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2_or_B2[j] = denom21*(s2s*m_pnts[i][j] - s1s*m_pnts[i+1][j]); + } + + Point B1_or_C; + denom = 1/(m_s[i+1] - m_s[i-1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1_or_C[j] = denom*(s2s*A1_or_A3[j] - s0s*A2_or_B2[j]); + } + + denom = 1/(m_s[ip2] - m_s[i+1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1_or_A3[j] = denom*(s3s*m_pnts[i+1][j] - s2s*m_pnts[ip2][j]); + } + + Point B2; + denom = 1/(m_s[ip2] - m_s[i]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2[j] = denom*(s3s*A2_or_B2[j] - s1s*A1_or_A3[j]); + } + + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1_or_C[j] = denom21*(s2s*B1_or_C[j] - s1s*B2[j]); + } + + return B1_or_C; +} + +template +Point catmull_rom::prime(const typename Point::value_type s) const +{ + using std_workaround::size; + // https://math.stackexchange.com/questions/843595/how-can-i-calculate-the-derivative-of-a-catmull-rom-spline-with-nonuniform-param + // http://denkovacs.com/2016/02/catmull-rom-spline-derivatives/ + if (s < 0 || s > m_max_s) + { + throw std::domain_error("Parameter outside bounds.\n"); + } + auto it = std::upper_bound(m_s.begin(), m_s.end(), s); + //Now *it >= s. We want the index such that m_s[i] <= s < m_s[i+1]: + size_t i = std::distance(m_s.begin(), it - 1); + Point A1; + typename Point::value_type denom = 1/(m_s[i] - m_s[i-1]); + typename Point::value_type k1 = (m_s[i]-s)*denom; + typename Point::value_type k2 = (s - m_s[i-1])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1[j] = k1*m_pnts[i-1][j] + k2*m_pnts[i][j]; + } + + Point A1p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1p[j] = denom*(m_pnts[i][j] - m_pnts[i-1][j]); + } + + Point A2; + denom = 1/(m_s[i+1] - m_s[i]); + k1 = (m_s[i+1]-s)*denom; + k2 = (s - m_s[i])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2[j] = k1*m_pnts[i][j] + k2*m_pnts[i+1][j]; + } + + Point A2p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2p[j] = denom*(m_pnts[i+1][j] - m_pnts[i][j]); + } + + + Point B1; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1[j] = k1*A1[j] + k2*A2[j]; + } + + Point A3; + denom = 1/(m_s[i+2] - m_s[i+1]); + k1 = (m_s[i+2]-s)*denom; + k2 = (s - m_s[i+1])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A3[j] = k1*m_pnts[i+1][j] + k2*m_pnts[i+2][j]; + } + + Point A3p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A3p[j] = denom*(m_pnts[i+2][j] - m_pnts[i+1][j]); + } + + Point B2; + denom = 1/(m_s[i+2] - m_s[i]); + k1 = (m_s[i+2]-s)*denom; + k2 = (s - m_s[i])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2[j] = k1*A2[j] + k2*A3[j]; + } + + Point B1p; + denom = 1/(m_s[i+1] - m_s[i-1]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1p[j] = denom*(A2[j] - A1[j] + (m_s[i+1]- s)*A1p[j] + (s-m_s[i-1])*A2p[j]); + } + + Point B2p; + denom = 1/(m_s[i+2] - m_s[i]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2p[j] = denom*(A3[j] - A2[j] + (m_s[i+2] - s)*A2p[j] + (s - m_s[i])*A3p[j]); + } + + Point Cp; + denom = 1/(m_s[i+1] - m_s[i]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + Cp[j] = denom*(B2[j] - B1[j] + (m_s[i+1] - s)*B1p[j] + (s - m_s[i])*B2p[j]); + } + return Cp; +} + + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cubic_b_spline.hpp b/third-party/boost-math/include/boost/math/interpolators/cubic_b_spline.hpp new file mode 100644 index 0000000000000..a634f5168f40b --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cubic_b_spline.hpp @@ -0,0 +1,90 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This implements the compactly supported cubic b spline algorithm described in +// Kress, Rainer. "Numerical analysis, volume 181 of Graduate Texts in Mathematics." (1998). +// Splines of compact support are faster to evaluate and are better conditioned than classical cubic splines. + +// Let f be the function we are trying to interpolate, and s be the interpolating spline. +// The routine constructs the interpolant in O(N) time, and evaluating s at a point takes constant time. +// The order of accuracy depends on the regularity of the f, however, assuming f is +// four-times continuously differentiable, the error is of O(h^4). +// In addition, we can differentiate the spline and obtain a good interpolant for f'. +// The main restriction of this method is that the samples of f must be evenly spaced. +// Look for barycentric rational interpolation for non-evenly sampled data. +// Properties: +// - s(x_j) = f(x_j) +// - All cubic polynomials interpolated exactly + +#ifndef BOOST_MATH_INTERPOLATORS_CUBIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CUBIC_B_SPLINE_HPP + +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost{ namespace math{ + +template +class cubic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cubic_b_spline(const BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + cubic_b_spline() = default; + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::shared_ptr> m_imp; +}; + +template +cubic_b_spline::cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, f + length, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +template +cubic_b_spline::cubic_b_spline(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, end_p, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +Real cubic_b_spline::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real cubic_b_spline::prime(Real x) const +{ + return m_imp->prime(x); +} + +template +Real cubic_b_spline::double_prime(Real x) const +{ + return m_imp->double_prime(x); +} + + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/cubic_hermite.hpp b/third-party/boost-math/include/boost/math/interpolators/cubic_hermite.hpp new file mode 100644 index 0000000000000..48346ab1ec138 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/cubic_hermite.hpp @@ -0,0 +1,141 @@ +// Copyright Nick Thompson, 2020 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CUBIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_CUBIC_HERMITE_HPP +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class cubic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + + cubic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx) + : impl_(std::make_shared>(std::move(x), std::move(y), std::move(dydx))) + {} + + inline Real operator()(Real x) const { + return impl_->operator()(x); + } + + inline Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cubic_hermite & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y, Real dydx) + { + impl_->push_back(x, y, dydx); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_cubic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + + cardinal_cubic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, Real x0, Real dx) + : impl_(std::make_shared>(std::move(y), std::move(dydx), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cardinal_cubic_hermite & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class cardinal_cubic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + cardinal_cubic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cardinal_cubic_hermite_aos & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/barycentric_rational_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/barycentric_rational_detail.hpp new file mode 100644 index 0000000000000..a363e1861bdbf --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/barycentric_rational_detail.hpp @@ -0,0 +1,214 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + */ + +#ifndef BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_DETAIL_HPP + +#include +#include // for std::move +#include // for std::is_sorted +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators { namespace detail{ + +template +class barycentric_rational_imp +{ +public: + template + barycentric_rational_imp(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order = 3); + + barycentric_rational_imp(std::vector&& x, std::vector&& y, size_t approximation_order = 3); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + // The barycentric weights are not really that interesting; except to the unit tests! + Real weight(size_t i) const { return m_w[i]; } + + std::vector&& return_x() + { + return std::move(m_x); + } + + std::vector&& return_y() + { + return std::move(m_y); + } + +private: + + void calculate_weights(size_t approximation_order); + + std::vector m_x; + std::vector m_y; + std::vector m_w; +}; + +template +template +barycentric_rational_imp::barycentric_rational_imp(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order) +{ + std::ptrdiff_t n = std::distance(start_x, end_x); + + if (approximation_order >= (std::size_t)n) + { + throw std::domain_error("Approximation order must be < data length."); + } + + // Big sad memcpy. + m_x.resize(n); + m_y.resize(n); + for(unsigned i = 0; start_x != end_x; ++start_x, ++start_y, ++i) + { + // But if we're going to do a memcpy, we can do some error checking which is inexpensive relative to the copy: + if(boost::math::isnan(*start_x)) + { + std::string msg = std::string("x[") + std::to_string(i) + "] is a NAN"; + throw std::domain_error(msg); + } + + if(boost::math::isnan(*start_y)) + { + std::string msg = std::string("y[") + std::to_string(i) + "] is a NAN"; + throw std::domain_error(msg); + } + + m_x[i] = *start_x; + m_y[i] = *start_y; + } + calculate_weights(approximation_order); +} + +template +barycentric_rational_imp::barycentric_rational_imp(std::vector&& x, std::vector&& y,size_t approximation_order) : m_x(std::move(x)), m_y(std::move(y)) +{ + BOOST_MATH_ASSERT_MSG(m_x.size() == m_y.size(), "There must be the same number of abscissas and ordinates."); + BOOST_MATH_ASSERT_MSG(approximation_order < m_x.size(), "Approximation order must be < data length."); + BOOST_MATH_ASSERT_MSG(std::is_sorted(m_x.begin(), m_x.end()), "The abscissas must be listed in increasing order x[0] < x[1] < ... < x[n-1]."); + calculate_weights(approximation_order); +} + +template +void barycentric_rational_imp::calculate_weights(size_t approximation_order) +{ + using std::abs; + int64_t n = m_x.size(); + m_w.resize(n, 0); + for(int64_t k = 0; k < n; ++k) + { + int64_t i_min = (std::max)(k - static_cast(approximation_order), static_cast(0)); + int64_t i_max = k; + if (k >= n - (std::ptrdiff_t)approximation_order) + { + i_max = n - approximation_order - 1; + } + + for(int64_t i = i_min; i <= i_max; ++i) + { + Real inv_product = 1; + int64_t j_max = (std::min)(static_cast(i + approximation_order), static_cast(n - 1)); + for(int64_t j = i; j <= j_max; ++j) + { + if (j == k) + { + continue; + } + + Real diff = m_x[k] - m_x[j]; + using std::numeric_limits; + if (abs(diff) < (numeric_limits::min)()) + { + std::string msg = std::string("Spacing between x[") + + std::to_string(k) + std::string("] and x[") + + std::to_string(i) + std::string("] is ") + + std::string("smaller than the epsilon of ") + + std::string(typeid(Real).name()); + throw std::logic_error(msg); + } + inv_product *= diff; + } + if (i % 2 == 0) + { + m_w[k] += 1/inv_product; + } + else + { + m_w[k] -= 1/inv_product; + } + } + } +} + + +template +Real barycentric_rational_imp::operator()(Real x) const +{ + Real numerator = 0; + Real denominator = 0; + for(size_t i = 0; i < m_x.size(); ++i) + { + // Presumably we should see if the accuracy is improved by using ULP distance of say, 5 here, instead of testing for floating point equality. + // However, it has been shown that if x approx x_i, but x != x_i, then inaccuracy in the numerator cancels the inaccuracy in the denominator, + // and the result is fairly accurate. See: http://epubs.siam.org/doi/pdf/10.1137/S0036144502417715 + if (x == m_x[i]) + { + return m_y[i]; + } + Real t = m_w[i]/(x - m_x[i]); + numerator += t*m_y[i]; + denominator += t; + } + return numerator/denominator; +} + +/* + * A formula for computing the derivative of the barycentric representation is given in + * "Some New Aspects of Rational Interpolation", by Claus Schneider and Wilhelm Werner, + * Mathematics of Computation, v47, number 175, 1986. + * http://www.ams.org/journals/mcom/1986-47-175/S0025-5718-1986-0842136-8/S0025-5718-1986-0842136-8.pdf + * and reviewed in + * Recent developments in barycentric rational interpolation + * Jean-Paul Berrut, Richard Baltensperger and Hans D. Mittelmann + * + * Is it possible to complete this in one pass through the data? + */ + +template +Real barycentric_rational_imp::prime(Real x) const +{ + Real rx = this->operator()(x); + Real numerator = 0; + Real denominator = 0; + for(size_t i = 0; i < m_x.size(); ++i) + { + if (x == m_x[i]) + { + Real sum = 0; + for (size_t j = 0; j < m_x.size(); ++j) + { + if (j == i) + { + continue; + } + sum += m_w[j]*(m_y[i] - m_y[j])/(m_x[i] - m_x[j]); + } + return -sum/m_w[i]; + } + Real t = m_w[i]/(x - m_x[i]); + Real diff = (rx - m_y[i])/(x-m_x[i]); + numerator += t*diff; + denominator += t; + } + + return numerator/denominator; +} +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/bezier_polynomial_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/bezier_polynomial_detail.hpp new file mode 100644 index 0000000000000..60fe5ab5d8496 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/bezier_polynomial_detail.hpp @@ -0,0 +1,167 @@ +// Copyright Nick Thompson, 2021 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost::math::interpolators::detail { + + +template +static inline RandomAccessContainer& get_bezier_storage() +{ + static thread_local RandomAccessContainer the_storage; + return the_storage; +} + + +template +class bezier_polynomial_imp +{ +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Z = typename RandomAccessContainer::size_type; + + bezier_polynomial_imp(RandomAccessContainer && control_points) + { + using std::to_string; + if (control_points.size() < 2) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " At least two points are required to form a Bezier curve. Only " + to_string(control_points.size()) + " points have been provided."; + throw std::logic_error(err); + } + Z dimension = control_points[0].size(); + for (Z i = 0; i < control_points.size(); ++i) { + if (control_points[i].size() != dimension) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " All points passed to the Bezier polynomial must have the same dimension."; + throw std::logic_error(err); + } + } + control_points_ = std::move(control_points); + auto & storage = get_bezier_storage(); + if (storage.size() < control_points_.size() -1) { + storage.resize(control_points_.size() -1); + } + } + + inline Point operator()(Real t) const + { + if (t < 0 || t > 1) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the Bezier curve interpolator at t = " << t << " is not allowed; t in [0,1] is required.\n"; + Point p; + for (Z i = 0; i < p.size(); ++i) { + p[i] = std::numeric_limits::quiet_NaN(); + } + return p; + } + + auto & scratch_space = get_bezier_storage(); + for (Z i = 0; i < control_points_.size() - 1; ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[i][j] = (1-t)*control_points_[i][j] + t*control_points_[i+1][j]; + } + } + + decasteljau_recursion(scratch_space, control_points_.size() - 1, t); + return scratch_space[0]; + } + + Point prime(Real t) { + auto & scratch_space = get_bezier_storage(); + for (Z i = 0; i < control_points_.size() - 1; ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[i][j] = control_points_[i+1][j] - control_points_[i][j]; + } + } + decasteljau_recursion(scratch_space, control_points_.size() - 1, t); + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[0][j] *= (control_points_.size()-1); + } + return scratch_space[0]; + } + + + void edit_control_point(Point const & p, Z index) + { + if (index >= control_points_.size()) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Attempting to edit a control point outside the bounds of the container; requested edit of index " << index << ", but there are only " << control_points_.size() << " control points.\n"; + return; + } + control_points_[index] = p; + } + + RandomAccessContainer const & control_points() const { + return control_points_; + } + + // See "Bezier and B-spline techniques", section 2.7: + // I cannot figure out why this doesn't work. + /*RandomAccessContainer indefinite_integral() const { + using std::fma; + // control_points_.size() == n + 1 + RandomAccessContainer c(control_points_.size() + 1); + // This is the constant of integration, chosen arbitrarily to be zero: + for (Z j = 0; j < control_points_[0].size(); ++j) { + c[0][j] = Real(0); + } + + // Make the reciprocal approximation to unroll the iteration into a pile of fma's: + Real rnp1 = Real(1)/control_points_.size(); + for (Z i = 1; i < c.size(); ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + //c[i][j] = c[i-1][j] + control_points_[i-1][j]*rnp1; + c[i][j] = fma(rnp1, control_points_[i-1][j], c[i-1][j]); + } + } + return c; + }*/ + + friend std::ostream& operator<<(std::ostream& out, bezier_polynomial_imp const & bp) { + out << "{"; + for (Z i = 0; i < bp.control_points_.size() - 1; ++i) { + out << "("; + for (Z j = 0; j < bp.control_points_[0].size() - 1; ++j) { + out << bp.control_points_[i][j] << ", "; + } + out << bp.control_points_[i][bp.control_points_[0].size() - 1] << "), "; + } + out << "("; + for (Z j = 0; j < bp.control_points_[0].size() - 1; ++j) { + out << bp.control_points_.back()[j] << ", "; + } + out << bp.control_points_.back()[bp.control_points_[0].size() - 1] << ")}"; + return out; + } + +private: + + void decasteljau_recursion(RandomAccessContainer & points, Z n, Real t) const { + if (n <= 1) { + return; + } + for (Z i = 0; i < n - 1; ++i) { + for (Z j = 0; j < points[0].size(); ++j) { + points[i][j] = (1-t)*points[i][j] + t*points[i+1][j]; + } + } + decasteljau_recursion(points, n - 1, t); + } + + RandomAccessContainer control_points_; +}; + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/bilinear_uniform_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/bilinear_uniform_detail.hpp new file mode 100644 index 0000000000000..590e961f7f893 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/bilinear_uniform_detail.hpp @@ -0,0 +1,137 @@ +// Copyright Nick Thompson, 2021 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost::math::interpolators::detail { + +template +class bilinear_uniform_imp +{ +public: + using Real = typename RandomAccessContainer::value_type; + using Z = typename RandomAccessContainer::size_type; + + bilinear_uniform_imp(RandomAccessContainer && fieldData, Z rows, Z cols, Real dx = 1, Real dy = 1, Real x0 = 0, Real y0 = 0) + { + using std::to_string; + if(fieldData.size() != rows*cols) + { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " The field data must have rows*cols elements. There are " + to_string(rows) + " rows and " + to_string(cols) + " columns but " + to_string(fieldData.size()) + " elements in the field data."; + throw std::logic_error(err); + } + if (rows < 2) { + throw std::logic_error("There must be at least two rows of data for bilinear interpolation to be well-defined."); + } + if (cols < 2) { + throw std::logic_error("There must be at least two columns of data for bilinear interpolation to be well-defined."); + } + + fieldData_ = std::move(fieldData); + rows_ = rows; + cols_ = cols; + x0_ = x0; + y0_ = y0; + dx_ = dx; + dy_ = dy; + + if (dx_ <= 0) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + " dx = " + to_string(dx) + ", but dx > 0 is required. Are the arguments out of order?"; + throw std::logic_error(err); + } + if (dy_ <= 0) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + " dy = " + to_string(dy) + ", but dy > 0 is required. Are the arguments out of order?"; + throw std::logic_error(err); + } + } + + Real operator()(Real x, Real y) const + { + using std::floor; + if (x > x0_ + (cols_ - 1)*dx_ || x < x0_) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the bilinear_uniform interpolator at (x,y) = (" << x << ", " << y << ") is not allowed.\n"; + std::cerr << "x must lie in the interval [" << x0_ << ", " << x0_ + (cols_ -1)*dx_ << "]\n"; + return std::numeric_limits::quiet_NaN(); + } + if (y > y0_ + (rows_ - 1)*dy_ || y < y0_) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the bilinear_uniform interpolator at (x,y) = (" << x << ", " << y << ") is not allowed.\n"; + std::cerr << "y must lie in the interval [" << y0_ << ", " << y0_ + (rows_ -1)*dy_ << "]\n"; + return std::numeric_limits::quiet_NaN(); + } + + Real s = (x - x0_)/dx_; + Real s0 = floor(s); + Real t = (y - y0_)/dy_; + Real t0 = floor(t); + auto xidx = static_cast(s0); + auto yidx = static_cast(t0); + Z idx = yidx*cols_ + xidx; + Real alpha = s - s0; + Real beta = t - t0; + + Real fhi; + // If alpha = 0, then we can segfault by reading fieldData_[idx+1]: + if (alpha <= 2*s0*std::numeric_limits::epsilon()) { + fhi = fieldData_[idx]; + } else { + fhi = (1 - alpha)*fieldData_[idx] + alpha*fieldData_[idx + 1]; + } + + // Again, we can get OOB access without this check. + // This corresponds to interpolation over a line segment aligned with the axes. + if (beta <= 2*t0*std::numeric_limits::epsilon()) { + return fhi; + } + + auto bottom_left = fieldData_[idx + cols_]; + Real flo; + if (alpha <= 2*s0*std::numeric_limits::epsilon()) { + flo = bottom_left; + } + else { + flo = (1 - alpha)*bottom_left + alpha*fieldData_[idx + cols_ + 1]; + } + // Convex combination over vertical to get the value: + return (1 - beta)*fhi + beta*flo; + } + + friend std::ostream& operator<<(std::ostream& out, bilinear_uniform_imp const & bu) { + out << "(x0, y0) = (" << bu.x0_ << ", " << bu.y0_ << "), (dx, dy) = (" << bu.dx_ << ", " << bu.dy_ << "), "; + out << "(xf, yf) = (" << bu.x0_ + (bu.cols_ - 1)*bu.dx_ << ", " << bu.y0_ + (bu.rows_ - 1)*bu.dy_ << ")\n"; + for (Z j = 0; j < bu.rows_; ++j) { + out << "{"; + for (Z i = 0; i < bu.cols_ - 1; ++i) { + out << bu.fieldData_[j*bu.cols_ + i] << ", "; + } + out << bu.fieldData_[j*bu.cols_ + bu.cols_ - 1] << "}\n"; + } + return out; + } + +private: + RandomAccessContainer fieldData_; + Z rows_; + Z cols_; + Real x0_; + Real y0_; + Real dx_; + Real dy_; +}; + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp new file mode 100644 index 0000000000000..2064caa515d3e --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp @@ -0,0 +1,331 @@ +// Copyright Nick Thompson, 2017 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + + +template +class cardinal_cubic_b_spline_imp +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cardinal_cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::vector m_beta; + Real m_h_inv; + Real m_a; + Real m_avg; +}; + + + +template +Real b3_spline(Real x) +{ + using std::abs; + Real absx = abs(x); + if (absx < 1) + { + Real y = 2 - absx; + Real z = 1 - absx; + return boost::math::constants::sixth()*(y*y*y - 4*z*z*z); + } + if (absx < 2) + { + Real y = 2 - absx; + return boost::math::constants::sixth()*y*y*y; + } + return static_cast(0); +} + +template +Real b3_spline_prime(Real x) +{ + if (x < 0) + { + return -b3_spline_prime(-x); + } + + if (x < 1) + { + return x*(3*boost::math::constants::half()*x - 2); + } + if (x < 2) + { + return -boost::math::constants::half()*(2 - x)*(2 - x); + } + return static_cast(0); +} + +template +Real b3_spline_double_prime(Real x) +{ + if (x < 0) + { + return b3_spline_double_prime(-x); + } + + if (x < 1) + { + return 3*x - 2; + } + if (x < 2) + { + return (2 - x); + } + return static_cast(0); +} + + +template +template +cardinal_cubic_b_spline_imp::cardinal_cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_a(left_endpoint), m_avg(0) +{ + using boost::math::constants::third; + + std::size_t length = end_p - f; + + if (length < 5) + { + if (boost::math::isnan(left_endpoint_derivative) || boost::math::isnan(right_endpoint_derivative)) + { + throw std::logic_error("Interpolation using a cubic b spline with derivatives estimated at the endpoints requires at least 5 points.\n"); + } + if (length < 3) + { + throw std::logic_error("Interpolation using a cubic b spline requires at least 3 points.\n"); + } + } + + if (boost::math::isnan(left_endpoint)) + { + throw std::logic_error("Left endpoint is NAN; this is disallowed.\n"); + } + if (left_endpoint + length*step_size >= (std::numeric_limits::max)()) + { + throw std::logic_error("Right endpoint overflows the maximum representable number of the specified precision.\n"); + } + if (step_size <= 0) + { + throw std::logic_error("The step size must be strictly > 0.\n"); + } + // Storing the inverse of the stepsize does provide a measurable speedup. + // It's not huge, but nonetheless worthwhile. + m_h_inv = 1/step_size; + + // Following Kress's notation, s'(a) = a1, s'(b) = b1 + Real a1 = left_endpoint_derivative; + // See the finite-difference table on Wikipedia for reference on how + // to construct high-order estimates for one-sided derivatives: + // https://en.wikipedia.org/wiki/Finite_difference_coefficient#Forward_and_backward_finite_difference + // Here, we estimate then to O(h^4), as that is the maximum accuracy we could obtain from this method. + if (boost::math::isnan(a1)) + { + // For simple functions (linear, quadratic, so on) + // almost all the error comes from derivative estimation. + // This does pairwise summation which gives us another digit of accuracy over naive summation. + Real t0 = 4*(f[1] + third()*f[3]); + Real t1 = -(25*third()*f[0] + f[4])/4 - 3*f[2]; + a1 = m_h_inv*(t0 + t1); + } + + Real b1 = right_endpoint_derivative; + if (boost::math::isnan(b1)) + { + size_t n = length - 1; + Real t0 = -4*(f[n - 1] + third()*f[n - 3]); + Real t1 = (25*third()*f[n] + f[n - 4])/4 + 3*f[n - 2]; + + b1 = m_h_inv*(t0 + t1); + } + + // s(x) = \sum \alpha_i B_{3}( (x- x_i - a)/h ) + // Of course we must reindex from Kress's notation, since he uses negative indices which make C++ unhappy. + m_beta.resize(length + 2, std::numeric_limits::quiet_NaN()); + + // Since the splines have compact support, they decay to zero very fast outside the endpoints. + // This is often very annoying; we'd like to evaluate the interpolant a little bit outside the + // boundary [a,b] without massive error. + // A simple way to deal with this is just to subtract the DC component off the signal, so we need the average. + // This algorithm for computing the average is recommended in + // http://www.heikohoffmann.de/htmlthesis/node134.html + Real t = 1; + for (size_t i = 0; i < length; ++i) + { + if (boost::math::isnan(f[i])) + { + std::string err = "This function you are trying to interpolate is a nan at index " + std::to_string(i) + "\n"; + throw std::logic_error(err); + } + m_avg += (f[i] - m_avg) / t; + t += 1; + } + + + // Now we must solve an almost-tridiagonal system, which requires O(N) operations. + // There are, in fact 5 diagonals, but they only differ from zero on the first and last row, + // so we can patch up the tridiagonal row reduction algorithm to deal with two special rows. + // See Kress, equations 8.41 + // The "tridiagonal" matrix is: + // 1 0 -1 + // 1 4 1 + // 1 4 1 + // 1 4 1 + // .... + // 1 4 1 + // 1 0 -1 + // Numerical estimate indicate that as N->Infinity, cond(A) -> 6.9, so this matrix is good. + std::vector rhs(length + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(length + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -2*step_size*a1; + rhs[rhs.size() - 1] = -2*step_size*b1; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) + { + rhs[i] = 6*(f[i - 1] - m_avg); + super_diagonal[i] = 1; + } + + + // One step of row reduction on the first row to patch up the 5-diagonal problem: + // 1 0 -1 | r0 + // 1 4 1 | r1 + // mapsto: + // 1 0 -1 | r0 + // 0 4 2 | r1 - r0 + // mapsto + // 1 0 -1 | r0 + // 0 1 1/2| (r1 - r0)/4 + super_diagonal[1] = static_cast(0.5); + rhs[1] = (rhs[1] - rhs[0])/4; + + // Now do a tridiagonal row reduction the standard way, until just before the last row: + for (size_t i = 2; i < rhs.size() - 1; ++i) + { + Real diagonal = 4 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // Now the last row, which is in the form + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 1 0 -1 | rhs[n-1] + Real final_subdiag = -super_diagonal[rhs.size() - 3]; + rhs[rhs.size() - 1] = (rhs[rhs.size() - 1] - rhs[rhs.size() - 3])/final_subdiag; + Real final_diag = -1/final_subdiag; + // Now we're here: + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 0 1 final_diag | (rhs[n-1] - rhs[n-3])/diag + + final_diag = final_diag - super_diagonal[rhs.size() - 2]; + rhs[rhs.size() - 1] = rhs[rhs.size() - 1] - rhs[rhs.size() - 2]; + + + // Back substitutions: + m_beta[rhs.size() - 1] = rhs[rhs.size() - 1]/final_diag; + for(size_t i = rhs.size() - 2; i > 0; --i) + { + m_beta[i] = rhs[i] - super_diagonal[i]*m_beta[i + 1]; + } + m_beta[0] = m_beta[2] + rhs[0]; +} + +template +Real cardinal_cubic_b_spline_imp::operator()(Real x) const +{ + // See Kress, 8.40: Since B3 has compact support, we don't have to sum over all terms, + // just the (at most 5) whose support overlaps the argument. + Real z = m_avg; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((max)((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2))), 0l)); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline(t - k); + } + + return z; +} + +template +Real cardinal_cubic_b_spline_imp::prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_prime(t - k); + } + return z*m_h_inv; +} + +template +Real cardinal_cubic_b_spline_imp::double_prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_double_prime(t - k); + } + return z*m_h_inv*m_h_inv; +} + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp new file mode 100644 index 0000000000000..cb5ce9f571db8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp @@ -0,0 +1,208 @@ +// Copyright Nick Thompson, 2019 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_DETAIL_HPP +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + +template +Real b2_spline(Real x) { + using std::abs; + Real absx = abs(x); + if (absx < 1/Real(2)) + { + Real y = absx - 1/Real(2); + Real z = absx + 1/Real(2); + return (2-y*y-z*z)/2; + } + if (absx < Real(3)/Real(2)) + { + Real y = absx - Real(3)/Real(2); + return y*y/2; + } + return static_cast(0); +} + +template +Real b2_spline_prime(Real x) { + if (x < 0) { + return -b2_spline_prime(-x); + } + + if (x < 1/Real(2)) + { + return -2*x; + } + if (x < Real(3)/Real(2)) + { + return x - Real(3)/Real(2); + } + return static_cast(0); +} + + +template +class cardinal_quadratic_b_spline_detail +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n -1] = y(b), step_size = (b - a)/(n -1). + + cardinal_quadratic_b_spline_detail(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + if (h <= 0) { + throw std::logic_error("Spacing must be > 0."); + } + m_inv_h = 1/h; + m_t0 = t0; + + if (n < 3) { + throw std::logic_error("The interpolator requires at least 3 points."); + } + + using std::isnan; + Real a; + if (isnan(left_endpoint_derivative)) { + // http://web.media.mit.edu/~crtaylor/calculator.html + a = -3*y[0] + 4*y[1] - y[2]; + } + else { + a = 2*h*left_endpoint_derivative; + } + + Real b; + if (isnan(right_endpoint_derivative)) { + b = 3*y[n-1] - 4*y[n-2] + y[n-3]; + } + else { + b = 2*h*right_endpoint_derivative; + } + + m_alpha.resize(n + 2); + + // Begin row reduction: + std::vector rhs(n + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(n + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -a; + rhs[rhs.size() - 1] = b; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) { + rhs[i] = 8*y[i - 1]; + super_diagonal[i] = 1; + } + + // Patch up 5-diagonal problem: + rhs[1] = (rhs[1] - rhs[0])/6; + super_diagonal[1] = Real(1)/Real(3); + // First two rows are now: + // 1 0 -1 | -2hy0' + // 0 1 1/3| (8y0+2hy0')/6 + + + // Start traditional tridiagonal row reduction: + for (size_t i = 2; i < rhs.size() - 1; ++i) { + Real diagonal = 6 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // 1 sd[n-1] 0 | rhs[n-1] + // 0 1 sd[n] | rhs[n] + // -1 0 1 | rhs[n+1] + + rhs[n+1] = rhs[n+1] + rhs[n-1]; + Real bottom_subdiagonal = super_diagonal[n-1]; + + // We're here: + // 1 sd[n-1] 0 | rhs[n-1] + // 0 1 sd[n] | rhs[n] + // 0 bs 1 | rhs[n+1] + + rhs[n+1] = (rhs[n+1]-bottom_subdiagonal*rhs[n])/(1-bottom_subdiagonal*super_diagonal[n]); + + m_alpha[n+1] = rhs[n+1]; + for (size_t i = n; i > 0; --i) { + m_alpha[i] = rhs[i] - m_alpha[i+1]*super_diagonal[i]; + } + m_alpha[0] = m_alpha[2] + rhs[0]; + } + + Real operator()(Real t) const { + if (t < m_t0 || t > m_t0 + (m_alpha.size()-2)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quadratic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + // Let k, gamma be defined via t = t0 + kh + gamma * h. + // Now find all j: |k-j+1+gamma|< 3/2, or, in other words + // j_min = ceil((t-t0)/h - 1/2) + // j_max = floor(t-t0)/h + 5/2) + using std::floor; + using std::ceil; + Real x = (t-m_t0)*m_inv_h; + auto j_min = static_cast(ceil(x - Real(1)/Real(2))); + auto j_max = static_cast(ceil(x + Real(5)/Real(2))); + if (j_max >= m_alpha.size()) { + j_max = m_alpha.size() - 1; + } + + Real y = 0; + x += 1; + for (size_t j = j_min; j <= j_max; ++j) { + y += m_alpha[j]*detail::b2_spline(x - j); + } + return y; + } + + Real prime(Real t) const { + if (t < m_t0 || t > m_t0 + (m_alpha.size()-2)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quadratic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + // Let k, gamma be defined via t = t0 + kh + gamma * h. + // Now find all j: |k-j+1+gamma|< 3/2, or, in other words + // j_min = ceil((t-t0)/h - 1/2) + // j_max = floor(t-t0)/h + 5/2) + using std::floor; + using std::ceil; + Real x = (t-m_t0)*m_inv_h; + auto j_min = static_cast(ceil(x - Real(1)/Real(2))); + auto j_max = static_cast(ceil(x + Real(5)/Real(2))); + if (j_max >= m_alpha.size()) { + j_max = m_alpha.size() - 1; + } + + Real y = 0; + x += 1; + for (size_t j = j_min; j <= j_max; ++j) { + y += m_alpha[j]*detail::b2_spline_prime(x - j); + } + return y*m_inv_h; + } + + Real t_max() const { + return m_t0 + (m_alpha.size()-3)/m_inv_h; + } + +private: + std::vector m_alpha; + Real m_inv_h; + Real m_t0; +}; + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp new file mode 100644 index 0000000000000..f189e79dd80a8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp @@ -0,0 +1,240 @@ +// Copyright Nick Thompson, 2019 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_DETAIL_HPP +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + + +template +class cardinal_quintic_b_spline_detail +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n -1] = y(b), step_size = (b - a)/(n -1). + + cardinal_quintic_b_spline_detail(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives, + std::pair right_endpoint_derivatives) + { + static_assert(!std::is_integral::value, "The quintic B-spline interpolator only works with floating point types."); + if (h <= 0) { + throw std::logic_error("Spacing must be > 0."); + } + m_inv_h = 1/h; + m_t0 = t0; + + if (n < 8) { + throw std::logic_error("The quintic B-spline interpolator requires at least 8 points."); + } + + using std::isnan; + // This interpolator has error of order h^6, so the derivatives should be estimated with the same error. + // See: https://en.wikipedia.org/wiki/Finite_difference_coefficient + if (isnan(left_endpoint_derivatives.first)) { + Real tmp = -49*y[0]/20 + 6*y[1] - 15*y[2]/2 + 20*y[3]/3 - 15*y[4]/4 + 6*y[5]/5 - y[6]/6; + left_endpoint_derivatives.first = tmp/h; + } + if (isnan(right_endpoint_derivatives.first)) { + Real tmp = 49*y[n-1]/20 - 6*y[n-2] + 15*y[n-3]/2 - 20*y[n-4]/3 + 15*y[n-5]/4 - 6*y[n-6]/5 + y[n-7]/6; + right_endpoint_derivatives.first = tmp/h; + } + if(isnan(left_endpoint_derivatives.second)) { + Real tmp = 469*y[0]/90 - 223*y[1]/10 + 879*y[2]/20 - 949*y[3]/18 + 41*y[4] - 201*y[5]/10 + 1019*y[6]/180 - 7*y[7]/10; + left_endpoint_derivatives.second = tmp/(h*h); + } + if (isnan(right_endpoint_derivatives.second)) { + Real tmp = 469*y[n-1]/90 - 223*y[n-2]/10 + 879*y[n-3]/20 - 949*y[n-4]/18 + 41*y[n-5] - 201*y[n-6]/10 + 1019*y[n-7]/180 - 7*y[n-8]/10; + right_endpoint_derivatives.second = tmp/(h*h); + } + + // This is really challenging my mental limits on by-hand row reduction. + // I debated bringing in a dependency on a sparse linear solver, but given that that would cause much agony for users I decided against it. + + std::vector rhs(n+4); + rhs[0] = 20*y[0] - 12*h*left_endpoint_derivatives.first + 2*h*h*left_endpoint_derivatives.second; + rhs[1] = 60*y[0] - 12*h*left_endpoint_derivatives.first; + for (size_t i = 2; i < n + 2; ++i) { + rhs[i] = 120*y[i-2]; + } + rhs[n+2] = 60*y[n-1] + 12*h*right_endpoint_derivatives.first; + rhs[n+3] = 20*y[n-1] + 12*h*right_endpoint_derivatives.first + 2*h*h*right_endpoint_derivatives.second; + + std::vector diagonal(n+4, 66); + diagonal[0] = 1; + diagonal[1] = 18; + diagonal[n+2] = 18; + diagonal[n+3] = 1; + + std::vector first_superdiagonal(n+4, 26); + first_superdiagonal[0] = 10; + first_superdiagonal[1] = 33; + first_superdiagonal[n+2] = 1; + // There is one less superdiagonal than diagonal; make sure that if we read it, it shows up as a bug: + first_superdiagonal[n+3] = std::numeric_limits::quiet_NaN(); + + std::vector second_superdiagonal(n+4, 1); + second_superdiagonal[0] = 9; + second_superdiagonal[1] = 8; + second_superdiagonal[n+2] = std::numeric_limits::quiet_NaN(); + second_superdiagonal[n+3] = std::numeric_limits::quiet_NaN(); + + std::vector first_subdiagonal(n+4, 26); + first_subdiagonal[0] = std::numeric_limits::quiet_NaN(); + first_subdiagonal[1] = 1; + first_subdiagonal[n+2] = 33; + first_subdiagonal[n+3] = 10; + + std::vector second_subdiagonal(n+4, 1); + second_subdiagonal[0] = std::numeric_limits::quiet_NaN(); + second_subdiagonal[1] = std::numeric_limits::quiet_NaN(); + second_subdiagonal[n+2] = 8; + second_subdiagonal[n+3] = 9; + + + for (size_t i = 0; i < n+2; ++i) { + Real di = diagonal[i]; + diagonal[i] = 1; + first_superdiagonal[i] /= di; + second_superdiagonal[i] /= di; + rhs[i] /= di; + + // Eliminate first subdiagonal: + Real nfsub = -first_subdiagonal[i+1]; + // Superfluous: + first_subdiagonal[i+1] /= nfsub; + // Not superfluous: + diagonal[i+1] /= nfsub; + first_superdiagonal[i+1] /= nfsub; + second_superdiagonal[i+1] /= nfsub; + rhs[i+1] /= nfsub; + + diagonal[i+1] += first_superdiagonal[i]; + first_superdiagonal[i+1] += second_superdiagonal[i]; + rhs[i+1] += rhs[i]; + // Superfluous, but clarifying: + first_subdiagonal[i+1] = 0; + + // Eliminate second subdiagonal: + Real nssub = -second_subdiagonal[i+2]; + first_subdiagonal[i+2] /= nssub; + diagonal[i+2] /= nssub; + first_superdiagonal[i+2] /= nssub; + second_superdiagonal[i+2] /= nssub; + rhs[i+2] /= nssub; + + first_subdiagonal[i+2] += first_superdiagonal[i]; + diagonal[i+2] += second_superdiagonal[i]; + rhs[i+2] += rhs[i]; + // Superfluous, but clarifying: + second_subdiagonal[i+2] = 0; + } + + // Eliminate last subdiagonal: + Real dnp2 = diagonal[n+2]; + diagonal[n+2] = 1; + first_superdiagonal[n+2] /= dnp2; + rhs[n+2] /= dnp2; + Real nfsubnp3 = -first_subdiagonal[n+3]; + diagonal[n+3] /= nfsubnp3; + rhs[n+3] /= nfsubnp3; + + diagonal[n+3] += first_superdiagonal[n+2]; + rhs[n+3] += rhs[n+2]; + + m_alpha.resize(n + 4, std::numeric_limits::quiet_NaN()); + + m_alpha[n+3] = rhs[n+3]/diagonal[n+3]; + m_alpha[n+2] = rhs[n+2] - first_superdiagonal[n+2]*m_alpha[n+3]; + for (int64_t i = int64_t(n+1); i >= 0; --i) { + m_alpha[i] = rhs[i] - first_superdiagonal[i]*m_alpha[i+1] - second_superdiagonal[i]*m_alpha[i+2]; + } + + } + + Real operator()(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline; + // tf = t0 + (n-1)*h + // alpha.size() = n+4 + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5. + // TODO: Zero pad m_alpha so that only the domain check is necessary. + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + // TODO: Use Cox 1972 to generate all integer translates of B5 simultaneously. + s += m_alpha[j]*cardinal_b_spline<5, Real>(x - j + 2); + } + return s; + } + + Real prime(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline_prime; + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5 + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + s += m_alpha[j]*cardinal_b_spline_prime<5, Real>(x - j + 2); + } + return s*m_inv_h; + + } + + Real double_prime(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline_double_prime; + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5 + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + s += m_alpha[j]*cardinal_b_spline_double_prime<5, Real>(x - j + 2); + } + return s*m_inv_h*m_inv_h; + } + + + Real t_max() const { + return m_t0 + (m_alpha.size()-5)/m_inv_h; + } + +private: + std::vector m_alpha; + Real m_inv_h; + Real m_t0; +}; + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp new file mode 100644 index 0000000000000..62ef4bacec17b --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp @@ -0,0 +1,684 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_DETAIL_CARDINAL_TRIGONOMETRIC_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_CARDINAL_TRIGONOMETRIC_HPP +#include +#include +#include +#include + +#ifdef BOOST_HAS_FLOAT128 +#include +#endif + +#ifdef __has_include +# if __has_include() +# include +# else +# error "This feature is unavailable without fftw3 installed" +#endif +#endif + +namespace boost { namespace math { namespace interpolators { namespace detail { + +template +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const Real* data, size_t length, Real t0, Real h) + { + m_data = data; + m_length = length; + m_t0 = t0; + m_h = h; + throw std::domain_error("Not implemented."); + } +private: + size_t m_length; + Real m_t0; + Real m_h; + Real* m_data; +}; + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const float* data, size_t length, float t0, float h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + // The period sadly must be stored, since the complex vector has length that cannot be used to recover the period: + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwf_alloc_complex(m_complex_vector_size); + // The const_cast is legitimate: FFTW does not change the data as long as FFTW_ESTIMATE is provided. + fftwf_plan plan = fftwf_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + // FFTW says a null plan is impossible with the basic interface we are using, and I have no reason to doubt them. + // But it just feels weird not to check this: + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwf_execute(plan); + fftwf_destroy_plan(plan); + + float denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + // numerically, m_gamma[m_complex_vector_size -1][1] should be zero . . . + // I believe, but need to check, that FFTW guarantees that it is identically zero. + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + float operator()(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float s = m_gamma[0][0]; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + // boost::math::cos_pi with a redefinition of x? Not now . . . + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + float prime(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + float double_prime(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + float period() const + { + return m_T; + } + + float integrate() const + { + return m_T*m_gamma[0][0]; + } + + float squared_l2() const + { + float s = 0; + // Always add smallest to largest for accuracy. + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwf_free(m_gamma); + m_gamma = nullptr; + } + } + + +private: + float m_t0; + float m_h; + float m_T; + fftwf_complex* m_gamma; + size_t m_complex_vector_size; +}; + + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const double* data, size_t length, double t0, double h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftw_alloc_complex(m_complex_vector_size); + fftw_plan plan = fftw_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftw_execute(plan); + fftw_destroy_plan(plan); + + double denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + double operator()(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double s = m_gamma[0][0]; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + double prime(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + double double_prime(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + double period() const + { + return m_T; + } + + double integrate() const + { + return m_T*m_gamma[0][0]; + } + + double squared_l2() const + { + double s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftw_free(m_gamma); + m_gamma = nullptr; + } + } + +private: + double m_t0; + double m_h; + double m_T; + fftw_complex* m_gamma; + size_t m_complex_vector_size; +}; + + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const long double* data, size_t length, long double t0, long double h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwl_alloc_complex(m_complex_vector_size); + fftwl_plan plan = fftwl_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwl_execute(plan); + fftwl_destroy_plan(plan); + + long double denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + long double operator()(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double s = m_gamma[0][0]; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + long double prime(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + // u = b*z + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + long double double_prime(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + // u = b*z + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + long double period() const + { + return m_T; + } + + long double integrate() const + { + return m_T*m_gamma[0][0]; + } + + long double squared_l2() const + { + long double s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwl_free(m_gamma); + m_gamma = nullptr; + } + } + +private: + long double m_t0; + long double m_h; + long double m_T; + fftwl_complex* m_gamma; + size_t m_complex_vector_size; +}; + +#ifdef BOOST_HAS_FLOAT128 +template<> +class cardinal_trigonometric_detail<__float128> { +public: + cardinal_trigonometric_detail(const __float128* data, size_t length, __float128 t0, __float128 h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwq_alloc_complex(m_complex_vector_size); + fftwq_plan plan = fftwq_plan_dft_r2c_1d(length, reinterpret_cast<__float128*>(const_cast<__float128*>(data)), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwq_execute(plan); + fftwq_destroy_plan(plan); + + __float128 denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + __float128 operator()(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 s = m_gamma[0][0]; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + __float128 prime(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + // u = b*z + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi<__float128>()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + __float128 double_prime(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + // u = b*z + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi<__float128>()*two_pi<__float128>()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + __float128 period() const + { + return m_T; + } + + __float128 integrate() const + { + return m_T*m_gamma[0][0]; + } + + __float128 squared_l2() const + { + __float128 s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwq_free(m_gamma); + m_gamma = nullptr; + } + } + + +private: + __float128 m_t0; + __float128 m_h; + __float128 m_T; + fftwq_complex* m_gamma; + size_t m_complex_vector_size; +}; +#endif + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cubic_b_spline_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cubic_b_spline_detail.hpp new file mode 100644 index 0000000000000..ac2ce29dd8a5b --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cubic_b_spline_detail.hpp @@ -0,0 +1,330 @@ +// Copyright Nick Thompson, 2017 +// 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) + +#ifndef CUBIC_B_SPLINE_DETAIL_HPP +#define CUBIC_B_SPLINE_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + + +template +class cubic_b_spline_imp +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::vector m_beta; + Real m_h_inv; + Real m_a; + Real m_avg; +}; + + + +template +Real b3_spline(Real x) +{ + using std::abs; + Real absx = abs(x); + if (absx < 1) + { + Real y = 2 - absx; + Real z = 1 - absx; + return boost::math::constants::sixth()*(y*y*y - 4*z*z*z); + } + if (absx < 2) + { + Real y = 2 - absx; + return boost::math::constants::sixth()*y*y*y; + } + return static_cast(0); +} + +template +Real b3_spline_prime(Real x) +{ + if (x < 0) + { + return -b3_spline_prime(-x); + } + + if (x < 1) + { + return x*(3*boost::math::constants::half()*x - 2); + } + if (x < 2) + { + return -boost::math::constants::half()*(2 - x)*(2 - x); + } + return static_cast(0); +} + +template +Real b3_spline_double_prime(Real x) +{ + if (x < 0) + { + return b3_spline_double_prime(-x); + } + + if (x < 1) + { + return 3*x - 2; + } + if (x < 2) + { + return (2 - x); + } + return static_cast(0); +} + + +template +template +cubic_b_spline_imp::cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_a(left_endpoint), m_avg(0) +{ + using boost::math::constants::third; + + std::size_t length = end_p - f; + + if (length < 5) + { + if (boost::math::isnan(left_endpoint_derivative) || boost::math::isnan(right_endpoint_derivative)) + { + throw std::logic_error("Interpolation using a cubic b spline with derivatives estimated at the endpoints requires at least 5 points.\n"); + } + if (length < 3) + { + throw std::logic_error("Interpolation using a cubic b spline requires at least 3 points.\n"); + } + } + + if (boost::math::isnan(left_endpoint)) + { + throw std::logic_error("Left endpoint is NAN; this is disallowed.\n"); + } + if (left_endpoint + length*step_size >= (std::numeric_limits::max)()) + { + throw std::logic_error("Right endpoint overflows the maximum representable number of the specified precision.\n"); + } + if (step_size <= 0) + { + throw std::logic_error("The step size must be strictly > 0.\n"); + } + // Storing the inverse of the stepsize does provide a measurable speedup. + // It's not huge, but nonetheless worthwhile. + m_h_inv = 1/step_size; + + // Following Kress's notation, s'(a) = a1, s'(b) = b1 + Real a1 = left_endpoint_derivative; + // See the finite-difference table on Wikipedia for reference on how + // to construct high-order estimates for one-sided derivatives: + // https://en.wikipedia.org/wiki/Finite_difference_coefficient#Forward_and_backward_finite_difference + // Here, we estimate then to O(h^4), as that is the maximum accuracy we could obtain from this method. + if (boost::math::isnan(a1)) + { + // For simple functions (linear, quadratic, so on) + // almost all the error comes from derivative estimation. + // This does pairwise summation which gives us another digit of accuracy over naive summation. + Real t0 = 4*(f[1] + third()*f[3]); + Real t1 = -(25*third()*f[0] + f[4])/4 - 3*f[2]; + a1 = m_h_inv*(t0 + t1); + } + + Real b1 = right_endpoint_derivative; + if (boost::math::isnan(b1)) + { + size_t n = length - 1; + Real t0 = 4*(f[n-3] + third()*f[n - 1]); + Real t1 = -(25*third()*f[n - 4] + f[n])/4 - 3*f[n - 2]; + + b1 = m_h_inv*(t0 + t1); + } + + // s(x) = \sum \alpha_i B_{3}( (x- x_i - a)/h ) + // Of course we must reindex from Kress's notation, since he uses negative indices which make C++ unhappy. + m_beta.resize(length + 2, std::numeric_limits::quiet_NaN()); + + // Since the splines have compact support, they decay to zero very fast outside the endpoints. + // This is often very annoying; we'd like to evaluate the interpolant a little bit outside the + // boundary [a,b] without massive error. + // A simple way to deal with this is just to subtract the DC component off the signal, so we need the average. + // This algorithm for computing the average is recommended in + // http://www.heikohoffmann.de/htmlthesis/node134.html + Real t = 1; + for (size_t i = 0; i < length; ++i) + { + if (boost::math::isnan(f[i])) + { + std::string err = "This function you are trying to interpolate is a nan at index " + std::to_string(i) + "\n"; + throw std::logic_error(err); + } + m_avg += (f[i] - m_avg) / t; + t += 1; + } + + + // Now we must solve an almost-tridiagonal system, which requires O(N) operations. + // There are, in fact 5 diagonals, but they only differ from zero on the first and last row, + // so we can patch up the tridiagonal row reduction algorithm to deal with two special rows. + // See Kress, equations 8.41 + // The the "tridiagonal" matrix is: + // 1 0 -1 + // 1 4 1 + // 1 4 1 + // 1 4 1 + // .... + // 1 4 1 + // 1 0 -1 + // Numerical estimate indicate that as N->Infinity, cond(A) -> 6.9, so this matrix is good. + std::vector rhs(length + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(length + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -2*step_size*a1; + rhs[rhs.size() - 1] = -2*step_size*b1; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) + { + rhs[i] = 6*(f[i - 1] - m_avg); + super_diagonal[i] = 1; + } + + + // One step of row reduction on the first row to patch up the 5-diagonal problem: + // 1 0 -1 | r0 + // 1 4 1 | r1 + // mapsto: + // 1 0 -1 | r0 + // 0 4 2 | r1 - r0 + // mapsto + // 1 0 -1 | r0 + // 0 1 1/2| (r1 - r0)/4 + super_diagonal[1] = 0.5; + rhs[1] = (rhs[1] - rhs[0])/4; + + // Now do a tridiagonal row reduction the standard way, until just before the last row: + for (size_t i = 2; i < rhs.size() - 1; ++i) + { + Real diagonal = 4 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // Now the last row, which is in the form + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 1 0 -1 | rhs[n-1] + Real final_subdiag = -super_diagonal[rhs.size() - 3]; + rhs[rhs.size() - 1] = (rhs[rhs.size() - 1] - rhs[rhs.size() - 3])/final_subdiag; + Real final_diag = -1/final_subdiag; + // Now we're here: + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 0 1 final_diag | (rhs[n-1] - rhs[n-3])/diag + + final_diag = final_diag - super_diagonal[rhs.size() - 2]; + rhs[rhs.size() - 1] = rhs[rhs.size() - 1] - rhs[rhs.size() - 2]; + + + // Back substitutions: + m_beta[rhs.size() - 1] = rhs[rhs.size() - 1]/final_diag; + for(size_t i = rhs.size() - 2; i > 0; --i) + { + m_beta[i] = rhs[i] - super_diagonal[i]*m_beta[i + 1]; + } + m_beta[0] = m_beta[2] + rhs[0]; +} + +template +Real cubic_b_spline_imp::operator()(Real x) const +{ + // See Kress, 8.40: Since B3 has compact support, we don't have to sum over all terms, + // just the (at most 5) whose support overlaps the argument. + Real z = m_avg; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((max)((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2))), 0l)); + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline(t - k); + } + + return z; +} + +template +Real cubic_b_spline_imp::prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_prime(t - k); + } + return z*m_h_inv; +} + +template +Real cubic_b_spline_imp::double_prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_double_prime(t - k); + } + return z*m_h_inv*m_h_inv; +} + + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/cubic_hermite_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/cubic_hermite_detail.hpp new file mode 100644 index 0000000000000..921902e1f2fc6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/cubic_hermite_detail.hpp @@ -0,0 +1,438 @@ +// Copyright Nick Thompson, 2020 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_DETAIL_CUBIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_CUBIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class cubic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + using Size = typename RandomAccessContainer::size_type; + + cubic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer dydx) + : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)} + { + using std::abs; + using std::isnan; + if (x_.size() != y_.size()) + { + throw std::domain_error("There must be the same number of ordinates as abscissas."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("There must be the same number of ordinates as derivative values."); + } + if (x_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + Real x0 = x_[0]; + for (size_t i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Abscissas must be listed in strictly increasing order x0 < x1 < ... < x_{n-1}, "; + oss << "but at x[" << i - 1 << "] = " << x0 << ", and x[" << i << "] = " << x1 << ".\n"; + throw std::domain_error(oss.str()); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) + { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + } + + Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // We need t := (x-x_k)/(x_{k+1}-x_k) \in [0,1) for this to work. + // Sadly this neccessitates this loathesome check, otherwise we get t = 1 at x = xf. + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real s0 = dydx_[i]; + Real s1 = dydx_[i+1]; + Real dx = (x1-x0); + Real t = (x-x0)/dx; + + // See the section 'Representations' in the page + // https://en.wikipedia.org/wiki/Cubic_Hermite_spline + Real y = (1-t)*(1-t)*(y0*(1+2*t) + s0*(x-x0)) + + t*t*(y1*(3-2*t) + dx*s1*(t-1)); + return y; + } + + Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real s0 = dydx_[i]; + Real s1 = dydx_[i+1]; + Real dx = (x1-x0); + + Real d1 = (y1 - y0 - s0*dx)/(dx*dx); + Real d2 = (s1 - s0)/(2*dx); + Real c2 = 3*d1 - 2*d2; + Real c3 = 2*(d2 - d1)/dx; + return s0 + 2*c2*(x-x0) + 3*c3*(x-x0)*(x-x0); + } + + + friend std::ostream& operator<<(std::ostream & os, const cubic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) + { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ")}"; + return os; + } + + Size size() const + { + return x_.size(); + } + + int64_t bytes() const + { + return 3*x_.size()*sizeof(Real) + 3*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; +}; + +template +class cardinal_cubic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + using Size = typename RandomAccessContainer::size_type; + + cardinal_cubic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer dydx, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, x0_{x0}, inv_dx_{1/dx} + { + using std::abs; + using std::isnan; + if (y_.size() != dy_.size()) + { + throw std::domain_error("There must be the same number of derivatives as ordinates."); + } + if (y_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + } + + // Why not implement push_back? It's awkward: If the buffer is circular, x0_ += dx_. + // If the buffer is not circular, x0_ is unchanged. + // We need a concept for circular_buffer! + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + + Real r = 1-t; + return r*r*(y0*(1+2*t) + dy0*t) + + t*t*(y1*(3-2*t) - dy1*r); + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()*inv_dx_; + } + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + + Real dy = 6*t*(1-t)*(y1 - y0) + (3*t*t - 4*t+1)*dy0 + t*(3*t-2)*dy1; + return dy*inv_dx_; + } + + + Size size() const + { + return y_.size(); + } + + int64_t bytes() const + { + return 2*y_.size()*sizeof(Real) + 2*sizeof(y_) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + + RandomAccessContainer y_; + RandomAccessContainer dy_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_cubic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Size = typename RandomAccessContainer::size_type; + + cardinal_cubic_hermite_detail_aos(RandomAccessContainer && dat, Real x0, Real dx) + : dat_{std::move(dat)}, x0_{x0}, inv_dx_{1/dx} + { + if (dat_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + if (dat_[0].size() != 2) + { + throw std::domain_error("Each datum must contain (y, y'), and nothing else."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & d : dat_) + { + d[1] *= dx; + } + } + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (dat_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dat_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + + Real t = s - ii; + // If we had infinite precision, this would never happen. + // But we don't have infinite precision. + if (t == 0) + { + return dat_[i][0]; + } + Real y0 = dat_[i][0]; + Real y1 = dat_[i+1][0]; + Real dy0 = dat_[i][1]; + Real dy1 = dat_[i+1][1]; + + Real r = 1-t; + return r*r*(y0*(1+2*t) + dy0*t) + + t*t*(y1*(3-2*t) - dy1*r); + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (dat_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dat_.back()[1]*inv_dx_; + } + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return dat_[i][1]*inv_dx_; + } + Real y0 = dat_[i][0]; + Real dy0 = dat_[i][1]; + Real y1 = dat_[i+1][0]; + Real dy1 = dat_[i+1][1]; + + Real dy = 6*t*(1-t)*(y1 - y0) + (3*t*t - 4*t+1)*dy0 + t*(3*t-2)*dy1; + return dy*inv_dx_; + } + + + Size size() const + { + return dat_.size(); + } + + int64_t bytes() const + { + return dat_.size()*dat_[0].size()*sizeof(Real) + sizeof(dat_) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (dat_.size()-1)/inv_dx_; + return {x0_, xf}; + } + + +private: + RandomAccessContainer dat_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/quintic_hermite_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/quintic_hermite_detail.hpp new file mode 100644 index 0000000000000..50c1b85ea75c4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/quintic_hermite_detail.hpp @@ -0,0 +1,585 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ +#ifndef BOOST_MATH_INTERPOLATORS_DETAIL_QUINTIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_QUINTIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class quintic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + quintic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2) : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)}, d2ydx2_{std::move(d2ydx2)} + { + if (x_.size() != y_.size()) + { + throw std::domain_error("Number of abscissas must = number of ordinates."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (x_.size() != d2ydx2_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (x_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + Real x0 = x_[0]; + for (decltype(x_.size()) i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + throw std::domain_error("Abscissas must be sorted in strictly increasing order x0 < x1 < ... < x_{n-1}"); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) + { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + d2ydx2_.push_back(d2ydx2); + } + + inline Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // We need t := (x-x_k)/(x_{k+1}-x_k) \in [0,1) for this to work. + // Sadly this neccessitates this loathesome check, otherwise we get t = 1 at x = xf. + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + + Real dx = (x1-x0); + Real t = (x-x0)/dx; + Real t2 = t*t; + Real t3 = t2*t; + + // See the 'Basis functions' section of: + // https://www.rose-hulman.edu/~finn/CCLI/Notes/day09.pdf + // Also: https://github.com/MrHexxx/QuinticHermiteSpline/blob/master/HermiteSpline.cs + Real y = (1- t3*(10 + t*(-15 + 6*t)))*y0; + y += t*(1+ t2*(-6 + t*(8 -3*t)))*v0*dx; + y += t2*(1 + t*(-3 + t*(3-t)))*a0*dx*dx/2; + y += t3*((1 + t*(-2 + t))*a1*dx*dx/2 + (-4 + t*(7 - 3*t))*v1*dx + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = x1 - x0; + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real t= (x-x0)/dx; + Real t2 = t*t; + + Real dydx = 30*t2*(1 - 2*t + t*t)*(y1-y0)/dx; + dydx += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*v0 - t*t*(12 - 28*t + 15*t*t)*v1; + dydx += (t*dx/2)*((2 - 9*t + 12*t*t - 5*t*t*t)*a0 + t*(3 - 8*t + 5*t*t)*a1); + return dydx; + } + + inline Real double_prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return d2ydx2_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = x1 - x0; + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real t = (x-x0)/dx; + + Real d2ydx2 = 60*t*(1 + t*(-3 + 2*t))*(y1-y0)/(dx*dx); + d2ydx2 += 12*t*(-3 + t*(8 - 5*t))*v0/dx; + d2ydx2 -= 12*t*(2 + t*(-7 + 5*t))*v1/dx; + d2ydx2 += (1 + t*(-9 + t*(18 - 10*t)))*a0; + d2ydx2 += t*(3 + t*(-12 + 10*t))*a1; + + return d2ydx2; + } + + friend std::ostream& operator<<(std::ostream & os, const quintic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << ", " << m.d2ydx2_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ", " << m.d2ydx2_[n] << ")}"; + return os; + } + + int64_t bytes() const + { + return 4*x_.size()*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + +private: + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; + RandomAccessContainer d2ydx2_; +}; + + +template +class cardinal_quintic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_quintic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, d2y_{std::move(d2ydx2)}, x0_{x0}, inv_dx_{1/dx} + { + if (y_.size() != dy_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (y_.size() != d2y_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (y_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + + for (auto & d2y : d2y_) + { + d2y *= (dx*dx)/2; + } + } + + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return y_[i]; + } + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + // See the 'Basis functions' section of: + // https://www.rose-hulman.edu/~finn/CCLI/Notes/day09.pdf + // Also: https://github.com/MrHexxx/QuinticHermiteSpline/blob/master/HermiteSpline.cs + Real y = (1- t*t*t*(10 + t*(-15 + 6*t)))*y0; + y += t*(1+ t*t*(-6 + t*(8 -3*t)))*dy0; + y += t*t*(1 + t*(-3 + t*(3-t)))*d2y0; + y += t*t*t*((1 + t*(-2 + t))*d2y1 + (-4 + t*(7 -3*t))*dy1 + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return dy_[i]*inv_dx_; + } + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + Real dydx = 30*t*t*(1 - 2*t + t*t)*(y1-y0); + dydx += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*dy0 - t*t*(12 - 28*t + 15*t*t)*dy1; + dydx += t*((2 - 9*t + 12*t*t - 5*t*t*t)*d2y0 + t*(3 - 8*t + 5*t*t)*d2y1); + dydx *= inv_dx_; + return dydx; + } + + inline Real double_prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return d2y_.back()*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t==0) + { + return d2y_[i]*2*inv_dx_*inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + Real d2ydx2 = 60*t*(1 - 3*t + 2*t*t)*(y1 - y0)*inv_dx_*inv_dx_; + d2ydx2 += (12*t)*((-3 + 8*t - 5*t*t)*dy0 - (2 - 7*t + 5*t*t)*dy1); + d2ydx2 += (1 - 9*t + 18*t*t - 10*t*t*t)*d2y0*(2*inv_dx_*inv_dx_) + t*(3 - 12*t + 10*t*t)*d2y1*(2*inv_dx_*inv_dx_); + return d2ydx2; + } + + int64_t bytes() const + { + return 3*y_.size()*sizeof(Real) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + RandomAccessContainer y_; + RandomAccessContainer dy_; + RandomAccessContainer d2y_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_quintic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_quintic_hermite_detail_aos(RandomAccessContainer && data, Real x0, Real dx) + : data_{std::move(data)} , x0_{x0}, inv_dx_{1/dx} + { + if (data_.size() < 2) + { + throw std::domain_error("At least two points are required to interpolate using cardinal_quintic_hermite_aos"); + } + + if (data_[0].size() != 3) + { + throw std::domain_error("Each datum passed to the cardinal_quintic_hermite_aos must have three elements: {y, y', y''}"); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & datum : data_) + { + datum[1] *= dx; + datum[2] *= (dx*dx/2); + } + } + + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return data_[i][0]; + } + + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real d2y0 = data_[i][2]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real d2y1 = data_[i+1][2]; + + Real y = (1 - t*t*t*(10 + t*(-15 + 6*t)))*y0; + y += t*(1 + t*t*(-6 + t*(8 - 3*t)))*dy0; + y += t*t*(1 + t*(-3 + t*(3 - t)))*d2y0; + y += t*t*t*((1 + t*(-2 + t))*d2y1 + (-4 + t*(7 - 3*t))*dy1 + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[1]*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return data_[i][1]*inv_dx_; + } + + + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real v0 = data_[i][1]; + Real v1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + + Real dy = 30*t*t*(1 - 2*t + t*t)*(y1-y0); + dy += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*v0 - t*t*(12 - 28*t + 15*t*t)*v1; + dy += t*((2 - 9*t + 12*t*t - 5*t*t*t)*a0 + t*(3 - 8*t + 5*t*t)*a1); + return dy*inv_dx_; + } + + inline Real double_prime(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[2]*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) { + return data_[i][2]*2*inv_dx_*inv_dx_; + } + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real d2y0 = data_[i][2]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real d2y1 = data_[i+1][2]; + + Real d2ydx2 = 60*t*(1 - 3*t + 2*t*t)*(y1 - y0)*inv_dx_*inv_dx_; + d2ydx2 += (12*t)*((-3 + 8*t - 5*t*t)*dy0 - (2 - 7*t + 5*t*t)*dy1); + d2ydx2 += (1 - 9*t + 18*t*t - 10*t*t*t)*d2y0*(2*inv_dx_*inv_dx_) + t*(3 - 12*t + 10*t*t)*d2y1*(2*inv_dx_*inv_dx_); + return d2ydx2; + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + RandomAccessContainer data_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/septic_hermite_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/septic_hermite_detail.hpp new file mode 100644 index 0000000000000..47d155561b229 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/septic_hermite_detail.hpp @@ -0,0 +1,652 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ +#ifndef BOOST_MATH_INTERPOLATORS_DETAIL_SEPTIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_SEPTIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class septic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + septic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3) + : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)}, d2ydx2_{std::move(d2ydx2)}, d3ydx3_{std::move(d3ydx3)} + { + if (x_.size() != y_.size()) + { + throw std::domain_error("Number of abscissas must = number of ordinates."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (x_.size() != d2ydx2_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (x_.size() != d3ydx3_.size()) + { + throw std::domain_error("Number of third derivatives must equal number of abscissas."); + } + + if (x_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + Real x0 = x_[0]; + for (decltype(x_.size()) i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + throw std::domain_error("Abscissas must be sorted in strictly increasing order x0 < x1 < ... < x_{n-1}"); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2, Real d3ydx3) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + d2ydx2_.push_back(d2ydx2); + d3ydx3_.push_back(d3ydx3); + } + + Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // t \in [0, 1) + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = (x1-x0); + Real t = (x-x0)/dx; + + // See: + // http://seisweb.usask.ca/classes/GEOL481/2017/Labs/interpolation_utilities_matlab/shermite.m + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + Real dx2 = dx*dx/2; + Real dx3 = dx2*dx/3; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36 + 10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15 + 4*t)))); + Real z3 = t3*(1 + t*(-4 + t*(6 + t*(-4 + t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13 - 4*t))); + Real z7 = t4*(-1 + t*(3 + t*(-3+t))); + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + // Velocity: + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + // Acceleration: + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + // Jerk: + Real j0 = d3ydx3_[i]; + Real j1 = d3ydx3_[i+1]; + + return z0*y0 + z4*y1 + (z1*v0 + z5*v1)*dx + (z2*a0 + z6*a1)*dx2 + (z3*j0 + z7*j1)*dx3; + } + + Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real j0 = d3ydx3_[i]; + Real j1 = d3ydx3_[i+1]; + Real dx = x1 - x0; + Real t = (x-x0)/dx; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)/dx; + dydx += z1*v0 + z2*v1; + dydx += (x-x0)*(z3*a0 + z4*a1); + dydx += (x-x0)*(x-x0)*(z5*j0 + z6*j1)/6; + return dydx; + } + + inline Real double_prime(Real) const + { + return std::numeric_limits::quiet_NaN(); + } + + friend std::ostream& operator<<(std::ostream & os, const septic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << ", " << m.d2ydx2_[i] << ", " << m.d3ydx3_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ", " << m.d2ydx2_[n] << m.d3ydx3_[n] << ")}"; + return os; + } + + int64_t bytes() + { + return 5*x_.size()*sizeof(Real) + 5*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + +private: + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; + RandomAccessContainer d2ydx2_; + RandomAccessContainer d3ydx3_; +}; + +template +class cardinal_septic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_septic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, d2y_{std::move(d2ydx2)}, d3y_{std::move(d3ydx3)}, x0_{x0}, inv_dx_{1/dx} + { + if (y_.size() != dy_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of ordinates."); + } + if (y_.size() != d2y_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of ordinates."); + } + if (y_.size() != d3y_.size()) + { + throw std::domain_error("Number of third derivatives must equal number of ordinates."); + } + if (y_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + for (auto & d2y : d2y_) + { + d2y *= (dx*dx/2); + } + for (auto & d3y : d3y_) + { + d3y *= (dx*dx*dx/6); + } + + } + + inline Real operator()(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) { + return y_[i]; + } + // See: + // http://seisweb.usask.ca/classes/GEOL481/2017/Labs/interpolation_utilities_matlab/shermite.m + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36+10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15+4*t)))); + Real z3 = t3*(1 + t*(-4+t*(6+t*(-4+t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13-4*t))); + Real z7 = t4*(-1 + t*(3+t*(-3+t))); + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + + return z0*y0 + z1*dy0 + z2*a0 + z3*j0 + z4*y1 + z5*dy1 + z6*a1 + z7*j1; + } + + inline Real prime(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()/inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return dy_[i]/inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)*inv_dx_; + dydx += (z1*dy0 + z2*dy1)*inv_dx_; + dydx += 2*t*(z3*a0 + z4*a1)*inv_dx_; + dydx += t*t*(z5*j0 + z6*j1); + return dydx; + } + + inline Real double_prime(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return d2y_.back()*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return d2y_[i]*2*inv_dx_*inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + Real t2 = t*t; + + Real z0 = 420*t2*(1 + t*(-4 + t*(5 - 2*t))); + Real z1 = 60*t2*(-4 + t*(15 + t*(-18 + 7*t))); + Real z2 = 60*t2*(-3 + t*(13 + t*(-17 + 7*t))); + Real z3 = (1 + t2*(-60 + t*(200 + t*(-225 + 84*t)))); + Real z4 = t2*(30 + t*(-140 + t*(195 - 84*t))); + Real z5 = t*(1 + t*(-8 + t*(20 + t*(-20 + 7*t)))); + Real z6 = t2*(-2 + t*(10 + t*(-15 + 7*t))); + + Real d2ydx2 = z0*(y1-y0)*inv_dx_*inv_dx_; + d2ydx2 += (z1*dy0 + z2*dy1)*inv_dx_*inv_dx_; + d2ydx2 += (z3*a0 + z4*a1)*2*inv_dx_*inv_dx_; + d2ydx2 += 6*(z5*j0 + z6*j1)/(inv_dx_*inv_dx_); + + return d2ydx2; + } + + int64_t bytes() const + { + return 4*y_.size()*sizeof(Real) + 2*sizeof(Real) + 4*sizeof(y_); + } + + std::pair domain() const + { + return {x0_, x0_ + (y_.size()-1)/inv_dx_}; + } + +private: + RandomAccessContainer y_; + RandomAccessContainer dy_; + RandomAccessContainer d2y_; + RandomAccessContainer d3y_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_septic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_septic_hermite_detail_aos(RandomAccessContainer && dat, Real x0, Real dx) + : data_{std::move(dat)}, x0_{x0}, inv_dx_{1/dx} + { + if (data_.size() < 2) { + throw std::domain_error("At least 2 abscissas are required."); + } + if (data_[0].size() != 4) { + throw std::domain_error("There must be 4 data items per struct."); + } + + for (auto & datum : data_) + { + datum[1] *= dx; + datum[2] *= (dx*dx/2); + datum[3] *= (dx*dx*dx/6); + } + } + + inline Real operator()(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return data_[i][0]; + } + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36+10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15+4*t)))); + Real z3 = t3*(1 + t*(-4+t*(6+t*(-4+t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13-4*t))); + Real z7 = t4*(-1 + t*(3+t*(-3+t))); + + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real a0 = data_[i][2]; + Real j0 = data_[i][3]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real a1 = data_[i+1][2]; + Real j1 = data_[i+1][3]; + + return z0*y0 + z1*dy0 + z2*a0 + z3*j0 + z4*y1 + z5*dy1 + z6*a1 + z7*j1; + } + + inline Real prime(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[1]*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) + { + return data_[i][1]*inv_dx_; + } + + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dy0 = data_[i][1]; + Real dy1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + Real j0 = data_[i][3]; + Real j1 = data_[i+1][3]; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)*inv_dx_; + dydx += (z1*dy0 + z2*dy1)*inv_dx_; + dydx += 2*t*(z3*a0 + z4*a1)*inv_dx_; + dydx += t*t*(z5*j0 + z6*j1); + return dydx; + } + + inline Real double_prime(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[2]*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) + { + return data_[i][2]*2*inv_dx_*inv_dx_; + } + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dy0 = data_[i][1]; + Real dy1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + Real j0 = data_[i][3]; + Real j1 = data_[i+1][3]; + Real t2 = t*t; + + Real z0 = 420*t2*(1 + t*(-4 + t*(5 - 2*t))); + Real z1 = 60*t2*(-4 + t*(15 + t*(-18 + 7*t))); + Real z2 = 60*t2*(-3 + t*(13 + t*(-17 + 7*t))); + Real z3 = (1 + t2*(-60 + t*(200 + t*(-225 + 84*t)))); + Real z4 = t2*(30 + t*(-140 + t*(195 - 84*t))); + Real z5 = t*(1 + t*(-8 + t*(20 + t*(-20 + 7*t)))); + Real z6 = t2*(-2 + t*(10 + t*(-15 + 7*t))); + + Real d2ydx2 = z0*(y1-y0)*inv_dx_*inv_dx_; + d2ydx2 += (z1*dy0 + z2*dy1)*inv_dx_*inv_dx_; + d2ydx2 += (z3*a0 + z4*a1)*2*inv_dx_*inv_dx_; + d2ydx2 += 6*(z5*j0 + z6*j1)/(inv_dx_*inv_dx_); + + return d2ydx2; + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + 2*sizeof(Real) + sizeof(data_); + } + + std::pair domain() const + { + return {x0_, x0_ + (data_.size() -1)/inv_dx_}; + } + +private: + RandomAccessContainer data_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp new file mode 100644 index 0000000000000..f4650784bf931 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp @@ -0,0 +1,195 @@ +/* + * Copyright Nick Thompson, 2019 + * 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) + */ + +#ifndef BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_DETAIL_HPP + +#include +#include +#include // for std::move +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + +template +class vector_barycentric_rational_imp +{ +public: + using Real = typename TimeContainer::value_type; + using Point = typename SpaceContainer::value_type; + + vector_barycentric_rational_imp(TimeContainer&& t, SpaceContainer&& y, size_t approximation_order); + + void operator()(Point& p, Real t) const; + + void eval_with_prime(Point& x, Point& dxdt, Real t) const; + + // The barycentric weights are only interesting to the unit tests: + Real weight(size_t i) const { return w_[i]; } + +private: + + void calculate_weights(size_t approximation_order); + + TimeContainer t_; + SpaceContainer y_; + TimeContainer w_; +}; + +template +vector_barycentric_rational_imp::vector_barycentric_rational_imp(TimeContainer&& t, SpaceContainer&& y, size_t approximation_order) +{ + using std::numeric_limits; + t_ = std::move(t); + y_ = std::move(y); + + BOOST_MATH_ASSERT_MSG(t_.size() == y_.size(), "There must be the same number of time points as space points."); + BOOST_MATH_ASSERT_MSG(approximation_order < y_.size(), "Approximation order must be < data length."); + for (size_t i = 1; i < t_.size(); ++i) + { + BOOST_MATH_ASSERT_MSG(t_[i] - t_[i-1] > (numeric_limits::min)(), "The abscissas must be listed in strictly increasing order t[0] < t[1] < ... < t[n-1]."); + } + calculate_weights(approximation_order); +} + + +template +void vector_barycentric_rational_imp::calculate_weights(size_t approximation_order) +{ + using Real = typename TimeContainer::value_type; + using std::abs; + int64_t n = t_.size(); + w_.resize(n, Real(0)); + for(int64_t k = 0; k < n; ++k) + { + int64_t i_min = (std::max)(k - static_cast(approximation_order), static_cast(0)); + int64_t i_max = k; + if (k >= n - (std::ptrdiff_t)approximation_order) + { + i_max = n - approximation_order - 1; + } + + for(int64_t i = i_min; i <= i_max; ++i) + { + Real inv_product = 1; + int64_t j_max = (std::min)(static_cast(i + approximation_order), static_cast(n - 1)); + for(int64_t j = i; j <= j_max; ++j) + { + if (j == k) + { + continue; + } + Real diff = t_[k] - t_[j]; + inv_product *= diff; + } + if (i % 2 == 0) + { + w_[k] += 1/inv_product; + } + else + { + w_[k] -= 1/inv_product; + } + } + } +} + + +template +void vector_barycentric_rational_imp::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const +{ + using Real = typename TimeContainer::value_type; + for (auto & x : p) + { + x = Real(0); + } + Real denominator = 0; + for(size_t i = 0; i < t_.size(); ++i) + { + // See associated commentary in the scalar version of this function. + if (t == t_[i]) + { + p = y_[i]; + return; + } + Real x = w_[i]/(t - t_[i]); + for (decltype(p.size()) j = 0; j < p.size(); ++j) + { + p[j] += x*y_[i][j]; + } + denominator += x; + } + for (decltype(p.size()) j = 0; j < p.size(); ++j) + { + p[j] /= denominator; + } + return; +} + +template +void vector_barycentric_rational_imp::eval_with_prime(typename SpaceContainer::value_type& x, typename SpaceContainer::value_type& dxdt, typename TimeContainer::value_type t) const +{ + using Point = typename SpaceContainer::value_type; + using Real = typename TimeContainer::value_type; + this->operator()(x, t); + Point numerator; + for (decltype(x.size()) i = 0; i < x.size(); ++i) + { + numerator[i] = 0; + } + Real denominator = 0; + for(decltype(t_.size()) i = 0; i < t_.size(); ++i) + { + if (t == t_[i]) + { + Point sum; + for (decltype(x.size()) i = 0; i < x.size(); ++i) + { + sum[i] = 0; + } + + for (decltype(t_.size()) j = 0; j < t_.size(); ++j) + { + if (j == i) + { + continue; + } + for (decltype(sum.size()) k = 0; k < sum.size(); ++k) + { + sum[k] += w_[j]*(y_[i][k] - y_[j][k])/(t_[i] - t_[j]); + } + } + for (decltype(sum.size()) k = 0; k < sum.size(); ++k) + { + dxdt[k] = -sum[k]/w_[i]; + } + return; + } + Real tw = w_[i]/(t - t_[i]); + Point diff; + for (decltype(diff.size()) j = 0; j < diff.size(); ++j) + { + diff[j] = (x[j] - y_[i][j])/(t-t_[i]); + } + for (decltype(diff.size()) j = 0; j < diff.size(); ++j) + { + numerator[j] += tw*diff[j]; + } + denominator += tw; + } + + for (decltype(dxdt.size()) j = 0; j < dxdt.size(); ++j) + { + dxdt[j] = numerator[j]/denominator; + } + return; +} + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/detail/whittaker_shannon_detail.hpp b/third-party/boost-math/include/boost/math/interpolators/detail/whittaker_shannon_detail.hpp new file mode 100644 index 0000000000000..74ff47c4636be --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/detail/whittaker_shannon_detail.hpp @@ -0,0 +1,128 @@ +// Copyright Nick Thompson, 2019 +// 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) +#ifndef BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace interpolators { namespace detail { + +template +class whittaker_shannon_detail { +public: + + using Real = typename RandomAccessContainer::value_type; + whittaker_shannon_detail(RandomAccessContainer&& y, Real const & t0, Real const & h) : m_y{std::move(y)}, m_t0{t0}, m_h{h} + { + for (size_t i = 1; i < m_y.size(); i += 2) + { + m_y[i] = -m_y[i]; + } + } + + inline Real operator()(Real t) const { + using boost::math::constants::pi; + using std::isfinite; + using std::floor; + using std::ceil; + Real y = 0; + Real x = (t - m_t0)/m_h; + Real z = x; + auto it = m_y.begin(); + + // For some reason, neither clang nor g++ will cache the address of m_y.end() in a register. + // Hence make a copy of it: + auto end = m_y.end(); + while(it != end) + { + y += *it++/z; + z -= 1; + } + + if (!isfinite(y)) + { + BOOST_MATH_ASSERT_MSG(floor(x) == ceil(x), "Floor and ceiling should be equal.\n"); + auto i = static_cast(floor(x)); + if (i & 1) + { + return -m_y[i]; + } + return m_y[i]; + } + return y*boost::math::sin_pi(x)/pi(); + } + + Real prime(Real t) const { + using boost::math::constants::pi; + using std::isfinite; + using std::floor; + using std::ceil; + + Real x = (t - m_t0)/m_h; + if (ceil(x) == x) { + Real s = 0; + auto j = static_cast(x); + auto n = static_cast(m_y.size()); + for (long i = 0; i < n; ++i) + { + if (j - i != 0) + { + s += m_y[i]/(j-i); + } + // else derivative of sinc at zero is zero. + } + if (j & 1) { + s /= -m_h; + } else { + s /= m_h; + } + return s; + } + Real z = x; + auto it = m_y.begin(); + Real cospix = boost::math::cos_pi(x); + Real sinpix_div_pi = boost::math::sin_pi(x)/pi(); + + Real s = 0; + auto end = m_y.end(); + while(it != end) + { + s += (*it++)*(z*cospix - sinpix_div_pi)/(z*z); + z -= 1; + } + + return s/m_h; + } + + + + Real operator[](size_t i) const { + if (i & 1) + { + return -m_y[i]; + } + return m_y[i]; + } + + RandomAccessContainer&& return_data() { + for (size_t i = 1; i < m_y.size(); i += 2) + { + m_y[i] = -m_y[i]; + } + return std::move(m_y); + } + + +private: + RandomAccessContainer m_y; + Real m_t0; + Real m_h; +}; +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/makima.hpp b/third-party/boost-math/include/boost/math/interpolators/makima.hpp new file mode 100644 index 0000000000000..f69fe40733a11 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/makima.hpp @@ -0,0 +1,178 @@ +// Copyright Nick Thompson, 2020 +// 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) + +// See: https://blogs.mathworks.com/cleve/2019/04/29/makima-piecewise-cubic-interpolation/ +// And: https://doi.org/10.1145/321607.321609 + +#ifndef BOOST_MATH_INTERPOLATORS_MAKIMA_HPP +#define BOOST_MATH_INTERPOLATORS_MAKIMA_HPP +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class makima { +public: + using Real = typename RandomAccessContainer::value_type; + + makima(RandomAccessContainer && x, RandomAccessContainer && y, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + using std::isnan; + using std::abs; + if (x.size() < 4) + { + throw std::domain_error("Must be at least four data points."); + } + RandomAccessContainer s(x.size(), std::numeric_limits::quiet_NaN()); + Real m2 = (y[3]-y[2])/(x[3]-x[2]); + Real m1 = (y[2]-y[1])/(x[2]-x[1]); + Real m0 = (y[1]-y[0])/(x[1]-x[0]); + // Quadratic extrapolation: m_{-1} = 2m_0 - m_1: + Real mm1 = 2*m0 - m1; + // Quadratic extrapolation: m_{-2} = 2*m_{-1}-m_0: + Real mm2 = 2*mm1 - m0; + Real w1 = abs(m1-m0) + abs(m1+m0)/2; + Real w2 = abs(mm1-mm2) + abs(mm1+mm2)/2; + if (isnan(left_endpoint_derivative)) + { + s[0] = (w1*mm1 + w2*m0)/(w1+w2); + if (isnan(s[0])) + { + s[0] = 0; + } + } + else + { + s[0] = left_endpoint_derivative; + } + + w1 = abs(m2-m1) + abs(m2+m1)/2; + w2 = abs(m0-mm1) + abs(m0+mm1)/2; + s[1] = (w1*m0 + w2*m1)/(w1+w2); + if (isnan(s[1])) { + s[1] = 0; + } + + for (decltype(s.size()) i = 2; i < s.size()-2; ++i) { + Real mim2 = (y[i-1]-y[i-2])/(x[i-1]-x[i-2]); + Real mim1 = (y[i ]-y[i-1])/(x[i ]-x[i-1]); + Real mi = (y[i+1]-y[i ])/(x[i+1]-x[i ]); + Real mip1 = (y[i+2]-y[i+1])/(x[i+2]-x[i+1]); + w1 = abs(mip1-mi) + abs(mip1+mi)/2; + w2 = abs(mim1-mim2) + abs(mim1+mim2)/2; + s[i] = (w1*mim1 + w2*mi)/(w1+w2); + if (isnan(s[i])) { + s[i] = 0; + } + } + // Quadratic extrapolation at the other end: + + decltype(s.size()) n = s.size(); + Real mnm4 = (y[n-3]-y[n-4])/(x[n-3]-x[n-4]); + Real mnm3 = (y[n-2]-y[n-3])/(x[n-2]-x[n-3]); + Real mnm2 = (y[n-1]-y[n-2])/(x[n-1]-x[n-2]); + Real mnm1 = 2*mnm2 - mnm3; + Real mn = 2*mnm1 - mnm2; + w1 = abs(mnm1 - mnm2) + abs(mnm1+mnm2)/2; + w2 = abs(mnm3 - mnm4) + abs(mnm3+mnm4)/2; + + s[n-2] = (w1*mnm3 + w2*mnm2)/(w1 + w2); + if (isnan(s[n-2])) { + s[n-2] = 0; + } + + w1 = abs(mn - mnm1) + abs(mn+mnm1)/2; + w2 = abs(mnm2 - mnm3) + abs(mnm2+mnm3)/2; + + + if (isnan(right_endpoint_derivative)) + { + s[n-1] = (w1*mnm2 + w2*mnm1)/(w1+w2); + if (isnan(s[n-1])) { + s[n-1] = 0; + } + } + else + { + s[n-1] = right_endpoint_derivative; + } + + impl_ = std::make_shared>(std::move(x), std::move(y), std::move(s)); + } + + Real operator()(Real x) const { + return impl_->operator()(x); + } + + Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const makima & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y) { + using std::abs; + using std::isnan; + if (x <= impl_->x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + impl_->x_.push_back(x); + impl_->y_.push_back(y); + impl_->dydx_.push_back(std::numeric_limits::quiet_NaN()); + // dydx_[n-2] was computed by extrapolation. Now dydx_[n-2] -> dydx_[n-3], and it can be computed by the same formula. + decltype(impl_->size()) n = impl_->size(); + auto i = n - 3; + Real mim2 = (impl_->y_[i-1]-impl_->y_[i-2])/(impl_->x_[i-1]-impl_->x_[i-2]); + Real mim1 = (impl_->y_[i ]-impl_->y_[i-1])/(impl_->x_[i ]-impl_->x_[i-1]); + Real mi = (impl_->y_[i+1]-impl_->y_[i ])/(impl_->x_[i+1]-impl_->x_[i ]); + Real mip1 = (impl_->y_[i+2]-impl_->y_[i+1])/(impl_->x_[i+2]-impl_->x_[i+1]); + Real w1 = abs(mip1-mi) + abs(mip1+mi)/2; + Real w2 = abs(mim1-mim2) + abs(mim1+mim2)/2; + impl_->dydx_[i] = (w1*mim1 + w2*mi)/(w1+w2); + if (isnan(impl_->dydx_[i])) { + impl_->dydx_[i] = 0; + } + + Real mnm4 = (impl_->y_[n-3]-impl_->y_[n-4])/(impl_->x_[n-3]-impl_->x_[n-4]); + Real mnm3 = (impl_->y_[n-2]-impl_->y_[n-3])/(impl_->x_[n-2]-impl_->x_[n-3]); + Real mnm2 = (impl_->y_[n-1]-impl_->y_[n-2])/(impl_->x_[n-1]-impl_->x_[n-2]); + Real mnm1 = 2*mnm2 - mnm3; + Real mn = 2*mnm1 - mnm2; + w1 = abs(mnm1 - mnm2) + abs(mnm1+mnm2)/2; + w2 = abs(mnm3 - mnm4) + abs(mnm3+mnm4)/2; + + impl_->dydx_[n-2] = (w1*mnm3 + w2*mnm2)/(w1 + w2); + if (isnan(impl_->dydx_[n-2])) { + impl_->dydx_[n-2] = 0; + } + + w1 = abs(mn - mnm1) + abs(mn+mnm1)/2; + w2 = abs(mnm2 - mnm3) + abs(mnm2+mnm3)/2; + + impl_->dydx_[n-1] = (w1*mnm2 + w2*mnm1)/(w1+w2); + if (isnan(impl_->dydx_[n-1])) { + impl_->dydx_[n-1] = 0; + } + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/pchip.hpp b/third-party/boost-math/include/boost/math/interpolators/pchip.hpp new file mode 100644 index 0000000000000..6697166df0caa --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/pchip.hpp @@ -0,0 +1,131 @@ +// Copyright Nick Thompson, 2020 +// 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) + +#ifndef BOOST_MATH_INTERPOLATORS_PCHIP_HPP +#define BOOST_MATH_INTERPOLATORS_PCHIP_HPP +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class pchip { +public: + using Real = typename RandomAccessContainer::value_type; + + pchip(RandomAccessContainer && x, RandomAccessContainer && y, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + using std::isnan; + if (x.size() < 4) + { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << " This interpolator requires at least four data points."; + throw std::domain_error(oss.str()); + } + RandomAccessContainer s(x.size(), std::numeric_limits::quiet_NaN()); + if (isnan(left_endpoint_derivative)) + { + // If the derivative is not specified, this seems as good a choice as any. + // In particular, it satisfies the monotonicity constraint 0 <= |y'[0]| < 4Delta_i, + // where Delta_i is the secant slope: + s[0] = (y[1]-y[0])/(x[1]-x[0]); + } + else + { + s[0] = left_endpoint_derivative; + } + + for (decltype(s.size()) k = 1; k < s.size()-1; ++k) { + Real hkm1 = x[k] - x[k-1]; + Real dkm1 = (y[k] - y[k-1])/hkm1; + + Real hk = x[k+1] - x[k]; + Real dk = (y[k+1] - y[k])/hk; + Real w1 = 2*hk + hkm1; + Real w2 = hk + 2*hkm1; + if ( (dk > 0 && dkm1 < 0) || (dk < 0 && dkm1 > 0) || dk == 0 || dkm1 == 0) + { + s[k] = 0; + } + else + { + // See here: + // https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/interp.pdf + // Un-numbered equation just before Section 3.5: + s[k] = (w1+w2)/(w1/dkm1 + w2/dk); + } + + } + auto n = s.size(); + if (isnan(right_endpoint_derivative)) + { + s[n-1] = (y[n-1]-y[n-2])/(x[n-1] - x[n-2]); + } + else + { + s[n-1] = right_endpoint_derivative; + } + impl_ = std::make_shared>(std::move(x), std::move(y), std::move(s)); + } + + Real operator()(Real x) const { + return impl_->operator()(x); + } + + Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const pchip & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y) { + using std::abs; + using std::isnan; + if (x <= impl_->x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + impl_->x_.push_back(x); + impl_->y_.push_back(y); + impl_->dydx_.push_back(std::numeric_limits::quiet_NaN()); + auto n = impl_->size(); + impl_->dydx_[n-1] = (impl_->y_[n-1]-impl_->y_[n-2])/(impl_->x_[n-1] - impl_->x_[n-2]); + // Now fix s_[n-2]: + auto k = n-2; + Real hkm1 = impl_->x_[k] - impl_->x_[k-1]; + Real dkm1 = (impl_->y_[k] - impl_->y_[k-1])/hkm1; + + Real hk = impl_->x_[k+1] - impl_->x_[k]; + Real dk = (impl_->y_[k+1] - impl_->y_[k])/hk; + Real w1 = 2*hk + hkm1; + Real w2 = hk + 2*hkm1; + if ( (dk > 0 && dkm1 < 0) || (dk < 0 && dkm1 > 0) || dk == 0 || dkm1 == 0) + { + impl_->dydx_[k] = 0; + } + else + { + impl_->dydx_[k] = (w1+w2)/(w1/dkm1 + w2/dk); + } + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/quintic_hermite.hpp b/third-party/boost-math/include/boost/math/interpolators/quintic_hermite.hpp new file mode 100644 index 0000000000000..c0ba067de2411 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/quintic_hermite.hpp @@ -0,0 +1,142 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ + +#ifndef BOOST_MATH_INTERPOLATORS_QUINTIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_QUINTIC_HERMITE_HPP +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class quintic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + quintic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2) + : impl_(std::make_shared>(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2))) + {} + + Real operator()(Real x) const + { + return impl_->operator()(x); + } + + Real prime(Real x) const + { + return impl_->prime(x); + } + + Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const quintic_hermite & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2) + { + impl_->push_back(x, y, dydx, d2ydx2); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_quintic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_quintic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, Real x0, Real dx) + : impl_(std::make_shared>(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx)) + {} + + inline Real operator()(Real x) const { + return impl_->operator()(x); + } + + inline Real prime(Real x) const { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_quintic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_quintic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/septic_hermite.hpp b/third-party/boost-math/include/boost/math/interpolators/septic_hermite.hpp new file mode 100644 index 0000000000000..f428a7651ab1c --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/septic_hermite.hpp @@ -0,0 +1,146 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ +#ifndef BOOST_MATH_INTERPOLATORS_SEPTIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_SEPTIC_HERMITE_HPP +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class septic_hermite +{ +public: + using Real = typename RandomAccessContainer::value_type; + septic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, + RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3) + : impl_(std::make_shared>(std::move(x), + std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3))) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const septic_hermite & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_septic_hermite +{ +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_septic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, + RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3, Real x0, Real dx) + : impl_(std::make_shared>( + std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class cardinal_septic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_septic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_.size() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/vector_barycentric_rational.hpp b/third-party/boost-math/include/boost/math/interpolators/vector_barycentric_rational.hpp new file mode 100644 index 0000000000000..1b899fbd5f808 --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/vector_barycentric_rational.hpp @@ -0,0 +1,82 @@ +/* + * Copyright Nick Thompson, 2019 + * 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) + * + * Exactly the same as barycentric_rational.hpp, but delivers values in $\mathbb{R}^n$. + * In some sense this is trivial, since each component of the vector is computed in exactly the same + * as would be computed by barycentric_rational.hpp. But this is a bit more efficient and convenient. + */ + +#ifndef BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP +#define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP + +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ + +template +class vector_barycentric_rational +{ +public: + using Real = typename TimeContainer::value_type; + using Point = typename SpaceContainer::value_type; + vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order = 3); + + void operator()(Point& x, Real t) const; + + // I have validated using google benchmark that returning a value is no more expensive populating it, + // at least for Eigen vectors with known size at compile-time. + // This is kinda a weird thing to discover since it goes against the advice of basically every high-performance computing book. + Point operator()(Real t) const { + Point p; + this->operator()(p, t); + return p; + } + + void prime(Point& dxdt, Real t) const { + Point x; + m_imp->eval_with_prime(x, dxdt, t); + } + + Point prime(Real t) const { + Point p; + this->prime(p, t); + return p; + } + + void eval_with_prime(Point& x, Point& dxdt, Real t) const { + m_imp->eval_with_prime(x, dxdt, t); + return; + } + + std::pair eval_with_prime(Real t) const { + Point x; + Point dxdt; + m_imp->eval_with_prime(x, dxdt, t); + return {x, dxdt}; + } + +private: + std::shared_ptr> m_imp; +}; + + +template +vector_barycentric_rational::vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order): + m_imp(std::make_shared>(std::move(times), std::move(points), approximation_order)) +{ + return; +} + +template +void vector_barycentric_rational::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const +{ + m_imp->operator()(p, t); + return; +} + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/interpolators/whittaker_shannon.hpp b/third-party/boost-math/include/boost/math/interpolators/whittaker_shannon.hpp new file mode 100644 index 0000000000000..a5c5367a9d4ff --- /dev/null +++ b/third-party/boost-math/include/boost/math/interpolators/whittaker_shannon.hpp @@ -0,0 +1,47 @@ +// Copyright Nick Thompson, 2019 +// 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) +#ifndef BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_HPP +#define BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_HPP +#include +#include + +namespace boost { namespace math { namespace interpolators { + +template +class whittaker_shannon { +public: + + using Real = typename RandomAccessContainer::value_type; + whittaker_shannon(RandomAccessContainer&& y, Real const & t0, Real const & h) + : m_impl(std::make_shared>(std::move(y), t0, h)) + {} + + inline Real operator()(Real t) const + { + return m_impl->operator()(t); + } + + inline Real prime(Real t) const + { + return m_impl->prime(t); + } + + inline Real operator[](size_t i) const + { + return m_impl->operator[](i); + } + + RandomAccessContainer&& return_data() + { + return m_impl->return_data(); + } + + +private: + std::shared_ptr> m_impl; +}; +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/octonion.hpp b/third-party/boost-math/include/boost/math/octonion.hpp new file mode 100644 index 0000000000000..5d147df58403b --- /dev/null +++ b/third-party/boost-math/include/boost/math/octonion.hpp @@ -0,0 +1,4250 @@ +// boost octonion.hpp header file + +// (C) Copyright Hubert Holin 2001. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_OCTONION_HPP +#define BOOST_OCTONION_HPP + +#include +#include + + +namespace boost +{ + namespace math + { + +#define BOOST_OCTONION_ACCESSOR_GENERATOR(type) \ + type real() const \ + { \ + return(a); \ + } \ + \ + octonion unreal() const \ + { \ + return( octonion(static_cast(0),b,c,d,e,f,g,h)); \ + } \ + \ + type R_component_1() const \ + { \ + return(a); \ + } \ + \ + type R_component_2() const \ + { \ + return(b); \ + } \ + \ + type R_component_3() const \ + { \ + return(c); \ + } \ + \ + type R_component_4() const \ + { \ + return(d); \ + } \ + \ + type R_component_5() const \ + { \ + return(e); \ + } \ + \ + type R_component_6() const \ + { \ + return(f); \ + } \ + \ + type R_component_7() const \ + { \ + return(g); \ + } \ + \ + type R_component_8() const \ + { \ + return(h); \ + } \ + \ + ::std::complex C_component_1() const \ + { \ + return(::std::complex(a,b)); \ + } \ + \ + ::std::complex C_component_2() const \ + { \ + return(::std::complex(c,d)); \ + } \ + \ + ::std::complex C_component_3() const \ + { \ + return(::std::complex(e,f)); \ + } \ + \ + ::std::complex C_component_4() const \ + { \ + return(::std::complex(g,h)); \ + } \ + \ + ::boost::math::quaternion H_component_1() const \ + { \ + return(::boost::math::quaternion(a,b,c,d)); \ + } \ + \ + ::boost::math::quaternion H_component_2() const \ + { \ + return(::boost::math::quaternion(e,f,g,h)); \ + } + + +#define BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type) \ + template \ + octonion & operator = (octonion const & a_affecter) \ + { \ + a = static_cast(a_affecter.R_component_1()); \ + b = static_cast(a_affecter.R_component_2()); \ + c = static_cast(a_affecter.R_component_3()); \ + d = static_cast(a_affecter.R_component_4()); \ + e = static_cast(a_affecter.R_component_5()); \ + f = static_cast(a_affecter.R_component_6()); \ + g = static_cast(a_affecter.R_component_7()); \ + h = static_cast(a_affecter.R_component_8()); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (octonion const & a_affecter) \ + { \ + a = a_affecter.a; \ + b = a_affecter.b; \ + c = a_affecter.c; \ + d = a_affecter.d; \ + e = a_affecter.e; \ + f = a_affecter.f; \ + g = a_affecter.g; \ + h = a_affecter.h; \ + \ + return(*this); \ + } \ + \ + octonion & operator = (type const & a_affecter) \ + { \ + a = a_affecter; \ + \ + b = c = d = e = f= g = h = static_cast(0); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (::std::complex const & a_affecter) \ + { \ + a = a_affecter.real(); \ + b = a_affecter.imag(); \ + \ + c = d = e = f = g = h = static_cast(0); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (::boost::math::quaternion const & a_affecter) \ + { \ + a = a_affecter.R_component_1(); \ + b = a_affecter.R_component_2(); \ + c = a_affecter.R_component_3(); \ + d = a_affecter.R_component_4(); \ + \ + e = f = g = h = static_cast(0); \ + \ + return(*this); \ + } + + +#define BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \ + type a; \ + type b; \ + type c; \ + type d; \ + type e; \ + type f; \ + type g; \ + type h; \ + + // LCOV_EXCL_START + // No code coverage for the generic case, like std::complex, + // the The behavior of octonion is unspecified if T is not + // one of float, double or long double. + + template + class octonion + { + public: + + using value_type = T; + + // constructor for O seen as R^8 + // (also default constructor) + + explicit octonion( T const & requested_a = T(), + T const & requested_b = T(), + T const & requested_c = T(), + T const & requested_d = T(), + T const & requested_e = T(), + T const & requested_f = T(), + T const & requested_g = T(), + T const & requested_h = T()) + : a(requested_a), + b(requested_b), + c(requested_c), + d(requested_d), + e(requested_e), + f(requested_f), + g(requested_g), + h(requested_h) + { + // nothing to do! + } + + + // constructor for H seen as C^4 + + explicit octonion( ::std::complex const & z0, + ::std::complex const & z1 = ::std::complex(), + ::std::complex const & z2 = ::std::complex(), + ::std::complex const & z3 = ::std::complex()) + : a(z0.real()), + b(z0.imag()), + c(z1.real()), + d(z1.imag()), + e(z2.real()), + f(z2.imag()), + g(z3.real()), + h(z3.imag()) + { + // nothing to do! + } + + + // constructor for O seen as H^2 + + explicit octonion( ::boost::math::quaternion const & q0, + ::boost::math::quaternion const & q1 = ::boost::math::quaternion()) + : a(q0.R_component_1()), + b(q0.R_component_2()), + c(q0.R_component_3()), + d(q0.R_component_4()), + e(q1.R_component_1()), + f(q1.R_component_2()), + g(q1.R_component_3()), + h(q1.R_component_4()) + { + // nothing to do! + } + + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + + // templated copy constructor + + template + explicit octonion(octonion const & a_recopier) + : a(static_cast(a_recopier.R_component_1())), + b(static_cast(a_recopier.R_component_2())), + c(static_cast(a_recopier.R_component_3())), + d(static_cast(a_recopier.R_component_4())), + e(static_cast(a_recopier.R_component_5())), + f(static_cast(a_recopier.R_component_6())), + g(static_cast(a_recopier.R_component_7())), + h(static_cast(a_recopier.R_component_8())) + { + // nothing to do! + } + + + // destructor + ~octonion() = default; + + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(T) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + octonion & operator += (T const & rhs) + { + T at = a + rhs; // exception guard + + a = at; + + return(*this); + } + + + octonion & operator += (::std::complex const & rhs) + { + T at = a + rhs.real(); // exception guard + T bt = b + rhs.imag(); // exception guard + + a = at; + b = bt; + + return(*this); + } + + + octonion & operator += (::boost::math::quaternion const & rhs) + { + T at = a + rhs.R_component_1(); // exception guard + T bt = b + rhs.R_component_2(); // exception guard + T ct = c + rhs.R_component_3(); // exception guard + T dt = d + rhs.R_component_4(); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + + return(*this); + } + + + template + octonion & operator += (octonion const & rhs) + { + T at = a + static_cast(rhs.R_component_1()); // exception guard + T bt = b + static_cast(rhs.R_component_2()); // exception guard + T ct = c + static_cast(rhs.R_component_3()); // exception guard + T dt = d + static_cast(rhs.R_component_4()); // exception guard + T et = e + static_cast(rhs.R_component_5()); // exception guard + T ft = f + static_cast(rhs.R_component_6()); // exception guard + T gt = g + static_cast(rhs.R_component_7()); // exception guard + T ht = h + static_cast(rhs.R_component_8()); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + + octonion & operator -= (T const & rhs) + { + T at = a - rhs; // exception guard + + a = at; + + return(*this); + } + + + octonion & operator -= (::std::complex const & rhs) + { + T at = a - rhs.real(); // exception guard + T bt = b - rhs.imag(); // exception guard + + a = at; + b = bt; + + return(*this); + } + + + octonion & operator -= (::boost::math::quaternion const & rhs) + { + T at = a - rhs.R_component_1(); // exception guard + T bt = b - rhs.R_component_2(); // exception guard + T ct = c - rhs.R_component_3(); // exception guard + T dt = d - rhs.R_component_4(); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + + return(*this); + } + + + template + octonion & operator -= (octonion const & rhs) + { + T at = a - static_cast(rhs.R_component_1()); // exception guard + T bt = b - static_cast(rhs.R_component_2()); // exception guard + T ct = c - static_cast(rhs.R_component_3()); // exception guard + T dt = d - static_cast(rhs.R_component_4()); // exception guard + T et = e - static_cast(rhs.R_component_5()); // exception guard + T ft = f - static_cast(rhs.R_component_6()); // exception guard + T gt = g - static_cast(rhs.R_component_7()); // exception guard + T ht = h - static_cast(rhs.R_component_8()); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (T const & rhs) + { + T at = a * rhs; // exception guard + T bt = b * rhs; // exception guard + T ct = c * rhs; // exception guard + T dt = d * rhs; // exception guard + T et = e * rhs; // exception guard + T ft = f * rhs; // exception guard + T gt = g * rhs; // exception guard + T ht = h * rhs; // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + + T at = +a*ar-b*br; + T bt = +a*br+b*ar; + T ct = +c*ar+d*br; + T dt = -c*br+d*ar; + T et = +e*ar+f*br; + T ft = -e*br+f*ar; + T gt = +g*ar-h*br; + T ht = +g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (::boost::math::quaternion const & rhs) + { + T ar = rhs.R_component_1(); + T br = rhs.R_component_2(); + T cr = rhs.R_component_2(); + T dr = rhs.R_component_2(); + + T at = +a*ar-b*br-c*cr-d*dr; + T bt = +a*br+b*ar+c*dr-d*cr; + T ct = +a*cr-b*dr+c*ar+d*br; + T dt = +a*dr+b*cr-c*br+d*ar; + T et = +e*ar+f*br+g*cr+h*dr; + T ft = -e*br+f*ar-g*dr+h*cr; + T gt = -e*cr+f*dr+g*ar-h*br; + T ht = -e*dr-f*cr+g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + template + octonion & operator *= (octonion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + T er = static_cast(rhs.R_component_5()); + T fr = static_cast(rhs.R_component_6()); + T gr = static_cast(rhs.R_component_7()); + T hr = static_cast(rhs.R_component_8()); + + T at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; + T bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; + T ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; + T dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; + T et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; + T ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; + T gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; + T ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (T const & rhs) + { + T at = a / rhs; // exception guard + T bt = b / rhs; // exception guard + T ct = c / rhs; // exception guard + T dt = d / rhs; // exception guard + T et = e / rhs; // exception guard + T ft = f / rhs; // exception guard + T gt = g / rhs; // exception guard + T ht = h / rhs; // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + + T denominator = ar*ar+br*br; + + T at = (+a*ar-b*br)/denominator; + T bt = (-a*br+b*ar)/denominator; + T ct = (+c*ar-d*br)/denominator; + T dt = (+c*br+d*ar)/denominator; + T et = (+e*ar-f*br)/denominator; + T ft = (+e*br+f*ar)/denominator; + T gt = (+g*ar+h*br)/denominator; + T ht = (+g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (::boost::math::quaternion const & rhs) + { + T ar = rhs.R_component_1(); + T br = rhs.R_component_2(); + T cr = rhs.R_component_2(); + T dr = rhs.R_component_2(); + + T denominator = ar*ar+br*br+cr*cr+dr*dr; + + T at = (+a*ar+b*br+c*cr+d*dr)/denominator; + T bt = (-a*br+b*ar-c*dr+d*cr)/denominator; + T ct = (-a*cr+b*dr+c*ar-d*br)/denominator; + T dt = (-a*dr-b*cr+c*br+d*ar)/denominator; + T et = (+e*ar-f*br-g*cr-h*dr)/denominator; + T ft = (+e*br+f*ar+g*dr-h*cr)/denominator; + T gt = (+e*cr-f*dr+g*ar+h*br)/denominator; + T ht = (+e*dr+f*cr-g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + template + octonion & operator /= (octonion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + T er = static_cast(rhs.R_component_5()); + T fr = static_cast(rhs.R_component_6()); + T gr = static_cast(rhs.R_component_7()); + T hr = static_cast(rhs.R_component_8()); + + T denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr; + + T at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator; + T bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator; + T ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator; + T dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator; + T et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator; + T ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator; + T gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator; + T ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(T) + + + private: + + }; + // LCOV_EXCL_STOP + + // declaration of octonion specialization + + template<> class octonion; + template<> class octonion; + template<> class octonion; + + + // helper templates for converting copy constructors (declaration) + + namespace detail + { + + template< typename T, + typename U + > + octonion octonion_type_converter(octonion const & rhs); + } + + + // implementation of octonion specialization + + +#define BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type) \ + explicit octonion( type const & requested_a = static_cast(0), \ + type const & requested_b = static_cast(0), \ + type const & requested_c = static_cast(0), \ + type const & requested_d = static_cast(0), \ + type const & requested_e = static_cast(0), \ + type const & requested_f = static_cast(0), \ + type const & requested_g = static_cast(0), \ + type const & requested_h = static_cast(0)) \ + : a(requested_a), \ + b(requested_b), \ + c(requested_c), \ + d(requested_d), \ + e(requested_e), \ + f(requested_f), \ + g(requested_g), \ + h(requested_h) \ + { \ + } \ + \ + explicit octonion( ::std::complex const & z0, \ + ::std::complex const & z1 = ::std::complex(), \ + ::std::complex const & z2 = ::std::complex(), \ + ::std::complex const & z3 = ::std::complex()) \ + : a(z0.real()), \ + b(z0.imag()), \ + c(z1.real()), \ + d(z1.imag()), \ + e(z2.real()), \ + f(z2.imag()), \ + g(z3.real()), \ + h(z3.imag()) \ + { \ + } \ + \ + explicit octonion( ::boost::math::quaternion const & q0, \ + ::boost::math::quaternion const & q1 = ::boost::math::quaternion()) \ + : a(q0.R_component_1()), \ + b(q0.R_component_2()), \ + c(q0.R_component_3()), \ + d(q0.R_component_4()), \ + e(q1.R_component_1()), \ + f(q1.R_component_2()), \ + g(q1.R_component_3()), \ + h(q1.R_component_4()) \ + { \ + } + + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ + octonion & operator += (type const & rhs) \ + { \ + a += rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ + octonion & operator += (::std::complex const & rhs) \ + { \ + a += rhs.real(); \ + b += rhs.imag(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ + octonion & operator += (::boost::math::quaternion const & rhs) \ + { \ + a += rhs.R_component_1(); \ + b += rhs.R_component_2(); \ + c += rhs.R_component_3(); \ + d += rhs.R_component_4(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) \ + template \ + octonion & operator += (octonion const & rhs) \ + { \ + a += static_cast(rhs.R_component_1()); \ + b += static_cast(rhs.R_component_2()); \ + c += static_cast(rhs.R_component_3()); \ + d += static_cast(rhs.R_component_4()); \ + e += static_cast(rhs.R_component_5()); \ + f += static_cast(rhs.R_component_6()); \ + g += static_cast(rhs.R_component_7()); \ + h += static_cast(rhs.R_component_8()); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ + octonion & operator -= (type const & rhs) \ + { \ + a -= rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ + octonion & operator -= (::std::complex const & rhs) \ + { \ + a -= rhs.real(); \ + b -= rhs.imag(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ + octonion & operator -= (::boost::math::quaternion const & rhs) \ + { \ + a -= rhs.R_component_1(); \ + b -= rhs.R_component_2(); \ + c -= rhs.R_component_3(); \ + d -= rhs.R_component_4(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) \ + template \ + octonion & operator -= (octonion const & rhs) \ + { \ + a -= static_cast(rhs.R_component_1()); \ + b -= static_cast(rhs.R_component_2()); \ + c -= static_cast(rhs.R_component_3()); \ + d -= static_cast(rhs.R_component_4()); \ + e -= static_cast(rhs.R_component_5()); \ + f -= static_cast(rhs.R_component_6()); \ + g -= static_cast(rhs.R_component_7()); \ + h -= static_cast(rhs.R_component_8()); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ + octonion & operator *= (type const & rhs) \ + { \ + a *= rhs; \ + b *= rhs; \ + c *= rhs; \ + d *= rhs; \ + e *= rhs; \ + f *= rhs; \ + g *= rhs; \ + h *= rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ + octonion & operator *= (::std::complex const & rhs) \ + { \ + type ar = rhs.real(); \ + type br = rhs.imag(); \ + \ + type at = +a*ar-b*br; \ + type bt = +a*br+b*ar; \ + type ct = +c*ar+d*br; \ + type dt = -c*br+d*ar; \ + type et = +e*ar+f*br; \ + type ft = -e*br+f*ar; \ + type gt = +g*ar-h*br; \ + type ht = +g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ + octonion & operator *= (::boost::math::quaternion const & rhs) \ + { \ + type ar = rhs.R_component_1(); \ + type br = rhs.R_component_2(); \ + type cr = rhs.R_component_2(); \ + type dr = rhs.R_component_2(); \ + \ + type at = +a*ar-b*br-c*cr-d*dr; \ + type bt = +a*br+b*ar+c*dr-d*cr; \ + type ct = +a*cr-b*dr+c*ar+d*br; \ + type dt = +a*dr+b*cr-c*br+d*ar; \ + type et = +e*ar+f*br+g*cr+h*dr; \ + type ft = -e*br+f*ar-g*dr+h*cr; \ + type gt = -e*cr+f*dr+g*ar-h*br; \ + type ht = -e*dr-f*cr+g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) \ + template \ + octonion & operator *= (octonion const & rhs) \ + { \ + type ar = static_cast(rhs.R_component_1()); \ + type br = static_cast(rhs.R_component_2()); \ + type cr = static_cast(rhs.R_component_3()); \ + type dr = static_cast(rhs.R_component_4()); \ + type er = static_cast(rhs.R_component_5()); \ + type fr = static_cast(rhs.R_component_6()); \ + type gr = static_cast(rhs.R_component_7()); \ + type hr = static_cast(rhs.R_component_8()); \ + \ + type at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; \ + type bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; \ + type ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; \ + type dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; \ + type et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; \ + type ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; \ + type gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; \ + type ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +// There is quite a lot of repetition in the code below. This is intentional. +// The last conditional block is the normal form, and the others merely +// consist of workarounds for various compiler deficiencies. Hopefully, when +// more compilers are conformant and we can retire support for those that are +// not, we will be able to remove the clutter. This is makes the situation +// (painfully) explicit. + +#define BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ + octonion & operator /= (type const & rhs) \ + { \ + a /= rhs; \ + b /= rhs; \ + c /= rhs; \ + d /= rhs; \ + \ + return(*this); \ + } + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + octonion & operator /= (::std::complex const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(2); \ + \ + tr[0] = rhs.real(); \ + tr[1] = rhs.imag(); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]-b*tr[1]; \ + tt[1] = -a*tr[1]+b*tr[0]; \ + tt[2] = +c*tr[0]-d*tr[1]; \ + tt[3] = +c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]; \ + tt[5] = +e*tr[1]+f*tr[0]; \ + tt[6] = +g*tr[0]+h*tr[1]; \ + tt[7] = +g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + octonion & operator /= (::std::complex const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(2); \ + \ + tr[0] = rhs.real(); \ + tr[1] = rhs.imag(); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]-b*tr[1]; \ + tt[1] = -a*tr[1]+b*tr[0]; \ + tt[2] = +c*tr[0]-d*tr[1]; \ + tt[3] = +c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]; \ + tt[5] = +e*tr[1]+f*tr[0]; \ + tt[6] = +g*tr[0]+h*tr[1]; \ + tt[7] = +g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + octonion & operator /= (::boost::math::quaternion const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(4); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + octonion & operator /= (::boost::math::quaternion const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(4); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ + template \ + octonion & operator /= (octonion const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(8); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + tr[4] = static_cast(rhs.R_component_5()); \ + tr[5] = static_cast(rhs.R_component_6()); \ + tr[6] = static_cast(rhs.R_component_7()); \ + tr[7] = static_cast(rhs.R_component_8()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ + tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ + template \ + octonion & operator /= (octonion const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(8); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + tr[4] = static_cast(rhs.R_component_5()); \ + tr[5] = static_cast(rhs.R_component_6()); \ + tr[6] = static_cast(rhs.R_component_7()); \ + tr[7] = static_cast(rhs.R_component_8()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ + tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) + + + template<> + class octonion + { + public: + + using value_type = float; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float) + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + // explicit copy constructors (precision-losing converters) + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // destructor + ~octonion() = default; + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(float) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(float) + }; + + + template<> + class octonion + { + public: + + using value_type = double; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double) + + // Untemplated copy constructor + octonion(const octonion&) = default; + + // converting copy constructor + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // explicit copy constructors (precision-losing converters) + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // destructor + // (this is taken care of by the compiler itself) + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(double) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(double) + }; + + + template<> + class octonion + { + public: + + using value_type = long double; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double) + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + // converting copy constructor + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + + // destructor + // (this is taken care of by the compiler itself) + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(long double) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double) + + + private: + + }; + + +#undef BOOST_OCTONION_CONSTRUCTOR_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_4 + + +#undef BOOST_OCTONION_MEMBER_DATA_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR + +#undef BOOST_OCTONION_ACCESSOR_GENERATOR + + + // operators + +#define BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \ + { \ + octonion res(lhs); \ + res op##= rhs; \ + return(res); \ + } + +#define BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ + template \ + inline octonion operator op (T const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, T const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ + template \ + inline octonion operator op (::std::complex const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, ::std::complex const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ + template \ + inline octonion operator op (::boost::math::quaternion const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, ::boost::math::quaternion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_4(op) \ + template \ + inline octonion operator op (octonion const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_4(op) + + + BOOST_OCTONION_OPERATOR_GENERATOR(+) + BOOST_OCTONION_OPERATOR_GENERATOR(-) + BOOST_OCTONION_OPERATOR_GENERATOR(*) + BOOST_OCTONION_OPERATOR_GENERATOR(/) + + +#undef BOOST_OCTONION_OPERATOR_GENERATOR + +#undef BOOST_OCTONION_OPERATOR_GENERATOR_1_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_1_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_2_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_2_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_3_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_3_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_4 + +#undef BOOST_OCTONION_OPERATOR_GENERATOR_BODY + + + template + inline octonion operator + (octonion const & o) + { + return(o); + } + + + template + inline octonion operator - (octonion const & o) + { + return(octonion(-o.R_component_1(),-o.R_component_2(),-o.R_component_3(),-o.R_component_4(),-o.R_component_5(),-o.R_component_6(),-o.R_component_7(),-o.R_component_8())); + } + + + template + inline bool operator == (T const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs)&& + (rhs.R_component_2() == static_cast(0))&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0))&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, T const & rhs) + { + return( + (lhs.R_component_1() == rhs)&& + (lhs.R_component_2() == static_cast(0))&& + (lhs.R_component_3() == static_cast(0))&& + (lhs.R_component_4() == static_cast(0))&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (::std::complex const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.real())&& + (rhs.R_component_2() == lhs.imag())&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0))&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, ::std::complex const & rhs) + { + return( + (lhs.R_component_1() == rhs.real())&& + (lhs.R_component_2() == rhs.imag())&& + (lhs.R_component_3() == static_cast(0))&& + (lhs.R_component_4() == static_cast(0))&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (::boost::math::quaternion const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4())&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, ::boost::math::quaternion const & rhs) + { + return( + (lhs.R_component_1() == rhs.R_component_1())&& + (lhs.R_component_2() == rhs.R_component_2())&& + (lhs.R_component_3() == rhs.R_component_3())&& + (lhs.R_component_4() == rhs.R_component_4())&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4())&& + (rhs.R_component_5() == lhs.R_component_5())&& + (rhs.R_component_6() == lhs.R_component_6())&& + (rhs.R_component_7() == lhs.R_component_7())&& + (rhs.R_component_8() == lhs.R_component_8()) + ); + } + + +#define BOOST_OCTONION_NOT_EQUAL_GENERATOR \ + { \ + return(!(lhs == rhs)); \ + } + + template + inline bool operator != (T const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, T const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (::std::complex const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, ::std::complex const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (::boost::math::quaternion const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, ::boost::math::quaternion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + #undef BOOST_OCTONION_NOT_EQUAL_GENERATOR + + // LCOV_EXCL_START + // Something like 2,100 lines of input-streaming up to line 3,800 and beyond. + + // Note: the default values in the constructors of the complex and quaternions make for + // a very complex and ambiguous situation; we have made choices to disambiguate. + template + ::std::basic_istream & operator >> ( ::std::basic_istream & is, + octonion & o) + { +#ifdef BOOST_NO_STD_LOCALE +#else + const ::std::ctype & ct = ::std::use_facet< ::std::ctype >(is.getloc()); +#endif /* BOOST_NO_STD_LOCALE */ + + T a = T(); + T b = T(); + T c = T(); + T d = T(); + T e = T(); + T f = T(); + T g = T(); + T h = T(); + + ::std::complex u = ::std::complex(); + ::std::complex v = ::std::complex(); + ::std::complex x = ::std::complex(); + ::std::complex y = ::std::complex(); + + ::boost::math::quaternion p = ::boost::math::quaternion(); + ::boost::math::quaternion q = ::boost::math::quaternion(); + + charT ch = charT(); + char cc; + + is >> ch; // get the first lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(" + { + is >> ch; // get the second lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((" + { + is >> ch; // get the third lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(((" + { + is.putback(ch); + + is >> u; // read "((u" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((u)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a))), (((a,b))) + { + o = octonion(u); + } + else if (cc == ',') // read "((u)," + { + p = ::boost::math::quaternion(u); + + is >> q; // read "((u),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a)),q), (((a,b)),q) + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc ==',') // read "((u," + { + is >> v; // read "((u,v" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((u,v)" + { + p = ::boost::math::quaternion(u,v); + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a),v)), (((a,b),v)) + { + o = octonion(p); + } + else if (cc == ',') // read "((u,v)," + { + is >> q; // read "(p,q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a),v),q), (((a,b),v),q) + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a" + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a))" + { + o = octonion(a); + } + else if (cc == ',') // read "((a)," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),((" + { + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value! + + is >> q; // read "((a),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),q)" + { + p = ::boost::math::quaternion(a); + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a),(c" or "((a),(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a),(c)," + { + u = ::std::complex(a); + + v = ::std::complex(c); + + is >> x; // read "((a),(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a),(c),x," + { + is >> y; // read "((a),(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(c," or "((a),(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),(e,(" (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + x = ::std::complex(c); // "c" was actually "e" + + is.putback(ch); // we can only backtrace once + + is >> y; // read "((a),(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,y)" + { + q = ::boost::math::quaternion(x,y); + + is >> ch; // get the next lexeme + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,y))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a),(c,d" or "((a),(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "((a),(c,d)," + { + u = ::std::complex(a); + + v = ::std::complex(c,d); + + is >> x; // read "((a),(c,d),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a),(c,d),x," + { + is >> y; // read "((a),(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + is >> g; // read "((a),(e,f,g" (too late to backtrack) + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g)" + { + q = ::boost::math::quaternion(c,d,g); // "c" was actually "e", and "d" was actually "f" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(e,f,g," + { + is >> h; // read "((a),(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g,h)" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" was actually "e", and "d" was actually "f" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g,h))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "((a),c" (ambiguity resolution) + { + is.putback(ch); + + is >> c; // we extract the third component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c)" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a),c," + { + is >> x; // read "((a),c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c,x)" + { + o = octonion(a,b,c,d,x.real(),x.imag()); + } + else if (cc == ',') // read "((a),c,x," + { + is >> y;if (!is.good()) goto finish; // read "((a),c,x,y" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c,x,y)" + { + o = octonion(a,b,c,d,x.real(),x.imag(),y.real(),y.imag()); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc ==',') // read "((a," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,(" + { + u = ::std::complex(a); + + is.putback(ch); // can only backtrack so much + + is >> v; // read "((a,v" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v))" + { + o = octonion(u,v); + } + else if (cc == ',') // read "((a,v)," + { + p = ::boost::math::quaternion(u,v); + + is >> q; // read "((a,v),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else + { + is.putback(ch); + + is >> b; // read "((a,b" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b))" + { + o = octonion(a,b); + } + else if (cc == ',') // read "((a,b)," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),((" + { + p = ::boost::math::quaternion(a,b); + + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value + + is >> q; // read "((a,b),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a,b),(c" or "((a,b),(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a,b),(c)," + { + u = ::std::complex(a,b); + + v = ::std::complex(c); + + is >> x; // read "((a,b),(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a,b),(c),x," + { + is >> y; // read "((a,b),(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(c," or "((a,b),(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),(e,(" (ambiguity resolution) + { + u = ::std::complex(a,b); + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); + + is >> y; // read "((a,b),(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,y)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,y))" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a,b),(c,d" or "((a,b),(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d)" (ambiguity resolution) + { + u = ::std::complex(a,b); + + v = ::std::complex(c,d); + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d))" + { + o = octonion(u,v); + } + else if (cc == ',') // read "((a,b),(c,d)," + { + is >> x; // read "((a,b),(c,d),x + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a,b),(c,d),x," + { + is >> y; // read "((a,b),(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a,b); // too late to backtrack + + is >> g; // read "((a,b),(e,f,g" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g))" + { + q = ::boost::math::quaternion(c,d,g); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(e,f,g," + { + is >> h; // read "((a,b),(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g,h)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read ((a,b),(e,f,g,h))" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b," + { + is >> c; // read "((a,b,c" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a,b,c)," + { + p = ::boost::math::quaternion(a,b,c); + + is >> q; // read "((a,b,c),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b,c," + { + is >> d; // read "((a,b,c,d" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "((a,b,c,d)," + { + p = ::boost::math::quaternion(a,b,c,d); + + is >> q; // read "((a,b,c,d),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "(a" + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a)" + { + o = octonion(a); + } + else if (cc == ',') // read "(a," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,((" + { + p = ::boost::math::quaternion(a); + + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value + + is >> q; // read "(a,q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,(c" or "(a,(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "(a,(c)," + { + u = ::std::complex(a); + + v = ::std::complex(c); + + is >> x; // read "(a,(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,(c),x," + { + is >> y; // read "(a,(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(c," or "(a,(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,(e,(" (ambiguity resolution) + { + u = ::std::complex(a); + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); // we backtrack + + is >> y; // read "(a,(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,y)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,y))" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,(c,d" or "(a,(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "(a,(c,d)," + { + u = ::std::complex(a); + + v = ::std::complex(c,d); + + is >> x; // read "(a,(c,d),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,(c,d),x," + { + is >> y; // read "(a,(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + is >> g; // read "(a,(e,f,g" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g))" + { + q = ::boost::math::quaternion(c,d,g); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(e,f,g," + { + is >> h; // read "(a,(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g,h)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g,h))" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "(a,b" or "(a,c" (ambiguity resolution) + { + is.putback(ch); + + is >> b; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b)" (ambiguity resolution) + { + o = octonion(a,b); + } + else if (cc == ',') // read "(a,b," or "(a,c," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,c,(" (ambiguity resolution) + { + u = ::std::complex(a); + + v = ::std::complex(b); // "b" is actually "c" + + is.putback(ch); // we backtrack + + is >> x; // read "(a,c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,c,x," + { + is >> y; // read "(a,c,x,y" // read "(a,c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b,c" or "(a,c,e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c)" (ambiguity resolution) + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "(a,b,c," or "(a,c,e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,c,e,(") (ambiguity resolution) + { + u = ::std::complex(a); + + v = ::std::complex(b); // "b" is actually "c" + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); // we backtrack + + is >> y; // read "(a,c,e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,e,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b,c,d" (ambiguity resolution) + { + is.putback(ch); // we backtrack + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d)" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "(a,b,c,d," + { + is >> e; // read "(a,b,c,d,e" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e)" + { + o = octonion(a,b,c,d,e); + } + else if (cc == ',') // read "(a,b,c,d,e," + { + is >> f; // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f)" + { + o = octonion(a,b,c,d,e,f); + } + else if (cc == ',') // read "(a,b,c,d,e,f," + { + is >> g; // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f,g)" + { + o = octonion(a,b,c,d,e,f,g); + } + else if (cc == ',') // read "(a,b,c,d,e,f,g," + { + is >> h; // read "(a,b,c,d,e,f,g,h" // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f,g,h)" + { + o = octonion(a,b,c,d,e,f,g,h); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // format: a + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + o = octonion(a); + } + + finish: + return(is); + } + // LCOV_EXCL_STOP + + + template + ::std::basic_ostream & operator << ( ::std::basic_ostream & os, + octonion const & o) + { + ::std::basic_ostringstream s; + + s.flags(os.flags()); +#ifdef BOOST_NO_STD_LOCALE +#else + s.imbue(os.getloc()); +#endif /* BOOST_NO_STD_LOCALE */ + s.precision(os.precision()); + + s << '(' << o.R_component_1() << ',' + << o.R_component_2() << ',' + << o.R_component_3() << ',' + << o.R_component_4() << ',' + << o.R_component_5() << ',' + << o.R_component_6() << ',' + << o.R_component_7() << ',' + << o.R_component_8() << ')'; + + return os << s.str(); + } + + + // values + + template + inline T real(octonion const & o) + { + return(o.real()); + } + + + template + inline octonion unreal(octonion const & o) + { + return(o.unreal()); + } + + +#define BOOST_OCTONION_VALARRAY_LOADER \ + using ::std::valarray; \ + \ + valarray temp(8); \ + \ + temp[0] = o.R_component_1(); \ + temp[1] = o.R_component_2(); \ + temp[2] = o.R_component_3(); \ + temp[3] = o.R_component_4(); \ + temp[4] = o.R_component_5(); \ + temp[5] = o.R_component_6(); \ + temp[6] = o.R_component_7(); \ + temp[7] = o.R_component_8(); + + + template + inline T sup(octonion const & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + BOOST_OCTONION_VALARRAY_LOADER + + return((abs(temp).max)()); + } + + + template + inline T l1(octonion const & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + BOOST_OCTONION_VALARRAY_LOADER + + return(abs(temp).sum()); + } + + + template + inline T abs(const octonion & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + using ::std::sqrt; + + BOOST_OCTONION_VALARRAY_LOADER + + T maxim = (abs(temp).max)(); // overflow protection + + if (maxim == static_cast(0)) + { + return(maxim); + } + else + { + T mixam = static_cast(1)/maxim; // prefer multiplications over divisions + + temp *= mixam; + + temp *= temp; + + return(maxim*sqrt(temp.sum())); + } + + //return(::std::sqrt(norm(o))); + } + + +#undef BOOST_OCTONION_VALARRAY_LOADER + + + // Note: This is the Cayley norm, not the Euclidean norm... + + template + inline T norm(octonion const & o) + { + return(real(o*conj(o))); + } + + + template + inline octonion conj(octonion const & o) + { + return(octonion( +o.R_component_1(), + -o.R_component_2(), + -o.R_component_3(), + -o.R_component_4(), + -o.R_component_5(), + -o.R_component_6(), + -o.R_component_7(), + -o.R_component_8())); + } + + + // Note: There is little point, for the octonions, to introduce the equivalents + // to the complex "arg" and the quaternionic "cylindropolar". + + + template + inline octonion spherical(T const & rho, + T const & theta, + T const & phi1, + T const & phi2, + T const & phi3, + T const & phi4, + T const & phi5, + T const & phi6) + { + using ::std::cos; + using ::std::sin; + + //T a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T f = sin(phi4)*cos(phi5)*cos(phi6); + //T g = sin(phi5)*cos(phi6); + //T h = sin(phi6); + + T courrant = static_cast(1); + + T h = sin(phi6); + + courrant *= cos(phi6); + + T g = sin(phi5)*courrant; + + courrant *= cos(phi5); + + T f = sin(phi4)*courrant; + + courrant *= cos(phi4); + + T e = sin(phi3)*courrant; + + courrant *= cos(phi3); + + T d = sin(phi2)*courrant; + + courrant *= cos(phi2); + + T c = sin(phi1)*courrant; + + courrant *= cos(phi1); + + T b = sin(theta)*courrant; + T a = cos(theta)*courrant; + + return(rho*octonion(a,b,c,d,e,f,g,h)); + } + + + template + inline octonion multipolar(T const & rho1, + T const & theta1, + T const & rho2, + T const & theta2, + T const & rho3, + T const & theta3, + T const & rho4, + T const & theta4) + { + using ::std::cos; + using ::std::sin; + + T a = rho1*cos(theta1); + T b = rho1*sin(theta1); + T c = rho2*cos(theta2); + T d = rho2*sin(theta2); + T e = rho3*cos(theta3); + T f = rho3*sin(theta3); + T g = rho4*cos(theta4); + T h = rho4*sin(theta4); + + return(octonion(a,b,c,d,e,f,g,h)); + } + + + template + inline octonion cylindrical(T const & r, + T const & angle, + T const & h1, + T const & h2, + T const & h3, + T const & h4, + T const & h5, + T const & h6) + { + using ::std::cos; + using ::std::sin; + + T a = r*cos(angle); + T b = r*sin(angle); + + return(octonion(a,b,h1,h2,h3,h4,h5,h6)); + } + + + template + inline octonion exp(octonion const & o) + { + using ::std::exp; + using ::std::cos; + + using ::boost::math::sinc_pi; + + T u = exp(real(o)); + + T z = abs(unreal(o)); + + T w = sinc_pi(z); + + return(u*octonion(cos(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion cos(octonion const & o) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(o)); + + T w = -sin(o.real())*sinhc_pi(z); + + return(octonion(cos(o.real())*cosh(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion sin(octonion const & o) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(o)); + + T w = +cos(o.real())*sinhc_pi(z); + + return(octonion(sin(o.real())*cosh(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion tan(octonion const & o) + { + return(sin(o)/cos(o)); + } + + + template + inline octonion cosh(octonion const & o) + { + return((exp(+o)+exp(-o))/static_cast(2)); + } + + + template + inline octonion sinh(octonion const & o) + { + return((exp(+o)-exp(-o))/static_cast(2)); + } + + + template + inline octonion tanh(octonion const & o) + { + return(sinh(o)/cosh(o)); + } + + + template + octonion pow(octonion const & o, + int n) + { + if (n > 1) + { + int m = n>>1; + + octonion result = pow(o, m); + + result *= result; + + if (n != (m<<1)) + { + result *= o; // n odd + } + + return(result); + } + else if (n == 1) + { + return(o); + } + else if (n == 0) + { + return(octonion(static_cast(1))); + } + else /* n < 0 */ + { + return(pow(octonion(static_cast(1))/o,-n)); + } + } + + + // helper templates for converting copy constructors (definition) + + namespace detail + { + + template< typename T, + typename U + > + octonion octonion_type_converter(octonion const & rhs) + { + return(octonion( static_cast(rhs.R_component_1()), + static_cast(rhs.R_component_2()), + static_cast(rhs.R_component_3()), + static_cast(rhs.R_component_4()), + static_cast(rhs.R_component_5()), + static_cast(rhs.R_component_6()), + static_cast(rhs.R_component_7()), + static_cast(rhs.R_component_8()))); + } + } + } +} + +#endif /* BOOST_OCTONION_HPP */ diff --git a/third-party/boost-math/include/boost/math/optimization/cma_es.hpp b/third-party/boost-math/include/boost/math/optimization/cma_es.hpp new file mode 100644 index 0000000000000..42b901a190008 --- /dev/null +++ b/third-party/boost-math/include/boost/math/optimization/cma_es.hpp @@ -0,0 +1,392 @@ +/* + * Copyright Nick Thompson, 2024 + * 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) + */ +#ifndef BOOST_MATH_OPTIMIZATION_CMA_ES_HPP +#define BOOST_MATH_OPTIMIZATION_CMA_ES_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __has_include() +#include +#else +#error "CMA-ES requires Eigen." +#endif + +// Follows the notation in: +// https://arxiv.org/pdf/1604.00772.pdf +// This is a (hopefully) faithful reproduction of the pseudocode in the arxiv review +// by Nikolaus Hansen. +// Comments referring to equations all refer to this arxiv review. +// A slide deck by the same author is given here: +// http://www.cmap.polytechnique.fr/~nikolaus.hansen/CmaTutorialGecco2023-no-audio.pdf +// which is also a very useful reference. + +#ifndef BOOST_MATH_DEBUG_CMA_ES +#define BOOST_MATH_DEBUG_CMA_ES 0 +#endif + +namespace boost::math::optimization { + +template struct cma_es_parameters { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + ArgumentContainer lower_bounds; + ArgumentContainer upper_bounds; + size_t max_generations = 1000; + ArgumentContainer const *initial_guess = nullptr; + // In the reference, population size = \lambda. + // If the population size is zero, it is set to equation (48) of the reference + // and rounded up to the nearest multiple of threads: + size_t population_size = 0; + // In the reference, learning_rate = c_m: + DimensionlessReal learning_rate = 1; +}; + +template +void validate_cma_es_parameters(cma_es_parameters ¶ms) { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + using std::isfinite; + using std::isnan; + using std::log; + using std::ceil; + using std::floor; + + std::ostringstream oss; + detail::validate_bounds(params.lower_bounds, params.upper_bounds); + if (params.initial_guess) { + detail::validate_initial_guess(*params.initial_guess, params.lower_bounds, params.upper_bounds); + } + const size_t n = params.upper_bounds.size(); + // Equation 48 of the arxiv review: + if (params.population_size == 0) { + //auto tmp = 4.0 + floor(3*log(n)); + // But round to the nearest multiple of the thread count: + //auto k = static_cast(std::ceil(tmp/params.threads)); + //params.population_size = k*params.threads; + params.population_size = static_cast(4 + floor(3*log(n))); + } + if (params.learning_rate <= DimensionlessReal(0) || !isfinite(params.learning_rate)) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The learning rate must be > 0, but got " << params.learning_rate << "."; + throw std::invalid_argument(oss.str()); + } +} + +template +ArgumentContainer cma_es( + const Func cost_function, + cma_es_parameters ¶ms, + URBG &gen, + std::invoke_result_t target_value = std::numeric_limits>::quiet_NaN(), + std::atomic *cancellation = nullptr, + std::atomic> *current_minimum_cost = nullptr, + std::vector>> *queries = nullptr) + { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + using ResultType = std::invoke_result_t; + using std::abs; + using std::log; + using std::exp; + using std::pow; + using std::min; + using std::max; + using std::sqrt; + using std::isnan; + using std::isfinite; + using std::uniform_real_distribution; + using std::normal_distribution; + validate_cma_es_parameters(params); + // n = dimension of problem: + const size_t n = params.lower_bounds.size(); + std::atomic target_attained = false; + std::atomic lowest_cost = std::numeric_limits::infinity(); + ArgumentContainer best_vector; + // p_{c} := evolution path, equation (24) of the arxiv review: + Eigen::Vector p_c(n); + // p_{\sigma} := conjugate evolution path, equation (31) of the arxiv review: + Eigen::Vector p_sigma(n); + if constexpr (detail::has_resize_v) { + best_vector.resize(n, std::numeric_limits::quiet_NaN()); + } + for (size_t i = 0; i < n; ++i) { + p_c[i] = DimensionlessReal(0); + p_sigma[i] = DimensionlessReal(0); + } + // Table 1, \mu = floor(\lambda/2): + size_t mu = params.population_size/2; + std::vector w_prime(params.population_size, std::numeric_limits::quiet_NaN()); + for (size_t i = 0; i < params.population_size; ++i) { + // Equation (49), but 0-indexed: + w_prime[i] = log(static_cast(params.population_size + 1)/(2*(i+1))); + } + // Table 1, notes at top: + DimensionlessReal positive_weight_sum = 0; + DimensionlessReal sq_weight_sum = 0; + for (size_t i = 0; i < mu; ++i) { + BOOST_MATH_ASSERT(w_prime[i] > 0); + positive_weight_sum += w_prime[i]; + sq_weight_sum += w_prime[i]*w_prime[i]; + } + DimensionlessReal mu_eff = positive_weight_sum*positive_weight_sum/sq_weight_sum; + BOOST_MATH_ASSERT(1 <= mu_eff); + BOOST_MATH_ASSERT(mu_eff <= mu); + DimensionlessReal negative_weight_sum = 0; + sq_weight_sum = 0; + for (size_t i = mu; i < params.population_size; ++i) { + BOOST_MATH_ASSERT(w_prime[i] <= 0); + negative_weight_sum += w_prime[i]; + sq_weight_sum += w_prime[i]*w_prime[i]; + } + DimensionlessReal mu_eff_m = negative_weight_sum*negative_weight_sum/sq_weight_sum; + // Equation (54): + DimensionlessReal c_m = params.learning_rate; + // Equation (55): + DimensionlessReal c_sigma = (mu_eff + 2)/(n + mu_eff + 5); + BOOST_MATH_ASSERT(c_sigma < 1); + DimensionlessReal d_sigma = 1 + 2*(max)(DimensionlessReal(0), sqrt(DimensionlessReal((mu_eff - 1)/(n + 1))) - DimensionlessReal(1)) + c_sigma; + // Equation (56): + DimensionlessReal c_c = (4 + mu_eff/n)/(n + 4 + 2*mu_eff/n); + BOOST_MATH_ASSERT(c_c <= 1); + // Equation (57): + DimensionlessReal c_1 = DimensionlessReal(2)/(pow(n + 1.3, 2) + mu_eff); + // Equation (58) + DimensionlessReal c_mu = (min)(1 - c_1, 2*(DimensionlessReal(0.25) + mu_eff + 1/mu_eff - 2)/((n+2)*(n+2) + mu_eff)); + BOOST_MATH_ASSERT(c_1 + c_mu <= DimensionlessReal(1)); + // Equation (50): + DimensionlessReal alpha_mu_m = 1 + c_1/c_mu; + // Equation (51): + DimensionlessReal alpha_mu_eff_m = 1 + 2*mu_eff_m/(mu_eff + 2); + // Equation (52): + DimensionlessReal alpha_m_pos_def = (1- c_1 - c_mu)/(n*c_mu); + // Equation (53): + std::vector weights(params.population_size, std::numeric_limits::quiet_NaN()); + for (size_t i = 0; i < mu; ++i) { + weights[i] = w_prime[i]/positive_weight_sum; + } + DimensionlessReal min_alpha = (min)(alpha_mu_m, (min)(alpha_mu_eff_m, alpha_m_pos_def)); + for (size_t i = mu; i < params.population_size; ++i) { + weights[i] = min_alpha*w_prime[i]/abs(negative_weight_sum); + } + // mu:= number of parents, lambda := number of offspring. + Eigen::Matrix C = Eigen::Matrix::Identity(n, n); + ArgumentContainer mean_vector; + // See the footnote in Figure 6 of the arxiv review: + // We should consider the more robust initialization described there. . . + Real sigma = DimensionlessReal(0.3)*(params.upper_bounds[0] - params.lower_bounds[0]);; + if (params.initial_guess) { + mean_vector = *params.initial_guess; + } + else { + mean_vector = detail::random_initial_population(params.lower_bounds, params.upper_bounds, 1, gen)[0]; + } + auto initial_cost = cost_function(mean_vector); + if (!isnan(initial_cost)) { + best_vector = mean_vector; + lowest_cost = initial_cost; + if (current_minimum_cost) { + *current_minimum_cost = initial_cost; + } + } +#if BOOST_MATH_DEBUG_CMA_ES + { + std::cout << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cout << "\tRunning a (" << params.population_size/2 << "/" << params.population_size/2 << "_W, " << params.population_size << ")-aCMA Evolutionary Strategy on " << params.threads << " threads.\n"; + std::cout << "\tInitial mean vector: {"; + for (size_t i = 0; i < n - 1; ++i) { + std::cout << mean_vector[i] << ", "; + } + std::cout << mean_vector[n - 1] << "}.\n"; + std::cout << "\tCost: " << lowest_cost << ".\n"; + std::cout << "\tInitial step length: " << sigma << ".\n"; + std::cout << "\tVariance effective selection mass: " << mu_eff << ".\n"; + std::cout << "\tLearning rate for rank-one update of covariance matrix: " << c_1 << ".\n"; + std::cout << "\tLearning rate for rank-mu update of covariance matrix: " << c_mu << ".\n"; + std::cout << "\tDecay rate for cumulation path for step-size control: " << c_sigma << ".\n"; + std::cout << "\tLearning rate for the mean: " << c_m << ".\n"; + std::cout << "\tDamping parameter for step-size update: " << d_sigma << ".\n"; + } +#endif + size_t generation = 0; + + std::vector> ys(params.population_size); + std::vector xs(params.population_size); + std::vector costs(params.population_size, std::numeric_limits::quiet_NaN()); + Eigen::Vector weighted_avg_y(n); + Eigen::Vector z(n); + if constexpr (detail::has_resize_v) { + for (auto & x : xs) { + x.resize(n, std::numeric_limits::quiet_NaN()); + } + } + for (auto & y : ys) { + y.resize(n); + } + normal_distribution dis(DimensionlessReal(0), DimensionlessReal(1)); + do { + if (cancellation && *cancellation) { + break; + } + // TODO: The reference contends the following in + // Section B.2 "Strategy internal numerical effort": + // "In practice, the re-calculation of B and D needs to be done not until about + // max(1, floor(1/(10n(c_1+c_mu)))) generations." + // Note that sigma can be dimensionless, in which case C carries the units. + // This is a weird decision-we're not gonna do that! + Eigen::SelfAdjointEigenSolver> eigensolver(C); + if (eigensolver.info() != Eigen::Success) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": Could not decompose the covariance matrix as BDB^{T}."; + throw std::logic_error(oss.str()); + } + Eigen::Matrix B = eigensolver.eigenvectors(); + // Eigen returns D^2, in the notation of the survey: + auto D = eigensolver.eigenvalues(); + // So make it better: + for (auto & d : D) { + if (d <= 0 || isnan(d)) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The covariance matrix is not positive definite. This breaks the evolution path computation downstream.\n"; + oss << "C=\n" << C << "\n"; + oss << "Eigenvalues: " << D; + throw std::domain_error(oss.str()); + } + d = sqrt(d); + } + + for (size_t k = 0; k < params.population_size; ++k) { + auto & y = ys[k]; + auto & x = xs[k]; + BOOST_MATH_ASSERT(static_cast(x.size()) == n); + BOOST_MATH_ASSERT(static_cast(y.size()) == n); + size_t resample_counter = 0; + do { + // equation (39) of Figure 6: + // Also see equation (4): + for (size_t i = 0; i < n; ++i) { + z[i] = dis(gen); + } + Eigen::Vector Dz(n); + for (size_t i = 0; i < n; ++i) { + Dz[i] = D[i]*z[i]; + } + y = B*Dz; + for (size_t i = 0; i < n; ++i) { + BOOST_MATH_ASSERT(!isnan(mean_vector[i])); + BOOST_MATH_ASSERT(!isnan(y[i])); + x[i] = mean_vector[i] + sigma*y[i]; // equation (40) of Figure 6. + } + costs[k] = cost_function(x); + if (resample_counter++ == 50) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": 50 resamples was not sufficient to find an argument to the cost function which did not return NaN."; + oss << " Giving up."; + throw std::domain_error(oss.str()); + } + } while (isnan(costs[k])); + + if (queries) { + queries->emplace_back(std::make_pair(x, costs[k])); + } + if (costs[k] < lowest_cost) { + lowest_cost = costs[k]; + best_vector = x; + if (current_minimum_cost && costs[k] < *current_minimum_cost) { + *current_minimum_cost = costs[k]; + } + if (lowest_cost < target_value) { + target_attained = true; + break; + } + } + } + if (target_attained) { + break; + } + if (cancellation && *cancellation) { + break; + } + auto indices = detail::best_indices(costs); + // Equation (41), Figure 6: + for (size_t j = 0; j < n; ++j) { + weighted_avg_y[j] = 0; + for (size_t i = 0; i < mu; ++i) { + BOOST_MATH_ASSERT(!isnan(weights[i])); + BOOST_MATH_ASSERT(!isnan(ys[indices[i]][j])); + weighted_avg_y[j] += weights[i]*ys[indices[i]][j]; + } + } + // Equation (42), Figure 6: + for (size_t j = 0; j < n; ++j) { + mean_vector[j] = mean_vector[j] + c_m*sigma*weighted_avg_y[j]; + } + // Equation (43), Figure 6: Start with C^{-1/2}_{w} + Eigen::Vector inv_D_B_transpose_y = B.transpose()*weighted_avg_y; + for (long j = 0; j < inv_D_B_transpose_y.size(); ++j) { + inv_D_B_transpose_y[j] /= D[j]; + } + Eigen::Vector C_inv_sqrt_y_avg = B*inv_D_B_transpose_y; + // Equation (43), Figure 6: + DimensionlessReal p_sigma_norm = 0; + for (size_t j = 0; j < n; ++j) { + p_sigma[j] = (1-c_sigma)*p_sigma[j] + sqrt(c_sigma*(2-c_sigma)*mu_eff)*C_inv_sqrt_y_avg[j]; + p_sigma_norm += p_sigma[j]*p_sigma[j]; + } + p_sigma_norm = sqrt(p_sigma_norm); + // A: Algorithm Summary: E[||N(0,1)||]: + const DimensionlessReal expectation_norm_0I = sqrt(static_cast(n))*(DimensionlessReal(1) - DimensionlessReal(1)/(4*n) + DimensionlessReal(1)/(21*n*n)); + // Equation (44), Figure 6: + sigma = sigma*exp(c_sigma*(p_sigma_norm/expectation_norm_0I -1)/d_sigma); + // A: Algorithm Summary: + DimensionlessReal h_sigma = 0; + DimensionlessReal rhs = (DimensionlessReal(1.4) + DimensionlessReal(2)/(n+1))*expectation_norm_0I*sqrt(1 - pow(1-c_sigma, 2*(generation+1))); + if (p_sigma_norm < rhs) { + h_sigma = 1; + } + // Equation (45), Figure 6: + p_c = (1-c_c)*p_c + h_sigma*sqrt(c_c*(2-c_c)*mu_eff)*weighted_avg_y; + DimensionlessReal delta_h_sigma = (1-h_sigma)*c_c*(2-c_c); + DimensionlessReal weight_sum = 0; + for (auto & w : weights) { + weight_sum += w; + } + // Equation (47), Figure 6: + DimensionlessReal K = (1 + c_1*delta_h_sigma - c_1 - c_mu*weight_sum); + // Can these operations be sped up using `.selfadjointView`? + // Maybe: A.selfadjointView().rankUpdate(p_c, c_1);? + C = K*C + c_1*p_c*p_c.transpose(); + // Incorporate positive weights of Equation (46): + for (size_t i = 0; i < params.population_size/2; ++i) { + C += c_mu*weights[i]*ys[indices[i]]*ys[indices[i]].transpose(); + } + for (size_t i = params.population_size/2; i < params.population_size; ++i) { + Eigen::Vector D_inv_BTy = B.transpose()*ys[indices[i]]; + for (size_t j = 0; j < n; ++j) { + D_inv_BTy[j] /= D[j]; + } + DimensionlessReal squared_norm = D_inv_BTy.squaredNorm(); + DimensionlessReal K2 = c_mu*weights[i]/squared_norm; + C += K2*ys[indices[i]]*ys[indices[i]].transpose(); + } + } while (generation++ < params.max_generations); + + return best_vector; +} + +} // namespace boost::math::optimization +#endif diff --git a/third-party/boost-math/include/boost/math/optimization/detail/common.hpp b/third-party/boost-math/include/boost/math/optimization/detail/common.hpp new file mode 100644 index 0000000000000..05124026e7c7c --- /dev/null +++ b/third-party/boost-math/include/boost/math/optimization/detail/common.hpp @@ -0,0 +1,200 @@ +/* + * Copyright Nick Thompson, 2024 + * 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) + */ +#ifndef BOOST_MATH_OPTIMIZATION_DETAIL_COMMON_HPP +#define BOOST_MATH_OPTIMIZATION_DETAIL_COMMON_HPP +#include // for std::sort +#include +#include +#include +#include +#include +#include // for std::false_type + +namespace boost::math::optimization::detail { + +template struct has_resize : std::false_type {}; + +template +struct has_resize().resize(size_t{}))>> : std::true_type {}; + +template constexpr bool has_resize_v = has_resize::value; + +template +void validate_bounds(ArgumentContainer const &lower_bounds, ArgumentContainer const &upper_bounds) { + using std::isfinite; + std::ostringstream oss; + if (lower_bounds.size() == 0) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The dimension of the problem cannot be zero."; + throw std::domain_error(oss.str()); + } + if (upper_bounds.size() != lower_bounds.size()) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be the same number of lower bounds as upper bounds, but given "; + oss << upper_bounds.size() << " upper bounds, and " << lower_bounds.size() << " lower bounds."; + throw std::domain_error(oss.str()); + } + for (size_t i = 0; i < lower_bounds.size(); ++i) { + auto lb = lower_bounds[i]; + auto ub = upper_bounds[i]; + if (lb > ub) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The upper bound must be greater than or equal to the lower bound, but the upper bound is " << ub + << " and the lower is " << lb << "."; + throw std::domain_error(oss.str()); + } + if (!isfinite(lb)) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The lower bound must be finite, but got " << lb << "."; + oss << " For infinite bounds, emulate with std::numeric_limits::lower() or use a standard infinite->finite " + "transform."; + throw std::domain_error(oss.str()); + } + if (!isfinite(ub)) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The upper bound must be finite, but got " << ub << "."; + oss << " For infinite bounds, emulate with std::numeric_limits::max() or use a standard infinite->finite " + "transform."; + throw std::domain_error(oss.str()); + } + } +} + +template +std::vector random_initial_population(ArgumentContainer const &lower_bounds, + ArgumentContainer const &upper_bounds, + size_t initial_population_size, URBG &&gen) { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + constexpr bool has_resize = detail::has_resize_v; + std::vector population(initial_population_size); + auto const dimension = lower_bounds.size(); + for (size_t i = 0; i < population.size(); ++i) { + if constexpr (has_resize) { + population[i].resize(dimension); + } else { + // Argument type must be known at compile-time; like std::array: + if (population[i].size() != dimension) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": For containers which do not have resize, the default size must be the same as the dimension, "; + oss << "but the default container size is " << population[i].size() << " and the dimension of the problem is " + << dimension << "."; + oss << " The function argument container type is " << typeid(ArgumentContainer).name() << ".\n"; + throw std::runtime_error(oss.str()); + } + } + } + + // Why don't we provide an option to initialize with (say) a Gaussian distribution? + // > If the optimum's location is fairly well known, + // > a Gaussian distribution may prove somewhat faster, although it + // > may also increase the probability that the population will converge prematurely. + // > In general, uniform distributions are preferred, since they best reflect + // > the lack of knowledge about the optimum's location. + // - Differential Evolution: A Practical Approach to Global Optimization + // That said, scipy uses Latin Hypercube sampling and says self-avoiding sequences are preferable. + // So this is something that could be investigated and potentially improved. + using std::uniform_real_distribution; + uniform_real_distribution dis(DimensionlessReal(0), DimensionlessReal(1)); + for (size_t i = 0; i < population.size(); ++i) { + for (size_t j = 0; j < dimension; ++j) { + auto const &lb = lower_bounds[j]; + auto const &ub = upper_bounds[j]; + population[i][j] = lb + dis(gen) * (ub - lb); + } + } + + return population; +} + +template +void validate_initial_guess(ArgumentContainer const &initial_guess, ArgumentContainer const &lower_bounds, + ArgumentContainer const &upper_bounds) { + using std::isfinite; + std::ostringstream oss; + auto const dimension = lower_bounds.size(); + if (initial_guess.size() != dimension) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The initial guess must have the same dimensions as the problem,"; + oss << ", but the problem size is " << dimension << " and the initial guess has " << initial_guess.size() + << " elements."; + throw std::domain_error(oss.str()); + } + for (size_t i = 0; i < dimension; ++i) { + auto lb = lower_bounds[i]; + auto ub = upper_bounds[i]; + if (!isfinite(initial_guess[i])) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": At index " << i << ", the initial guess is " << initial_guess[i] + << ", make sure all elements of the initial guess are finite."; + throw std::domain_error(oss.str()); + } + if (initial_guess[i] < lb || initial_guess[i] > ub) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": At index " << i << " the initial guess " << initial_guess[i] << " is not in the bounds [" << lb << ", " + << ub << "]."; + throw std::domain_error(oss.str()); + } + } +} + +// Return indices corresponding to the minimum function values. +template std::vector best_indices(std::vector const &function_values) { + using std::isnan; + const size_t n = function_values.size(); + std::vector indices(n); + for (size_t i = 0; i < n; ++i) { + indices[i] = i; + } + + std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { + if (isnan(function_values[a])) { + return false; + } + if (isnan(function_values[b])) { + return true; + } + return function_values[a] < function_values[b]; + }); + return indices; +} + +template +auto weighted_lehmer_mean(RandomAccessContainer const & values, RandomAccessContainer const & weights) { + using std::isfinite; + if (values.size() != weights.size()) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be the same number of weights as values, but got " << values.size() << " values and " << weights.size() << " weights."; + throw std::logic_error(oss.str()); + } + if (values.size() == 0) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must at least one value provided."; + throw std::logic_error(oss.str()); + } + using Real = typename RandomAccessContainer::value_type; + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < values.size(); ++i) { + if (weights[i] < 0 || !isfinite(weights[i])) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": All weights must be positive and finite, but got received weight " << weights[i] << " at index " << i << " of " << weights.size() << "."; + throw std::domain_error(oss.str()); + } + Real tmp = weights[i]*values[i]; + numerator += tmp*values[i]; + denominator += tmp; + } + return numerator/denominator; +} + +} // namespace boost::math::optimization::detail +#endif diff --git a/third-party/boost-math/include/boost/math/optimization/differential_evolution.hpp b/third-party/boost-math/include/boost/math/optimization/differential_evolution.hpp new file mode 100644 index 0000000000000..f734f921115bb --- /dev/null +++ b/third-party/boost-math/include/boost/math/optimization/differential_evolution.hpp @@ -0,0 +1,236 @@ +/* + * Copyright Nick Thompson, 2024 + * 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) + */ +#ifndef BOOST_MATH_OPTIMIZATION_DIFFERENTIAL_EVOLUTION_HPP +#define BOOST_MATH_OPTIMIZATION_DIFFERENTIAL_EVOLUTION_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::optimization { + +// Storn, R., Price, K. (1997). Differential evolution-a simple and efficient heuristic for global optimization over +// continuous spaces. +// Journal of global optimization, 11, 341-359. +// See: +// https://www.cp.eng.chula.ac.th/~prabhas//teaching/ec/ec2012/storn_price_de.pdf + +// We provide the parameters in a struct-there are too many of them and they are too unwieldy to pass individually: +template struct differential_evolution_parameters { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + ArgumentContainer lower_bounds; + ArgumentContainer upper_bounds; + // mutation factor is also called scale factor or just F in the literature: + DimensionlessReal mutation_factor = static_cast(0.65); + DimensionlessReal crossover_probability = static_cast(0.5); + // Population in each generation: + size_t NP = 500; + size_t max_generations = 1000; + ArgumentContainer const *initial_guess = nullptr; + unsigned threads = std::thread::hardware_concurrency(); +}; + +template +void validate_differential_evolution_parameters(differential_evolution_parameters const &de_params) { + using std::isfinite; + using std::isnan; + std::ostringstream oss; + detail::validate_bounds(de_params.lower_bounds, de_params.upper_bounds); + if (de_params.NP < 4) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The population size must be at least 4, but requested population size of " << de_params.NP << "."; + throw std::invalid_argument(oss.str()); + } + // From: "Differential Evolution: A Practical Approach to Global Optimization (Natural Computing Series)" + // > The scale factor, F in (0,1+), is a positive real number that controls the rate at which the population evolves. + // > While there is no upper limit on F, effective values are seldom greater than 1.0. + // ... + // Also see "Limits on F", Section 2.5.1: + // > This discontinuity at F = 1 reduces the number of mutants by half and can result in erratic convergence... + auto F = de_params.mutation_factor; + if (isnan(F) || F >= 1 || F <= 0) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": F in (0, 1) is required, but got F=" << F << "."; + throw std::domain_error(oss.str()); + } + if (de_params.max_generations < 1) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be at least one generation."; + throw std::invalid_argument(oss.str()); + } + if (de_params.initial_guess) { + detail::validate_initial_guess(*de_params.initial_guess, de_params.lower_bounds, de_params.upper_bounds); + } + if (de_params.threads == 0) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be at least one thread."; + throw std::invalid_argument(oss.str()); + } +} + +template +ArgumentContainer differential_evolution( + const Func cost_function, differential_evolution_parameters const &de_params, URBG &gen, + std::invoke_result_t target_value = + std::numeric_limits>::quiet_NaN(), + std::atomic *cancellation = nullptr, + std::atomic> *current_minimum_cost = nullptr, + std::vector>> *queries = nullptr) { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + using ResultType = std::invoke_result_t; + using std::clamp; + using std::isnan; + using std::round; + using std::uniform_real_distribution; + validate_differential_evolution_parameters(de_params); + const size_t dimension = de_params.lower_bounds.size(); + auto NP = de_params.NP; + auto population = detail::random_initial_population(de_params.lower_bounds, de_params.upper_bounds, NP, gen); + if (de_params.initial_guess) { + population[0] = *de_params.initial_guess; + } + std::vector cost(NP, std::numeric_limits::quiet_NaN()); + std::atomic target_attained = false; + // This mutex is only used if the queries are stored: + std::mutex mt; + + std::vector thread_pool; + auto const threads = de_params.threads; + for (size_t j = 0; j < threads; ++j) { + // Note that if some members of the population take way longer to compute, + // then this parallelization strategy is very suboptimal. + // However, we tried using std::async (which should be robust to this particular problem), + // but the overhead was just totally unacceptable on ARM Macs (the only platform tested). + // As the economists say "there are no solutions, only tradeoffs". + thread_pool.emplace_back([&, j]() { + for (size_t i = j; i < cost.size(); i += threads) { + cost[i] = cost_function(population[i]); + if (current_minimum_cost && cost[i] < *current_minimum_cost) { + *current_minimum_cost = cost[i]; + } + if (queries) { + std::scoped_lock lock(mt); + queries->push_back(std::make_pair(population[i], cost[i])); + } + if (!isnan(target_value) && cost[i] <= target_value) { + target_attained = true; + } + } + }); + } + for (auto &thread : thread_pool) { + thread.join(); + } + + std::vector trial_vectors(NP); + for (size_t i = 0; i < NP; ++i) { + if constexpr (detail::has_resize_v) { + trial_vectors[i].resize(dimension); + } + } + std::vector thread_generators(threads); + for (size_t j = 0; j < threads; ++j) { + thread_generators[j].seed(gen()); + } + // std::vector isn't threadsafe! + std::vector updated_indices(NP, 0); + + for (size_t generation = 0; generation < de_params.max_generations; ++generation) { + if (cancellation && *cancellation) { + break; + } + if (target_attained) { + break; + } + thread_pool.resize(0); + for (size_t j = 0; j < threads; ++j) { + thread_pool.emplace_back([&, j]() { + auto& tlg = thread_generators[j]; + uniform_real_distribution unif01(DimensionlessReal(0), DimensionlessReal(1)); + for (size_t i = j; i < cost.size(); i += threads) { + if (target_attained) { + return; + } + if (cancellation && *cancellation) { + return; + } + size_t r1, r2, r3; + do { + r1 = tlg() % NP; + } while (r1 == i); + do { + r2 = tlg() % NP; + } while (r2 == i || r2 == r1); + do { + r3 = tlg() % NP; + } while (r3 == i || r3 == r2 || r3 == r1); + + for (size_t k = 0; k < dimension; ++k) { + // See equation (4) of the reference: + auto guaranteed_changed_idx = tlg() % dimension; + if (unif01(tlg) < de_params.crossover_probability || k == guaranteed_changed_idx) { + auto tmp = population[r1][k] + de_params.mutation_factor * (population[r2][k] - population[r3][k]); + auto const &lb = de_params.lower_bounds[k]; + auto const &ub = de_params.upper_bounds[k]; + // Some others recommend regenerating the indices rather than clamping; + // I dunno seems like it could get stuck regenerating . . . + trial_vectors[i][k] = clamp(tmp, lb, ub); + } else { + trial_vectors[i][k] = population[i][k]; + } + } + + auto const trial_cost = cost_function(trial_vectors[i]); + if (isnan(trial_cost)) { + continue; + } + if (queries) { + std::scoped_lock lock(mt); + queries->push_back(std::make_pair(trial_vectors[i], trial_cost)); + } + if (trial_cost < cost[i] || isnan(cost[i])) { + cost[i] = trial_cost; + if (!isnan(target_value) && cost[i] <= target_value) { + target_attained = true; + } + if (current_minimum_cost && cost[i] < *current_minimum_cost) { + *current_minimum_cost = cost[i]; + } + // Can't do this! It's a race condition! + //population[i] = trial_vectors[i]; + // Instead mark all the indices that need to be updated: + updated_indices[i] = 1; + } + } + }); + } + for (auto &thread : thread_pool) { + thread.join(); + } + for (size_t i = 0; i < NP; ++i) { + if (updated_indices[i]) { + population[i] = trial_vectors[i]; + updated_indices[i] = 0; + } + } + } + + auto it = std::min_element(cost.begin(), cost.end()); + return population[std::distance(cost.begin(), it)]; +} + +} // namespace boost::math::optimization +#endif diff --git a/third-party/boost-math/include/boost/math/optimization/jso.hpp b/third-party/boost-math/include/boost/math/optimization/jso.hpp new file mode 100644 index 0000000000000..e792298285142 --- /dev/null +++ b/third-party/boost-math/include/boost/math/optimization/jso.hpp @@ -0,0 +1,465 @@ +/* + * Copyright Nick Thompson, 2024 + * 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) + */ +#ifndef BOOST_MATH_OPTIMIZATION_JSO_HPP +#define BOOST_MATH_OPTIMIZATION_JSO_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::optimization { + +#ifndef BOOST_MATH_DEBUG_JSO +#define BOOST_MATH_DEBUG_JSO 0 +#endif +// Follows: Brest, Janez, Mirjam Sepesy Maucec, and Borko Boskovic. "Single +// objective real-parameter optimization: Algorithm jSO." 2017 IEEE congress on +// evolutionary computation (CEC). IEEE, 2017. In the sequel, this wil be +// referred to as "the reference". Note that the reference is rather difficult +// to understand without also reading: Zhang, J., & Sanderson, A. C. (2009). +// JADE: adaptive differential evolution with optional external archive. +// IEEE Transactions on evolutionary computation, 13(5), 945-958." +template struct jso_parameters { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + ArgumentContainer lower_bounds; + ArgumentContainer upper_bounds; + // Population in the first generation. + // This defaults to 0, which indicates "use the default specified in the + // referenced paper". To wit, initial population size + // =ceil(25log(D+1)sqrt(D)), where D is the dimension of the problem. + size_t initial_population_size = 0; + // Maximum number of function evaluations. + // The default of 0 indicates "use max_function_evaluations = 10,000D", where + // D is the dimension of the problem. + size_t max_function_evaluations = 0; + size_t threads = std::thread::hardware_concurrency(); + ArgumentContainer const *initial_guess = nullptr; +}; + +template +void validate_jso_parameters(jso_parameters &jso_params) { + using std::isfinite; + using std::isnan; + std::ostringstream oss; + if (jso_params.threads == 0) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": Requested zero threads to perform the calculation, but at least " + "1 is required."; + throw std::invalid_argument(oss.str()); + } + detail::validate_bounds(jso_params.lower_bounds, jso_params.upper_bounds); + auto const dimension = jso_params.lower_bounds.size(); + if (jso_params.initial_population_size == 0) { + // Ever so slightly different than the reference-the dimension can be 1, + // but if we followed the reference, the population size would then be zero. + jso_params.initial_population_size = static_cast( + std::ceil(25 * std::log(dimension + 1.0) * sqrt(dimension))); + } + if (jso_params.max_function_evaluations == 0) { + // Recommended value from the reference: + jso_params.max_function_evaluations = 10000 * dimension; + } + if (jso_params.initial_population_size < 4) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": The population size must be at least 4, but requested population " + "size of " + << jso_params.initial_population_size << "."; + throw std::invalid_argument(oss.str()); + } + if (jso_params.threads > jso_params.initial_population_size) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be more individuals in the population than threads."; + throw std::invalid_argument(oss.str()); + } + if (jso_params.initial_guess) { + detail::validate_initial_guess(*jso_params.initial_guess, + jso_params.lower_bounds, + jso_params.upper_bounds); + } +} + +template +ArgumentContainer +jso(const Func cost_function, jso_parameters &jso_params, + URBG &gen, + std::invoke_result_t target_value = + std::numeric_limits< + std::invoke_result_t>::quiet_NaN(), + std::atomic *cancellation = nullptr, + std::atomic> + *current_minimum_cost = nullptr, + std::vector>> + *queries = nullptr) { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + validate_jso_parameters(jso_params); + + using ResultType = std::invoke_result_t; + using std::abs; + using std::cauchy_distribution; + using std::clamp; + using std::isnan; + using std::max; + using std::round; + using std::isfinite; + using std::uniform_real_distribution; + + // Refer to the referenced paper, pseudocode on page 1313: + // Algorithm 1, jSO, Line 1: + std::vector archive; + + // Algorithm 1, jSO, Line 2 + // "Initialize population P_g = (x_0,g, ..., x_{np-1},g) randomly. + auto population = detail::random_initial_population( + jso_params.lower_bounds, jso_params.upper_bounds, + jso_params.initial_population_size, gen); + if (jso_params.initial_guess) { + population[0] = *jso_params.initial_guess; + } + size_t dimension = jso_params.lower_bounds.size(); + // Don't force the user to initialize to sane value: + if (current_minimum_cost) { + *current_minimum_cost = std::numeric_limits::infinity(); + } + std::atomic target_attained = false; + std::vector cost(jso_params.initial_population_size, + std::numeric_limits::quiet_NaN()); + for (size_t i = 0; i < cost.size(); ++i) { + cost[i] = cost_function(population[i]); + if (!isnan(target_value) && cost[i] <= target_value) { + target_attained = true; + } + if (current_minimum_cost && cost[i] < *current_minimum_cost) { + *current_minimum_cost = cost[i]; + } + if (queries) { + queries->push_back(std::make_pair(population[i], cost[i])); + } + } + std::vector indices = detail::best_indices(cost); + std::atomic function_evaluations = population.size(); +#if BOOST_MATH_DEBUG_JSO + { + auto const &min_cost = cost[indices[0]]; + auto const &location = population[indices[0]]; + std::cout << __FILE__ << ":" << __LINE__ << ":" << __func__; + std::cout << "\n\tMinimum cost after evaluation of initial random " + "population of size " + << population.size() << " is " << min_cost << "." + << "\n\tLocation {"; + for (size_t i = 0; i < location.size() - 1; ++i) { + std::cout << location[i] << ", "; + } + std::cout << location.back() << "}.\n"; + } +#endif + // Algorithm 1: jSO algorithm, Line 3: + // "Set all values in M_F to 0.5": + // I believe this is a typo: Compare with "Section B. Experimental Results", + // last bullet, which claims this should be set to 0.3. The reference + // implementation also does 0.3: + size_t H = 5; + std::vector M_F(H, static_cast(0.3)); + // Algorithm 1: jSO algorithm, Line 4: + // "Set all values in M_CR to 0.8": + std::vector M_CR(H, static_cast(0.8)); + + std::uniform_real_distribution unif01(DimensionlessReal(0), DimensionlessReal(1)); + bool keep_going = !target_attained; + if (cancellation && *cancellation) { + keep_going = false; + } + // k from: + // http://metahack.org/CEC2014-Tanabe-Fukunaga.pdf, Algorithm 1: + // Determines where Lehmer means are stored in the memory: + size_t k = 0; + size_t minimum_population_size = (max)(size_t(4), size_t(jso_params.threads)); + while (keep_going) { + // Algorithm 1, jSO, Line 7: + std::vector S_CR; + std::vector S_F; + // Equation 9 of L-SHADE: + std::vector delta_f; + for (size_t i = 0; i < population.size(); ++i) { + // Algorithm 1, jSO, Line 9: + auto ri = gen() % H; + // Algorithm 1, jSO, Line 10-13: + // Again, what is written in the pseudocode is not quite right. + // What they mean is mu_F = 0.9-the historical memory is not used. + // I confess I find it weird to store the historical memory if we're just + // gonna ignore it, but that's what the paper and the reference + // implementation says! + DimensionlessReal mu_F = static_cast(0.9); + DimensionlessReal mu_CR = static_cast(0.9); + if (ri != H - 1) { + mu_F = M_F[ri]; + mu_CR = M_CR[ri]; + } + // Algorithm 1, jSO, Line 14-18: + DimensionlessReal crossover_probability = static_cast(0); + if (mu_CR >= 0) { + using std::normal_distribution; + normal_distribution normal(mu_CR, static_cast(0.1)); + crossover_probability = normal(gen); + // Clamp comes from L-SHADE description: + crossover_probability = clamp(crossover_probability, DimensionlessReal(0), DimensionlessReal(1)); + } + // Algorithm 1, jSO, Line 19-23: + // Note that the pseudocode uses a "max_generations parameter", + // but the reference implementation does not. + // Since we already require specification of max_function_evaluations, + // the pseudocode adds an unnecessary parameter. + if (4 * function_evaluations < jso_params.max_function_evaluations) { + crossover_probability = (max)(crossover_probability, DimensionlessReal(0.7)); + } else if (2 * function_evaluations < + jso_params.max_function_evaluations) { + crossover_probability = (max)(crossover_probability, DimensionlessReal(0.6)); + } + + // Algorithm 1, jSO, Line 24-27: + // Note the adjustments to the pseudocode given in the reference + // implementation. + cauchy_distribution cauchy(mu_F, static_cast(0.1)); + DimensionlessReal F; + do { + F = cauchy(gen); + if (F > 1) { + F = 1; + } + } while (F <= 0); + DimensionlessReal threshold = static_cast(7) / static_cast(10); + if ((10 * function_evaluations < + 6 * jso_params.max_function_evaluations) && + (F > threshold)) { + F = threshold; + } + // > p value for mutation strategy linearly decreases from pmax to pmin + // during the evolutionary process, > where pmax = 0.25 in jSO and pmin = + // pmax/2. + DimensionlessReal p = DimensionlessReal(0.25) * (1 - static_cast(function_evaluations) / + (2 * jso_params.max_function_evaluations)); + // Equation (4) of the reference: + DimensionlessReal Fw = static_cast(1.2) * F; + if (10 * function_evaluations < 4 * jso_params.max_function_evaluations) { + if (10 * function_evaluations < + 2 * jso_params.max_function_evaluations) { + Fw = static_cast(0.7) * F; + } else { + Fw = static_cast(0.8) * F; + } + } + // Algorithm 1, jSO, Line 28: + // "ui,g := current-to-pBest-w/1/bin using Eq. (3)" + // This is not explained in the reference, but "current-to-pBest" + // strategy means "select randomly among the best values available." + // See: + // Zhang, J., & Sanderson, A. C. (2009). + // JADE: adaptive differential evolution with optional external archive. + // IEEE Transactions on evolutionary computation, 13(5), 945-958. + // > As a generalization of DE/current-to- best, + // > DE/current-to-pbest utilizes not only the best solution information + // > but also the information of other good solutions. + // > To be specific, any of the top 100p%, p in (0, 1], + // > solutions can be randomly chosen in DE/current-to-pbest to play the + // role > designed exclusively for the single best solution in + // DE/current-to-best." + size_t max_p_index = static_cast(std::ceil(p * indices.size())); + size_t p_best_idx = gen() % max_p_index; + // We now need r1, r2 so that r1 != r2 != i: + size_t r1; + do { + r1 = gen() % population.size(); + } while (r1 == i); + size_t r2; + do { + r2 = gen() % (population.size() + archive.size()); + } while (r2 == r1 || r2 == i); + + ArgumentContainer trial_vector; + if constexpr (detail::has_resize_v) { + trial_vector.resize(dimension); + } + auto const &xi = population[i]; + auto const &xr1 = population[r1]; + ArgumentContainer xr2; + if (r2 < population.size()) { + xr2 = population[r2]; + } else { + xr2 = archive[r2 - population.size()]; + } + auto const &x_p_best = population[p_best_idx]; + for (size_t j = 0; j < dimension; ++j) { + auto guaranteed_changed_idx = gen() % dimension; + if (unif01(gen) < crossover_probability || + j == guaranteed_changed_idx) { + auto tmp = xi[j] + Fw * (x_p_best[j] - xi[j]) + F * (xr1[j] - xr2[j]); + auto const &lb = jso_params.lower_bounds[j]; + auto const &ub = jso_params.upper_bounds[j]; + // Some others recommend regenerating the indices rather than + // clamping; I dunno seems like it could get stuck regenerating . . . + // Another suggestion is provided in: + // "JADE: Adaptive Differential Evolution with Optional External + // Archive" page 947. Perhaps we should implement it! + trial_vector[j] = clamp(tmp, lb, ub); + } else { + trial_vector[j] = population[i][j]; + } + } + auto trial_cost = cost_function(trial_vector); + function_evaluations++; + if (isnan(trial_cost)) { + continue; + } + if (queries) { + queries->push_back(std::make_pair(trial_vector, trial_cost)); + } + + // Successful trial: + if (trial_cost < cost[i] || isnan(cost[i])) { + if (!isnan(target_value) && trial_cost <= target_value) { + target_attained = true; + } + if (current_minimum_cost && trial_cost < *current_minimum_cost) { + *current_minimum_cost = trial_cost; + } + // Can't decide on improvement if the previous evaluation was a NaN: + if (!isnan(cost[i])) { + if (crossover_probability > 1 || crossover_probability < 0) { + throw std::domain_error("Crossover probability is weird."); + } + if (F > 1 || F < 0) { + throw std::domain_error("Scale factor (F) is weird."); + } + S_CR.push_back(crossover_probability); + S_F.push_back(F); + delta_f.push_back(abs(cost[i] - trial_cost)); + } + // Build the historical archive: + // The historical archive stores inferior solutions for the purpose of maintaining diversity. + if (archive.size() < cost.size()) { + archive.push_back(population[i]); + } else { + // If it's already built, then put the eliminated individual in a random index: + archive.resize(cost.size()); + auto idx = gen() % archive.size(); + archive[idx] = population[i]; + } + cost[i] = trial_cost; + population[i] = trial_vector; + } + } + + indices = detail::best_indices(cost); + + // If there are no successful updates this generation, we do not update the + // historical memory: + if (S_CR.size() > 0) { + std::vector weights(S_CR.size(), + std::numeric_limits::quiet_NaN()); + ResultType delta_sum = static_cast(0); + for (auto const &delta : delta_f) { + delta_sum += delta; + } + if (delta_sum <= 0 || !isfinite(delta_sum)) { + std::ostringstream oss; + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << "\n\tYou've hit a bug: The sum of improvements must be strictly " + "positive, but got " + << delta_sum << " improvement from " << S_CR.size() + << " successful updates.\n"; + oss << "\tImprovements: {" << std::hexfloat; + for (size_t l = 0; l < delta_f.size() -1; ++l) { + oss << delta_f[l] << ", "; + } + oss << delta_f.back() << "}.\n"; + throw std::logic_error(oss.str()); + } + for (size_t i = 0; i < weights.size(); ++i) { + weights[i] = delta_f[i] / delta_sum; + } + + M_CR[k] = detail::weighted_lehmer_mean(S_CR, weights); + M_F[k] = detail::weighted_lehmer_mean(S_F, weights); + } + k++; + if (k == M_F.size()) { + k = 0; + } + if (target_attained) { + break; + } + if (cancellation && *cancellation) { + break; + } + if (function_evaluations >= jso_params.max_function_evaluations) { + break; + } + // Linear population size reduction: + size_t new_population_size = static_cast(round( + -double(jso_params.initial_population_size - minimum_population_size) * + function_evaluations / + static_cast(jso_params.max_function_evaluations) + + jso_params.initial_population_size)); + size_t num_erased = population.size() - new_population_size; + std::vector indices_to_erase(num_erased); + size_t j = 0; + for (size_t i = population.size() - 1; i >= new_population_size; --i) { + indices_to_erase[j++] = indices[i]; + } + std::sort(indices_to_erase.rbegin(), indices_to_erase.rend()); + for (auto const &idx : indices_to_erase) { + population.erase(population.begin() + idx); + cost.erase(cost.begin() + idx); + } + indices.resize(new_population_size); + } + +#if BOOST_MATH_DEBUG_JSO + { + auto const &min_cost = cost[indices[0]]; + auto const &location = population[indices[0]]; + std::cout << __FILE__ << ":" << __LINE__ << ":" << __func__; + std::cout << "\n\tMinimum cost after completion is " << min_cost + << ".\n\tLocation: {"; + for (size_t i = 0; i < location.size() - 1; ++i) { + std::cout << location[i] << ", "; + } + std::cout << location.back() << "}.\n"; + std::cout << "\tRequired " << function_evaluations + << " function calls out of " + << jso_params.max_function_evaluations << " allowed.\n"; + if (target_attained) { + std::cout << "\tReason for return: Target value attained.\n"; + } + std::cout << "\tHistorical crossover probabilities (M_CR): {"; + for (size_t i = 0; i < M_CR.size() - 1; ++i) { + std::cout << M_CR[i] << ", "; + } + std::cout << M_CR.back() << "}.\n"; + std::cout << "\tHistorical scale factors (M_F): {"; + for (size_t i = 0; i < M_F.size() - 1; ++i) { + std::cout << M_F[i] << ", "; + } + std::cout << M_F.back() << "}.\n"; + std::cout << "\tFinal population size: " << population.size() << ".\n"; + } +#endif + return population[indices[0]]; +} + +} // namespace boost::math::optimization +#endif diff --git a/third-party/boost-math/include/boost/math/optimization/random_search.hpp b/third-party/boost-math/include/boost/math/optimization/random_search.hpp new file mode 100644 index 0000000000000..4ecd4ce36775a --- /dev/null +++ b/third-party/boost-math/include/boost/math/optimization/random_search.hpp @@ -0,0 +1,145 @@ +/* + * Copyright Nick Thompson, 2024 + * 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) + */ +#ifndef BOOST_MATH_OPTIMIZATION_RANDOM_SEARCH_HPP +#define BOOST_MATH_OPTIMIZATION_RANDOM_SEARCH_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::optimization { + +template struct random_search_parameters { + using Real = typename ArgumentContainer::value_type; + ArgumentContainer lower_bounds; + ArgumentContainer upper_bounds; + size_t max_function_calls = 10000*std::thread::hardware_concurrency(); + ArgumentContainer const *initial_guess = nullptr; + unsigned threads = std::thread::hardware_concurrency(); +}; + +template +void validate_random_search_parameters(random_search_parameters const ¶ms) { + using std::isfinite; + using std::isnan; + std::ostringstream oss; + detail::validate_bounds(params.lower_bounds, params.upper_bounds); + if (params.initial_guess) { + detail::validate_initial_guess(*params.initial_guess, params.lower_bounds, params.upper_bounds); + } + if (params.threads == 0) { + oss << __FILE__ << ":" << __LINE__ << ":" << __func__; + oss << ": There must be at least one thread."; + throw std::invalid_argument(oss.str()); + } +} + +template +ArgumentContainer random_search( + const Func cost_function, + random_search_parameters const ¶ms, + URBG &gen, + std::invoke_result_t target_value = std::numeric_limits>::quiet_NaN(), + std::atomic *cancellation = nullptr, + std::atomic> *current_minimum_cost = nullptr, + std::vector>> *queries = nullptr) + { + using Real = typename ArgumentContainer::value_type; + using DimensionlessReal = decltype(Real()/Real()); + using ResultType = std::invoke_result_t; + using std::isnan; + using std::uniform_real_distribution; + validate_random_search_parameters(params); + const size_t dimension = params.lower_bounds.size(); + std::atomic target_attained = false; + // Unfortunately, the "minimum_cost" variable can either be passed + // (for observability) or not (if the user doesn't care). + // That makes this a bit awkward . . . + std::atomic lowest_cost = std::numeric_limits::infinity(); + + ArgumentContainer best_vector; + if constexpr (detail::has_resize_v) { + best_vector.resize(dimension, std::numeric_limits::quiet_NaN()); + } + if (params.initial_guess) { + auto initial_cost = cost_function(*params.initial_guess); + if (!isnan(initial_cost)) { + lowest_cost = initial_cost; + best_vector = *params.initial_guess; + if (current_minimum_cost) { + *current_minimum_cost = initial_cost; + } + } + } + std::mutex mt; + std::vector thread_pool; + std::atomic function_calls = 0; + for (unsigned j = 0; j < params.threads; ++j) { + auto seed = gen(); + thread_pool.emplace_back([&, seed]() { + URBG g(seed); + ArgumentContainer trial_vector; + // This vector is empty unless the user requests the queries be stored: + std::vector>> local_queries; + if constexpr (detail::has_resize_v) { + trial_vector.resize(dimension, std::numeric_limits::quiet_NaN()); + } + while (function_calls < params.max_function_calls) { + if (cancellation && *cancellation) { + break; + } + if (target_attained) { + break; + } + // Fill trial vector: + uniform_real_distribution unif01(DimensionlessReal(0), DimensionlessReal(1)); + for (size_t i = 0; i < dimension; ++i) { + trial_vector[i] = params.lower_bounds[i] + (params.upper_bounds[i] - params.lower_bounds[i])*unif01(g); + } + ResultType trial_cost = cost_function(trial_vector); + ++function_calls; + if (isnan(trial_cost)) { + continue; + } + if (trial_cost < lowest_cost) { + lowest_cost = trial_cost; + if (current_minimum_cost) { + *current_minimum_cost = trial_cost; + } + // We expect to need to acquire this lock with decreasing frequency + // as the computation proceeds: + std::scoped_lock lock(mt); + best_vector = trial_vector; + } + if (queries) { + local_queries.push_back(std::make_pair(trial_vector, trial_cost)); + } + if (!isnan(target_value) && trial_cost <= target_value) { + target_attained = true; + } + } + if (queries) { + std::scoped_lock lock(mt); + queries->insert(queries->begin(), local_queries.begin(), local_queries.end()); + } + }); + } + for (auto &thread : thread_pool) { + thread.join(); + } + return best_vector; +} + +} // namespace boost::math::optimization +#endif diff --git a/third-party/boost-math/include/boost/math/policies/error_handling.hpp b/third-party/boost-math/include/boost/math/policies/error_handling.hpp new file mode 100644 index 0000000000000..d7ba694564ba4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/policies/error_handling.hpp @@ -0,0 +1,1058 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP +#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#ifndef BOOST_MATH_NO_EXCEPTIONS +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_MATH_NO_EXCEPTIONS +#include +#endif +#include +#ifndef BOOST_MATH_NO_RTTI +#include +#endif + +#ifdef _MSC_VER +# pragma warning(push) // Quiet warnings in boost/format.hpp +# pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE +# pragma warning(disable: 4512) // assignment operator could not be generated. +# pragma warning(disable: 4127) // conditional expression is constant +// And warnings in error handling: +# pragma warning(disable: 4702) // unreachable code. +// Note that this only occurs when the compiler can deduce code is unreachable, +// for example when policy macros are used to ignore errors rather than throw. +#endif + +namespace boost{ namespace math{ + +#ifndef BOOST_MATH_NO_EXCEPTIONS + +class evaluation_error : public std::runtime_error +{ +public: + explicit evaluation_error(const std::string& s) : std::runtime_error(s){} +}; + +class rounding_error : public std::runtime_error +{ +public: + explicit rounding_error(const std::string& s) : std::runtime_error(s){} +}; + +#else + +class evaluation_error {}; +class rounding_error {}; + +#endif + +namespace policies{ +// +// Forward declarations of user error handlers, +// it's up to the user to provide the definition of these: +// +template +T user_domain_error(const char* function, const char* message, const T& val); +template +T user_pole_error(const char* function, const char* message, const T& val); +template +T user_overflow_error(const char* function, const char* message, const T& val); +template +T user_underflow_error(const char* function, const char* message, const T& val); +template +T user_denorm_error(const char* function, const char* message, const T& val); +template +T user_evaluation_error(const char* function, const char* message, const T& val); +template +TargetType user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t); +template +T user_indeterminate_result_error(const char* function, const char* message, const T& val); + +namespace detail +{ + +template +inline std::string prec_format(const T& val) +{ + using prec_type = typename boost::math::policies::precision >::type; + + std::stringstream strm { }; + + if(prec_type::value) + { + const std::streamsize prec { static_cast(2UL + (prec_type::value * 30103UL) / 100000UL) }; + + strm << std::setprecision(prec); + } + + strm << val; + + return strm.str(); +} + +#ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION + +template <> +inline std::string prec_format(const std::float128_t& val) +{ + char buffer[128] {}; + const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val); + return std::string(buffer, r.ptr); +} + +#endif + +inline void replace_all_in_string(std::string& result, const char* what, const char* with) +{ + std::string::size_type pos = 0; + std::string::size_type slen = std::strlen(what); + std::string::size_type rlen = std::strlen(with); + while((pos = result.find(what, pos)) != std::string::npos) + { + result.replace(pos, slen, with); + pos += rlen; + } +} + +template +inline const char* name_of() +{ +#ifndef BOOST_MATH_NO_RTTI + return typeid(T).name(); +#else + return "unknown"; +#endif +} +template <> inline const char* name_of(){ return "float"; } +template <> inline const char* name_of(){ return "double"; } +template <> inline const char* name_of(){ return "long double"; } + +#ifdef BOOST_MATH_USE_FLOAT128 +template <> +inline const char* name_of() +{ + return "__float128"; +} +#endif + +#ifndef BOOST_MATH_NO_EXCEPTIONS +template +void raise_error(const char* pfunction, const char* message) +{ + if(pfunction == nullptr) + { + pfunction = "Unknown function operating on type %1%"; + } + if(message == nullptr) + { + message = "Cause unknown"; + } + + std::string function(pfunction); + std::string msg("Error in function "); +#ifndef BOOST_MATH_NO_RTTI + replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of()); +#else + replace_all_in_string(function, "%1%", "Unknown"); +#endif + msg += function; + msg += ": "; + msg += message; + + BOOST_MATH_THROW_EXCEPTION(E(msg)) +} + +template +void raise_error(const char* pfunction, const char* pmessage, const T& val) +{ + if(pfunction == nullptr) + { + pfunction = "Unknown function operating on type %1%"; + } + if(pmessage == nullptr) + { + pmessage = "Cause unknown: error caused by bad argument with value %1%"; + } + + std::string function(pfunction); + std::string message(pmessage); + std::string msg("Error in function "); +#ifndef BOOST_MATH_NO_RTTI + replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of()); +#else + replace_all_in_string(function, "%1%", "Unknown"); +#endif + msg += function; + msg += ": "; + + std::string sval = prec_format(val); + replace_all_in_string(message, "%1%", sval.c_str()); + msg += message; + + BOOST_MATH_THROW_EXCEPTION(E(msg)) +} +#endif + +template +BOOST_MATH_GPU_ENABLED inline T raise_domain_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return boost::math::numeric_limits::quiet_NaN(); +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error( + const char* , + const char* , + const T& , + const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::quiet_NaN(); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_domain_error( + const char* , + const char* , + const T& , + const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return boost::math::numeric_limits::quiet_NaN(); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_domain_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&) +{ + return user_domain_error(function, message, val); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>()); +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&) +{ + return user_pole_error(function, message, val); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* function, + const char* message, + const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric overflow"); + // We should never get here: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +#endif +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric overflow", val); + // We should never get here: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error( + const char* , + const char* , + const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error( + const char* , + const char* , + const T&, + const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* , + const char* , + const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* , + const char* , + const T&, + const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* function, + const char* message, + const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) +{ + return user_overflow_error(function, message, boost::math::numeric_limits::infinity()); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_overflow_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) +{ + std::string m(message ? message : ""); + std::string sval = prec_format(val); + replace_all_in_string(m, "%1%", sval.c_str()); + + return user_overflow_error(function, m.c_str(), boost::math::numeric_limits::infinity()); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_underflow_error( + const char* function, + const char* message, + const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric underflow"); + // We should never get here: + return 0; +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error( + const char* , + const char* , + const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return T(0); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_underflow_error( + const char* /* function */, + const char* /* message */, + const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return T(0); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_underflow_error( + const char* function, + const char* message, + const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&) +{ + return user_underflow_error(function, message, T(0)); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_denorm_error( + const char* function, + const char* message, + const T& /* val */, + const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "denormalised result"); + // we never get here: + return T(0); +#endif +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_denorm_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_denorm_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&) +{ + return user_denorm_error(function, message, val); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return T(0); +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&) +{ + return user_evaluation_error(function, message, val); +} + +template +BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return TargetType(0); +#endif +} + +template +BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + static_assert(boost::math::numeric_limits::is_specialized, "The target type must have std::numeric_limits specialized."); + return val > 0 ? (boost::math::numeric_limits::max)() : (boost::math::numeric_limits::is_integer ? (boost::math::numeric_limits::min)() : -(boost::math::numeric_limits::max)()); +} + +template +BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + static_assert(boost::math::numeric_limits::is_specialized, "The target type must have std::numeric_limits specialized."); + return val > 0 ? (boost::math::numeric_limits::max)() : (boost::math::numeric_limits::is_integer ? (boost::math::numeric_limits::min)() : -(boost::math::numeric_limits::max)()); +} +template +BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType& t, + const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&) +{ + return user_rounding_error(function, message, val, t); +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error( + const char* function, + const char* message, + const T& val, + const R& , + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_MATH_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return boost::math::numeric_limits::quiet_NaN(); +#endif +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error( + const char* , + const char* , + const T& , + const R& result, + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error( + const char* , + const char* , + const T& , + const R& result, + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error( + const char* function, + const char* message, + const T& val, + const R& , + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&) +{ + return user_indeterminate_result_error(function, message, val); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::domain_error_type policy_type; + return detail::raise_domain_error( + function, message ? message : "Domain Error evaluating function at %1%", + val, policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::pole_error_type policy_type; + return detail::raise_pole_error( + function, message ? message : "Evaluation of function at pole %1%", + val, policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::overflow_error_type policy_type; + return detail::raise_overflow_error( + function, message ? message : "Overflow Error", + policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::overflow_error_type policy_type; + return detail::raise_overflow_error( + function, message ? message : "Overflow evaluating function at %1%", + val, policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::underflow_error_type policy_type; + return detail::raise_underflow_error( + function, message ? message : "Underflow Error", + policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::denorm_error_type policy_type; + return detail::raise_denorm_error( + function, message ? message : "Denorm Error", + val, + policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::evaluation_error_type policy_type; + return detail::raise_evaluation_error( + function, message ? message : "Internal Evaluation Error, best value so far was %1%", + val, policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::rounding_error_type policy_type; + return detail::raise_rounding_error( + function, message ? message : "Value %1% can not be represented in the target integer type.", + val, t, policy_type()); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::indeterminate_result_error_type policy_type; + return detail::raise_indeterminate_result_error( + function, message ? message : "Indeterminate result with value %1%", + val, result, policy_type()); +} + +// +// checked_narrowing_cast: +// +namespace detail +{ + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_overflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + BOOST_MATH_STD_USING + if(fabs(val) > tools::max_value()) + { + boost::math::policies::detail::raise_overflow_error(function, nullptr, pol); + *result = static_cast(val); + return true; + } + return false; +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_overflow(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_overflow(val.real(), &re, function, pol); + r = check_overflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_underflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + if((val != 0) && (static_cast(val) == 0)) + { + *result = static_cast(boost::math::policies::detail::raise_underflow_error(function, nullptr, pol)); + return true; + } + return false; +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_underflow(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_underflow(val.real(), &re, function, pol); + r = check_underflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_denorm(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + BOOST_MATH_STD_USING + if((fabs(val) < static_cast(tools::min_value())) && (static_cast(val) != 0)) + { + *result = static_cast(boost::math::policies::detail::raise_denorm_error(function, 0, static_cast(val), pol)); + return true; + } + return false; +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_denorm(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_denorm(val.real(), &re, function, pol); + r = check_denorm(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} + +// Default instantiations with ignore_error policy. +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_overflow(std::complex /* val */, R* /* result */, const char* /* function */, const overflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_underflow(std::complex /* val */, R* /* result */, const char* /* function */, const underflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_denorm(std::complex /* val */, R* /* result*/, const char* /* function */, const denorm_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE R checked_narrowing_cast(T val, const char* function) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + typedef typename Policy::overflow_error_type overflow_type; + typedef typename Policy::underflow_error_type underflow_type; + typedef typename Policy::denorm_error_type denorm_type; + // + // Most of what follows will evaluate to a no-op: + // + R result = 0; + if(detail::check_overflow(val, &result, function, overflow_type())) + return result; + if(detail::check_underflow(val, &result, function, underflow_type())) + return result; + if(detail::check_denorm(val, &result, function, denorm_type())) + return result; + + return static_cast(val); +} + +template +BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + if(max_iter >= policies::get_max_series_iterations()) + raise_evaluation_error( + function, + "Series evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + if(max_iter >= policies::get_max_root_iterations()) + raise_evaluation_error( + function, + "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +} //namespace policies + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +}} // namespaces boost/math + +#else // Special values for NVRTC + +namespace boost { +namespace math { +namespace policies { + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error( + const char* , + const char* , + const T& , + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::quiet_NaN(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error( + const char* function, + const char* message, + const T& val, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + return boost::math::numeric_limits::quiet_NaN(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error( + const char* , + const char* , + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : (boost::math::numeric_limits::max)(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error( + const char* , + const char* , + const T&, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return boost::math::numeric_limits::has_infinity ? boost::math::numeric_limits::infinity() : (boost::math::numeric_limits::max)(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error( + const char* , + const char* , + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error( + const char* , + const char* , + const T& val, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error( + const char* , + const char* , + const T& val, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + static_assert(boost::math::numeric_limits::is_specialized, "The target type must have std::numeric_limits specialized."); + return val > 0 ? (boost::math::numeric_limits::max)() : (boost::math::numeric_limits::is_integer ? (boost::math::numeric_limits::min)() : -(boost::math::numeric_limits::max)()); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error( + const char* , + const char* , + const T& , + const R& result, + const Policy&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return result; +} + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE R checked_narrowing_cast(T val, const char* function) noexcept(boost::math::is_floating_point_v && boost::math::is_floating_point_v) +{ + // We only have ignore error policy so no reason to check + return static_cast(val); +} + +template +BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v) +{ + if(max_iter >= policies::get_max_series_iterations()) + raise_evaluation_error( + function, + "Series evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v) +{ + if(max_iter >= policies::get_max_root_iterations()) + raise_evaluation_error( + function, + "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +} // namespace policies +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +namespace boost { namespace math { namespace detail { + +// +// Simple helper function to assist in returning a pair from a single value, +// that value usually comes from one of the error handlers above: +// +template +BOOST_MATH_GPU_ENABLED boost::math::pair pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T) +{ + return boost::math::make_pair(val, val); +} + +}}} // boost::math::detail + +#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP + diff --git a/third-party/boost-math/include/boost/math/policies/policy.hpp b/third-party/boost-math/include/boost/math/policies/policy.hpp new file mode 100644 index 0000000000000..bec8886408161 --- /dev/null +++ b/third-party/boost-math/include/boost/math/policies/policy.hpp @@ -0,0 +1,1009 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_POLICY_HPP +#define BOOST_MATH_POLICY_HPP + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace mp = tools::meta_programming; + +namespace tools{ + +template +BOOST_MATH_GPU_ENABLED constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept; +template +BOOST_MATH_GPU_ENABLED constexpr T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value); + +} + +namespace policies{ + +// +// Define macros for our default policies, if they're not defined already: +// + + +// +// Generic support for GPUs +// +#ifdef BOOST_MATH_HAS_GPU_SUPPORT +# ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY +# define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error +# endif +# ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY +# define BOOST_MATH_PROMOTE_DOUBLE_POLICY false +# endif +# ifndef BOOST_MATH_DOMAIN_ERROR_POLICY +# define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error +# endif +# ifndef BOOST_MATH_POLE_ERROR_POLICY +# define BOOST_MATH_POLE_ERROR_POLICY ignore_error +# endif +# ifndef BOOST_MATH_EVALUATION_ERROR_POLICY +# define BOOST_MATH_EVALUATION_ERROR_POLICY ignore_error +# endif +# ifndef BOOST_MATH_ROUNDING_ERROR_POLICY +# define BOOST_MATH_ROUNDING_ERROR_POLICY ignore_error +# endif +#endif + +// +// Special cases for exceptions disabled first: +// +#ifdef BOOST_MATH_NO_EXCEPTIONS +# ifndef BOOST_MATH_DOMAIN_ERROR_POLICY +# define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_POLE_ERROR_POLICY +# define BOOST_MATH_POLE_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY +# define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_EVALUATION_ERROR_POLICY +# define BOOST_MATH_EVALUATION_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_ROUNDING_ERROR_POLICY +# define BOOST_MATH_ROUNDING_ERROR_POLICY errno_on_error +# endif +#endif +// +// Then the regular cases: +// +#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY +#define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_POLE_ERROR_POLICY +#define BOOST_MATH_POLE_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY +#define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY +#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_ROUNDING_ERROR_POLICY +#define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY +#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_DENORM_ERROR_POLICY +#define BOOST_MATH_DENORM_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY +#define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_DIGITS10_POLICY +#define BOOST_MATH_DIGITS10_POLICY 0 +#endif +#ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY +#define BOOST_MATH_PROMOTE_FLOAT_POLICY true +#endif +#ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#define BOOST_MATH_PROMOTE_DOUBLE_POLICY false +#else +#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true +#endif +#endif +#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY +#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards +#endif +#ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY +#define BOOST_MATH_ASSERT_UNDEFINED_POLICY true +#endif +#ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY +#define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000 +#endif +#ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY +#define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200 +#endif + +#define BOOST_MATH_META_INT(Type, name, Default) \ + template \ + class name : public boost::math::integral_constant { }; \ + \ + namespace detail{ \ + template \ + BOOST_MATH_GPU_ENABLED char test_is_valid_arg(const name* = nullptr); \ + BOOST_MATH_GPU_ENABLED char test_is_default_arg(const name* = nullptr); \ + \ + template \ + class is_##name##_imp \ + { \ + private: \ + template \ + BOOST_MATH_GPU_ENABLED static char test(const name* = nullptr); \ + BOOST_MATH_GPU_ENABLED static double test(...); \ + public: \ + static constexpr bool value = sizeof(test(static_cast(nullptr))) == sizeof(char); \ + }; \ + } \ + \ + template \ + class is_##name \ + { \ + public: \ + static constexpr bool value = boost::math::policies::detail::is_##name##_imp::value; \ + using type = boost::math::integral_constant; \ + }; + +#define BOOST_MATH_META_BOOL(name, Default) \ + template \ + class name : public boost::math::integral_constant{}; \ + \ + namespace detail{ \ + template \ + BOOST_MATH_GPU_ENABLED char test_is_valid_arg(const name* = nullptr); \ + BOOST_MATH_GPU_ENABLED char test_is_default_arg(const name* = nullptr); \ + \ + template \ + class is_##name##_imp \ + { \ + private: \ + template \ + BOOST_MATH_GPU_ENABLED static char test(const name* = nullptr); \ + BOOST_MATH_GPU_ENABLED static double test(...); \ + public: \ + static constexpr bool value = sizeof(test(static_cast(nullptr))) == sizeof(char); \ + }; \ + } \ + \ + template \ + class is_##name \ + { \ + public: \ + static constexpr bool value = boost::math::policies::detail::is_##name##_imp::value; \ + using type = boost::math::integral_constant; \ + }; + +// +// Begin by defining policy types for error handling: +// +enum error_policy_type +{ + throw_on_error = 0, + errno_on_error = 1, + ignore_error = 2, + user_error = 3 +}; + +BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY) + +// +// Policy types for internal promotion: +// +BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY) +BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY) +BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY) +// +// Policy types for discrete quantiles: +// +enum discrete_quantile_policy_type +{ + real, + integer_round_outwards, + integer_round_inwards, + integer_round_down, + integer_round_up, + integer_round_nearest +}; + +BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY) +// +// Precision: +// +BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY) +BOOST_MATH_META_INT(int, digits2, 0) +// +// Iterations: +// +BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY) +BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY) +// +// Define the names for each possible policy: +// +#define BOOST_MATH_PARAMETER(name)\ + BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\ + BOOST_PARAMETER_NAME(name##_name) + +struct default_policy{}; + +namespace detail{ +// +// Trait to work out bits precision from digits10 and digits2: +// +template +struct precision +{ + // + // Now work out the precision: + // + using digits2_type = typename boost::math::conditional< + (Digits10::value == 0), + digits2<0>, + digits2<((Digits10::value + 1) * 1000L) / 301L> + >::type; +public: +#ifdef BOOST_BORLANDC + using type = typename boost::math::conditional< + (Digits2::value > ::boost::math::policies::detail::precision::digits2_type::value), + Digits2, digits2_type>::type; +#else + using type = typename boost::math::conditional< + (Digits2::value > digits2_type::value), + Digits2, digits2_type>::type; +#endif +}; + +BOOST_MATH_GPU_ENABLED double test_is_valid_arg(...); +BOOST_MATH_GPU_ENABLED double test_is_default_arg(...); +BOOST_MATH_GPU_ENABLED char test_is_valid_arg(const default_policy*); +BOOST_MATH_GPU_ENABLED char test_is_default_arg(const default_policy*); + +template +class is_valid_policy_imp +{ +public: + static constexpr bool value = sizeof(boost::math::policies::detail::test_is_valid_arg(static_cast(nullptr))) == sizeof(char); +}; + +template +class is_valid_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_valid_policy_imp::value; +}; + +template +class is_default_policy_imp +{ +public: + static constexpr bool value = sizeof(boost::math::policies::detail::test_is_default_arg(static_cast(nullptr))) == sizeof(char); +}; + +template +class is_default_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_default_policy_imp::value; + using type = boost::math::integral_constant; + + template + struct apply + { + using type = is_default_policy; + }; +}; + +template +struct append_N +{ + using type = typename append_N, T, N-1>::type; +}; + +template +struct append_N +{ + using type = Seq; +}; + +// +// Traits class to work out what template parameters our default +// policy<> class will have when modified for forwarding: +// +template +struct default_args +{ + typedef promote_float arg1; + typedef promote_double arg2; +}; + +template <> +struct default_args +{ + typedef default_policy arg1; + typedef default_policy arg2; +}; + +template <> +struct default_args +{ + typedef promote_float arg1; + typedef default_policy arg2; +}; + +template <> +struct default_args +{ + typedef promote_double arg1; + typedef default_policy arg2; +}; + +typedef default_args::arg1 forwarding_arg1; +typedef default_args::arg2 forwarding_arg2; + +} // detail + +// +// Now define the policy type with enough arguments to handle all +// the policies: +// +template +class policy +{ +private: + // + // Validate all our arguments: + // + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + // + // Typelist of the arguments: + // + using arg_list = mp::mp_list; + static constexpr boost::math::size_t arg_list_size = mp::mp_size::value; + + template + struct pick_arg + { + using type = A; + }; + + template + struct pick_arg + { + using type = mp::mp_at; + }; + + template + class arg_type + { + private: + using index = mp::mp_find_if_q; + static constexpr bool end = (index::value >= arg_list_size); + public: + using type = typename pick_arg::type; + }; + + // Work out the base 2 and 10 precisions to calculate the public precision_type: + using digits10_type = typename arg_type, digits10<>>::type; + using bits_precision_type = typename arg_type, digits2<>>::type; + +public: + + // Error Types: + using domain_error_type = typename arg_type, domain_error<>>::type; + using pole_error_type = typename arg_type, pole_error<>>::type; + using overflow_error_type = typename arg_type, overflow_error<>>::type; + using underflow_error_type = typename arg_type, underflow_error<>>::type; + using denorm_error_type = typename arg_type, denorm_error<>>::type; + using evaluation_error_type = typename arg_type, evaluation_error<>>::type; + using rounding_error_type = typename arg_type, rounding_error<>>::type; + using indeterminate_result_error_type = typename arg_type, indeterminate_result_error<>>::type; + + // Precision: + using precision_type = typename detail::precision::type; + + // Internal promotion: + using promote_float_type = typename arg_type, promote_float<>>::type; + using promote_double_type = typename arg_type, promote_double<>>::type; + + // Discrete quantiles: + using discrete_quantile_type = typename arg_type, discrete_quantile<>>::type; + + // Mathematically undefined properties: + using assert_undefined_type = typename arg_type, assert_undefined<>>::type; + + // Max iterations: + using max_series_iterations_type = typename arg_type, max_series_iterations<>>::type; + using max_root_iterations_type = typename arg_type, max_root_iterations<>>::type; +}; + +// +// These full specializations are defined to reduce the amount of +// template instantiations that have to take place when using the default +// policies, they have quite a large impact on compile times: +// +template <> +class policy +{ +public: + using domain_error_type = domain_error<>; + using pole_error_type = pole_error<>; + using overflow_error_type = overflow_error<>; + using underflow_error_type = underflow_error<>; + using denorm_error_type = denorm_error<>; + using evaluation_error_type = evaluation_error<>; + using rounding_error_type = rounding_error<>; + using indeterminate_result_error_type = indeterminate_result_error<>; +#if BOOST_MATH_DIGITS10_POLICY == 0 + using precision_type = digits2<>; +#else + using precision_type = detail::precision, digits2<>>::type; +#endif + using promote_float_type = promote_float<>; + using promote_double_type = promote_double<>; + using discrete_quantile_type = discrete_quantile<>; + using assert_undefined_type = assert_undefined<>; + using max_series_iterations_type = max_series_iterations<>; + using max_root_iterations_type = max_root_iterations<>; +}; + +template <> +struct policy +{ +public: + using domain_error_type = domain_error<>; + using pole_error_type = pole_error<>; + using overflow_error_type = overflow_error<>; + using underflow_error_type = underflow_error<>; + using denorm_error_type = denorm_error<>; + using evaluation_error_type = evaluation_error<>; + using rounding_error_type = rounding_error<>; + using indeterminate_result_error_type = indeterminate_result_error<>; +#if BOOST_MATH_DIGITS10_POLICY == 0 + using precision_type = digits2<>; +#else + using precision_type = detail::precision, digits2<>>::type; +#endif + using promote_float_type = promote_float; + using promote_double_type = promote_double; + using discrete_quantile_type = discrete_quantile<>; + using assert_undefined_type = assert_undefined<>; + using max_series_iterations_type = max_series_iterations<>; + using max_root_iterations_type = max_root_iterations<>; +}; + +template +class normalise +{ +private: + using arg_list = mp::mp_list; + static constexpr boost::math::size_t arg_list_size = mp::mp_size::value; + + template + struct pick_arg + { + using type = A; + }; + + template + struct pick_arg + { + using type = mp::mp_at; + }; + + template + class arg_type + { + private: + using index = mp::mp_find_if_q; + static constexpr bool end = (index::value >= arg_list_size); + public: + using type = typename pick_arg::type; + }; + + // Error types: + using domain_error_type = typename arg_type, typename Policy::domain_error_type>::type; + using pole_error_type = typename arg_type, typename Policy::pole_error_type>::type; + using overflow_error_type = typename arg_type, typename Policy::overflow_error_type>::type; + using underflow_error_type = typename arg_type, typename Policy::underflow_error_type>::type; + using denorm_error_type = typename arg_type, typename Policy::denorm_error_type>::type; + using evaluation_error_type = typename arg_type, typename Policy::evaluation_error_type>::type; + using rounding_error_type = typename arg_type, typename Policy::rounding_error_type>::type; + using indeterminate_result_error_type = typename arg_type, typename Policy::indeterminate_result_error_type>::type; + + // Precision: + using digits10_type = typename arg_type, digits10<>>::type; + using bits_precision_type = typename arg_type, typename Policy::precision_type>::type; + using precision_type = typename detail::precision::type; + + // Internal promotion: + using promote_float_type = typename arg_type, typename Policy::promote_float_type>::type; + using promote_double_type = typename arg_type, typename Policy::promote_double_type>::type; + + // Discrete quantiles: + using discrete_quantile_type = typename arg_type, typename Policy::discrete_quantile_type>::type; + + // Mathematically undefined properties: + using assert_undefined_type = typename arg_type, typename Policy::assert_undefined_type>::type; + + // Max iterations: + using max_series_iterations_type = typename arg_type, typename Policy::max_series_iterations_type>::type; + using max_root_iterations_type = typename arg_type, typename Policy::max_root_iterations_type>::type; + + // Define a typelist of the policies: + using result_list = mp::mp_list< + domain_error_type, + pole_error_type, + overflow_error_type, + underflow_error_type, + denorm_error_type, + evaluation_error_type, + rounding_error_type, + indeterminate_result_error_type, + precision_type, + promote_float_type, + promote_double_type, + discrete_quantile_type, + assert_undefined_type, + max_series_iterations_type, + max_root_iterations_type>; + + // Remove all the policies that are the same as the default: + using fn = mp::mp_quote_trait; + using reduced_list = mp::mp_remove_if_q; + + // Pad out the list with defaults: + using result_type = typename detail::append_N::value)>::type; + +public: + using type = policy< + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c + >; +}; + +// Full specialisation to speed up compilation of the common case: +template <> +struct normalise, + promote_float, + promote_double, + discrete_quantile<>, + assert_undefined<>, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy> +{ + using type = policy; +}; + +template <> +struct normalise, + promote_float, + promote_double, + discrete_quantile<>, + assert_undefined<>, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy> +{ + using type = policy; +}; + +BOOST_MATH_GPU_ENABLED constexpr policy<> make_policy() noexcept +{ return {}; } + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1>::type make_policy(const A1&) noexcept +{ + typedef typename normalise, A1>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2>::type make_policy(const A1&, const A2&) noexcept +{ + typedef typename normalise, A1, A2>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&) noexcept +{ + typedef typename normalise, A1, A2, A3>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type; + return result_type(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&, const A11&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type; + return result_type(); +} + +// +// Traits class to handle internal promotion: +// +template +struct evaluation +{ + typedef Real type; +}; + +template +struct evaluation +{ + using type = typename boost::math::conditional::type; +}; + +template +struct evaluation +{ + using type = typename boost::math::conditional::type; +}; + +template +struct precision +{ + static_assert((boost::math::numeric_limits::radix == 2) || ((boost::math::numeric_limits::is_specialized == 0) || (boost::math::numeric_limits::digits == 0)), + "(boost::math::numeric_limits::radix == 2) || ((boost::math::numeric_limits::is_specialized == 0) || (boost::math::numeric_limits::digits == 0))"); +#ifndef BOOST_BORLANDC + using precision_type = typename Policy::precision_type; + using type = typename boost::math::conditional< + ((boost::math::numeric_limits::is_specialized == 0) || (boost::math::numeric_limits::digits == 0)), + // Possibly unknown precision: + precision_type, + typename boost::math::conditional< + ((boost::math::numeric_limits::digits <= precision_type::value) + || (Policy::precision_type::value <= 0)), + // Default case, full precision for RealType: + digits2< boost::math::numeric_limits::digits>, + // User customised precision: + precision_type + >::type + >::type; +#else + using precision_type = typename Policy::precision_type; + using digits_t = boost::math::integral_constant::digits>; + using spec_t = boost::math::integral_constant::is_specialized>; + using type = typename boost::math::conditional< + (spec_t::value == true boost::math::true_type || digits_t::value == 0), + // Possibly unknown precision: + precision_type, + typename boost::math::conditional< + (digits_t::value <= precision_type::value || precision_type::value <= 0), + // Default case, full precision for RealType: + digits2< boost::math::numeric_limits::digits>, + // User customised precision: + precision_type + >::type + >::type; +#endif +}; + +#ifdef BOOST_MATH_USE_FLOAT128 + +template +struct precision +{ + typedef boost::math::integral_constant type; +}; + +#endif + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED constexpr int digits_imp(boost::math::true_type const&) noexcept +{ + static_assert( boost::math::numeric_limits::is_specialized, "boost::math::numeric_limits::is_specialized"); + typedef typename boost::math::policies::precision::type p_t; + return p_t::value; +} + +template +BOOST_MATH_GPU_ENABLED constexpr int digits_imp(boost::math::false_type const&) noexcept +{ + return tools::digits(); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept +{ + typedef boost::math::integral_constant::is_specialized > tag_type; + return detail::digits_imp(tag_type()); +} +template +BOOST_MATH_GPU_ENABLED constexpr int digits_base10(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept +{ + return boost::math::policies::digits() * 301 / 1000L; +} + +template +BOOST_MATH_GPU_ENABLED constexpr unsigned long get_max_series_iterations() noexcept +{ + typedef typename Policy::max_series_iterations_type iter_type; + return iter_type::value; +} + +template +BOOST_MATH_GPU_ENABLED constexpr unsigned long get_max_root_iterations() noexcept +{ + typedef typename Policy::max_root_iterations_type iter_type; + return iter_type::value; +} + +namespace detail{ + +template +struct series_factor_calc +{ + BOOST_MATH_GPU_ENABLED static T get() noexcept(boost::math::is_floating_point::value) + { + return ldexp(T(1.0), 1 - Digits::value); + } +}; + +template +struct series_factor_calc +{ + BOOST_MATH_GPU_ENABLED static constexpr T get() noexcept(boost::math::is_floating_point::value) + { + return boost::math::tools::epsilon(); + } +}; +template +struct series_factor_calc +{ + BOOST_MATH_GPU_ENABLED static constexpr T get() noexcept(boost::math::is_floating_point::value) + { + return 1 / static_cast(static_cast(1u) << (Digits::value - 1)); + } +}; +template +struct series_factor_calc +{ + BOOST_MATH_GPU_ENABLED static constexpr T get() noexcept(boost::math::is_floating_point::value) + { + return boost::math::tools::epsilon(); + } +}; + +template +BOOST_MATH_GPU_ENABLED constexpr T get_epsilon_imp(boost::math::true_type const&) noexcept(boost::math::is_floating_point::value) +{ + static_assert(boost::math::numeric_limits::is_specialized, "boost::math::numeric_limits::is_specialized"); + static_assert(boost::math::numeric_limits::radix == 2, "boost::math::numeric_limits::radix == 2"); + + typedef typename boost::math::policies::precision::type p_t; + typedef boost::math::integral_constant::digits> is_small_int; + typedef boost::math::integral_constant= boost::math::numeric_limits::digits> is_default_value; + return series_factor_calc::get(); +} + +template +BOOST_MATH_GPU_ENABLED constexpr T get_epsilon_imp(boost::math::false_type const&) noexcept(boost::math::is_floating_point::value) +{ + return tools::epsilon(); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED constexpr T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + typedef boost::math::integral_constant::is_specialized && (boost::math::numeric_limits::radix == 2)) > tag_type; + return detail::get_epsilon_imp(tag_type()); +} + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED char test_is_policy(const policy*); +BOOST_MATH_GPU_ENABLED double test_is_policy(...); + +template +class is_policy_imp +{ +public: + static constexpr bool value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast(nullptr))) == sizeof(char)); +}; + +} + +template +class is_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_policy_imp

::value; + using type = boost::math::integral_constant; +}; + +// +// Helper traits class for distribution error handling: +// +template +struct constructor_error_check +{ + using domain_error_type = typename Policy::domain_error_type; + using type = typename boost::math::conditional< + (domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error) || (domain_error_type::value == errno_on_error), + boost::math::true_type, + boost::math::false_type>::type; +}; + +template +struct method_error_check +{ + using domain_error_type = typename Policy::domain_error_type; + using type = typename boost::math::conditional< + (domain_error_type::value == throw_on_error), + boost::math::false_type, + boost::math::true_type>::type; +}; +// +// Does the Policy ever throw on error? +// +template +struct is_noexcept_error_policy +{ + typedef typename Policy::domain_error_type t1; + typedef typename Policy::pole_error_type t2; + typedef typename Policy::overflow_error_type t3; + typedef typename Policy::underflow_error_type t4; + typedef typename Policy::denorm_error_type t5; + typedef typename Policy::evaluation_error_type t6; + typedef typename Policy::rounding_error_type t7; + typedef typename Policy::indeterminate_result_error_type t8; + + static constexpr bool value = + ((t1::value != throw_on_error) && (t1::value != user_error) + && (t2::value != throw_on_error) && (t2::value != user_error) + && (t3::value != throw_on_error) && (t3::value != user_error) + && (t4::value != throw_on_error) && (t4::value != user_error) + && (t5::value != throw_on_error) && (t5::value != user_error) + && (t6::value != throw_on_error) && (t6::value != user_error) + && (t7::value != throw_on_error) && (t7::value != user_error) + && (t8::value != throw_on_error) && (t8::value != user_error)); +}; + +}}} // namespaces + +#endif // BOOST_MATH_POLICY_HPP + diff --git a/third-party/boost-math/include/boost/math/quadrature/detail/exp_sinh_detail.hpp b/third-party/boost-math/include/boost/math/quadrature/detail/exp_sinh_detail.hpp new file mode 100644 index 0000000000000..77f2fbf060529 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/detail/exp_sinh_detail.hpp @@ -0,0 +1,2002 @@ +// Copyright Nick Thompson, 2017 +// 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) + +#ifndef BOOST_MATH_QUADRATURE_DETAIL_EXP_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_EXP_SINH_DETAIL_HPP + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + +// Returns the exp-sinh quadrature of a function f over the open interval (0, infinity) + +template +class exp_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + exp_sinh_detail(size_t max_refinements); + + template + auto integrate(const F& f, Real* error, Real* L1, const char* function, Real tolerance, std::size_t* levels) const ->decltype(std::declval()(std::declval())); + +private: + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const std::integral_constant&); +#endif + + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + using std::sinh; + using std::cosh; + using std::exp; + std::size_t row = ++m_committed_refinements; + + Real h = ldexp(static_cast(1), -static_cast(row)); + const Real t_max = m_t_min + m_abscissas[0].size() - 1; + + size_t k = static_cast(boost::math::lltrunc(ceil((t_max - m_t_min) / (2 * h)))); + m_abscissas[row].reserve(k); + m_weights[row].reserve(k); + Real arg = m_t_min; + size_t j = 0; + size_t l = 2; + while (arg + l*h < t_max) + { + arg = m_t_min + (2 * j + 1)*h; + Real x = exp(constants::half_pi()*sinh(arg)); + m_abscissas[row].emplace_back(x); + Real w = cosh(arg)*constants::half_pi()*x; + m_weights[row].emplace_back(w); + ++j; + } + } + + Real m_tol, m_t_min; + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + std::size_t m_max_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif +}; + +template +exp_sinh_detail::exp_sinh_detail(size_t max_refinements) + : m_abscissas(max_refinements), m_weights(max_refinements), + m_max_refinements(max_refinements) +{ + init(std::integral_constant()); +} +template +template +auto exp_sinh_detail::integrate(const F& f, Real* error, Real* L1, const char* function, Real tolerance, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + typedef decltype(f(static_cast(0))) K; + using std::abs; + using std::floor; + using std::tanh; + using std::sinh; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + // This provided a nice error message for real valued integrals, but it's super awkward for complex-valued integrals: + /*K y_max = f(tools::max_value()); + if(abs(y_max) > tools::epsilon() || !(boost::math::isfinite)(y_max)) + { + K val = abs(y_max); + return static_cast(policies::raise_domain_error(function, "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", val, Policy())); + }*/ + + //std::cout << std::setprecision(5*std::numeric_limits::digits10); + + // Get the party started with two estimates of the integral: + Real min_abscissa{ 0 }, max_abscissa{ boost::math::tools::max_value() }; + K I0 = 0; + Real L1_I0 = 0; + for(size_t i = 0; i < m_abscissas[0].size(); ++i) + { + K y = f(m_abscissas[0][i]); + K I0_last = I0; + I0 += y*m_weights[0][i]; + L1_I0 += abs(y)*m_weights[0][i]; + if ((I0_last == I0) && (abs(I0) != 0)) + { + max_abscissa = m_abscissas[0][i]; + break; + } + } + + //std::cout << "First estimate : " << I0 << std::endl; + K I1 = I0; + Real L1_I1 = L1_I0; + bool have_first_j = false; + std::size_t first_j = 0; + for (size_t i = 0; (i < m_abscissas[1].size()) && (m_abscissas[1][i] < max_abscissa); ++i) + { + K y = f(m_abscissas[1][i]); + K I1_last = I1; + I1 += y*m_weights[1][i]; + L1_I1 += abs(y)*m_weights[1][i]; + if (!have_first_j && (I1_last == I1)) + { + // No change to the sum, disregard these values on the LHS: + if ((i < m_abscissas[1].size() - 1) && (m_abscissas[1][i + 1] > max_abscissa)) + { + // The summit is so high, that we found nothing in this row which added to the integral!! + have_first_j = true; + } + else + { + min_abscissa = m_abscissas[1][i]; + first_j = i; + } + } + else + have_first_j = true; + } + + if (I0 == static_cast(0)) + { + // We failed to find anything, is the integral zero, or have we just not found it yet? + // We'll try one more level, if that still finds nothing then it'll terminate. + min_abscissa = 0; + max_abscissa = boost::math::tools::max_value(); + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + //std::cout << "Second estimate: " << I1 << " Error estimate at level " << 1 << " = " << err << std::endl; + + size_t i = 2; + for(; i < m_abscissas.size(); ++i) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1)/static_cast(1 << i); + K sum = 0; + Real absum = 0; + + auto abscissas_row = get_abscissa_row(i); + auto weight_row = get_weight_row(i); + + first_j = first_j == 0 ? 0 : 2 * first_j - 1; // appoximate location to start looking for lowest meaningful abscissa value + std::size_t j = first_j; + while (abscissas_row[j] < min_abscissa) + ++j; + for(; (j < m_weights[i].size()) && (abscissas_row[j] < max_abscissa); ++j) + { + Real x = abscissas_row[j]; + K y = f(x); + sum += y*weight_row[j]; + Real abterm0 = abs(y)*weight_row[j]; + absum += abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + //std::cout << "Estimate: " << I1 << " Error estimate at level " << i << " = " << err << std::endl; + // Use L1_I1 here to make it work with both complex and real valued integrands: + if (!(boost::math::isfinite)(L1_I1)) + { + return static_cast(policies::raise_evaluation_error(function, "The exp_sinh quadrature evaluated your function at a singular point and returned %1%. Please ensure your function evaluates to a finite number over its entire domain.", I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if(L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + using std::exp; + using std::log; + using std::sqrt; + using std::cosh; + using std::sinh; + using std::asinh; + using std::ceil; + using boost::math::constants::two_div_pi; + using boost::math::constants::half_pi; + using boost::math::constants::half; + + m_committed_refinements = 4; + // m_t_min is chosen such that x = exp(pi/2 sinh(-t_max)) = very small, but not too small. + // This is a compromise; we wish to approach a singularity at zero without hitting it through roundoff error. + // If we choose the small number as epsilon, we do not get close enough to the singularity to achieve high accuracy. + // If we choose the small number as the min(), then we round off to zero and hit the singularity. + // The logarithmic average of the min() and the epsilon() has been found to be a reasonable compromise, which achieves high accuracy + // but does not evaluate the function at the singularity. + Real tmp = (boost::math::tools::log_min_value() + log(boost::math::tools::epsilon()))*half(); + m_t_min = asinh(two_div_pi()*tmp); + + // t_max is chosen to make g'(t_max) ~ sqrt(max) (g' grows faster than g). + // This will allow some flexibility on the users part; they can at least square a number function without overflow. + // But there is no unique choice; the further out we can evaluate the function, the better we can do on slowly decaying integrands. + const Real t_max = log(2 * two_div_pi()*log(2 * two_div_pi()*sqrt(tools::max_value()))); + + for (size_t i = 0; i <= m_committed_refinements; ++i) + { + Real h = static_cast(1) / static_cast(1 << i); + size_t k = static_cast(boost::math::lltrunc(ceil((t_max - m_t_min) / (2 * h)))); + m_abscissas[i].reserve(k); + m_weights[i].reserve(k); + Real arg = m_t_min; + size_t j = 0; + size_t l = 2; + if (i == 0) + { + l = 1; + } + while (arg + l*h < t_max) + { + if (i != 0) + { + arg = m_t_min + (2 * j + 1)*h; + } + else + { + arg = m_t_min + j*h; + } + Real x = exp(half_pi()*sinh(arg)); + m_abscissas[i].emplace_back(x); + Real w = cosh(arg)*half_pi()*x; + m_weights[i].emplace_back(w); + ++j; + } + } + /* + std::cout << std::setprecision(40) << m_t_min << std::endl; + for (unsigned i = 0; i <= m_committed_refinements; ++i) + { + std::cout << "{ "; + for (unsigned j = 0; j < m_abscissas[i].size(); ++j) + std::cout << m_abscissas[i][j] << "Q, "; + std::cout << " },\n"; + } + for (unsigned i = 0; i <= m_committed_refinements; ++i) + { + std::cout << "{ "; + for (unsigned j = 0; j < m_weights[i].size(); ++j) + std::cout << m_weights[i][j] << "Q, "; + std::cout << " },\n"; + } + */ +} + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.47876573e-23f, 5.62503650e-09f, 9.95706124e-04f, 9.67438487e-02f, 7.43599217e-01f, 4.14293205e+00f, 1.08086768e+02f, 4.56291316e+05f, 2.70123007e+15f, }, + { 2.41870864e-14f, 1.02534662e-05f, 1.65637566e-02f, 3.11290799e-01f, 1.64691269e+00f, 1.49800773e+01f, 2.57724301e+03f, 2.24833766e+09f, }, + { 3.24983286e-18f, 2.51095186e-11f, 3.82035773e-07f, 1.33717837e-04f, 4.80260650e-03f, 4.41526928e-02f, 1.83045938e-01f, 4.91960276e-01f, 1.10322609e+00f, 2.53681744e+00f, 7.39791792e+00f, 3.59560256e+01f, 4.36061333e+02f, 2.49501460e+04f, 1.89216933e+07f, 1.03348694e+12f, }, + { 1.51941172e-20f, 3.70201714e-16f, 9.67598102e-13f, 4.44773051e-10f, 5.28493928e-08f, 2.19158236e-06f, 4.00799258e-05f, 3.88011529e-04f, 2.29325538e-03f, 9.25182629e-03f, 2.78117501e-02f, 6.67553298e-02f, 1.35173168e-01f, 2.41374946e-01f, 3.94194704e-01f, 6.07196731e-01f, 9.06432514e-01f, 1.34481045e+00f, 2.03268444e+00f, 3.21243032e+00f, 5.46310949e+00f, 1.03365745e+01f, 2.26486752e+01f, 6.03727778e+01f, 2.08220266e+02f, 1.00431239e+03f, 7.47843388e+03f, 9.75279951e+04f, 2.61755592e+06f, 1.77776624e+08f, 3.98255346e+10f, 4.13443763e+13f, 3.07708133e+17f, }, + { 7.99409438e-22f, 2.41624595e-19f, 3.73461321e-17f, 3.19397902e-15f, 1.62042378e-13f, 5.18579386e-12f, 1.10520072e-10f, 1.64548212e-09f, 1.78534009e-08f, 1.46529196e-07f, 9.40168786e-07f, 4.85507733e-06f, 2.07038029e-05f, 7.45799409e-05f, 2.31536599e-04f, 6.30580368e-04f, 1.53035449e-03f, 3.35582040e-03f, 6.73124842e-03f, 1.24856832e-02f, 2.16245309e-02f, 3.52720523e-02f, 5.45995171e-02f, 8.07587788e-02f, 1.14840025e-01f, 1.57867103e-01f, 2.10837078e-01f, 2.74805391e-01f, 3.51015955e-01f, 4.41077540e-01f, 5.47194016e-01f, 6.72466825e-01f, 8.21304567e-01f, 1.00000000e+00f, 1.21757511e+00f, 1.48706221e+00f, 1.82750536e+00f, 2.26717507e+00f, 2.84887335e+00f, 3.63893880e+00f, 4.74299876e+00f, 6.33444194e+00f, 8.70776542e+00f, 1.23825548e+01f, 1.83151803e+01f, 2.83510579e+01f, 4.62437776e+01f, 8.00917327e+01f, 1.48560852e+02f, 2.97989725e+02f, 6.53443372e+02f, 1.58584068e+03f, 4.31897162e+03f, 1.34084311e+04f, 4.83003053e+04f, 2.05969943e+05f, 1.06363880e+06f, 6.82457850e+06f, 5.60117371e+07f, 6.07724622e+08f, 9.04813016e+09f, 1.92834507e+11f, 6.17122515e+12f, 3.13089095e+14f, 2.67765347e+16f, 4.13865153e+18f, }, + { 1.70893932e-22f, 3.56621447e-21f, 6.19138882e-20f, 9.04299298e-19f, 1.12287188e-17f, 1.19706303e-16f, 1.10583090e-15f, 8.92931857e-15f, 6.35404710e-14f, 4.01527389e-13f, 2.26955738e-12f, 1.15522811e-11f, 5.32913181e-11f, 2.24130967e-10f, 8.64254491e-10f, 3.07161058e-09f, 1.01117742e-08f, 3.09775637e-08f, 8.87004371e-08f, 2.38368096e-07f, 6.03520392e-07f, 1.44488635e-06f, 3.28212299e-06f, 7.09655821e-06f, 1.46494407e-05f, 2.89537394e-05f, 5.49357161e-05f, 1.00313252e-04f, 1.76700203e-04f, 3.00920507e-04f, 4.96484845e-04f, 7.95150594e-04f, 1.23845781e-03f, 1.87911525e-03f, 2.78210510e-03f, 4.02538552e-03f, 5.70009588e-03f, 7.91020800e-03f, 1.07716137e-02f, 1.44106884e-02f, 1.89624177e-02f, 2.45682104e-02f, 3.13735515e-02f, 3.95256605e-02f, 4.91713196e-02f, 6.04550279e-02f, 7.35176150e-02f, 8.84954195e-02f, 1.05520113e-01f, 1.24719213e-01f, 1.46217318e-01f, 1.70138063e-01f, 1.96606781e-01f, 2.25753880e-01f, 2.57718900e-01f, 2.92655274e-01f, 3.30735809e-01f, 3.72158929e-01f, 4.17155794e-01f, 4.65998399e-01f, 5.19008863e-01f, 5.76570161e-01f, 6.39138643e-01f, 7.07258781e-01f, 7.81580731e-01f, 8.62881450e-01f, 9.52090320e-01f, 1.05032052e+00f, 1.15890775e+00f, 1.27945836e+00f, 1.41390963e+00f, 1.56460576e+00f, 1.73439430e+00f, 1.92674937e+00f, 2.14593012e+00f, 2.39718593e+00f, 2.68702407e+00f, 3.02356133e+00f, 3.41698950e+00f, 3.88019661e+00f, 4.42960272e+00f, 5.08629455e+00f, 5.87757956e+00f, 6.83913514e+00f, 8.01801085e+00f, 9.47686632e+00f, 1.13000199e+01f, 1.36021823e+01f, 1.65412214e+01f, 2.03370584e+01f, 2.53000199e+01f, 3.18739815e+01f, 4.07030054e+01f, 5.27358913e+01f, 6.93929374e+01f, 9.28366010e+01f, 1.26418926e+02f, 1.75435645e+02f, 2.48423411e+02f, 3.59440052e+02f, 5.32165336e+02f, 8.07455844e+02f, 1.25762341e+03f, 2.01416017e+03f, 3.32313676e+03f, 5.65930306e+03f, 9.96877263e+03f, 1.82030939e+04f, 3.45378531e+04f, 6.82619916e+04f, 1.40913380e+05f, 3.04680844e+05f, 6.92095957e+05f, 1.65694484e+06f, 4.19519229e+06f, 1.12739016e+07f, 3.22814282e+07f, 9.88946136e+07f, 3.25562103e+08f, 1.15706659e+09f, 4.46167708e+09f, 1.87647826e+10f, 8.65629909e+10f, 4.40614549e+11f, 2.49049013e+12f, 1.57380011e+13f, 1.11990629e+14f, 9.04297390e+14f, 8.35377903e+15f, 8.90573552e+16f, 1.10582857e+18f, 1.61514650e+19f, }, + { 7.75845008e-23f, 3.71846701e-22f, 1.69833677e-21f, 7.40284853e-21f, 3.08399399e-20f, 1.22962599e-19f, 4.69855182e-19f, 1.72288020e-18f, 6.07012059e-18f, 2.05742924e-17f, 6.71669437e-17f, 2.11441966e-16f, 6.42566550e-16f, 1.88715605e-15f, 5.36188198e-15f, 1.47533056e-14f, 3.93507835e-14f, 1.01841667e-13f, 2.55981752e-13f, 6.25453236e-13f, 1.48683211e-12f, 3.44173601e-12f, 7.76421789e-12f, 1.70831312e-11f, 3.66877698e-11f, 7.69632540e-11f, 1.57822184e-10f, 3.16577320e-10f, 6.21604166e-10f, 1.19551931e-09f, 2.25364361e-09f, 4.16647469e-09f, 7.55905964e-09f, 1.34658870e-08f, 2.35675936e-08f, 4.05458117e-08f, 6.86052525e-08f, 1.14227960e-07f, 1.87243781e-07f, 3.02323521e-07f, 4.81026747e-07f, 7.54564302e-07f, 1.16746531e-06f, 1.78236867e-06f, 2.68618781e-06f, 3.99792342e-06f, 5.87841837e-06f, 8.54236163e-06f, 1.22728487e-05f, 1.74387947e-05f, 2.45154696e-05f, 3.41083807e-05f, 4.69806683e-05f, 6.40841007e-05f, 8.65936597e-05f, 1.15945600e-04f, 1.53878746e-04f, 2.02478652e-04f, 2.64224143e-04f, 3.42035594e-04f, 4.39324211e-04f, 5.60041454e-04f, 7.08727668e-04f, 8.90558896e-04f, 1.11139085e-03f, 1.37779898e-03f, 1.69711358e-03f, 2.07744903e-03f, 2.52772622e-03f, 3.05768742e-03f, 3.67790298e-03f, 4.39976940e-03f, 5.23549846e-03f, 6.19809738e-03f, 7.30134015e-03f, 8.55973022e-03f, 9.98845520e-03f, 1.16033342e-02f, 1.34207587e-02f, 1.54576276e-02f, 1.77312787e-02f, 2.02594158e-02f, 2.30600348e-02f, 2.61513493e-02f, 2.95517158e-02f, 3.32795626e-02f, 3.73533204e-02f, 4.17913590e-02f, 4.66119283e-02f, 5.18331072e-02f, 5.74727595e-02f, 6.35484986e-02f, 7.00776615e-02f, 7.70772927e-02f, 8.45641386e-02f, 9.25546518e-02f, 1.01065008e-01f, 1.10111132e-01f, 1.19708739e-01f, 1.29873379e-01f, 1.40620505e-01f, 1.51965539e-01f, 1.63923958e-01f, 1.76511391e-01f, 1.89743720e-01f, 2.03637197e-01f, 2.18208574e-01f, 2.33475238e-01f, 2.49455360e-01f, 2.66168055e-01f, 2.83633553e-01f, 3.01873381e-01f, 3.20910560e-01f, 3.40769809e-01f, 3.61477772e-01f, 3.83063247e-01f, 4.05557445e-01f, 4.28994258e-01f, 4.53410546e-01f, 4.78846448e-01f, 5.05345717e-01f, 5.32956079e-01f, 5.61729623e-01f, 5.91723220e-01f, 6.22998983e-01f, 6.55624768e-01f, 6.89674714e-01f, 7.25229845e-01f, 7.62378724e-01f, 8.01218171e-01f, 8.41854062e-01f, 8.84402205e-01f, 9.28989312e-01f, 9.75754080e-01f, 1.02484839e+00f, 1.07643865e+00f, 1.13070727e+00f, 1.18785434e+00f, 1.24809950e+00f, 1.31168403e+00f, 1.37887320e+00f, 1.44995892e+00f, 1.52526270e+00f, 1.60513906e+00f, 1.68997931e+00f, 1.78021589e+00f, 1.87632722e+00f, 1.97884333e+00f, 2.08835213e+00f, 2.20550671e+00f, 2.33103353e+00f, 2.46574193e+00f, 2.61053497e+00f, 2.76642183e+00f, 2.93453226e+00f, 3.11613304e+00f, 3.31264716e+00f, 3.52567596e+00f, 3.75702486e+00f, 4.00873326e+00f, 4.28310945e+00f, 4.58277134e+00f, 4.91069419e+00f, 5.27026666e+00f, 5.66535674e+00f, 6.10038953e+00f, 6.58043928e+00f, 7.11133842e+00f, 7.69980735e+00f, 8.35360902e+00f, 9.08173387e+00f, 9.89462150e+00f, 1.08044272e+01f, 1.18253437e+01f, 1.29739897e+01f, 1.42698826e+01f, 1.57360130e+01f, 1.73995473e+01f, 1.92926887e+01f, 2.14537359e+01f, 2.39283915e+01f, 2.67713817e+01f, 3.00484719e+01f, 3.38389827e+01f, 3.82389447e+01f, 4.33650689e+01f, 4.93597649e+01f, 5.63975118e+01f, 6.46929803e+01f, 7.45114359e+01f, 8.61821250e+01f, 1.00115581e+02f, 1.16826112e+02f, 1.36961158e+02f, 1.61339834e+02f, 1.91003781e+02f, 2.27284639e+02f, 2.71894067e+02f, 3.27044548e+02f, 3.95612465e+02f, 4.81359585e+02f, 5.89235756e+02f, 7.25795284e+02f, 8.99773468e+02f, 1.12289036e+03f, 1.41097920e+03f, 1.78558211e+03f, 2.27622329e+03f, 2.92367233e+03f, 3.78466551e+03f, 4.93879227e+03f, 6.49862329e+03f, 8.62473434e+03f, 1.15481896e+04f, 1.56044945e+04f, 2.12853507e+04f, 2.93183077e+04f, 4.07905708e+04f, 5.73434125e+04f, 8.14806753e+04f, 1.17063646e+05f, 1.70113785e+05f, 2.50129854e+05f, 3.72274789e+05f, 5.61051155e+05f, 8.56556497e+05f, 1.32526810e+06f, 2.07888648e+06f, 3.30771485e+06f, 5.34063130e+06f, 8.75442405e+06f, 1.45761434e+07f, 2.46634599e+07f, 4.24311457e+07f, 7.42617251e+07f, 1.32291588e+08f, 2.40011058e+08f, 4.43725882e+08f, 8.36456588e+08f, 1.60874083e+09f, 3.15878598e+09f, 6.33624483e+09f, 1.29932136e+10f, 2.72570398e+10f, 5.85372779e+10f, 1.28795973e+11f, 2.90551047e+11f, 6.72570892e+11f, 1.59884056e+12f, 3.90652847e+12f, 9.81916374e+12f, 2.54124546e+13f, 6.77814197e+13f, 1.86501681e+14f, 5.29897885e+14f, 1.55625904e+15f, 4.72943011e+15f, 1.48882761e+16f, 4.86043448e+16f, 1.64741373e+17f, 5.80423410e+17f, 2.12831536e+18f, 8.13255421e+18f, }, + { 5.20331508e-23f, 1.15324162e-22f, 2.52466875e-22f, 5.46028730e-22f, 1.16690465e-21f, 2.46458927e-21f, 5.14543768e-21f, 1.06205431e-20f, 2.16767715e-20f, 4.37564009e-20f, 8.73699691e-20f, 1.72595588e-19f, 3.37377643e-19f, 6.52669145e-19f, 1.24976973e-18f, 2.36916845e-18f, 4.44691383e-18f, 8.26580373e-18f, 1.52174118e-17f, 2.77517606e-17f, 5.01415830e-17f, 8.97689232e-17f, 1.59270821e-16f, 2.80084735e-16f, 4.88253693e-16f, 8.43846463e-16f, 1.44610939e-15f, 2.45762595e-15f, 4.14251017e-15f, 6.92627770e-15f, 1.14889208e-14f, 1.89084205e-14f, 3.08802476e-14f, 5.00504297e-14f, 8.05169965e-14f, 1.28579121e-13f, 2.03847833e-13f, 3.20880532e-13f, 5.01568631e-13f, 7.78600100e-13f, 1.20044498e-12f, 1.83848331e-12f, 2.79712543e-12f, 4.22808302e-12f, 6.35035779e-12f, 9.47805307e-12f, 1.40588174e-11f, 2.07266430e-11f, 3.03739182e-11f, 4.42491437e-11f, 6.40886341e-11f, 9.22929507e-11f, 1.32161843e-10f, 1.88205259e-10f, 2.66552657e-10f, 3.75488615e-10f, 5.26149742e-10f, 7.33426418e-10f, 1.01712318e-09f, 1.40344387e-09f, 1.92688222e-09f, 2.63261606e-09f, 3.57952343e-09f, 4.84396276e-09f, 6.52448685e-09f, 8.74769197e-09f, 1.16754399e-08f, 1.55137320e-08f, 2.05235608e-08f, 2.70341184e-08f, 3.54587968e-08f, 4.63144836e-08f, 6.02447248e-08f, 7.80474059e-08f, 1.00707687e-07f, 1.29437018e-07f, 1.65719157e-07f, 2.11364220e-07f, 2.68571894e-07f, 3.40005066e-07f, 4.28875221e-07f, 5.39041105e-07f, 6.75122241e-07f, 8.42629031e-07f, 1.04811127e-06f, 1.29932703e-06f, 1.60543396e-06f, 1.97720518e-06f, 2.42727196e-06f, 2.97039558e-06f, 3.62377065e-06f, 4.40736236e-06f, 5.34428013e-06f, 6.46118994e-06f, 7.78876789e-06f, 9.36219733e-06f, 1.12217116e-05f, 1.34131848e-05f, 1.59887725e-05f, 1.90076038e-05f, 2.25365270e-05f, 2.66509096e-05f, 3.14354940e-05f, 3.69853096e-05f, 4.34066412e-05f, 5.08180543e-05f, 5.93514765e-05f, 6.91533342e-05f, 8.03857429e-05f, 9.32277499e-05f, 1.07876627e-04f, 1.24549208e-04f, 1.43483273e-04f, 1.64938971e-04f, 1.89200275e-04f, 2.16576471e-04f, 2.47403671e-04f, 2.82046341e-04f, 3.20898851e-04f, 3.64387021e-04f, 4.12969671e-04f, 4.67140163e-04f, 5.27427922e-04f, 5.94399942e-04f, 6.68662248e-04f, 7.50861330e-04f, 8.41685517e-04f, 9.41866302e-04f, 1.05217960e-03f, 1.17344692e-03f, 1.30653650e-03f, 1.45236427e-03f, 1.61189482e-03f, 1.78614219e-03f, 1.97617055e-03f, 2.18309485e-03f, 2.40808123e-03f, 2.65234740e-03f, 2.91716284e-03f, 3.20384886e-03f, 3.51377855e-03f, 3.84837661e-03f, 4.20911898e-03f, 4.59753235e-03f, 5.01519359e-03f, 5.46372894e-03f, 5.94481312e-03f, 6.46016832e-03f, 7.01156301e-03f, 7.60081065e-03f, 8.22976829e-03f, 8.90033499e-03f, 9.61445021e-03f, 1.03740920e-02f, 1.11812753e-02f, 1.20380497e-02f, 1.29464978e-02f, 1.39087327e-02f, 1.49268962e-02f, 1.60031562e-02f, 1.71397050e-02f, 1.83387564e-02f, 1.96025436e-02f, 2.09333170e-02f, 2.23333419e-02f, 2.38048956e-02f, 2.53502659e-02f, 2.69717481e-02f, 2.86716433e-02f, 3.04522558e-02f, 3.23158911e-02f, 3.42648538e-02f, 3.63014456e-02f, 3.84279634e-02f, 4.06466974e-02f, 4.29599296e-02f, 4.53699317e-02f, 4.78789641e-02f, 5.04892744e-02f, 5.32030959e-02f, 5.60226468e-02f, 5.89501290e-02f, 6.19877276e-02f, 6.51376099e-02f, 6.84019251e-02f, 7.17828036e-02f, 7.52823576e-02f, 7.89026802e-02f, 8.26458461e-02f, 8.65139116e-02f, 9.05089155e-02f, 9.46328794e-02f, 9.88878087e-02f, 1.03275694e-01f, 1.07798510e-01f, 1.12458223e-01f, 1.17256783e-01f, 1.22196135e-01f, 1.27278214e-01f, 1.32504950e-01f, 1.37878272e-01f, 1.43400107e-01f, 1.49072382e-01f, 1.54897032e-01f, 1.60875997e-01f, 1.67011231e-01f, 1.73304700e-01f, 1.79758387e-01f, 1.86374297e-01f, 1.93154462e-01f, 2.00100939e-01f, 2.07215821e-01f, 2.14501238e-01f, 2.21959362e-01f, 2.29592410e-01f, 2.37402653e-01f, 2.45392415e-01f, 2.53564085e-01f, 2.61920117e-01f, 2.70463037e-01f, 2.79195450e-01f, 2.88120044e-01f, 2.97239599e-01f, 3.06556989e-01f, 3.16075193e-01f, 3.25797297e-01f, 3.35726506e-01f, 3.45866147e-01f, 3.56219679e-01f, 3.66790698e-01f, 3.77582948e-01f, 3.88600328e-01f, 3.99846898e-01f, 4.11326892e-01f, 4.23044723e-01f, 4.35004995e-01f, 4.47212512e-01f, 4.59672288e-01f, 4.72389556e-01f, 4.85369781e-01f, 4.98618671e-01f, 5.12142186e-01f, 5.25946554e-01f, 5.40038281e-01f, 5.54424165e-01f, 5.69111309e-01f, 5.84107138e-01f, 5.99419409e-01f, 6.15056232e-01f, 6.31026081e-01f, 6.47337815e-01f, 6.64000696e-01f, 6.81024405e-01f, 6.98419060e-01f, 7.16195243e-01f, 7.34364016e-01f, 7.52936944e-01f, 7.71926120e-01f, 7.91344191e-01f, 8.11204381e-01f, 8.31520518e-01f, 8.52307069e-01f, 8.73579162e-01f, 8.95352625e-01f, 9.17644013e-01f, 9.40470650e-01f, 9.63850664e-01f, 9.87803022e-01f, 1.01234758e+00f, 1.03750512e+00f, 1.06329740e+00f, 1.08974721e+00f, 1.11687839e+00f, 1.14471595e+00f, 1.17328606e+00f, 1.20261614e+00f, 1.23273496e+00f, 1.26367264e+00f, 1.29546076e+00f, 1.32813247e+00f, 1.36172249e+00f, 1.39626730e+00f, 1.43180514e+00f, 1.46837616e+00f, 1.50602252e+00f, 1.54478848e+00f, 1.58472055e+00f, 1.62586760e+00f, 1.66828098e+00f, 1.71201469e+00f, 1.75712551e+00f, 1.80367319e+00f, 1.85172058e+00f, 1.90133388e+00f, 1.95258276e+00f, 2.00554062e+00f, 2.06028484e+00f, 2.11689693e+00f, 2.17546288e+00f, 2.23607339e+00f, 2.29882418e+00f, 2.36381627e+00f, 2.43115639e+00f, 2.50095725e+00f, 2.57333803e+00f, 2.64842468e+00f, 2.72635049e+00f, 2.80725648e+00f, 2.89129193e+00f, 2.97861498e+00f, 3.06939317e+00f, 3.16380413e+00f, 3.26203621e+00f, 3.36428929e+00f, 3.47077553e+00f, 3.58172026e+00f, 3.69736291e+00f, 3.81795798e+00f, 3.94377618e+00f, 4.07510558e+00f, 4.21225285e+00f, 4.35554468e+00f, 4.50532923e+00f, 4.66197775e+00f, 4.82588634e+00f, 4.99747780e+00f, 5.17720373e+00f, 5.36554672e+00f, 5.56302277e+00f, 5.77018396e+00f, 5.98762126e+00f, 6.21596768e+00f, 6.45590164e+00f, 6.70815069e+00f, 6.97349551e+00f, 7.25277437e+00f, 7.54688785e+00f, 7.85680417e+00f, 8.18356491e+00f, 8.52829128e+00f, 8.89219104e+00f, 9.27656603e+00f, 9.68282047e+00f, 1.01124700e+01f, 1.05671518e+01f, 1.10486353e+01f, 1.15588347e+01f, 1.20998217e+01f, 1.26738407e+01f, 1.32833247e+01f, 1.39309131e+01f, 1.46194716e+01f, 1.53521138e+01f, 1.61322255e+01f, 1.69634913e+01f, 1.78499242e+01f, 1.87958987e+01f, 1.98061868e+01f, 2.08859991e+01f, 2.20410294e+01f, 2.32775056e+01f, 2.46022448e+01f, 2.60227166e+01f, 2.75471124e+01f, 2.91844234e+01f, 3.09445281e+01f, 3.28382897e+01f, 3.48776660e+01f, 3.70758319e+01f, 3.94473180e+01f, 4.20081658e+01f, 4.47761023e+01f, 4.77707378e+01f, 5.10137879e+01f, 5.45293247e+01f, 5.83440613e+01f, 6.24876734e+01f, 6.69931639e+01f, 7.18972765e+01f, 7.72409663e+01f, 8.30699343e+01f, 8.94352364e+01f, 9.63939781e+01f, 1.04010108e+02f, 1.12355322e+02f, 1.21510104e+02f, 1.31564914e+02f, 1.42621552e+02f, 1.54794728e+02f, 1.68213867e+02f, 1.83025185e+02f, 1.99394097e+02f, 2.17507985e+02f, 2.37579409e+02f, 2.59849828e+02f, 2.84593917e+02f, 3.12124587e+02f, 3.42798827e+02f, 3.77024517e+02f, 4.15268384e+02f, 4.58065302e+02f, 5.06029199e+02f, 5.59865843e+02f, 6.20387872e+02f, 6.88532497e+02f, 7.65382367e+02f, 8.52190227e+02f, 9.50408087e+02f, 1.06172182e+03f, 1.18809220e+03f, 1.33180384e+03f, 1.49552334e+03f, 1.68236894e+03f, 1.89599367e+03f, 2.14068513e+03f, 2.42148533e+03f, 2.74433485e+03f, 3.11624675e+03f, 3.54551666e+03f, 4.04197722e+03f, 4.61730674e+03f, 5.28540457e+03f, 6.06284853e+03f, 6.96945350e+03f, 8.02895513e+03f, 9.26984864e+03f, 1.07264200e+04f, 1.24400169e+04f, 1.44606187e+04f, 1.68487805e+04f, 1.96780458e+04f, 2.30379493e+04f, 2.70377620e+04f, 3.18111749e+04f, 3.75221715e+04f, 4.43724093e+04f, 5.26105241e+04f, 6.25438881e+04f, 7.45535092e+04f, 8.91129656e+04f, 1.06812532e+05f, 1.28390012e+05f, 1.54770253e+05f, 1.87115940e+05f, 2.26893075e+05f, 2.75955654e+05f, 3.36655497e+05f, 4.11985149e+05f, 5.05764405e+05f, 6.22884544e+05f, 7.69629183e+05f, 9.54097173e+05f, 1.18676186e+06f, 1.48121324e+06f, 1.85514609e+06f, 2.33168052e+06f, 2.94113264e+06f, 3.72339780e+06f, 4.73116974e+06f, 6.03430539e+06f, 7.72576515e+06f, 9.92972861e+06f, 1.28127257e+07f, 1.65989637e+07f, 2.15915179e+07f, 2.82017465e+07f, 3.69902945e+07f, 4.87244884e+07f, 6.44590226e+07f, 8.56498776e+07f, 1.14315868e+08f, 1.53268759e+08f, 2.06442545e+08f, 2.79366798e+08f, 3.79850300e+08f, 5.18973079e+08f, 7.12532948e+08f, 9.83165083e+08f, 1.36346329e+09f, 1.90059962e+09f, 2.66319659e+09f, 3.75160395e+09f, 5.31334782e+09f, 7.56648043e+09f, 1.08350637e+10f, 1.56033907e+10f, 2.25993074e+10f, 3.29229832e+10f, 4.82470799e+10f, 7.11297379e+10f, 1.05506900e+11f, 1.57471442e+11f, 2.36513804e+11f, 3.57509889e+11f, 5.43926613e+11f, 8.33024431e+11f, 1.28435637e+12f, 1.99374510e+12f, 3.11642465e+12f, 4.90561997e+12f, 7.77731247e+12f, 1.24197380e+13f, 1.99798484e+13f, 3.23831600e+13f, 5.28864904e+13f, 8.70403770e+13f, 1.44377694e+14f, 2.41399528e+14f, 4.06896744e+14f, 6.91510621e+14f, 1.18504970e+15f, 2.04811559e+15f, 3.57034809e+15f, 6.27861398e+15f, 1.11397125e+16f, 1.99435267e+16f, 3.60337498e+16f, 6.57141972e+16f, 1.20980371e+17f, 2.24875057e+17f, 4.22089025e+17f, 8.00147402e+17f, 1.53216987e+18f, 2.96403754e+18f, 5.79389087e+18f, 1.14455803e+19f, 2.28537992e+19f, }, + }; + m_weights = { + { 1.79979618e-21f, 1.07218106e-07f, 7.05786060e-03f, 2.72310168e-01f, 1.18863515e+00f, 8.77655464e+00f, 5.33879432e+02f, 5.98892409e+06f, 9.60751551e+16f, }, + { 7.59287827e-13f, 1.18886775e-04f, 7.27332179e-02f, 6.09156795e-01f, 2.71431234e+00f, 4.68800805e+01f, 2.06437304e+04f, 4.85431236e+10f, }, + { 1.30963564e-16f, 6.14135316e-10f, 5.67743391e-06f, 1.21108690e-03f, 2.67259824e-02f, 1.54234107e-01f, 4.23412860e-01f, 8.47913037e-01f, 1.73632925e+00f, 4.63203354e+00f, 1.88206826e+01f, 1.40643917e+02f, 2.73736946e+03f, 2.55633252e+05f, 3.18438602e+08f, 2.86363931e+13f, }, + { 6.93769555e-19f, 1.31670336e-14f, 2.68107110e-11f, 9.60294960e-09f, 8.89417585e-07f, 2.87650015e-05f, 4.10649371e-04f, 3.10797444e-03f, 1.43958814e-02f, 4.56980985e-02f, 1.08787148e-01f, 2.08910486e-01f, 3.43887471e-01f, 5.11338439e-01f, 7.19769211e-01f, 1.00073403e+00f, 1.42660267e+00f, 2.14966467e+00f, 3.50341221e+00f, 6.28632057e+00f, 1.26369961e+01f, 2.90949180e+01f, 7.91163114e+01f, 2.65103292e+02f, 1.15872311e+03f, 7.11886439e+03f, 6.77324248e+04f, 1.13081650e+06f, 3.88995005e+07f, 3.38857764e+09f, 9.74063570e+11f, 1.29789430e+15f, 1.24001927e+19f, }, + { 3.88541434e-20f, 1.03646493e-17f, 1.41388360e-15f, 1.06725054e-13f, 4.77908002e-12f, 1.34999345e-10f, 2.53970414e-09f, 3.33804787e-08f, 3.19755978e-07f, 2.31724882e-06f, 1.31302324e-05f, 5.98917639e-05f, 2.25650360e-04f, 7.18397083e-04f, 1.97196929e-03f, 4.75106406e-03f, 1.02072514e-02f, 1.98317011e-02f, 3.52844239e-02f, 5.81350403e-02f, 8.95955146e-02f, 1.30335749e-01f, 1.80445384e-01f, 2.39557131e-01f, 3.07102681e-01f, 3.82648608e-01f, 4.66260909e-01f, 5.58867257e-01f, 6.62616429e-01f, 7.81267733e-01f, 9.20677638e-01f, 1.08949034e+00f, 1.30019425e+00f, 1.57079633e+00f, 1.92752387e+00f, 2.40924883e+00f, 3.07485695e+00f, 4.01578082e+00f, 5.37784753e+00f, 7.40045071e+00f, 1.04890228e+01f, 1.53538346e+01f, 2.32861156e+01f, 3.67307348e+01f, 6.05296516e+01f, 1.04761593e+02f, 1.91598840e+02f, 3.72918009e+02f, 7.78738763e+02f, 1.76101294e+03f, 4.35837629e+03f, 1.19484066e+04f, 3.67841605e+04f, 1.29157756e+05f, 5.26424122e+05f, 2.54082527e+06f, 1.48545930e+07f, 1.07925566e+08f, 1.00317513e+09f, 1.23283860e+10f, 2.07922173e+11f, 5.01997049e+12f, 1.82006578e+14f, 1.04617001e+16f, 1.01373023e+18f, 1.77530238e+20f, }, + { 8.56958007e-21f, 1.68000718e-19f, 2.74008750e-18f, 3.75978801e-17f, 4.38589881e-16f, 4.39263787e-15f, 3.81223973e-14f, 2.89198757e-13f, 1.93338859e-12f, 1.14783389e-11f, 6.09544349e-11f, 2.91499607e-10f, 1.26339559e-09f, 4.99234840e-09f, 1.80872790e-08f, 6.03998541e-08f, 1.86829770e-07f, 5.37807971e-07f, 1.44704121e-06f, 3.65421571e-06f, 8.69454276e-06f, 1.95621880e-05f, 4.17628758e-05f, 8.48713297e-05f, 1.64680159e-04f, 3.05960283e-04f, 5.45748909e-04f, 9.36950301e-04f, 1.55189915e-03f, 2.48542560e-03f, 3.85690505e-03f, 5.81079770e-03f, 8.51529070e-03f, 1.21588421e-02f, 1.69446644e-02f, 2.30834400e-02f, 3.07847946e-02f, 4.02482241e-02f, 5.16542634e-02f, 6.51566792e-02f, 8.08763802e-02f, 9.88975757e-02f, 1.19266512e-01f, 1.41992893e-01f, 1.67053901e-01f, 1.94400532e-01f, 2.23965873e-01f, 2.55674859e-01f, 2.89455038e-01f, 3.25247905e-01f, 3.63020457e-01f, 4.02776696e-01f, 4.44568958e-01f, 4.88509042e-01f, 5.34779290e-01f, 5.83643845e-01f, 6.35460497e-01f, 6.90693630e-01f, 7.49928915e-01f, 8.13890578e-01f, 8.83462209e-01f, 9.59712352e-01f, 1.04392634e+00f, 1.13764623e+00f, 1.24272128e+00f, 1.36137177e+00f, 1.49627028e+00f, 1.65064527e+00f, 1.82841374e+00f, 2.03435175e+00f, 2.27431458e+00f, 2.55552245e+00f, 2.88693336e+00f, 3.27973254e+00f, 3.74797919e+00f, 4.30946679e+00f, 4.98687594e+00f, 5.80933099e+00f, 6.81451887e+00f, 8.05159726e+00f, 9.58522167e+00f, 1.15011733e+01f, 1.39143002e+01f, 1.69798351e+01f, 2.09096993e+01f, 2.59962450e+01f, 3.26472377e+01f, 4.14380231e+01f, 5.31903193e+01f, 6.90928164e+01f, 9.08883744e+01f, 1.21168895e+02f, 1.63847041e+02f, 2.24923217e+02f, 3.13754154e+02f, 4.45189215e+02f, 6.43236850e+02f, 9.47484116e+02f, 1.42457583e+03f, 2.18920236e+03f, 3.44338342e+03f, 5.55184130e+03f, 9.19045432e+03f, 1.56468513e+04f, 2.74471462e+04f, 4.97037777e+04f, 9.31107740e+04f, 1.80835335e+05f, 3.64968793e+05f, 7.67360053e+05f, 1.68525439e+06f, 3.87686515e+06f, 9.37022570e+06f, 2.38705733e+07f, 6.43128750e+07f, 1.83920179e+08f, 5.60444636e+08f, 1.82722217e+09f, 6.40182180e+09f, 2.42153053e+10f, 9.93804949e+10f, 4.44863150e+11f, 2.18425069e+12f, 1.18337660e+13f, 7.11948688e+13f, 4.78870731e+14f, 3.62710215e+15f, 3.11747341e+16f, 3.06542975e+17f, 3.47854955e+18f, 4.59768243e+19f, 7.14806140e+20f, }, + { 3.95175890e-21f, 1.83575349e-20f, 8.12661397e-20f, 3.43336935e-19f, 1.38634563e-18f, 5.35757029e-18f, 1.98424944e-17f, 7.05221126e-17f, 2.40827550e-16f, 7.91175869e-16f, 2.50347754e-15f, 7.63871031e-15f, 2.25003103e-14f, 6.40502166e-14f, 1.76389749e-13f, 4.70424252e-13f, 1.21618334e-12f, 3.05082685e-12f, 7.43273471e-12f, 1.76028616e-11f, 4.05602375e-11f, 9.10055013e-11f, 1.98994391e-10f, 4.24390078e-10f, 8.83436580e-10f, 1.79636925e-09f, 3.57059250e-09f, 6.94247187e-09f, 1.32133371e-08f, 2.46332536e-08f, 4.50110843e-08f, 8.06630537e-08f, 1.41856144e-07f, 2.44958654e-07f, 4.15579069e-07f, 6.93056106e-07f, 1.13675616e-06f, 1.83473665e-06f, 2.91544023e-06f, 4.56318858e-06f, 7.03833675e-06f, 1.07030190e-05f, 1.60534529e-05f, 2.37597559e-05f, 3.47141604e-05f, 5.00883685e-05f, 7.14005734e-05f, 1.00592372e-04f, 1.40115414e-04f, 1.93027181e-04f, 2.63094779e-04f, 3.54905080e-04f, 4.73978972e-04f, 6.26886955e-04f, 8.21362793e-04f, 1.06641153e-03f, 1.37240787e-03f, 1.75118071e-03f, 2.21607971e-03f, 2.78201983e-03f, 3.46550010e-03f, 4.28459361e-03f, 5.25890609e-03f, 6.40950150e-03f, 7.75879384e-03f, 9.33040551e-03f, 1.11489935e-02f, 1.32400455e-02f, 1.56296499e-02f, 1.83442433e-02f, 2.14103400e-02f, 2.48542509e-02f, 2.87017958e-02f, 3.29780164e-02f, 3.77068968e-02f, 4.29110964e-02f, 4.86117029e-02f, 5.48280093e-02f, 6.15773214e-02f, 6.88747982e-02f, 7.67333308e-02f, 8.51634602e-02f, 9.41733378e-02f, 1.03768728e-01f, 1.13953051e-01f, 1.24727473e-01f, 1.36091031e-01f, 1.48040798e-01f, 1.60572082e-01f, 1.73678660e-01f, 1.87353038e-01f, 2.01586736e-01f, 2.16370598e-01f, 2.31695113e-01f, 2.47550758e-01f, 2.63928342e-01f, 2.80819365e-01f, 2.98216379e-01f, 3.16113348e-01f, 3.34506011e-01f, 3.53392244e-01f, 3.72772414e-01f, 3.92649735e-01f, 4.13030618e-01f, 4.33925021e-01f, 4.55346789e-01f, 4.77314001e-01f, 4.99849320e-01f, 5.22980337e-01f, 5.46739932e-01f, 5.71166640e-01f, 5.96305036e-01f, 6.22206131e-01f, 6.48927802e-01f, 6.76535247e-01f, 7.05101473e-01f, 7.34707835e-01f, 7.65444619e-01f, 7.97411688e-01f, 8.30719192e-01f, 8.65488366e-01f, 9.01852407e-01f, 9.39957463e-01f, 9.79963735e-01f, 1.02204672e+00f, 1.06639858e+00f, 1.11322974e+00f, 1.16277062e+00f, 1.21527359e+00f, 1.27101525e+00f, 1.33029891e+00f, 1.39345744e+00f, 1.46085648e+00f, 1.53289803e+00f, 1.61002461e+00f, 1.69272386e+00f, 1.78153384e+00f, 1.87704900e+00f, 1.97992701e+00f, 2.09089644e+00f, 2.21076567e+00f, 2.34043290e+00f, 2.48089770e+00f, 2.63327413e+00f, 2.79880590e+00f, 2.97888368e+00f, 3.17506505e+00f, 3.38909744e+00f, 3.62294469e+00f, 3.87881764e+00f, 4.15920968e+00f, 4.46693789e+00f, 4.80519096e+00f, 5.17758497e+00f, 5.58822853e+00f, 6.04179895e+00f, 6.54363157e+00f, 7.09982467e+00f, 7.71736306e+00f, 8.40426388e+00f, 9.16974906e+00f, 1.00244499e+01f, 1.09806502e+01f, 1.20525758e+01f, 1.32567410e+01f, 1.46123627e+01f, 1.61418586e+01f, 1.78714466e+01f, 1.98318690e+01f, 2.20592694e+01f, 2.45962577e+01f, 2.74932084e+01f, 3.08098460e+01f, 3.46171893e+01f, 3.89999428e+01f, 4.40594471e+01f, 4.99173320e+01f, 5.67200545e+01f, 6.46445583e+01f, 7.39053537e+01f, 8.47634121e+01f, 9.75373786e+01f, 1.12617765e+02f, 1.30484989e+02f, 1.51732386e+02f, 1.77095712e+02f, 2.07491096e+02f, 2.44064119e+02f, 2.88253545e+02f, 3.41874461e+02f, 4.07227291e+02f, 4.87241400e+02f, 5.85665251e+02f, 7.07319497e+02f, 8.58435639e+02f, 1.04711167e+03f, 1.28392853e+03f, 1.58278901e+03f, 1.96206607e+03f, 2.44618436e+03f, 3.06781187e+03f, 3.87091688e+03f, 4.91505977e+03f, 6.28145970e+03f, 8.08162997e+03f, 1.04697579e+04f, 1.36605846e+04f, 1.79554230e+04f, 2.37803156e+04f, 3.17424455e+04f, 4.27142204e+04f, 5.79596727e+04f, 7.93261335e+04f, 1.09537503e+05f, 1.52647130e+05f, 2.14743829e+05f, 3.05063335e+05f, 4.37755687e+05f, 6.34724899e+05f, 9.30240305e+05f, 1.37850753e+06f, 2.06623977e+06f, 3.13377596e+06f, 4.81098405e+06f, 7.47905793e+06f, 1.17782423e+07f, 1.87980927e+07f, 3.04180655e+07f, 4.99257437e+07f, 8.31551852e+07f, 1.40614107e+08f, 2.41519712e+08f, 4.21576502e+08f, 7.48209440e+08f, 1.35089892e+09f, 2.48263348e+09f, 4.64662007e+09f, 8.86235204e+09f, 1.72348930e+10f, 3.41967381e+10f, 6.92714904e+10f, 1.43352142e+11f, 3.03269524e+11f, 6.56345865e+11f, 1.45422052e+12f, 3.30099910e+12f, 7.68267630e+12f, 1.83474885e+13f, 4.49980389e+13f, 1.13430702e+14f, 2.94148450e+14f, 7.85402504e+14f, 2.16127995e+15f, 6.13534293e+15f, 1.79847736e+16f, 5.44944507e+16f, 1.70858922e+17f, 5.54922744e+17f, 1.86905990e+18f, 6.53599225e+18f, 2.37582887e+19f, 8.98810682e+19f, 3.54341330e+20f, }, + { 2.67108015e-21f, 5.82833463e-21f, 1.25616316e-20f, 2.67469785e-20f, 5.62745845e-20f, 1.17014394e-19f, 2.40511019e-19f, 4.88739481e-19f, 9.82072303e-19f, 1.95168062e-18f, 3.83661097e-18f, 7.46163208e-18f, 1.43594942e-17f, 2.73485792e-17f, 5.15573612e-17f, 9.62223075e-17f, 1.77810682e-16f, 3.25389618e-16f, 5.89765054e-16f, 1.05888451e-15f, 1.88354538e-15f, 3.31989417e-15f, 5.79902273e-15f, 1.00398818e-14f, 1.72308010e-14f, 2.93186753e-14f, 4.94655967e-14f, 8.27635884e-14f, 1.37343706e-13f, 2.26082511e-13f, 3.69205736e-13f, 5.98228147e-13f, 9.61866975e-13f, 1.53484658e-12f, 2.43090464e-12f, 3.82185577e-12f, 5.96531965e-12f, 9.24474797e-12f, 1.42267754e-11f, 2.17427910e-11f, 3.30041201e-11f, 4.97635091e-11f, 7.45399354e-11f, 1.10929412e-10f, 1.64031748e-10f, 2.41032586e-10f, 3.51991946e-10f, 5.10905560e-10f, 7.37124150e-10f, 1.05723929e-09f, 1.50757352e-09f, 2.13744796e-09f, 3.01344401e-09f, 4.22492806e-09f, 5.89117093e-09f, 8.17046854e-09f, 1.12717587e-08f, 1.54693324e-08f, 2.11213594e-08f, 2.86930859e-08f, 3.87857241e-08f, 5.21722335e-08f, 6.98414017e-08f, 9.30518593e-08f, 1.23397923e-07f, 1.62889442e-07f, 2.14048123e-07f, 2.80023159e-07f, 3.64729321e-07f, 4.73011070e-07f, 6.10836627e-07f, 7.85526363e-07f, 1.00602028e-06f, 1.28318979e-06f, 1.63019938e-06f, 2.06292424e-06f, 2.60043021e-06f, 3.26552286e-06f, 4.08537275e-06f, 5.09222413e-06f, 6.32419483e-06f, 7.82617466e-06f, 9.65083023e-06f, 1.18597236e-05f, 1.45245521e-05f, 1.77285168e-05f, 2.15678251e-05f, 2.61533347e-05f, 3.16123436e-05f, 3.80905295e-05f, 4.57540432e-05f, 5.47917575e-05f, 6.54176707e-05f, 7.78734661e-05f, 9.24312223e-05f, 1.09396271e-04f, 1.29110197e-04f, 1.51953965e-04f, 1.78351176e-04f, 2.08771424e-04f, 2.43733750e-04f, 2.83810168e-04f, 3.29629253e-04f, 3.81879756e-04f, 4.41314233e-04f, 5.08752659e-04f, 5.85085996e-04f, 6.71279692e-04f, 7.68377076e-04f, 8.77502620e-04f, 9.99865030e-04f, 1.13676015e-03f, 1.28957360e-03f, 1.45978322e-03f, 1.64896113e-03f, 1.85877551e-03f, 2.09099200e-03f, 2.34747474e-03f, 2.63018699e-03f, 2.94119122e-03f, 3.28264890e-03f, 3.65681963e-03f, 4.06605991e-03f, 4.51282135e-03f, 4.99964828e-03f, 5.52917497e-03f, 6.10412222e-03f, 6.72729343e-03f, 7.40157020e-03f, 8.12990738e-03f, 8.91532760e-03f, 9.76091537e-03f, 1.06698107e-02f, 1.16452023e-02f, 1.26903202e-02f, 1.38084285e-02f, 1.50028172e-02f, 1.62767940e-02f, 1.76336759e-02f, 1.90767806e-02f, 2.06094173e-02f, 2.22348784e-02f, 2.39564300e-02f, 2.57773028e-02f, 2.77006834e-02f, 2.97297055e-02f, 3.18674406e-02f, 3.41168899e-02f, 3.64809756e-02f, 3.89625331e-02f, 4.15643030e-02f, 4.42889240e-02f, 4.71389254e-02f, 5.01167213e-02f, 5.32246039e-02f, 5.64647382e-02f, 5.98391571e-02f, 6.33497571e-02f, 6.69982939e-02f, 7.07863800e-02f, 7.47154815e-02f, 7.87869165e-02f, 8.30018539e-02f, 8.73613125e-02f, 9.18661613e-02f, 9.65171203e-02f, 1.01314762e-01f, 1.06259513e-01f, 1.11351656e-01f, 1.16591337e-01f, 1.21978563e-01f, 1.27513213e-01f, 1.33195039e-01f, 1.39023671e-01f, 1.44998628e-01f, 1.51119321e-01f, 1.57385061e-01f, 1.63795066e-01f, 1.70348473e-01f, 1.77044340e-01f, 1.83881662e-01f, 1.90859375e-01f, 1.97976367e-01f, 2.05231492e-01f, 2.12623572e-01f, 2.20151415e-01f, 2.27813822e-01f, 2.35609599e-01f, 2.43537565e-01f, 2.51596569e-01f, 2.59785494e-01f, 2.68103274e-01f, 2.76548903e-01f, 2.85121445e-01f, 2.93820047e-01f, 3.02643950e-01f, 3.11592502e-01f, 3.20665165e-01f, 3.29861530e-01f, 3.39181328e-01f, 3.48624439e-01f, 3.58190905e-01f, 3.67880941e-01f, 3.77694943e-01f, 3.87633504e-01f, 3.97697421e-01f, 4.07887708e-01f, 4.18205605e-01f, 4.28652591e-01f, 4.39230391e-01f, 4.49940993e-01f, 4.60786652e-01f, 4.71769905e-01f, 4.82893580e-01f, 4.94160809e-01f, 5.05575036e-01f, 5.17140031e-01f, 5.28859900e-01f, 5.40739096e-01f, 5.52782432e-01f, 5.64995090e-01f, 5.77382639e-01f, 5.89951040e-01f, 6.02706666e-01f, 6.15656310e-01f, 6.28807202e-01f, 6.42167019e-01f, 6.55743908e-01f, 6.69546490e-01f, 6.83583887e-01f, 6.97865729e-01f, 7.12402181e-01f, 7.27203953e-01f, 7.42282322e-01f, 7.57649155e-01f, 7.73316926e-01f, 7.89298740e-01f, 8.05608358e-01f, 8.22260217e-01f, 8.39269463e-01f, 8.56651970e-01f, 8.74424378e-01f, 8.92604116e-01f, 9.11209442e-01f, 9.30259469e-01f, 9.49774208e-01f, 9.69774604e-01f, 9.90282579e-01f, 1.01132107e+00f, 1.03291408e+00f, 1.05508673e+00f, 1.07786529e+00f, 1.10127728e+00f, 1.12535146e+00f, 1.15011796e+00f, 1.17560829e+00f, 1.20185546e+00f, 1.22889400e+00f, 1.25676010e+00f, 1.28549162e+00f, 1.31512826e+00f, 1.34571158e+00f, 1.37728514e+00f, 1.40989460e+00f, 1.44358784e+00f, 1.47841507e+00f, 1.51442894e+00f, 1.55168471e+00f, 1.59024039e+00f, 1.63015687e+00f, 1.67149810e+00f, 1.71433126e+00f, 1.75872698e+00f, 1.80475947e+00f, 1.85250679e+00f, 1.90205105e+00f, 1.95347869e+00f, 2.00688065e+00f, 2.06235275e+00f, 2.11999592e+00f, 2.17991652e+00f, 2.24222670e+00f, 2.30704472e+00f, 2.37449538e+00f, 2.44471039e+00f, 2.51782884e+00f, 2.59399766e+00f, 2.67337209e+00f, 2.75611628e+00f, 2.84240383e+00f, 2.93241843e+00f, 3.02635449e+00f, 3.12441791e+00f, 3.22682682e+00f, 3.33381238e+00f, 3.44561973e+00f, 3.56250887e+00f, 3.68475574e+00f, 3.81265333e+00f, 3.94651282e+00f, 4.08666490e+00f, 4.23346116e+00f, 4.38727553e+00f, 4.54850596e+00f, 4.71757611e+00f, 4.89493722e+00f, 5.08107015e+00f, 5.27648761e+00f, 5.48173646e+00f, 5.69740032e+00f, 5.92410235e+00f, 6.16250823e+00f, 6.41332946e+00f, 6.67732689e+00f, 6.95531455e+00f, 7.24816384e+00f, 7.55680807e+00f, 7.88224735e+00f, 8.22555401e+00f, 8.58787841e+00f, 8.97045530e+00f, 9.37461076e+00f, 9.80176975e+00f, 1.02534643e+01f, 1.07313428e+01f, 1.12371793e+01f, 1.17728848e+01f, 1.23405187e+01f, 1.29423019e+01f, 1.35806306e+01f, 1.42580922e+01f, 1.49774818e+01f, 1.57418213e+01f, 1.65543795e+01f, 1.74186947e+01f, 1.83385994e+01f, 1.93182476e+01f, 2.03621450e+01f, 2.14751816e+01f, 2.26626686e+01f, 2.39303784e+01f, 2.52845893e+01f, 2.67321348e+01f, 2.82804577e+01f, 2.99376708e+01f, 3.17126238e+01f, 3.36149769e+01f, 3.56552840e+01f, 3.78450835e+01f, 4.01970005e+01f, 4.27248599e+01f, 4.54438126e+01f, 4.83704762e+01f, 5.15230921e+01f, 5.49217006e+01f, 5.85883374e+01f, 6.25472527e+01f, 6.68251567e+01f, 7.14514957e+01f, 7.64587609e+01f, 8.18828353e+01f, 8.77633847e+01f, 9.41442967e+01f, 1.01074176e+02f, 1.08606902e+02f, 1.16802259e+02f, 1.25726650e+02f, 1.35453899e+02f, 1.46066166e+02f, 1.57654979e+02f, 1.70322410e+02f, 1.84182406e+02f, 1.99362306e+02f, 2.16004568e+02f, 2.34268740e+02f, 2.54333703e+02f, 2.76400239e+02f, 3.00693971e+02f, 3.27468728e+02f, 3.57010397e+02f, 3.89641362e+02f, 4.25725590e+02f, 4.65674502e+02f, 5.09953726e+02f, 5.59090900e+02f, 6.13684688e+02f, 6.74415211e+02f, 7.42056139e+02f, 8.17488717e+02f, 9.01718069e+02f, 9.95892168e+02f, 1.10132394e+03f, 1.21951707e+03f, 1.35219615e+03f, 1.50134197e+03f, 1.66923291e+03f, 1.85849349e+03f, 2.07215152e+03f, 2.31370536e+03f, 2.58720328e+03f, 2.89733724e+03f, 3.24955383e+03f, 3.65018587e+03f, 4.10660860e+03f, 4.62742547e+03f, 5.22268956e+03f, 5.90416786e+03f, 6.68565726e+03f, 7.58336313e+03f, 8.61635357e+03f, 9.80710572e+03f, 1.11821637e+04f, 1.27729327e+04f, 1.46166396e+04f, 1.67574960e+04f, 1.92481112e+04f, 2.21512104e+04f, 2.55417295e+04f, 2.95093735e+04f, 3.41617487e+04f, 3.96282043e+04f, 4.60645561e+04f, 5.36589049e+04f, 6.26388223e+04f, 7.32802431e+04f, 8.59184957e+04f, 1.00962017e+05f, 1.18909442e+05f, 1.40370957e+05f, 1.66095034e+05f, 1.97001996e+05f, 2.34226253e+05f, 2.79169596e+05f, 3.33568603e+05f, 3.99580125e+05f, 4.79889989e+05f, 5.77851588e+05f, 6.97663062e+05f, 8.44594440e+05f, 1.02527965e+06f, 1.24809298e+06f, 1.52363581e+06f, 1.86536786e+06f, 2.29042802e+06f, 2.82070529e+06f, 3.48424008e+06f, 4.31706343e+06f, 5.36561882e+06f, 6.68996113e+06f, 8.36799594e+06f, 1.05011160e+07f, 1.32217203e+07f, 1.67032788e+07f, 2.11738506e+07f, 2.69343047e+07f, 3.43829654e+07f, 4.40490690e+07f, 5.66383460e+07f, 7.30953564e+07f, 9.46890531e+07f, 1.23130681e+08f, 1.60736861e+08f, 2.10656057e+08f, 2.77184338e+08f, 3.66207397e+08f, 4.85821891e+08f, 6.47212479e+08f, 8.65895044e+08f, 1.16348659e+09f, 1.57023596e+09f, 2.12865840e+09f, 2.89877917e+09f, 3.96573294e+09f, 5.45082863e+09f, 7.52773593e+09f, 1.04462776e+10f, 1.45675716e+10f, 2.04161928e+10f, 2.87579864e+10f, 4.07167363e+10f, 5.79499965e+10f, 8.29154750e+10f, 1.19276754e+11f, 1.72524570e+11f, 2.50933409e+11f, 3.67042596e+11f, 5.39962441e+11f, 7.98985690e+11f, 1.18927611e+12f, 1.78088199e+12f, 2.68310388e+12f, 4.06753710e+12f, 6.20525592e+12f, 9.52719664e+12f, 1.47228407e+13f, 2.29025392e+13f, 3.58662837e+13f, 5.65517100e+13f, 8.97859411e+13f, 1.43556057e+14f, 2.31171020e+14f, 3.74966777e+14f, 6.12702071e+14f, 1.00868013e+15f, 1.67323268e+15f, 2.79711270e+15f, 4.71267150e+15f, 8.00353033e+15f, 1.37027503e+16f, 2.36538022e+16f, 4.11734705e+16f, 7.22793757e+16f, 1.27982244e+17f, 2.28603237e+17f, 4.11976277e+17f, 7.49169358e+17f, 1.37488861e+18f, 2.54681529e+18f, 4.76248383e+18f, 8.99167123e+18f, 1.71428840e+19f, 3.30088717e+19f, 6.42020070e+19f, 1.26155602e+20f, 2.50480806e+20f, 5.02601059e+20f, 1.01935525e+21f, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -4.18750000f; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 7.241670621354483269e-163, 2.257639733856759198e-60, 1.153241619257215165e-22, 8.747691973876861825e-09, 1.173446923800022477e-03, 1.032756936219208144e-01, 7.719261204224504866e-01, 4.355544675823585545e+00, 1.215101039066652656e+02, 6.228845436711506169e+05, 6.278613977336989392e+15, 9.127414935180233465e+42, 6.091127771174027909e+116, }, + { 4.547459836328942014e-99, 6.678756542928857080e-37, 5.005042973041566360e-14, 1.341318484151208960e-05, 1.833875636365939263e-02, 3.257972971286326131e-01, 1.712014688483495078e+00, 1.613222549264089627e+01, 3.116246745274236447e+03, 3.751603952020919663e+09, 1.132259067258797346e+26, 6.799257464097374238e+70, }, + { 5.314690663257815465e-127, 2.579830034615362946e-77, 3.534801062399966878e-47, 6.733941646704537777e-29, 8.265803726974829043e-18, 4.424914371157762285e-11, 5.390411046738629465e-07, 1.649389713333761449e-04, 5.463728936866216652e-03, 4.787896410534771955e-02, 1.931544616590306846e-01, 5.121421856617965197e-01, 1.144715949265016019e+00, 2.648424684387670480e+00, 7.856804169938798917e+00, 3.944731803343517708e+01, 5.060291993016831194e+02, 3.181117494063683297e+04, 2.820174654949211729e+07, 1.993745099515255184e+12, 1.943469269499068563e+20, 2.858803732300638372e+33, 1.457292199029008637e+55, 8.943565831706355607e+90, 9.016198369791554655e+149, }, + { 8.165631636299519857e-144, 3.658949309353149331e-112, 1.635242513882908826e-87, 2.578381184977746454e-68, 2.305546416275824199e-53, 1.016725540031465162e-41, 1.191823622917539774e-32, 1.379018088205016509e-25, 4.375640088826073184e-20, 8.438464631330991606e-16, 1.838483310261119782e-12, 7.334264181393092650e-10, 7.804740587931068021e-08, 2.970395577741681504e-06, 5.081805431666579484e-05, 4.671401627620431498e-04, 2.652347404231090523e-03, 1.037409202661683856e-02, 3.045225582205323946e-02, 7.178280364982721201e-02, 1.434001065841990688e-01, 2.535640852949085796e-01, 4.113268917643175920e-01, 6.310260805648534613e-01, 9.404706503455087817e-01, 1.396267301972783068e+00, 2.116896928689963277e+00, 3.364289290471596568e+00, 5.770183960005836987e+00, 1.104863531218761752e+01, 2.460224479439805859e+01, 6.699316387888639988e+01, 2.375794092475844708e+02, 1.188092202760116066e+03, 9.269848635975416108e+03, 1.283900116155671304e+05, 3.723397798030112514e+06, 2.793667983952389721e+08, 7.112973790863854188e+10, 8.704037695808749572e+13, 8.001474015782459984e+17, 9.804091819390540578e+22, 3.342777673392873288e+29, 8.160092668471508447e+37, 4.798775331663586528e+48, 3.228614320248853938e+62, 1.836986041572136151e+80, 1.153145986877483804e+103, 2.160972586723647751e+132, }, + { 4.825077401709435655e-153, 3.813781211050297560e-135, 2.377824349780240844e-119, 2.065817295388293122e-105, 4.132105770181358886e-93, 2.963965169989404311e-82, 1.127296662046635391e-72, 3.210346399945695041e-64, 9.282992368222161062e-57, 3.565977853916619677e-50, 2.306962519220473637e-44, 3.098751038516535098e-39, 1.039558064722960891e-34, 1.025256027381235200e-30, 3.432612000569885403e-27, 4.429681881379089961e-24, 2.464589267395236846e-21, 6.526691446363344923e-19, 8.976892324445928684e-17, 6.926277695183452225e-15, 3.208805316815751272e-13, 9.478053068835988899e-12, 1.882052586691155400e-10, 2.632616062773909009e-09, 2.703411837703917665e-08, 2.113642195965330965e-07, 1.299327029813074013e-06, 6.461189935136030673e-06, 2.665090959570723827e-05, 9.322774986189288194e-05, 2.820463407940068813e-04, 7.508613300035051413e-04, 1.786142185986551786e-03, 3.848376610765768211e-03, 7.600810651854199771e-03, 1.390873269178271700e-02, 2.380489559528694982e-02, 3.842796337748997654e-02, 5.895012901671883992e-02, 8.651391160689367948e-02, 1.221961347398101671e-01, 1.670112314557845555e-01, 2.219593619059930701e-01, 2.881200442770917241e-01, 3.667906976948184315e-01, 4.596722879563388211e-01, 5.691113093602836208e-01, 6.984190600916228379e-01, 8.523070690462583711e-01, 1.037505121571600249e+00, 1.263672635742961915e+00, 1.544788480334120896e+00, 1.901333876886441433e+00, 2.363816272813317635e+00, 2.978614980117902904e+00, 3.817957977526709364e+00, 4.997477803461245639e+00, 6.708150685706236545e+00, 9.276566033183386532e+00, 1.328332469239125539e+01, 1.980618680552458639e+01, 3.094452809319702849e+01, 5.101378787119006225e+01, 8.943523638413590523e+01, 1.682138665185088325e+02, 3.427988270281270587e+02, 7.653823671943767281e+02, 1.895993667030670343e+03, 5.285404568827643942e+03, 1.684878049282191210e+04, 6.254388805482299369e+04, 2.759556544455721132e+05, 1.481213238071008345e+06, 9.929728611179601424e+06, 8.564987764771851841e+07, 9.831650826344826952e+08, 1.560339073978569502e+10, 3.575098885016726922e+11, 1.241973798101884982e+13, 6.915106205748805839e+14, 6.571419716645131084e+16, 1.144558033138694099e+19, 3.960915669532823553e+21, 2.984410558028297842e+24, 5.430494850258846715e+27, 2.683747612498502676e+31, 4.114885708325522701e+35, 2.276004816861421600e+40, 5.387544917595833246e+45, 6.623575732955432303e+51, 5.266881304835239338e+58, 3.473234812654772210e+66, 2.517492645985977377e+75, 2.759797646289240629e+85, 6.569603829502412077e+96, 5.116181648220647995e+109, 2.073901892339407423e+124, 7.406462446666255838e+140, }, + { 7.053618140948655098e-158, 2.343354218558056628e-148, 2.062509087689351439e-139, 5.212388628332260488e-131, 4.079380320868843387e-123, 1.061481285006738214e-115, 9.816727607793017691e-109, 3.435400719609722581e-102, 4.825198574681495574e-96, 2.874760995089533358e-90, 7.652499977338879996e-85, 9.556944498127119032e-80, 5.862241023038227937e-75, 1.843934000129616663e-70, 3.096983980846232911e-66, 2.885057452402340330e-62, 1.544904681826443837e-58, 4.917572705671511534e-55, 9.602608566391652866e-52, 1.184882375237471009e-48, 9.499223316355714793e-46, 5.078965858882528461e-43, 1.856080838373584123e-40, 4.744245560917271585e-38, 8.667497891102658240e-36, 1.155086178652063612e-33, 1.144541329818836153e-31, 8.585083084065812874e-30, 4.957702933032408922e-28, 2.239353794616277882e-26, 8.030405447708765492e-25, 2.318459271131684362e-23, 5.460287296679086677e-22, 1.062054307071706375e-20, 1.725955878033239909e-19, 2.369168446274347137e-18, 2.775176063916613602e-17, 2.800847352316621903e-16, 2.457625954357892245e-15, 1.890842052364646528e-14, 1.285791209258834942e-13, 7.786001004707878219e-13, 4.228083024410741194e-12, 2.072664297543567489e-11, 9.229295073519997559e-11, 3.754886152592311575e-10, 1.403443871774813834e-09, 4.843962757371872495e-09, 1.551373196623161433e-08, 4.631448362339623514e-08, 1.294370176865168120e-07, 3.400050664017164356e-07, 8.426290307581447654e-07, 1.977205177561996033e-06, 4.407362363338667830e-06, 9.362197325373404563e-06, 1.900760383449277992e-05, 3.698530963711860636e-05, 6.915333419235766653e-05, 1.245492076251852927e-04, 2.165764713808099093e-04, 3.643870211078977292e-04, 5.943999416122372516e-04, 9.418663022314558591e-04, 1.452364274261880083e-03, 2.183094846035196562e-03, 3.203848855069215278e-03, 4.597532353031862490e-03, 6.460168315117479792e-03, 8.900334989802041559e-03, 1.203804973137064275e-02, 1.600315622064554965e-02, 2.093331703849583304e-02, 2.697174812170771748e-02, 3.426485378063329473e-02, 4.295992956149806344e-02, 5.320309587203163231e-02, 6.513760993479510261e-02, 7.890268021756337834e-02, 9.463287940877026649e-02, 1.124582226719385153e-01, 1.325049504086213973e-01, 1.548970316076579260e-01, 1.797583869192584860e-01, 2.072158210677632145e-01, 2.374026527414815016e-01, 2.704630368855767324e-01, 3.065569893452247137e-01, 3.458661469783558388e-01, 3.886003277325320632e-01, 4.350049951304795319e-01, 4.853697810067132707e-01, 5.400382807495678589e-01, 5.994194092045578293e-01, 6.640006964388650918e-01, 7.343640159321037167e-01, 8.112043806284638130e-01, 8.953526245122194172e-01, 9.878030224123093447e-01, 1.089747207002141516e+00, 1.202616144679226559e+00, 1.328132465995424226e+00, 1.468376159872979355e+00, 1.625867601500928277e+00, 1.803673186618691186e+00, 2.005540624723209206e+00, 2.236073393446881709e+00, 2.500957254018255004e+00, 2.807256477663534857e+00, 3.163804128101147487e+00, 3.581720263742550029e+00, 4.075105576391566303e+00, 4.661977749936137761e+00, 5.365546718714963091e+00, 6.215967676434536043e+00, 7.252774367330402583e+00, 8.528291278204291331e+00, 1.011247001122720391e+01, 1.209982167952718578e+01, 1.461947158782994207e+01, 1.784992423404041042e+01, 2.204102944968352178e+01, 2.754711235628932374e+01, 3.487766600641650640e+01, 4.477610230214251576e+01, 5.834406132739843834e+01, 7.724096630394042216e+01, 1.040101075374387191e+02, 1.426215523101601730e+02, 1.993940974645466479e+02, 2.845939167898235356e+02, 4.152683836292551147e+02, 6.203878718481709769e+02, 9.504080873581791535e+02, 1.495523342124078853e+03, 2.421485328006836634e+03, 4.041977218227396500e+03, 6.969453497454785202e+03, 1.244001690461442846e+04, 2.303794930506892099e+04, 4.437240927040385250e+04, 8.911296561746717657e+04, 1.871159398849787994e+05, 4.119851492265743330e+05, 9.540971729944126398e+05, 2.331680521880789706e+06, 6.034305391011695472e+06, 1.659896369452266448e+07, 4.872448839341613053e+07, 1.532687586549090392e+08, 5.189730792935011722e+08, 1.900599621040508288e+09, 7.566480431232731818e+09, 3.292298322781643849e+10, 1.574714421665075635e+11, 8.330244306239795892e+11, 4.905619969814187571e+12, 3.238316002757222702e+13, 2.413995281454699076e+14, 2.048115587426077343e+15, 1.994352670766892066e+16, 2.248750566422739144e+17, 2.964037541992353401e+18, 4.613233119968213445e+19, 8.569680508342001161e+20, 1.921851711942844799e+22, 5.266829246099861758e+23, 1.786779952992288976e+25, 7.607919705736976491e+26, 4.125721424346450007e+28, 2.894340142292214313e+30, 2.670720269656428272e+32, 3.299248229135205151e+34, 5.560105583582310103e+36, 1.304167266599523020e+39, 4.349382146382717353e+41, 2.109720387774341509e+44, 1.524825352702403324e+47, 1.684941265105084589e+50, 2.925572737558413426e+53, 8.217834961057481281e+56, 3.852117991896536784e+60, 3.114452310394384063e+64, 4.498555465873245751e+68, 1.205113215232800796e+73, 6.230864727145221322e+77, 6.487131248948465269e+82, 1.422810109167834249e+88, 6.897656089181724717e+93, 7.779163462756485195e+99, 2.155213251859555072e+106, 1.554347160152705281e+113, 3.103875072425192272e+120, 1.832673821557018634e+128, 3.431285951865278376e+136, 2.194542081542393530e+145, }, + { 2.363803632659058081e-160, 1.926835442612677686e-155, 1.109114905180506786e-150, 4.556759282087534164e-146, 1.350172241067816232e-141, 2.914359263635229435e-137, 4.627545976953585825e-133, 5.456508344460398758e-129, 4.821828861306345485e-125, 3.221779152402086241e-121, 1.641732102111619421e-117, 6.433569189921227126e-114, 1.954582672700428961e-110, 4.639912078942456372e-107, 8.671928891742699827e-104, 1.285485264305858782e-100, 1.522161801460927566e-97, 1.449767844425295085e-94, 1.118122255504445235e-91, 7.028344777398825069e-89, 3.623454064991238081e-86, 1.541513438874996543e-83, 5.443699502170284982e-81, 1.604913673768949456e-78, 3.972206240977317536e-76, 8.297975554162539562e-74, 1.470748835855054032e-71, 2.222935801472624670e-69, 2.879160361851977720e-67, 3.210837413250902178e-65, 3.097303984958235490e-63, 2.595974479763180595e-61, 1.898656799199089593e-59, 1.216865518398435626e-57, 6.862041810601184397e-56, 3.418134121780773218e-54, 1.509758535747580387e-52, 5.934924977563731784e-51, 2.083865009061241099e-49, 6.558128104492290092e-48, 1.856133016606468181e-46, 4.739964621828176249e-45, 1.095600459825324697e-43, 2.299177139060262518e-42, 4.393663812095906869e-41, 7.667728102142858487e-40, 1.225476279042445010e-38, 1.798526997315960782e-37, 2.430201154741018716e-36, 3.030993518975438712e-35, 3.497966609954172613e-34, 3.744308272796551045e-33, 3.726132797819332658e-32, 3.455018936399215381e-31, 2.991524108706319604e-30, 2.423818520801870809e-29, 1.841452809687011486e-28, 1.314419760826235421e-27, 8.831901010260867670e-27, 5.596660060604091621e-26, 3.350745417080507841e-25, 1.898675566025820409e-24, 1.019982287418197376e-23, 5.203315082978366918e-23, 2.524668746906057148e-22, 1.166904646009344233e-21, 5.145437675264868732e-21, 2.167677145279166596e-20, 8.736996911006110678e-20, 3.373776431076593266e-19, 1.249769727462160008e-18, 4.446913832647864892e-18, 1.521741180930875343e-17, 5.014158301377399707e-17, 1.592708205361177316e-16, 4.882536933653862982e-16, 1.446109387544416586e-15, 4.142510168443201880e-15, 1.148892083132325407e-14, 3.088024760858924214e-14, 8.051699653634442236e-14, 2.038478329249539199e-13, 5.015686309363884049e-13, 1.200444984849900298e-12, 2.797125428309156462e-12, 6.350357793399881333e-12, 1.405881744263466936e-11, 3.037391821635123795e-11, 6.408863411016101449e-11, 1.321618431565916164e-10, 2.665526566207284474e-10, 5.261497418654313068e-10, 1.017123184766088896e-09, 1.926882221639203388e-09, 3.579523428497157488e-09, 6.524486847652635035e-09, 1.167543991262942921e-08, 2.052356080018121741e-08, 3.545879678923676129e-08, 6.024472481556065885e-08, 1.007076869023518125e-07, 1.657191565891799652e-07, 2.685718943404479677e-07, 4.288752213761154116e-07, 6.751222405372943925e-07, 1.048111270324302884e-06, 1.605433960692314060e-06, 2.427271958412371013e-06, 3.623770645356477660e-06, 5.344280132492750309e-06, 7.788767891027678939e-06, 1.122171160022519082e-05, 1.598877254198599908e-05, 2.253652700952153115e-05, 3.143549403208496646e-05, 4.340664122305257288e-05, 5.935147653125578529e-05, 8.038574285450253209e-05, 1.078766266062957565e-04, 1.434832731669987826e-04, 1.892002753957224677e-04, 2.474036705329449166e-04, 3.208988510028906069e-04, 4.129696713145546995e-04, 5.274279220384250390e-04, 6.686622480794640482e-04, 8.416855170641220285e-04, 1.052179598744440400e-03, 1.306536501050643762e-03, 1.611894824798787196e-03, 1.976170547826080496e-03, 2.408081229927640721e-03, 2.917162840577481875e-03, 3.513778549028205519e-03, 4.209118976964403112e-03, 5.015193592567630665e-03, 5.944813116164644191e-03, 7.011563005746090924e-03, 8.229768289624073049e-03, 9.614450207543986041e-03, 1.118127530523730813e-02, 1.294649779580742160e-02, 1.492689615029751590e-02, 1.713970500593860526e-02, 1.960254358145296755e-02, 2.233334186285684056e-02, 2.535026586984720664e-02, 2.867164333232700310e-02, 3.231589109997912964e-02, 3.630144557680610965e-02, 4.064669741956638109e-02, 4.536993166688766414e-02, 5.048927437769432941e-02, 5.602264675683979161e-02, 6.198772763597769678e-02, 6.840192506222012774e-02, 7.528235762939712171e-02, 8.264584606994605986e-02, 9.050891551257121825e-02, 9.888780870447738360e-02, 1.077985103995250356e-01, 1.172567830270636607e-01, 1.272782136821146663e-01, 1.378782724173011162e-01, 1.490723817714478840e-01, 1.608759974398061173e-01, 1.733046999768424060e-01, 1.863742974247175786e-01, 2.001009387790379976e-01, 2.145012382381487190e-01, 2.295924102330349785e-01, 2.453924153016625057e-01, 2.619201169541956490e-01, 2.791954497739298773e-01, 2.972395991130188526e-01, 3.160751928723792943e-01, 3.357265060019327741e-01, 3.562196785212496373e-01, 3.775829480426418792e-01, 3.998468979800887046e-01, 4.230447228497335035e-01, 4.472125123131631074e-01, 4.723895558858634018e-01, 4.986186705332947608e-01, 5.259465537097384485e-01, 5.544241647649479754e-01, 5.841071380560416511e-01, 6.150562315632864018e-01, 6.473378153258308278e-01, 6.810244045956889952e-01, 7.161952432654565143e-01, 7.529369438691556459e-01, 7.913441913000366617e-01, 8.315205183502086596e-01, 8.735791622734589226e-01, 9.176440128265773576e-01, 9.638506636817484398e-01, 1.012347580753402101e+00, 1.063297402882930381e+00, 1.116878392515788506e+00, 1.173286056537125469e+00, 1.232734960362603918e+00, 1.295460761779549539e+00, 1.361722494981910846e+00, 1.431805139837984876e+00, 1.506022516788234345e+00, 1.584720554029819354e+00, 1.668280980969603645e+00, 1.757125510515793421e+00, 1.851720582866847453e+00, 1.952582755329533200e+00, 2.060284836698905963e+00, 2.175462881275503983e+00, 2.298824177179966629e+00, 2.431156386859774759e+00, 2.573338025304717222e+00, 2.726350494395667363e+00, 2.891291931102408784e+00, 3.069393174263124520e+00, 3.262036211067640944e+00, 3.470775532153801919e+00, 3.697362905908153155e+00, 3.943776181224350319e+00, 4.212252847439515687e+00, 4.505329225191826639e+00, 4.825886338442190807e+00, 5.177203733275742875e+00, 5.563022772612923373e+00, 5.987621259260909859e+00, 6.455901637501497370e+00, 6.973495514195020291e+00, 7.546887847708181032e+00, 8.183564906772872855e+00, 8.892191039842283431e+00, 9.682820467523296204e+00, 1.056715177903931837e+01, 1.155883465937652851e+01, 1.267384070151528947e+01, 1.393091310389918289e+01, 1.535211379418177923e+01, 1.696349128797309510e+01, 1.879589868990482198e+01, 2.088599907466058846e+01, 2.327750557804054323e+01, 2.602271658731131093e+01, 2.918442338619305962e+01, 3.283828974258811174e+01, 3.707583192189045823e+01, 4.200816575721451990e+01, 4.777073782243997224e+01, 5.452932468101429049e+01, 6.248767344468634478e+01, 7.189727649240108469e+01, 8.306993427631743111e+01, 9.639397813652482031e+01, 1.123553215857374919e+02, 1.315649140340119335e+02, 1.547947284376312334e+02, 1.830251850988715552e+02, 2.175079854175568113e+02, 2.598498278995140400e+02, 3.121245867818556035e+02, 3.770245173783702458e+02, 4.580653020257635092e+02, 5.598658426219653689e+02, 6.885324967857802403e+02, 8.521902266884453403e+02, 1.061721815114114004e+03, 1.331803836529085656e+03, 1.682368940494210217e+03, 2.140685129891926443e+03, 2.744334847491432747e+03, 3.545516659371773357e+03, 4.617306735234797694e+03, 6.062848530677391758e+03, 8.028955134017154634e+03, 1.072641999277462936e+04, 1.446061873485939411e+04, 1.967804579389513789e+04, 2.703776201447279367e+04, 3.752217148194723312e+04, 5.261052412010591097e+04, 7.455350923854624329e+04, 1.068125318497402759e+05, 1.547702528541975911e+05, 2.268930751685412563e+05, 3.366554971645478061e+05, 5.057644049026088560e+05, 7.696291826884134742e+05, 1.186761864945790800e+06, 1.855146094294667715e+06, 2.941132644236832276e+06, 4.731169740596920355e+06, 7.725765147199987935e+06, 1.281272565991955126e+07, 2.159151785284808339e+07, 3.699029448836502904e+07, 6.445902263727884020e+07, 1.143158678867853615e+08, 2.064425450996979446e+08, 3.798502995329785506e+08, 7.125329484929003007e+08, 1.363463294023391629e+09, 2.663196590686555077e+09, 5.313347815419462975e+09, 1.083506369700027396e+10, 2.259930737910197667e+10, 4.824707991473375387e+10, 1.055069002818752104e+11, 2.365138040635727209e+11, 5.439266129959972285e+11, 1.284356371641026839e+12, 3.116424654245920797e+12, 7.777312465656280419e+12, 1.997984843259596733e+13, 5.288649037339853118e+13, 1.443776937640548342e+14, 4.068967444890414804e+14, 1.185049702391501141e+15, 3.570348091883284324e+15, 1.113971254034978026e+16, 3.603374982229766184e+16, 1.209803708182151942e+17, 4.220890251904870611e+17, 1.532169872312865862e+18, 5.793890867821715890e+18, 2.285379920879842924e+19, 9.415714369232187727e+19, 4.057471211245170887e+20, 1.831405465804324767e+21, 8.671209773404504008e+21, 4.313209261217173994e+22, 2.257498454242656934e+23, 1.245267136898199709e+24, 7.251536499435180219e+24, 4.465573963364524765e+25, 2.913233420596266283e+26, 2.017063171206072979e+27, 1.485014353353330393e+28, 1.164811091759882662e+29, 9.753661264047912784e+29, 8.737124417851167566e+30, 8.390503265508677363e+31, 8.657362701430272680e+32, 9.619472292454361392e+33, 1.153735498483960294e+35, 1.497284701983562213e+36, 2.107816695320163748e+37, 3.227106623185610745e+38, 5.387696372515021985e+39, 9.835496017627849225e+40, 1.968904749086105300e+42, 4.334704147416758275e+43, 1.052717645113369473e+45, 2.829013521120326147e+46, 8.439656297525588822e+47, 2.804279894508234869e+49, 1.041383695988523864e+51, 4.337366591019718310e+52, 2.033523569151676725e+54, 1.077238847489773081e+56, 6.472891251891105455e+57, 4.429404678715878536e+59, 3.466135480828349864e+61, 3.114928656972704276e+63, 3.228947925415990689e+65, 3.878402486902381042e+67, 5.423187597439531197e+69, 8.870779393460412583e+71, 1.705832285076755970e+74, 3.876224350373120420e+76, 1.046359534886878004e+79, 3.373858809560757544e+81, 1.306762499786044015e+84, 6.115300889685679832e+86, 3.478550048884517349e+89, 2.420073578988056289e+92, 2.072453567501123129e+95, 2.199029867204449277e+98, 2.910868575802139983e+101, 4.840699137490951163e+104, 1.018669397739170369e+108, 2.733025017438095928e+111, 9.420797277586029837e+114, 4.205525105722885986e+118, 2.451352708852151939e+122, 1.881577053794165543e+126, 1.918506219134233785e+130, 2.622069659115564900e+134, 4.848463485415763756e+138, 1.224645005481997780e+143, 4.267387286482591954e+147, 2.072505613372582377e+152, }, + { 1.323228129684237783e-161, 4.129002973520822791e-159, 1.178655462569548882e-156, 3.082189008893206231e-154, 7.393542832199414487e-152, 1.629100644355328639e-149, 3.301545529059822941e-147, 6.162031390854241227e-145, 1.060528194470986309e-142, 1.685225757497235089e-140, 2.475534097582263629e-138, 3.365764749507587192e-136, 4.240562683924022383e-134, 4.956794227885611715e-132, 5.381716367914161520e-130, 5.433507172294988849e-128, 5.107031242794315420e-126, 4.473704932098646394e-124, 3.656376947377888629e-122, 2.791170022694259001e-120, 1.992200238692415032e-118, 1.330894359393789718e-116, 8.330356767359890503e-115, 4.890256639970245146e-113, 2.695128935451165447e-111, 1.395829605415630844e-109, 6.799997527188085942e-108, 3.119037767379032293e-106, 1.348260131419216291e-104, 5.497526018943990804e-103, 2.116384670251198533e-101, 7.699148714858061209e-100, 2.649065347250598345e-98, 8.628189263549727753e-97, 2.662520943248368922e-95, 7.790698623582886341e-94, 2.163354866683077281e-92, 5.705576739797220361e-91, 1.430338193028564913e-89, 3.411040781372328747e-88, 7.744268073516449037e-87, 1.675136564303435813e-85, 3.454795810595704816e-84, 6.798573137099477363e-83, 1.277474708033782661e-81, 2.293702139426309483e-80, 3.938021700015175030e-79, 6.469593934876300124e-78, 1.017725266990912471e-76, 1.534019529793324951e-75, 2.216999886838860916e-74, 3.074100747562803362e-73, 4.092295330837549092e-72, 5.233434175636538471e-71, 6.433506079763357418e-70, 7.607042677901362161e-69, 8.656714387163425357e-68, 9.486746058685489974e-67, 1.001756724248288397e-65, 1.019853943834854330e-64, 1.001591106610665630e-63, 9.494277822444263952e-63, 8.691422918891890649e-62, 7.687977047887448276e-61, 6.574408104196605248e-60, 5.438162502918425191e-59, 4.353340831363003212e-58, 3.374338762181243411e-57, 2.533770921173042330e-56, 1.844048925248616738e-55, 1.301410812308480184e-54, 8.910466744374470063e-54, 5.921538384124132331e-53, 3.821356134297705127e-52, 2.395780657353036891e-51, 1.459882187581820236e-50, 8.650105472076777327e-50, 4.985933550797199316e-49, 2.796911903237435916e-48, 1.527570118993503332e-47, 8.126314048196993302e-47, 4.212436363948578182e-46, 2.128604050242564662e-45, 1.048938356323431072e-44, 5.042753142653687842e-44, 2.365999225494165364e-43, 1.083813462091040325e-42, 4.848963367960316169e-42, 2.119612873737657277e-41, 9.055947139022002648e-41, 3.782987192192666650e-40, 1.545649846917574765e-39, 6.178909752126026357e-39, 2.417597558625940386e-38, 9.261305999966332746e-38, 3.474712971194656115e-37, 1.277215890629181345e-36, 4.600938133935473864e-36, 1.624804314773052044e-35, 5.626808103137929972e-35, 1.911442429947086471e-34, 6.371300415498187125e-34, 2.084444531309441237e-33, 6.695356060065574234e-33, 2.112038435637792931e-32, 6.544802906551512393e-32, 1.992864937623987114e-31, 5.964358817764151755e-31, 1.754973231464949500e-30, 5.078231558861773863e-30, 1.445447866528259475e-29, 4.048099759391660786e-29, 1.115752878927994221e-28, 3.027334168442338592e-28, 8.087868498106224788e-28, 2.128106544151858936e-27, 5.516210113930227985e-27, 1.408890921124863906e-26, 3.546520734326774807e-26, 8.800636481096360494e-26, 2.153319509043984465e-25, 5.196136544731926346e-25, 1.236869058422202190e-24, 2.904891674490918873e-24, 6.732707317563258763e-24, 1.540253603361391055e-23, 3.478765727687221019e-23, 7.758450079933031976e-23, 1.708939324269830276e-22, 3.718467010568811152e-22, 7.994094376769029920e-22, 1.698336774318343123e-21, 3.566214469724002275e-21, 7.402848534866351662e-21, 1.519411719755297549e-20, 3.083993994528608740e-20, 6.191388817974459809e-20, 1.229625987010589227e-19, 2.416245949308411084e-19, 4.698551818749419706e-19, 9.042992978848520439e-19, 1.722880198390020817e-18, 3.249832858354112322e-18, 6.070120594586457562e-18, 1.122871881646098441e-17, 2.057429235664205922e-17, 3.734613207742816399e-17, 6.716694369267842075e-17, 1.197063025055043952e-16, 2.114419661115663617e-16, 3.702017138231021853e-16, 6.425665498746337860e-16, 1.105830903726985419e-15, 1.887156051660563224e-15, 3.193979018679125833e-15, 5.361881977473204459e-15, 8.929318568606692809e-15, 1.475330560958586660e-14, 2.418708636765824964e-14, 3.935078350904051302e-14, 6.354047096308654479e-14, 1.018416666466509442e-13, 1.620423782999307693e-13, 2.559817517056126166e-13, 4.015273886294212810e-13, 6.254532358261761291e-13, 9.675981021394182858e-13, 1.486832112534566186e-12, 2.269557377760486879e-12, 3.441736008766365832e-12, 5.185793859860652413e-12, 7.764217889314004663e-12, 1.155228105746548036e-11, 1.708313121464262097e-11, 2.510951856086201897e-11, 3.668776978510952341e-11, 5.329131813941740314e-11, 7.696325397299480856e-11, 1.105200723643722855e-10, 1.578221843796034825e-10, 2.241309672940976766e-10, 3.165773201144956642e-10, 4.447730510871610704e-10, 6.216041661455164049e-10, 8.642544905395987868e-10, 1.195519306516659349e-09, 1.645482121417189823e-09, 2.253643612941620883e-09, 3.071610576496751310e-09, 4.166474690460445927e-09, 5.625036504185181035e-09, 7.559059638953998396e-09, 1.011177417876491092e-08, 1.346588701906267454e-08, 1.785340092957703350e-08, 2.356759364235337519e-08, 3.097756373337616088e-08, 4.054581171302714730e-08, 5.284939280085554173e-08, 6.860525247854168448e-08, 8.870043714076795346e-08, 1.142279599340281637e-07, 1.465291959965373757e-07, 1.872437814520259903e-07, 2.383680961705324062e-07, 3.023235208219232784e-07, 3.820357732606947876e-07, 4.810267467496160044e-07, 6.035203917139166314e-07, 7.545643021775656875e-07, 9.401687861337141280e-07, 1.167465314019272078e-06, 1.444886349199346242e-06, 1.782368666762205796e-06, 2.191582359683820240e-06, 2.686187812137005286e-06, 3.282122985909738110e-06, 3.997923415034129149e-06, 4.855077333283880469e-06, 5.878418366687560187e-06, 7.096558206229387964e-06, 8.542361632206236097e-06, 1.025346618920209381e-05, 1.227284870748632855e-05, 1.464944073127878202e-05, 1.743879474552002742e-05, 2.070380288967650755e-05, 2.451546960924430874e-05, 2.895373942298085844e-05, 3.410838067694928604e-05, 4.007992581615393488e-05, 4.698066833232878622e-05, 5.493571614427227251e-05, 6.408410073746518169e-05, 7.457994093551813828e-05, 8.659365970069775654e-05, 1.003132518682442285e-04, 1.159456002136906496e-04, 1.337178367385581674e-04, 1.538787455425709779e-04, 1.767002031351005554e-04, 2.024786515302844608e-04, 2.315365989746650402e-04, 2.642241426787982083e-04, 3.009205074706080013e-04, 3.420355938637258307e-04, 3.880115286439000550e-04, 4.393242107257947798e-04, 4.964848447258090522e-04, 5.600414544382562271e-04, 6.305803681962314437e-04, 7.087276679481586600e-04, 7.951505937892094439e-04, 8.905588956558126794e-04, 9.957061239230124343e-04, 1.111390850739538593e-03, 1.238457814094548688e-03, 1.377798976832850428e-03, 1.530354493121150144e-03, 1.697113575214988470e-03, 1.879115253782404405e-03, 2.077449025503311209e-03, 2.293255382179820056e-03, 2.527726216158548279e-03, 2.782105097477072741e-03, 3.057687418798497807e-03, 3.355820404885606963e-03, 3.677902984083964409e-03, 4.025385520026097270e-03, 4.399769402530814407e-03, 4.802606497446985045e-03, 5.235498455973840111e-03, 5.700095884774212336e-03, 6.198097378977308725e-03, 6.731248420937948614e-03, 7.301340148374219834e-03, 7.910207996239952125e-03, 8.559730217397303903e-03, 9.251826287833445298e-03, 9.988455202809488913e-03, 1.077161367093554544e-02, 1.160333421372954856e-02, 1.248568317873621646e-02, 1.342075867475355427e-02, 1.441068843813546585e-02, 1.545762763950860648e-02, 1.656375664055830135e-02, 1.773127871080136402e-02, 1.896241771447260382e-02, 2.025941577780677588e-02, 2.162453094709917839e-02, 2.306003484797691421e-02, 2.456821035631025318e-02, 2.615134929114115217e-02, 2.781175013990572523e-02, 2.955171582608151263e-02, 3.137355152920124081e-02, 3.327956256694509270e-02, 3.527205234875621605e-02, 3.735332041012234938e-02, 3.952566053633324126e-02, 4.179135898416228534e-02, 4.415269280953487221e-02, 4.661192830883879903e-02, 4.917131958110712872e-02, 5.183310721786459418e-02, 5.459951712697841302e-02, 5.747275949639657337e-02, 6.045502790319455825e-02, 6.354849857288828754e-02, 6.675532979350985865e-02, 7.007766148848641979e-02, 7.351761495191403887e-02, 7.707729274938041525e-02, 8.075877878706524317e-02, 8.456413855143733669e-02, 8.849541952147546057e-02, 9.255465175496720496e-02, 9.674384865008904765e-02, 1.010650078831426502e-01, 1.055201125230189472e-01, 1.101111323226840632e-01, 1.148400251877307103e-01, 1.197087388218165293e-01, 1.247192125486176994e-01, 1.298733793097628269e-01, 1.351731678380792159e-01, 1.406205050053816316e-01, 1.462173183439629526e-01, 1.519655387409069424e-01, 1.578671033043359383e-01, 1.639239584007306411e-01, 1.701380628625154331e-01, 1.765113913651907042e-01, 1.830459379734134606e-01, 1.897437198555789051e-01, 1.966067811666385690e-01, 2.036371970991047974e-01, 2.108370781024367852e-01, 2.182085742712797843e-01, 2.257538799033364379e-01, 2.334752382279873511e-01, 2.413749463071469410e-01, 2.494553601102403241e-01, 2.577188997656175820e-01, 2.661680549911833443e-01, 2.748053907075124803e-01, 2.836335528372471376e-01, 2.926552742951268547e-01, 3.018733811735925662e-01, 3.112907991295277084e-01, 3.209105599783561596e-01, 3.307358085024083972e-01, 3.407698094811951648e-01, 3.510159549519934555e-01, 3.614777717099542274e-01, 3.721589290577866932e-01, 3.830632468159621812e-01, 3.941947036053136035e-01, 4.055574454148868711e-01, 4.171557944689308074e-01, 4.289942584079951543e-01, 4.410775398002453309e-01, 4.534105460003012245e-01, 4.659983993741692944e-01, 4.788464479101668631e-01, 4.919602762371392109e-01, 5.053457170727489659e-01, 5.190088631261786795e-01, 5.329560794812372669e-01, 5.471940164876055195e-01, 5.617296231898020413e-01, 5.765701613254061793e-01, 5.917232199261468491e-01, 6.071967305576643327e-01, 6.229989832360855492e-01, 6.391386430620321596e-01, 6.556247676153161584e-01, 6.724668251563812272e-01, 6.896747136835329047e-01, 7.072587808981804764e-01, 7.252298451337033758e-01, 7.435992173071710726e-01, 7.623787239570054101e-01, 7.815807314337971290e-01, 8.012181713158943859e-01, 8.213045671260926392e-01, 8.418540624307963733e-01, 8.628814504084197628e-01, 8.844022049795737430e-01, 9.064325135977815717e-01, 9.289893118061069464e-01, 9.520903196722039764e-01, 9.757540802219457353e-01, 1.000000000000000000e+00, 1.024848391894543008e+00, 1.050320520372784475e+00, 1.076438649284173871e+00, 1.103226092399127978e+00, 1.130707266862927052e+00, 1.158907749757141229e+00, 1.187854337974646084e+00, 1.217575111629048984e+00, 1.248099501235266386e+00, 1.279458358915164500e+00, 1.311684033900709062e+00, 1.344810452627081143e+00, 1.378873203729832710e+00, 1.413909628283517352e+00, 1.449958915644490754e+00, 1.487062205287898607e+00, 1.525262695058439148e+00, 1.564605756286502811e+00, 1.605139056255971231e+00, 1.646912688547541313e+00, 1.689979311822189937e+00, 1.734394297653598793e+00, 1.780215888066332921e+00, 1.827505363488657555e+00, 1.876327221885466881e+00, 1.926749369898304239e+00, 1.978843326886336694e+00, 2.032684442834914613e+00, 2.088352131177556992e+00, 2.145930117663470432e+00, 2.205506706496711366e+00, 2.267175065075584681e+00, 2.331033528772661605e+00, 2.397185927317806037e+00, 2.465741934479827004e+00, 2.536817442887937264e+00, 2.610534965993323711e+00, 2.687024069345184956e+00, 2.766421833546071979e+00, 2.848873351459948781e+00, 2.934532262474922666e+00, 3.023561326873131923e+00, 3.116133043635102211e+00, 3.212430315307524598e+00, 3.312647163894682976e+00, 3.416989502097797957e+00, 3.525675964626843197e+00, 3.638938804749809967e+00, 3.757024861729272487e+00, 3.880196605330264341e+00, 4.008733264172298986e+00, 4.142932045347867609e+00, 4.283109453446644399e+00, 4.429602717916437040e+00, 4.582771338567048147e+00, 4.742998759991079249e+00, 4.910694186746867507e+00, 5.086294552335034437e+00, 5.270266656314831820e+00, 5.463109485364516396e+00, 5.665356735708146927e+00, 5.877579556128345480e+00, 6.100389532781943879e+00, 6.334441939256981670e+00, 6.580439277782222274e+00, 6.839135140254664526e+00, 7.111338420820842566e+00, 7.397917915172903763e+00, 7.699807345544508469e+00, 8.018010854664294474e+00, 8.353609016702406728e+00, 8.707765418592385473e+00, 9.081733871099147484e+00, 9.476866315716376006e+00, 9.894621501007146275e+00, 1.033657451045679019e+01, 1.080442723340841910e+01, 1.130001988133777781e+01, 1.182534366375335115e+01, 1.238255475156052427e+01, 1.297398967101161563e+01, 1.360218228861306245e+01, 1.426988256684760289e+01, 1.498007729260327644e+01, 1.573601300513857081e+01, 1.654122137866316500e+01, 1.739954734664685784e+01, 1.831518029132688981e+01, 1.929268866318984532e+01, 2.033705844217826172e+01, 2.145373590584482942e+01, 2.264867523060898736e+01, 2.392839152177298272e+01, 2.530001994731418268e+01, 2.677138174118011529e+01, 2.835105794560498805e+01, 3.004847188085487195e+01, 3.187398146713610639e+01, 3.383898267989664904e+01, 3.595602559959535672e+01, 3.823894472392493310e+01, 4.070300544879345396e+01, 4.336506889917953679e+01, 4.624377760823269784e+01, 4.935976490967979071e+01, 5.273589133292714765e+01, 5.639751178186770847e+01, 6.037277784867852275e+01, 6.469298027622754351e+01, 6.939293735292118365e+01, 7.451143592061966836e+01, 8.009173272176674066e+01, 8.618212503236856949e+01, 9.283660095406551480e+01, 1.001155814082968890e+02, 1.080867678325352448e+02, 1.168261118752949279e+02, 1.264189260858047240e+02, 1.369611577708331715e+02, 1.485608519349011866e+02, 1.613398336385932743e+02, 1.754356453320629017e+02, 1.910037809024609590e+02, 2.082202655019913565e+02, 2.272846389233001078e+02, 2.484234106336023257e+02, 2.718940668983047258e+02, 2.979897251188232016e+02, 3.270445480633676878e+02, 3.594400516741229885e+02, 3.956124653087335485e+02, 4.360613334959077953e+02, 4.813595846269808355e+02, 5.321653357808338203e+02, 5.892357556996862196e+02, 6.534433717775449045e+02, 7.257952842284018994e+02, 8.074558443729566627e+02, 8.997734679339701200e+02, 1.004312392957944252e+03, 1.122890361185594877e+03, 1.257623408459775530e+03, 1.410979202907522234e+03, 1.585840680166573460e+03, 1.785582106601447262e+03, 2.014160171499825914e+03, 2.276223289283167479e+03, 2.577243010007973485e+03, 2.923672325162804598e+03, 3.323136759290736047e+03, 3.784665511113575050e+03, 4.318971620160236406e+03, 4.938792274850918489e+03, 5.659303058273368331e+03, 6.498623292476395004e+03, 7.478433875318933386e+03, 8.624734342286166238e+03, 9.968772633484590145e+03, 1.154818959559393902e+04, 1.340843110702649390e+04, 1.560449453908580443e+04, 1.820309391023133793e+04, 2.128535066649680777e+04, 2.495014598048375046e+04, 2.931830770482188047e+04, 3.453785313845473397e+04, 4.079057084931056631e+04, 4.830030527863206410e+04, 5.734341246586992004e+04, 6.826199159022146453e+04, 8.148067525594191464e+04, 9.752799507478730867e+04, 1.170636462204808295e+05, 1.409133795481584143e+05, 1.701137853111825512e+05, 2.059699426710509940e+05, 2.501298539735692463e+05, 3.046808435555379486e+05, 3.722747886360361411e+05, 4.562913164460176067e+05, 5.610511554921845541e+05, 6.920959565810343691e+05, 8.565564972181198149e+05, 1.063638800552326000e+06, 1.325268101226286025e+06, 1.656944841847240121e+06, 2.078886479301160156e+06, 2.617555920130068069e+06, 3.307714852226224955e+06, 4.195192293202626259e+06, 5.340631300250745566e+06, 6.824578495767020734e+06, 8.754424053248831818e+06, 1.127390159772263517e+07, 1.457614342739689625e+07, 1.892169326841938100e+07, 2.466345986800667442e+07, 3.228142821711217588e+07, 4.243114571539869754e+07, 5.601173714434088431e+07, 7.426172509723072112e+07, 9.889461357830121731e+07, 1.322915875470427182e+08, 1.777766240727455981e+08, 2.400110583389834263e+08, 3.255621033641982742e+08, 4.437258820593761403e+08, 6.077246218504877165e+08, 8.364565879857375417e+08, 1.157066594326456169e+09, 1.608740826498742961e+09, 2.248337657948688269e+09, 3.158785978851336228e+09, 4.461677081363911380e+09, 6.336244831048209270e+09, 9.048130159588677560e+09, 1.299321362309972265e+10, 1.876478261212947929e+10, 2.725703976712888971e+10, 3.982553459064288940e+10, 5.853727794017415415e+10, 8.656299089553103385e+10, 1.287959733041898747e+11, 1.928345065430099883e+11, 2.905510467545806044e+11, 4.406145488098485809e+11, 6.725708918778493152e+11, 1.033486938212196930e+12, 1.598840557086695854e+12, 2.490490134218272825e+12, 3.906528466724583921e+12, 6.171225147961354244e+12, 9.819163736485109137e+12, 1.573800106991564475e+13, 2.541245461530031221e+13, 4.134437628407981776e+13, 6.778141973485971528e+13, 1.119906286595884492e+14, 1.865016806041768967e+14, 3.130890948724989738e+14, 5.298978847669068280e+14, 9.042973899804181753e+14, 1.556259036818991439e+15, 2.701230066368200812e+15, 4.729430105054711279e+15, 8.353779033096586530e+15, 1.488827606293191651e+16, 2.677653466031614956e+16, 4.860434481369499270e+16, 8.905735519300993312e+16, 1.647413728306871552e+17, 3.077081325673016377e+17, 5.804234101329097680e+17, 1.105828570628099614e+18, 2.128315358808074026e+18, 4.138651532085235581e+18, 8.132554212123920035e+18, 1.615146503312570855e+19, 3.242548467260718193e+19, 6.581494581080701321e+19, 1.350831366183090003e+20, 2.804093832520937396e+20, 5.888113683467563837e+20, 1.250923435312468276e+21, 2.689280279098215635e+21, 5.851582825664479700e+21, 1.288917231788944660e+22, 2.874582763768997631e+22, 6.492437335109217869e+22, 1.485286605867082177e+23, 3.442469159113307066e+23, 8.084930196860438207e+23, 1.924506778048094878e+24, 4.643992662491470729e+24, 1.136281452083591334e+25, 2.819664891060694571e+25, 7.097781559991856367e+25, 1.812838850127688486e+26, 4.699012851344539124e+26, 1.236419707162832951e+27, 3.303236261210411286e+27, 8.962558097638891218e+27, 2.470294852986226117e+28, 6.918270960555942883e+28, 1.969189447958411510e+29, 5.698092609453981289e+29, 1.676626156396922084e+30, 5.017901520171556970e+30, 1.527929892279834489e+31, 4.734762318366711949e+31, 1.493572546446777040e+32, 4.797441164681908184e+32, 1.569538296400998732e+33, 5.231651156910242454e+33, 1.777206511525290941e+34, 6.154587299576916134e+34, 2.173469781356604872e+35, 7.829529896526581616e+35, 2.877935554073076917e+36, 1.079761320923458592e+37, 4.136337730951207042e+37, 1.618408489711185844e+38, 6.469770640447824771e+38, 2.643413654859316358e+39, 1.104246728308525703e+40, 4.717842641881260665e+40, 2.062296462389327711e+41, 9.226680005161257219e+41, 4.226544071632731963e+42, 1.983043729707066518e+43, 9.533448690970155039e+43, 4.697914578740208606e+44, 2.373923101980436574e+45, 1.230570211868531753e+46, 6.546344338411695147e+46, 3.575371819335804914e+47, 2.005642453538335506e+48, 1.156055268028903078e+49, 6.849867807870312958e+49, 4.174004815218951121e+50, 2.616872034052857472e+51, 1.688750346837297725e+52, 1.122275666009684101e+53, 7.683968740248677071e+53, 5.422849612654278583e+54, 3.946686701799533415e+55, 2.963543587288132884e+56, 2.297086395798939516e+57, 1.838856414208555761e+58, 1.521049475711243996e+59, 1.300732291175071112e+60, 1.150559591141716740e+61, 1.053265997373725461e+62, 9.984114209879020836e+62, 9.805325615938694719e+63, 9.982463564199115995e+64, 1.054102211457911410e+66, 1.155172684780782463e+67, 1.314571302334116663e+68, 1.554362407685457310e+69, 1.910791206002645077e+70, 2.443616403890711206e+71, 3.252983822318823232e+72, 4.510600140020139737e+73, 6.518821831001902447e+74, 9.825834460774267633e+75, 1.545692063622722856e+77, 2.539346088408163253e+78, 4.359763993811836117e+79, 7.827943627464404744e+80, 1.470896877674301183e+82, 2.894527071420674290e+83, 5.969662541607915492e+84, 1.291277613981057357e+86, 2.931656535626877923e+87, 6.991353547531463135e+88, 1.752671194525972852e+90, 4.622450137056020715e+91, 1.283581933169566226e+93, 3.755839001138390788e+94, 1.158991729845978702e+96, 3.774916315438862678e+97, 1.298844894462381673e+99, 4.725038949943384889e+100, 1.819000031203286740e+102, 7.416966330876906188e+103, 3.206116996910598204e+105, 1.470588770071975193e+107, 7.164198238238641057e+108, 3.710397624567077270e+110, 2.044882454279709373e+112, 1.200428778654730225e+114, 7.513744370030172114e+115, 5.019575746343410636e+117, 3.582726927665698318e+119, 2.734947775877248560e+121, 2.235283764078944248e+123, 1.958084751118243323e+125, 1.840431913109305657e+127, 1.858143260692831108e+129, 2.017432949655777136e+131, 2.358177615888101494e+133, 2.971092974178603610e+135, 4.039532321435816302e+137, 5.933923069661132195e+139, 9.429263693444953240e+141, 1.622841456932873872e+144, 3.028884476067694180e+146, 6.138356175015339477e+148, 1.352531557191942648e+151, 3.244447362295582945e+153, }, + }; + m_weights = { + { 2.703640234162693583e-160, 3.100862940179668765e-58, 5.828334625665462970e-21, 1.628894422402653830e-07, 8.129907377394029252e-03, 2.851214447180802931e-01, 1.228894002317118650e+00, 9.374610761705565881e+00, 6.136846875218162167e+02, 8.367995944653844271e+06, 2.286032371256753845e+17, 9.029964022492184559e+44, 1.637973037681055808e+119, }, + { 1.029757744225565290e-96, 5.564174008086804112e-35, 1.534846576427062716e-12, 1.519539651119905182e-04, 7.878691652861874032e-02, 6.288072016384128612e-01, 2.842403831496369386e+00, 5.152309209026500589e+01, 2.554172947873109927e+04, 8.291547503290989754e+10, 6.794911791960761587e+27, 1.108995159102362663e+73, }, + { 1.545310485347377408e-124, 4.549745016271158113e-75, 3.781189989988588481e-45, 4.369440793304363176e-27, 3.253896178006708087e-16, 1.057239289288944987e-09, 7.826174663495492476e-06, 1.459783224353939263e-03, 2.972970552567852420e-02, 1.637950661613330541e-01, 4.392303913269138921e-01, 8.744243777287317807e-01, 1.804759465860974506e+00, 4.894937215283148383e+00, 2.036214502429748943e+01, 1.576549789679037479e+02, 3.249553828744194733e+03, 3.335686029489862584e+05, 4.858218914917275532e+08, 5.655171002571584464e+13, 9.084276291356790926e+21, 2.202757570781655071e+35, 1.851176020895552142e+57, 1.873046373612647920e+93, 3.113183070605141140e+152, }, + { 2.690380169654157101e-141, 9.388760099830475385e-110, 3.267856956418766261e-85, 4.012903562780032075e-66, 2.794595941054873674e-51, 9.598140333687791635e-40, 8.762766371925782803e-31, 7.896919977115783593e-24, 1.951680620313826776e-18, 2.931867534349928041e-14, 4.976350908135118762e-11, 1.546933241860617074e-08, 1.283189791774752963e-06, 3.809052946018782340e-05, 5.087526585392884730e-04, 3.656819625189471368e-03, 1.627679402690602992e-02, 5.011672130624018967e-02, 1.165913368715250324e-01, 2.201514148384271336e-01, 3.581909054968942386e-01, 5.288599003801643436e-01, 7.422823219366348741e-01, 1.032914080772662205e+00, 1.478415067523268199e+00, 2.242226697017918644e+00, 3.684755742578570582e+00, 6.677326887819023056e+00, 1.358063058433697357e+01, 3.171262375809110066e+01, 8.776338468947827779e+01, 3.006939713363920293e+02, 1.352196150715330628e+03, 8.616353573310419356e+03, 8.591849573350877359e+04, 1.523635814554291966e+06, 5.663834603448267056e+07, 5.450828629396188577e+09, 1.780881993484818221e+12, 2.797112703281894578e+15, 3.300887168363313931e+19, 5.192538272313512016e+24, 2.273085973059979872e+31, 7.124498195222272142e+39, 5.379592741425673874e+50, 4.647296508337283075e+64, 3.395147156494395571e+82, 2.736576372417856435e+105, 6.584825756536212781e+134, }, + { 1.692276285171240629e-150, 1.180420021590838281e-132, 6.494931071412232065e-117, 4.979673804239645358e-103, 8.790122245397054202e-91, 5.564311726870413043e-80, 1.867634664877268411e-70, 4.693767384843440310e-62, 1.197772698674604837e-54, 4.060530886983702887e-48, 2.318268710612758367e-42, 2.748088060676949794e-37, 8.136086869664039226e-33, 7.081491999860360593e-29, 2.092407629019781417e-25, 2.383020547076997517e-22, 1.170143938604536054e-19, 2.734857915002515580e-17, 3.319894174569245506e-15, 2.260825106530477104e-13, 9.244747974241858562e-12, 2.410325858091057071e-10, 4.224928060220423782e-09, 5.217223349652829804e-08, 4.730110697329046717e-07, 3.265522864288710545e-06, 1.772851678458610971e-05, 7.787346612077215804e-05, 2.838101678971546354e-04, 8.775026198694109646e-04, 2.347474744139291716e-03, 5.529174974874315725e-03, 1.164520226280038968e-02, 2.223487842904240574e-02, 3.896253311038730452e-02, 6.334975706136386464e-02, 9.651712033300261848e-02, 1.390236708907266445e-01, 1.908593745910709887e-01, 2.515965688234414960e-01, 3.206651646562737595e-01, 3.976974208167367099e-01, 4.828935799767836828e-01, 5.773826389735376677e-01, 6.835838865575605461e-01, 8.056083579298257627e-01, 9.497742078309479997e-01, 1.125351459431134254e+00, 1.345711576612114788e+00, 1.630156867495860456e+00, 2.006880650908830857e+00, 2.517828844916874130e+00, 3.226826819856410846e+00, 4.233461155863004269e+00, 5.697400323487776530e+00, 7.882247346334201378e+00, 1.123717929435969530e+01, 1.655437952523069781e+01, 2.528458931361129124e+01, 4.019700050163276117e+01, 6.682515670231120695e+01, 1.168022589948424530e+02, 2.160045684819153702e+02, 4.257255901158116698e+02, 9.017180693982791021e+02, 2.072151523320542727e+03, 5.222689557952776194e+03, 1.461663959276604441e+04, 4.606455611513396576e+04, 1.660950339384278845e+05, 6.976630616605097333e+05, 3.484240083705972727e+06, 2.117385064786894718e+07, 1.607368605379557548e+08, 1.570235957877638143e+09, 2.041619284762317483e+10, 3.670425964529826371e+11, 9.527196643411724126e+12, 3.749667772735766186e+14, 2.365380223523087981e+16, 2.546815287226970627e+18, 5.026010591299970789e+20, 1.970775914722195502e+23, 1.682531038342715298e+26, 3.469062187981719410e+29, 1.942614547946028081e+33, 3.375034694941022784e+37, 2.115298406181711256e+42, 5.673738540911562268e+47, 7.904099301170483654e+53, 7.121903115084356741e+60, 5.321820777644930491e+68, 4.370977753639010591e+77, 5.429657931755513797e+87, 1.464602226824232950e+99, 1.292445035662836561e+112, 5.936633203060705474e+126, 2.402419924621336913e+143, }, + { 2.552410363565288863e-155, 7.965872719315690060e-146, 6.586401422963018216e-137, 1.563673437419490296e-128, 1.149636272392214573e-120, 2.810189759625314580e-113, 2.441446149780773329e-106, 8.026292508555041710e-100, 1.059034284623927886e-93, 5.927259046205893861e-88, 1.482220909125121967e-82, 1.738946448501809732e-77, 1.002047910184021813e-72, 2.960929073720769637e-68, 4.671749731809402860e-64, 4.088398674807775827e-60, 2.056642628601930023e-56, 6.149878578966749305e-53, 1.128142221531950274e-49, 1.307702777646013040e-46, 9.848757125541659318e-44, 4.946847667192787369e-41, 1.698284656321589089e-38, 4.077947349805764486e-36, 6.998897321243266048e-34, 8.762183229651405846e-32, 8.156281709801700633e-30, 5.747366069381804213e-28, 3.117951907317865517e-26, 1.323052992594482858e-24, 4.457166057119926322e-23, 1.208896132634708032e-21, 2.674697849739340358e-20, 4.887394807742436672e-19, 7.461632083041868391e-18, 9.622230748739818989e-17, 1.058884510032627118e-15, 1.003988180288807180e-14, 8.276358838778374127e-14, 5.982281469656734375e-13, 3.821855766886203088e-12, 2.174279097299082001e-11, 1.109294120074848583e-10, 5.109055596902086022e-10, 2.137447956882816268e-09, 8.170468538364022161e-09, 2.869308592926374871e-08, 9.305185930419436742e-08, 2.800231592227134982e-07, 7.855263634214717091e-07, 2.062924236714395731e-06, 5.092224131071637441e-06, 1.185972357373608535e-05, 2.615333473470835518e-05, 5.479175746096322166e-05, 1.093962713107868416e-04, 2.087714243290528595e-04, 3.818797556417767457e-04, 6.712796918790164790e-04, 1.136760145626956604e-03, 1.858775505765622915e-03, 2.941191222579735746e-03, 4.512821350378020080e-03, 6.727293426938802892e-03, 9.760915371480980900e-03, 1.380842853102550981e-02, 1.907678055354397196e-02, 2.577730275571060412e-02, 3.411688991056810143e-02, 4.428892397843486143e-02, 5.646473816310556552e-02, 7.078637998740884103e-02, 8.736131246718460273e-02, 1.062595125372295046e-01, 1.275132133780278017e-01, 1.511193209351630349e-01, 1.770443400812491404e-01, 2.052314915777496186e-01, 2.356095985715091716e-01, 2.681032744853198083e-01, 3.026439500331752405e-01, 3.391813282438962329e-01, 3.776949427111484449e-01, 4.182056049753837852e-01, 4.607866519948383101e-01, 5.055750360563806155e-01, 5.527824318481410262e-01, 6.027066663808878454e-01, 6.557439076684384801e-01, 7.124021812071310501e-01, 7.733169258916167748e-01, 8.392694625821144443e-01, 9.112094418201526544e-01, 9.902825786957198607e-01, 1.077865293953107863e+00, 1.175608288920191064e+00, 1.285491624542001346e+00, 1.409894601042286311e+00, 1.551684711657329886e+00, 1.714331263928885829e+00, 1.902051053858215699e+00, 2.119995922515087770e+00, 2.374495377438728901e+00, 2.673372087884984440e+00, 3.026354489757871517e+00, 3.445619726158519068e+00, 3.946512819227006419e+00, 4.548505964859933724e+00, 5.276487613615791435e+00, 6.162508226184798743e+00, 7.248163842886806184e+00, 8.587878410768473380e+00, 1.025346434903602082e+01, 1.234051869120733230e+01, 1.497748183201988157e+01, 1.833859935862139637e+01, 2.266266859437541631e+01, 2.828045768298752298e+01, 3.565528397044830339e+01, 4.544381261232990127e+01, 5.858833744254070379e+01, 7.645876087681923606e+01, 1.010741758687003802e+02, 1.354538987141142977e+02, 1.841824059064608872e+02, 2.543337025162468240e+02, 3.570103970895535977e+02, 5.099537256432247190e+02, 7.420561390174965949e+02, 1.101323941193719451e+03, 1.669232910686306616e+03, 2.587203282090385703e+03, 4.106608602134535014e+03, 6.685657263550896700e+03, 1.118216368762133982e+04, 1.924811115485038079e+04, 3.416174865734933127e+04, 6.263882227839496242e+04, 1.189094418952240294e+05, 2.342262528110389793e+05, 4.798899889628646876e+05, 1.025279649144740527e+06, 2.290428015483177407e+06, 5.365618820221241118e+06, 1.322172034826883742e+07, 3.438296542047893623e+07, 9.468905314460992170e+07, 2.771843378168242512e+08, 8.658950437199969679e+08, 2.898779165825890846e+09, 1.044627762990198184e+10, 4.071673625087267154e+10, 1.725245696783106160e+11, 7.989856904303845909e+11, 4.067537100664303783e+12, 2.290253922913114847e+13, 1.435560574531699914e+14, 1.008680130601194048e+15, 8.003530334765274913e+15, 7.227937568629809266e+16, 7.491693576707361828e+17, 8.991671234614216799e+18, 1.261556024888540618e+20, 2.090038400033346091e+21, 4.132773073376509056e+22, 9.865671928781943336e+23, 2.877978132616007671e+25, 1.039303004928044064e+27, 4.710544722984128252e+28, 2.719194692980296464e+30, 2.030608169419634520e+32, 1.994536427964099457e+34, 2.622806931876485852e+36, 4.705142628855489738e+38, 1.174794916996875010e+41, 4.170574236544843559e+43, 2.153441953645800917e+46, 1.656794933445123415e+49, 1.948830907651317326e+52, 3.601980393005358786e+55, 1.077033440153993124e+59, 5.374188883861674378e+62, 4.625267105826449467e+66, 7.111646979020385006e+70, 2.027996051444846521e+75, 1.116168784120367146e+80, 1.237019821283735086e+85, 2.888108172342166477e+90, 1.490426937972460544e+96, 1.789306677271856318e+102, 5.276973875344766848e+108, 4.051217867886536330e+115, 8.611617868168979525e+122, 5.412634353380155695e+130, 1.078756609821147465e+139, 7.344353246966125053e+147, }, + { 8.688318611421924613e-158, 6.864317997043424201e-153, 3.829638174036322920e-148, 1.524985558970066863e-143, 4.379527631402474835e-139, 9.162408388991747001e-135, 1.410086556664696347e-130, 1.611529786006329005e-126, 1.380269212504431613e-122, 8.938739565456142404e-119, 4.414803004265274778e-115, 1.676831992534574674e-111, 4.937648515671545377e-108, 1.136068312653058895e-104, 2.057969760853201132e-101, 2.956779836249922681e-98, 3.393449014375824853e-95, 3.132619285740674842e-92, 2.341677665639346254e-89, 1.426656997926173190e-86, 7.128825597334931865e-84, 2.939485275517928205e-81, 1.006113300119903410e-78, 2.874969402023240560e-76, 6.896713338909433222e-74, 1.396405038640012785e-71, 2.398869799873387326e-69, 3.514180228970525006e-67, 4.411557600438730779e-65, 4.768408435763044172e-63, 4.458287229998440383e-61, 3.621710763086768959e-59, 2.567373174003034094e-57, 1.594829856885795944e-55, 8.716746897177859412e-54, 4.208424534880021226e-52, 1.801637343401221381e-50, 6.864432292330768862e-49, 2.336084584516383243e-47, 7.125716658075193173e-46, 1.954733295862350631e-44, 4.838195020814970471e-43, 1.083903033389729471e-41, 2.204655424309513426e-40, 4.083431629921110537e-39, 6.907095608064865023e-38, 1.069951518082577963e-36, 1.521972185061747284e-35, 1.993254198127980161e-34, 2.409552194902670884e-33, 2.695243589253751811e-32, 2.796309045342585624e-31, 2.697138787161831243e-30, 2.423968619042656074e-29, 2.034233848004972409e-28, 1.597498662808006882e-27, 1.176341105034547043e-26, 8.138404856556384931e-26, 5.300199402716282910e-25, 3.255367628680633536e-24, 1.889060856810273071e-23, 1.037502167741821871e-22, 5.402129194695882094e-22, 2.671080147950250592e-21, 1.256163163817414397e-20, 5.627458451375099018e-20, 2.405110192151924414e-19, 9.820723025892385774e-19, 3.836610965933493002e-18, 1.435949417965440387e-17, 5.155736116435221852e-17, 1.778106820243535736e-16, 5.897650538103448384e-16, 1.883545377386949394e-15, 5.799022727889041128e-15, 1.723080101027408120e-14, 4.946559668895564981e-14, 1.373437058883951037e-13, 3.692057356296675476e-13, 9.618669754374864080e-13, 2.430904641718059201e-12, 5.965319652795549281e-12, 1.422677541958913512e-11, 3.300412010407028696e-11, 7.453993539444124847e-11, 1.640317480539372495e-10, 3.519919455549922227e-10, 7.371241496931924727e-10, 1.507573517782825692e-09, 3.013444008176544118e-09, 5.891170930525923854e-09, 1.127175867596519203e-08, 2.112135943063526334e-08, 3.878572405868819131e-08, 6.984140168311147329e-08, 1.233979234102365865e-07, 2.140481233406505212e-07, 3.647293211756793211e-07, 6.108366265875129839e-07, 1.006020283089617901e-06, 1.630199379920459998e-06, 2.600430208375972125e-06, 4.085372746054298735e-06, 6.324194831966406940e-06, 9.650830226718535837e-06, 1.452455211307694488e-05, 2.156782506321975658e-05, 3.161234361554654466e-05, 4.575404320696170555e-05, 6.541767069965264068e-05, 9.243122234114186712e-05, 1.291101968446571125e-04, 1.783511762821284409e-04, 2.437337497712608884e-04, 3.296292528289701234e-04, 4.413142327104518440e-04, 5.850859955683163216e-04, 7.683770763700705263e-04, 9.998650298180469208e-04, 1.289573601590465490e-03, 1.648961132392222413e-03, 2.090991995585424661e-03, 2.630186988492201910e-03, 3.282648895332118799e-03, 4.066059914467245175e-03, 4.999648283080481820e-03, 6.104122218554241819e-03, 7.401570199659662364e-03, 8.915327597805008451e-03, 1.066981070009509413e-02, 1.269032020049755525e-02, 1.500281723149735994e-02, 1.763367592672867332e-02, 2.060941730962251417e-02, 2.395642996410886880e-02, 2.770068343772389725e-02, 3.186744063963193757e-02, 3.648097561865623097e-02, 4.156430303997019336e-02, 4.713892543167989540e-02, 5.322460385886412684e-02, 5.983915712308283792e-02, 6.699829390463281224e-02, 7.471548149065050122e-02, 8.300185389391494996e-02, 9.186616129460712899e-02, 1.013147618591979452e-01, 1.113516561340355690e-01, 1.219785634003157786e-01, 1.331950386328042665e-01, 1.449986280439946752e-01, 1.573850606313672716e-01, 1.703484726870446791e-01, 1.838816618814874884e-01, 1.979763672973498048e-01, 2.126235716643688402e-01, 2.278138220265254991e-01, 2.435375651517067386e-01, 2.597854941629632707e-01, 2.765489031191654411e-01, 2.938200465906351752e-01, 3.115925016510994851e-01, 3.298615301301230823e-01, 3.486244394295739435e-01, 3.678809406939879716e-01, 3.876335036292959599e-01, 4.078877077798518471e-01, 4.286525905940105684e-01, 4.499409931290513174e-01, 4.717699047639316286e-01, 4.941608088016098926e-01, 5.171400313514193966e-01, 5.407390963876342256e-01, 5.649950903858123945e-01, 5.899510404480374918e-01, 6.156563103475134535e-01, 6.421670194591982411e-01, 6.695464901047961714e-01, 6.978657294374126896e-01, 7.272039526349696447e-01, 7.576491548751669105e-01, 7.892987403432202489e-01, 8.222602173936578230e-01, 8.566519699682320391e-01, 8.926041164852169437e-01, 9.302594686857616145e-01, 9.697746043788558519e-01, 1.011321069700320644e+00, 1.055086728430498711e+00, 1.101277278143300224e+00, 1.150117955536247302e+00, 1.201855456275760449e+00, 1.256760098152647779e+00, 1.315128260359919236e+00, 1.377285136373095709e+00, 1.443587843343442141e+00, 1.514428937238563465e+00, 1.590240390338335337e+00, 1.671498096302065311e+00, 1.758726978084942299e+00, 1.852506785760205887e+00, 1.953478685110838140e+00, 2.062352754065132708e+00, 2.179916523112736371e+00, 2.307044718290330681e+00, 2.444710391817196957e+00, 2.593997656772008968e+00, 2.756116279277535182e+00, 2.932418425642610903e+00, 3.124417914187536020e+00, 3.333812383735923205e+00, 3.562508865047068391e+00, 3.812653330296280988e+00, 4.086664902155689132e+00, 4.387275531849634155e+00, 4.717576109385405085e+00, 5.081070154695596855e+00, 5.481736462718817995e+00, 5.924102347216244340e+00, 6.413329458204850426e+00, 6.955314549766230740e+00, 7.556808065486941215e+00, 8.225554008952760095e+00, 8.970455302965185036e+00, 9.801769746699598466e+00, 1.073134279679936208e+01, 1.177288477943655549e+01, 1.294230185297226511e+01, 1.425809217068106541e+01, 1.574182134943112610e+01, 1.741869467329444792e+01, 1.931824763074534781e+01, 2.147518163232618457e+01, 2.393037838236259586e+01, 2.673213477270754163e+01, 2.993767083537830673e+01, 3.361497689655818107e+01, 3.784508348524495401e+01, 4.272485990900652026e+01, 4.837047622725585887e+01, 5.492170063250241752e+01, 6.254725265973777743e+01, 7.145149574983117631e+01, 8.188283528217430591e+01, 9.414429671899321190e+01, 1.086069017070108772e+02, 1.257266497442910506e+02, 1.460661655727672308e+02, 1.703224100743601641e+02, 1.993623058409479084e+02, 2.342687403011957198e+02, 2.764002385528330658e+02, 3.274687277481591846e+02, 3.896413615832930151e+02, 4.656745019682919178e+02, 5.590908996105107215e+02, 6.744152109571297875e+02, 8.174887172033244140e+02, 9.958921680864290197e+02, 1.219517071629880108e+03, 1.501341972869855447e+03, 1.858493492282554856e+03, 2.313705362529768409e+03, 2.897337235279879262e+03, 3.650185874628374320e+03, 4.627425468074182920e+03, 5.904167858279871204e+03, 7.583363128219763259e+03, 9.807105719965428472e+03, 1.277293273832114230e+04, 1.675749596877978193e+04, 2.215121038263169759e+04, 2.950937349291504490e+04, 3.962820433513419525e+04, 5.365890489878942635e+04, 7.328024305737981431e+04, 1.009620167752942516e+05, 1.403709568321740997e+05, 1.970019955923188504e+05, 2.791695960502382133e+05, 3.995801250202947693e+05, 5.778515877588312220e+05, 8.445944401474017243e+05, 1.248092975135001687e+06, 1.865367859966950385e+06, 2.820705292493674480e+06, 4.317063433830483499e+06, 6.689961127164684387e+06, 1.050111601631327499e+07, 1.670327884792325766e+07, 2.693430470211696200e+07, 4.404906898054894166e+07, 7.309535640536363311e+07, 1.231306812701882145e+08, 2.106560568719367745e+08, 3.662073971851359192e+08, 6.472124787519330196e+08, 1.163486593592585616e+09, 2.128658395254150452e+09, 3.965732938755983605e+09, 7.527735928223242836e+09, 1.456757162128879538e+10, 2.875798636941021041e+10, 5.794999654160054887e+10, 1.192767536774485257e+11, 2.509334090779650360e+11, 5.399624414800303207e+11, 1.189276111740286910e+12, 2.683103883355551677e+12, 6.205255919751506427e+12, 1.472284072112162717e+13, 3.586628373992547853e+13, 8.978594107356889337e+13, 2.311710197091641250e+14, 6.127020712804348908e+14, 1.673232679378485978e+15, 4.712671499032329365e+15, 1.370275025680988289e+16, 4.117347054027612886e+16, 1.279822436878842710e+17, 4.119762767831332886e+17, 1.374888606936629814e+18, 4.762483833659790733e+18, 1.714288404980390540e+19, 6.420200704842635702e+19, 2.504808062315322558e+20, 1.019355251138167687e+21, 4.332952958521756932e+21, 1.926416464889827426e+22, 8.971059571108856501e+22, 4.382317748928748816e+23, 2.249003059943548727e+24, 1.214458587662725100e+25, 6.911683912813140938e+25, 4.152578123301633020e+26, 2.638346388179288086e+27, 1.775811490887700718e+28, 1.268552401544524965e+29, 9.635786341213661742e+29, 7.797939379813000783e+30, 6.736900087983560033e+31, 6.226288752443836475e+32, 6.169035287163451891e+33, 6.567250104576983172e+34, 7.528666735185428595e+35, 9.316271421365627344e+36, 1.247410737003664698e+38, 1.811787648043939987e+39, 2.861918583157116420e+40, 4.929657099622567574e+41, 9.284951278562156071e+42, 1.917687997037326435e+44, 4.355948096683946408e+45, 1.091453486585817118e+47, 3.026206402784023251e+48, 9.314478983991942688e+49, 3.193195693823940775e+51, 1.223447678968662613e+53, 5.257403184148516426e+54, 2.543108925126136766e+56, 1.389947584026783879e+58, 8.616987336205957549e+59, 6.083777056769299984e+61, 4.911841077800001710e+63, 4.554259483169784661e+65, 4.870815185962582259e+67, 6.036211886847067841e+69, 8.708377755587698026e+71, 1.469655296381977267e+74, 2.915822924489215887e+76, 6.836044306573246016e+78, 1.903917300559946782e+81, 6.333813341980360028e+83, 2.531082268773868753e+86, 1.222077360592898816e+89, 7.172167453276776330e+91, 5.148160232410244898e+94, 4.548619807672339638e+97, 4.979632843475864923e+100, 6.800802744782331957e+103, 1.166855497965918386e+107, 2.533457765534279043e+110, 7.012864641215147208e+113, 2.494083354169569414e+117, 1.148722178881219993e+121, 6.908313932158993510e+124, 5.470912484744367184e+128, 5.755359832684120769e+132, 8.115681923907451939e+136, 1.548304780334447081e+141, 4.034912159113614601e+145, 1.450632759611715526e+150, 7.268799665580789770e+154, }, + { 4.901759085947701448e-159, 1.505832423620814399e-156, 4.231872109262999523e-154, 1.089479701785106001e-151, 2.572922387150651649e-149, 5.581311054334156941e-147, 1.113575900126970040e-144, 2.046165051332286084e-142, 3.466994885004770636e-140, 5.423795404073501922e-138, 7.843833272402847010e-136, 1.049922957933194415e-133, 1.302301071957418603e-131, 1.498659737828393008e-129, 1.601906622414286282e-127, 1.592248618401983561e-125, 1.473375345916436274e-123, 1.270651551394009593e-121, 1.022408263525766209e-119, 7.683762602329562781e-118, 5.399268127233373186e-116, 3.551074274853494676e-114, 2.188235409519121010e-112, 1.264667515430816934e-110, 6.861807566737243712e-109, 3.498691686825209963e-107, 1.678016807398375157e-105, 7.577439431441931490e-104, 3.224703770159386809e-102, 1.294487090677705963e-100, 4.906133250963454139e-99, 1.757121317988153326e-97, 5.952042491454320383e-96, 1.908566653286417264e-94, 5.798224459236429212e-93, 1.670293239978334727e-91, 4.566236673398083038e-90, 1.185617342791547945e-88, 2.926160027801296929e-87, 6.870061134126707137e-86, 1.535565783500379945e-84, 3.270036736778401257e-83, 6.639558007206580362e-82, 1.286319750967398593e-80, 2.379566581139022958e-79, 4.206268231398883425e-78, 7.109719237833379433e-77, 1.149915104115372777e-75, 1.780876201255594220e-74, 2.642703796179329883e-73, 3.760085375941719327e-72, 5.132920951124251993e-71, 6.727100274601427696e-70, 8.469585621347697498e-69, 1.025032382672232848e-67, 1.193219127557863348e-66, 1.336816930381306582e-65, 1.442283479679798385e-64, 1.499374555004793991e-63, 1.502797203133501438e-62, 1.453005969318485303e-61, 1.355980448377862540e-60, 1.222072412212552127e-59, 1.064223180270520159e-58, 8.959667396075636845e-58, 7.296288808079294105e-57, 5.750255296190181158e-56, 4.388011664829013518e-55, 3.243852451291832398e-54, 2.324239357665538806e-53, 1.614869776203026446e-52, 1.088524605545274842e-51, 7.121755574192829045e-51, 4.524647662549067074e-50, 2.792730715818793035e-49, 1.675384879603864227e-48, 9.773114328777676091e-48, 5.545910766847627082e-47, 3.062809705627873645e-46, 1.646862118038266234e-45, 8.625108513887155847e-45, 4.401687663868890701e-44, 2.189755778847646746e-43, 1.062345336449265889e-42, 5.028036663485684049e-42, 2.322524635717249223e-41, 1.047406593898341306e-40, 4.613438388449698168e-40, 1.985397445118162005e-39, 8.351027367454628343e-39, 3.434440903484543389e-38, 1.381489131877196646e-37, 5.437051201310225224e-37, 2.094357548080647717e-36, 7.898676618592006902e-36, 2.917536870947471272e-35, 1.055788886022716597e-34, 3.744333812160330812e-34, 1.301801185251957290e-33, 4.438346216893387768e-33, 1.484348268951816542e-32, 4.871001129849836971e-32, 1.568903000742513942e-31, 4.961295315917935235e-31, 1.540773910027990821e-30, 4.700558022172014910e-30, 1.409115230718949596e-29, 4.151913103955692034e-29, 1.202737613715427748e-28, 3.426327374934496736e-28, 9.601405359397026012e-28, 2.647278642033773301e-27, 7.183442220565147103e-27, 1.918850545981494042e-26, 5.046974779455992494e-26, 1.307394799925911700e-25, 3.336342198236957082e-25, 8.389259581136262194e-25, 2.079051813513548608e-24, 5.079178967243765280e-24, 1.223501794357837278e-23, 2.906654911057549530e-23, 6.811668606095015470e-23, 1.574985938238025303e-22, 3.593796788969348326e-22, 8.094185411205212564e-22, 1.799796183237481721e-21, 3.951758901641017285e-21, 8.569580068050865775e-21, 1.835753486517298696e-20, 3.885414339966022317e-20, 8.126613972895021790e-20, 1.680007182889503141e-19, 3.433369351563962828e-19, 6.937695550399427499e-19, 1.386345631008981755e-18, 2.740087497759230881e-18, 5.357570288683386626e-18, 1.036464933022803784e-17, 1.984249442010084992e-17, 3.759788006060003409e-17, 7.052211261821684795e-17, 1.309635641529546221e-16, 2.408275496109180528e-16, 4.385898809611711552e-16, 7.911758686849121285e-16, 1.413883597877183873e-15, 2.503477536644680210e-15, 4.392637866550705827e-15, 7.638710306960574612e-15, 1.316703360377476041e-14, 2.250031027275448919e-14, 3.812239733412214953e-14, 6.405021660191363479e-14, 1.067250538270319484e-13, 1.763897493784721010e-13, 2.891987565334547756e-13, 4.704242520369958085e-13, 7.592878273512691990e-13, 1.216183338372525172e-12, 1.933388593436624879e-12, 3.050826852442290751e-12, 4.779080020017636657e-12, 7.432734713385425098e-12, 1.147833888125873666e-11, 1.760286160372422754e-11, 2.681071101623953168e-11, 4.056023754295965437e-11, 6.095443492241537222e-11, 9.100550129616064211e-11, 1.349993452136967652e-10, 1.989943912395156051e-10, 2.914996073619059788e-10, 4.243900781412219621e-10, 6.141353162671391082e-10, 8.834365795894798511e-10, 1.263395594025933170e-09, 1.796369250051716047e-09, 2.539704143326480862e-09, 3.570592498287890499e-09, 4.992348403150539107e-09, 6.942471870489931483e-09, 9.602949600164561371e-09, 1.321333712761666777e-08, 1.808727901635346390e-08, 2.463325364767791516e-08, 3.338047870136870496e-08, 4.501108426108505069e-08, 6.039985413333259594e-08, 8.066305374526097834e-08, 1.072181059018892614e-07, 1.418561443795353991e-07, 1.868297699836383305e-07, 2.449586539172972009e-07, 3.197559780442760832e-07, 4.155790690867544334e-07, 5.378079713325544678e-07, 6.930561064776686194e-07, 8.894175852502122454e-07, 1.136756157868726006e-06, 1.447041212534730898e-06, 1.834736645332833504e-06, 2.317248822354253644e-06, 2.915440225825303911e-06, 3.654215709863551870e-06, 4.563188576773760151e-06, 5.677433909482232878e-06, 7.038336747307571784e-06, 8.694542758083067228e-06, 1.070301902702759858e-05, 1.313023243937403750e-05, 1.605345286789073897e-05, 1.956218797728780449e-05, 2.375975591555218862e-05, 2.876500146954361208e-05, 3.471416041263076209e-05, 4.176287576185915239e-05, 5.008836848967403773e-05, 5.989176390181730373e-05, 7.140057340280213227e-05, 8.487132973049760036e-05, 1.005923719620999934e-04, 1.188867746885496973e-04, 1.401154137398069279e-04, 1.646801587388731249e-04, 1.930271805904271778e-04, 2.256503597954330556e-04, 2.630947792533707128e-04, 3.059602829980946180e-04, 3.549050801425155303e-04, 4.106493712131842727e-04, 4.739789720708565436e-04, 5.457489087697051069e-04, 6.268869550379884668e-04, 7.183970825975973673e-04, 8.213627933082928901e-04, 9.369503011517966364e-04, 1.066411531385725184e-03, 1.211086903819095417e-03, 1.372407867107646339e-03, 1.551899151252505624e-03, 1.751180706119547318e-03, 1.971969294784470944e-03, 2.216079711850908971e-03, 2.485425598581779636e-03, 2.782019828718993257e-03, 3.107974441230220176e-03, 3.465500098895993776e-03, 3.856905054613959619e-03, 4.284593610523639393e-03, 4.751064058515097225e-03, 5.258906094345618421e-03, 5.810797701414435799e-03, 6.409501504198915943e-03, 7.057860595396970186e-03, 7.758793844909123446e-03, 8.515290702888369372e-03, 9.330405513145299523e-03, 1.020725135717912572e-02, 1.114899345297222760e-02, 1.215884213639836574e-02, 1.324004545661629463e-02, 1.439588142011718850e-02, 1.562964992113485073e-02, 1.694466439888404584e-02, 1.834424326453982033e-02, 1.983170114298836870e-02, 2.141033997615067889e-02, 2.308344003609062690e-02, 2.485425089716015368e-02, 2.672598241710042669e-02, 2.870179577730820310e-02, 3.078479463239356953e-02, 3.297801641870515720e-02, 3.528442387069167064e-02, 3.770689679281728890e-02, 4.024822413326941635e-02, 4.291109640390936770e-02, 4.569809848884132640e-02, 4.861170288163592155e-02, 5.165426338866744454e-02, 5.482800933323496446e-02, 5.813504029216542680e-02, 6.157732139347005467e-02, 6.515667920037330165e-02, 6.887479820368566403e-02, 7.273321794107712090e-02, 7.673333075835566151e-02, 8.087638022439339824e-02, 8.516346020789830747e-02, 8.959551462082867423e-02, 9.417333782991444898e-02, 9.889757573450802477e-02, 1.037687275058577967e-01, 1.087871479799008567e-01, 1.139530506928239996e-01, 1.192665115459606141e-01, 1.247274730840887416e-01, 1.303357493688843496e-01, 1.360910314271734020e-01, 1.419928932517243620e-01, 1.480407983306351483e-01, 1.542341066798992024e-01, 1.605720823524863565e-01, 1.670539013962460335e-01, 1.736786602321317742e-01, 1.804453844236544912e-01, 1.873530378080931153e-01, 1.944005319598201097e-01, 2.015867359561292115e-01, 2.089104864161762672e-01, 2.163705977840528187e-01, 2.239658728275971045e-01, 2.316951133252986765e-01, 2.395571309145607347e-01, 2.475507580756380088e-01, 2.556748592267567912e-01, 2.639283419072366399e-01, 2.723101680268593668e-01, 2.808193651612593497e-01, 2.894550378747292326e-01, 2.982163790535362503e-01, 3.071026812346166036e-01, 3.161133479163487600e-01, 3.252479048399920142e-01, 3.345060112323053140e-01, 3.438874710018250777e-01, 3.533922438832718793e-01, 3.630204565265675291e-01, 3.727724135289699431e-01, 3.826486084108677024e-01, 3.926497345378144818e-01, 4.027766959934214472e-01, 4.130306184097598756e-01, 4.234128597639539906e-01, 4.339250211516634154e-01, 4.445689575501645526e-01, 4.553467885857401860e-01, 4.662609093220769612e-01, 4.773140010883521767e-01, 4.885090423676662636e-01, 4.998493197684479070e-01, 5.113384391034281429e-01, 5.229803366027518117e-01, 5.347792902897740156e-01, 5.467399315500809553e-01, 5.588672569262846167e-01, 5.711666401731758417e-01, 5.836438446098876156e-01, 5.963050358078278898e-01, 6.091567946552975691e-01, 6.222061308419237716e-01, 6.354604968083211637e-01, 6.489278022087558681e-01, 6.626164289370386795e-01, 6.765352467684294227e-01, 6.906936296730053994e-01, 7.051014728587479919e-01, 7.197692106055475377e-01, 7.347078349544334315e-01, 7.499289153196209421e-01, 7.654446190944464391e-01, 7.812677333259577661e-01, 7.974116875368567865e-01, 8.138905777776784362e-01, 8.307191919965581771e-01, 8.479130368187123741e-01, 8.654883658328603475e-01, 8.834622094872810766e-01, 9.018524067040521621e-01, 9.206776383262963142e-01, 9.399574625199963151e-01, 9.597123522591707284e-01, 9.799637350309700387e-01, 1.000734034905599933e+00, 1.022046717124952010e+00, 1.043926335373472893e+00, 1.066398581905185161e+00, 1.089490340711946628e+00, 1.113229743930062164e+00, 1.137646231695313314e+00, 1.162770615670420260e+00, 1.188635146483979071e+00, 1.215273585336112390e+00, 1.242721280043529050e+00, 1.271015245815510799e+00, 1.300194251072644711e+00, 1.330298908642019971e+00, 1.361371772686240192e+00, 1.393457441749111730e+00, 1.426602668328411758e+00, 1.460856475415888358e+00, 1.496270280476785338e+00, 1.532898027375920169e+00, 1.570796326794896619e+00, 1.610024605725646420e+00, 1.650645266669431435e+00, 1.692723857217988332e+00, 1.736329250744977731e+00, 1.781533838991654903e+00, 1.828413737391087381e+00, 1.877049004040720448e+00, 1.927523873304087635e+00, 1.979927005099477087e+00, 2.034351751016940433e+00, 2.090896438495766214e+00, 2.149664674393090421e+00, 2.210765669381402212e+00, 2.274314584729113927e+00, 2.340432903144970240e+00, 2.409248825504827076e+00, 2.480897695429288043e+00, 2.555522453844001656e+00, 2.633274125832370887e+00, 2.714312342284411608e+00, 2.798805899057066353e+00, 2.886933356592141886e+00, 2.978883683190077867e+00, 3.074856945413050211e+00, 3.175065049391765683e+00, 3.279732537139255280e+00, 3.389097442334834102e+00, 3.503412210435275865e+00, 3.622944688401595705e+00, 3.747979189802462585e+00, 3.878817641573403805e+00, 4.015780819279312670e+00, 4.159209678351536168e+00, 4.309466789455788368e+00, 4.466937886899736897e+00, 4.632033539816493591e+00, 4.805190956770360727e+00, 4.986875935432896972e+00, 5.177584970080537688e+00, 5.377847530880629761e+00, 5.588228530273088035e+00, 5.809330993233640059e+00, 6.041798949837089488e+00, 6.286320570342285919e+00, 6.543631565013652661e+00, 6.814518873098582608e+00, 7.099824667819718682e+00, 7.400450706942931008e+00, 7.717363061475788814e+00, 8.051597258371279584e+00, 8.404263876795383951e+00, 8.776554641607500109e+00, 9.169749062247565207e+00, 9.585221670276993889e+00, 1.002444991444300704e+01, 1.048902277839603856e+01, 1.098065019316492606e+01, 1.150117332427169985e+01, 1.205257582204547280e+01, 1.263699613338454324e+01, 1.325674098404332380e+01, 1.391430015262873368e+01, 1.461236267104086712e+01, 1.535383460126837531e+01, 1.614185855545811846e+01, 1.697983514525758524e+01, 1.787144656784601339e+01, 1.882068256013178484e+01, 1.983186897964764985e+01, 2.090969930111845450e+01, 2.205926935196095527e+01, 2.328611564861881683e+01, 2.459625773922860138e+01, 2.599624500732998276e+01, 2.749320844694889238e+01, 2.909491798228195984e+01, 3.080984597641076715e+01, 3.264723765414180400e+01, 3.461718925554321861e+01, 3.673073484057443067e+01, 3.899994278315456980e+01, 4.143802312713618427e+01, 4.405944712930142330e+01, 4.688008048840357439e+01, 4.991733195758662298e+01, 5.319031926387298369e+01, 5.672005451703465811e+01, 6.052965158594831140e+01, 6.464455825915836491e+01, 6.909281639443131774e+01, 7.390535370725211687e+01, 7.911631135942343489e+01, 8.476341209659472308e+01, 9.088837435982152722e+01, 9.753737857533253823e+01, 1.047615927251647361e+02, 1.126177653386554197e+02, 1.211688952437418817e+02, 1.304849888043593828e+02, 1.406439169773708701e+02, 1.517323863863765989e+02, 1.638470407739824279e+02, 1.770957117100033620e+02, 1.915988403612775885e+02, 2.074910955409497265e+02, 2.249232172361061194e+02, 2.440641194630869936e+02, 2.651032917390266964e+02, 2.882535448280364212e+02, 3.137541538897424513e+02, 3.418744609277612322e+02, 3.729180087461214321e+02, 4.072272907593818790e+02, 4.451892153103389878e+02, 4.872414000388630927e+02, 5.338794318098249932e+02, 5.856652513400113117e+02, 6.432368496766822816e+02, 7.073194969336578611e+02, 7.787387632221277236e+02, 8.584356387770406827e+02, 9.474841163944599543e+02, 1.047111666301969297e+03, 1.158723113719277435e+03, 1.283928525349707755e+03, 1.424575826189363437e+03, 1.582789006393775706e+03, 1.761012944445459235e+03, 1.962066073573121788e+03, 2.189202360708354222e+03, 2.446184360349559652e+03, 2.737369460761187093e+03, 3.067811870808767638e+03, 3.443383419509962754e+03, 3.870916878218207705e+03, 4.358376293464465508e+03, 4.915059769420260559e+03, 5.551841303216967404e+03, 6.281459704453426129e+03, 7.118864385205665710e+03, 8.081629967627799596e+03, 9.190454321738597280e+03, 1.046975794051835702e+04, 1.194840663946247320e+04, 1.366058463062104793e+04, 1.564685131637809273e+04, 1.795542299179967539e+04, 2.064373043744082514e+04, 2.378031563732670807e+04, 2.744714621995650953e+04, 3.174244552480722739e+04, 3.678416050731336226e+04, 4.271422037773508051e+04, 4.970377768100323981e+04, 5.795967273138576164e+04, 6.773242484608792593e+04, 7.932613346949942761e+04, 9.311077397156915450e+04, 1.095375030536372224e+05, 1.291577556735669526e+05, 1.526471301608741586e+05, 1.808353350969648289e+05, 2.147438294770164181e+05, 2.556332515573999948e+05, 3.050633345562097502e+05, 3.649687926665853954e+05, 4.377556866857485380e+05, 5.264241222943208736e+05, 6.347248990108319410e+05, 7.673600526542426466e+05, 9.302403050337502786e+05, 1.130816502666451845e+06, 1.378507531155523742e+06, 1.685254393964162275e+06, 2.066239770168639390e+06, 2.540825270229354918e+06, 3.133775962036416630e+06, 3.876865148275802393e+06, 4.810984054018349430e+06, 5.988924089534678664e+06, 7.479057929608060924e+06, 9.370225698693408867e+06, 1.177824230977510661e+07, 1.485459301432580619e+07, 1.879809270383398104e+07, 2.387057334436346400e+07, 3.041806552258603202e+07, 3.889950046843262151e+07, 4.992574374586696017e+07, 6.431287504495613210e+07, 8.315518519925858136e+07, 1.079255664704117961e+08, 1.406141073390035115e+08, 1.839201785677305607e+08, 2.415197116904975365e+08, 3.184386015381112281e+08, 4.215765018929686736e+08, 5.604446356915114550e+08, 7.482094398046911572e+08, 1.003175129668246151e+09, 1.350898918997482870e+09, 1.827222165053491590e+09, 2.482633480831760933e+09, 3.388577637234919719e+09, 4.646620065299105644e+09, 6.401821801566297122e+09, 8.862352038053251473e+09, 1.232838602859196811e+10, 1.723489297480180023e+10, 2.421530528469447376e+10, 3.419673813208063025e+10, 4.854312364622606540e+10, 6.927149043760342676e+10, 9.938049490186203616e+10, 1.433521424759854145e+11, 2.079221734483088227e+11, 3.032695241820108158e+11, 4.448631503727710431e+11, 6.563458646477901051e+11, 9.740635696398910980e+11, 1.454220520059656158e+12, 2.184250688898627320e+12, 3.300999104757560757e+12, 5.019970485022749012e+12, 7.682676299017607834e+12, 1.183376596003983872e+13, 1.834748853557035315e+13, 2.863639312458363586e+13, 4.499803892715039958e+13, 7.119486876989154498e+13, 1.134307017980122346e+14, 1.820065782363618395e+14, 2.941484500615394037e+14, 4.788707305890930382e+14, 7.854025036928623551e+14, 1.297894304619860251e+15, 2.161279954782425640e+15, 3.627102147035003834e+15, 6.135342933440950378e+15, 1.046170006362244506e+16, 1.798477357839665686e+16, 3.117473412332331475e+16, 5.449445073049184222e+16, 9.607515505017978212e+16, 1.708589224452677852e+17, 3.065429751110228665e+17, 5.549227437451149511e+17, 1.013730232778046314e+18, 1.869059895876405824e+18, 3.478549552381578424e+18, 6.535992245975463763e+18, 1.240019272261066308e+19, 2.375828866910936629e+19, 4.597682433604432625e+19, 8.988106816837128428e+19, 1.775302379393632263e+20, 3.543413304390973486e+20, 7.148061397675525327e+20, 1.457620510577186305e+21, 3.005137124879829797e+21, 6.265024861633250697e+21, 1.320979941090283816e+22, 2.817487535902146221e+22, 6.079933041429805231e+22, 1.327658853647212083e+23, 2.934311759183641318e+23, 6.565087216807130026e+23, 1.487212273437937650e+24, 3.411840196076788128e+24, 7.928189928797018762e+24, 1.866451877029704857e+25, 4.452521859886739549e+25, 1.076545435174977662e+26, 2.638685681190697586e+26, 6.557908470244186498e+26, 1.652952243735585721e+27, 4.226383395914916199e+27, 1.096450394268080148e+28, 2.886822082999286080e+28, 7.715480389344015925e+28, 2.093728789309964846e+29, 5.770275789447655037e+29, 1.615463845391781140e+30, 4.595470055795608691e+30, 1.328629392686523255e+31, 3.905079681530784219e+31, 1.167134024271997252e+32, 3.548058538654277403e+32, 1.097378059358046160e+33, 3.454102978064445595e+33, 1.106745393701652323e+34, 3.610899559139069994e+34, 1.199946999283670567e+35, 4.062687014190878792e+35, 1.401835223893224514e+36, 4.931085527333162173e+36, 1.768812393284919500e+37, 6.472148293945199961e+37, 2.416453721739211922e+38, 9.208944720398123862e+38, 3.583297028622126676e+39, 1.424097482596699440e+40, 5.782627833426411524e+40, 2.399862204084363183e+41, 1.018291572042305460e+42, 4.419105414822034531e+42, 1.962126117680499311e+43, 8.916742424061253707e+43, 4.148882478294757720e+44, 1.977256529558276930e+45, 9.655300233875401080e+45, 4.832878898335598922e+46, 2.480575878223098058e+47, 1.306102809757654706e+48, 7.057565717289569232e+48, 3.915276522229618618e+49, 2.230898980943393318e+50, 1.306141334496309306e+51, 7.861021286656392627e+51, 4.865583758538451107e+52, 3.098487425915704674e+53, 2.031037614862563901e+54, 1.370999647608260200e+55, 9.534736274325001528e+55, 6.834959923166415407e+56, 5.052733546324789020e+57, 3.853810997282159979e+58, 3.034183107853208298e+59, 2.467161926009838899e+60, 2.072901039813580593e+61, 1.800563980579615383e+62, 1.617764027895344257e+63, 1.504283028250688329e+64, 1.448393206525427172e+65, 1.444855510980115799e+66, 1.494120428855029243e+67, 1.602566566107015722e+68, 1.783880504153942988e+69, 2.061999240572760738e+70, 2.476521794698572715e+71, 3.092349914153497358e+72, 4.016927238305985810e+73, 5.431607545226497387e+74, 7.650086824042822759e+75, 1.123017984114349288e+77, 1.719382952966052004e+78, 2.747335718690686674e+79, 4.584545010557684123e+80, 7.995082041539250252e+81, 1.458119909365899044e+83, 2.783001178679600175e+84, 5.562812231966194628e+85, 1.165338768982404578e+87, 2.560399126432838224e+88, 5.904549641859098192e+89, 1.430278474749838710e+91, 3.642046122956932563e+92, 9.756698571206402300e+93, 2.751946044275883051e+95, 8.179164793643197279e+96, 2.563704735086825890e+98, 8.481656496128255880e+99, 2.964260254403981007e+101, 1.095342970031208886e+103, 4.283148547584870628e+104, 1.773954352944319744e+106, 7.788991081894224760e+107, 3.628931721056821352e+109, 1.795729272516020592e+111, 9.446685151482835339e+112, 5.288263179614488101e+114, 3.153311236741401362e+116, 2.004807079683827669e+118, 1.360407192665237716e+120, 9.862825609807810517e+121, 7.647551788591128099e+123, 6.348802224871730088e+125, 5.649062361980019098e+127, 5.393248003523784781e+129, 5.530897191915703916e+131, 6.099598644640894333e+133, 7.242098433491964504e+135, 9.268083053637375570e+137, 1.279942702416040582e+140, 1.909796626960621302e+142, 3.082540300669885040e+144, 5.388809732384179657e+146, 1.021610251056626535e+149, 2.103005440072790650e+151, 4.706753990348725570e+153, 1.146834128125248991e+156, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -6.164062500000000000; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#if LDBL_MAX_EXP == 16384 +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 1.02756529896290544244959196973059583e-2497L, 2.56737528671961581475200468317128232e-919L, 1.17417808941462434184174780056564573e-338L, 4.82182886130634548471358754377036370e-125L, 1.85613301660646818149136526457281019e-46L, 1.52174118093087534300657777272732001e-17L, 6.75122240537294392532710530940672267e-07L, 5.94481311616464419075825632567494453e-03L, 2.00100938779037997581424620542543429e-01L, 1.17328605653712546899681147538372171e+00L, 8.18356490677287285512063117929807241e+00L, 5.59865842621965368881982340891928481e+02L, 3.69902944883650290371636082450503730e+07L, 4.05747121124517088709477132072461878e+20L, 1.07723884748977308147226626407207905e+56L, 2.07250561337258237728923403163755392e+152L, 1.09889904624000153879292638133263171e+414L, 3.02463014753652876878705286965250144e+1125L, }, + { 3.16339947894004847541521297710937343e-1515L, 7.02786763812753004271170107158747593e-558L, 1.08465499866859733494552744914276656e-205L, 3.97220624097731753646493300738183748e-76L, 1.84145280968701148636501796762008815e-28L, 6.40886341101610144938011594904313817e-11L, 1.89200275395722467663251234615351291e-04L, 5.04892743776943294143478969573235061e-02L, 5.25946553709738448524487603870477588e-01L, 2.72635049439566736308739858009584752e+00L, 4.20081657572145199006060015525396829e+01L, 3.75221714819472331206969009243353365e+04L, 3.11642465424592079726559332629050577e+12L, 9.61947229245436139236957297153092319e+33L, 2.42007357898805628851519620917402234e+92L, 1.34351470989086331111432001407522043e+251L, 4.34937560839564995558174638985438726e+682L, 4.01820305474077838467315109614612109e+1855L, }, + { 2.20630426387562582340901270736066292e-1945L, 3.20902289525796097195876526710905754e-1180L, 3.99075419312896749376535004306952481e-716L, 1.22680463935505388461578092999320797e-434L, 6.60416836081631149205027836695167940e-264L, 2.36380363265905808053031227647927829e-160L, 1.52216180146092756550894692311532796e-97L, 1.89865679919908959317123677189779258e-59L, 2.43020115474101871630434504433731237e-36L, 2.52466874690605714759066961852641028e-22L, 8.05169965363444223580324196979926112e-14L, 1.16754399126294292055540155961164512e-08L, 1.59887725419859990767684898940272339e-05L, 1.30653650105064376247657363109776765e-03L, 1.96025435814529675467866513121889090e-02L, 1.07798510399525035644857486110150806e-01L, 3.35726506001932774135392168623644982e-01L, 7.91344191300036661743190713036639943e-01L, 1.75712551051579342077493249233109834e+00L, 4.50532922519182663928094313196688277e+00L, 1.69634912879730950991827009814964854e+01L, 1.31564914034011933527149556208430823e+02L, 3.54551665937177335700906931219692079e+03L, 7.69629182688413474235641078406238234e+05L, 5.31334781541946297455601223275400364e+09L, 1.11397125403497802554344014693570895e+16L, 2.91323342059626628322620905024841007e+26L, 4.33470414741675827465254900104887599e+43L, 8.87077939346041258291094819287939414e+71L, 4.20552510572288598564618972079522209e+118L, 3.78998758665619810759092788424597102e+195L, 2.85285821381079277498378752581228807e+322L, 4.35767992687500025738868152293904617e+531L, 3.35101732969916400190150631384628168e+876L, 1.39907636805339624393396738787997778e+1445L, 4.39310839133852761600954729262867435e+2382L, }, + { 2.60416027838200926634868701489352534e-2204L, 7.02786036162213986704884019362612079e-1717L, 2.87472449554862557122883045361480216e-1337L, 1.26052689335617094297502885256721406e-1041L, 2.22203737723769125613395083355625930e-811L, 4.59925691253299141912321586723335574e-632L, 2.06110387430222811031505778840893135e-492L, 1.18783333719310840737835079091916047e-383L, 5.99339963191580129696690680497340117e-299L, 5.55156577871295836646608994333019205e-233L, 1.31650343182343962237291034126486362e-181L, 1.35017224106781623208439493207058713e-141L, 1.95458267270042896122641878745090637e-110L, 3.62345406499123808121116200173051239e-86L, 2.87916036185197771976746396107338099e-67L, 1.50975853574758038650941626753584613e-52L, 4.39366381209590686916061999351406334e-41L, 3.72613279781933265810269222029431206e-32L, 3.35074541708050784063416140930256908e-25L, 8.73699691100611067810340427391712629e-20L, 1.44610938754441658588026566732900630e-15L, 2.79712542830915646153531586097835651e-12L, 1.01712318476608889609455916646557919e-09L, 1.00707686902351812525332969334486408e-07L, 3.62377064535647765957086044101238700e-06L, 5.93514765312557852887858990273347709e-05L, 5.27427922038425038994892508697801291e-04L, 2.91716284057748187538183216214780172e-03L, 1.11812753052373081344852811278990196e-02L, 3.23158910999791296389217134204252891e-02L, 7.52823576293971217140453145701166400e-02L, 1.49072381771447883955117212578891471e-01L, 2.61920116954195648982059938116700281e-01L, 4.23044722849733503488984642521144095e-01L, 6.47337815325830827783598163922905049e-01L, 9.63850663681748439752705317539095691e-01L, 1.43180513983798487645924505146418541e+00L, 2.17546288127550398262362304432746644e+00L, 3.47077553215380191942193887548951574e+00L, 5.98762125926090985873603940556086485e+00L, 1.15588346593765285104362265791852722e+01L, 2.60227165873113109321939526707132515e+01L, 7.18972764924010846908346544069757730e+01L, 2.59849827899514040038730358528910272e+02L, 1.33180383652908565595482681440747426e+03L, 1.07264199927746293597346233164919561e+04L, 1.54770252854197591129695964624494039e+05L, 4.73116974059692035499030617203501902e+06L, 3.79850299532978550624970142683299187e+08L, 1.05506900281875210383901752883017567e+11L, 1.44377693764054834189876938092028936e+14L, 1.53216987231286586179401429003390945e+18L, 2.25749845424265693444972830430363021e+23L, 9.75366126404791278425650801377275643e+29L, 3.22710662318561074542283240061745423e+38L, 2.80427989450823486864584373674252213e+49L, 3.11492865697270427645920832671970699e+63L, 3.37385880956075754428852062324609716e+81L, 4.84069913749095116306098688426537434e+104L, 2.62206965911556490036221731139595538e+134L, 3.95724512624896651389226023882699109e+172L, 4.16658233419696139622872515762144259e+221L, 3.67870997815873300310505495683155714e+284L, 2.45353561048417937411865685638919263e+365L, 1.47890836767899626666102902312593029e+469L, 2.66842264577698782467085710268227542e+602L, 3.39406520823137428862537121090858482e+773L, 1.71072929388916771882465310676448508e+993L, 2.17124413154098944294625847065193945e+1275L, 3.67108839134079465802181460380664133e+1637L, 4.72992162468569560939225829187204387e+2102L, }, + { 1.98007625288857013412122004727810624e-2346L, 8.39652992194258659266745309526472882e-2071L, 1.46030671151231956105710426802408027e-1827L, 6.65727248909208458885310717390128801e-1613L, 1.81581117219394388092797723844111009e-1423L, 2.72619674739250219990613941747932927e-1256L, 9.29590026994488020433315206443278096e-1109L, 1.46377917106366800430984793284730939e-978L, 1.15901956513202291149840314964756250e-863L, 2.89578802021929239619753606490350524e-762L, 8.80858736107764685086031513644364894e-673L, 8.19416690740938676449696497280686335e-594L, 4.00916745706227520865721440095991259e-524L, 1.27020033549323657895766092175564312e-462L, 2.38869695900235565316537719061693975e-408L, 1.88391475973801739487501436111488490e-360L, 3.49894275509125434733587030489899389e-318L, 7.01615886164307390146523314851863544e-281L, 5.82310443050787035609701710903434681e-248L, 6.54836166711216765944679142249433382e-219L, 2.84149263299034989667159925017962142e-193L, 1.19812648186130338854458247959762818e-170L, 1.10911490518050678588403791608480488e-150L, 4.62754597695358582538782054737574180e-133L, 1.64173210211161942076907089038989838e-117L, 8.67192889174269982709959745767681981e-104L, 1.11812225550444523531457194417899189e-91L, 5.44369950217028498211921027217139012e-81L, 1.47074883585505403248443957516006445e-71L, 3.09730398495823549037183157408809652e-63L, 6.86204181060118439675162432029019608e-56L, 2.08386500906124109876681630886775453e-49L, 1.09560045982532469724721792988430545e-43L, 1.22547627904244500951228300724497066e-38L, 3.49796660995417261286766404577301528e-34L, 2.99152410870631960427539566799345990e-30L, 8.83190101026086766963628794276374683e-27L, 1.01998228741819737621697177531967545e-23L, 5.14543767526486873178240241354085638e-21L, 1.24976972746216000788747786633668576e-18L, 1.59270820536117731616569419326771375e-16L, 1.14889208313232540746001768184091876e-14L, 5.01568630936388404881919116817433643e-13L, 1.40588174426346693556351457090253957e-11L, 2.66552656620728447371725338328298653e-10L, 3.57952342849715748848195322266581664e-09L, 3.54587967892367612935335788099896843e-08L, 2.68571894340447967655761437829800783e-07L, 1.60543396069231405992036918112042239e-06L, 7.78876789102767893920047052886009844e-06L, 3.14354940320849664611373818938001854e-05L, 1.07876626606295756489869617036039985e-04L, 3.20898851002890606916875803454736038e-04L, 8.41685517064122028463642895198591848e-04L, 1.97617054782608049591289962378898411e-03L, 4.20911897696440311235672067499450921e-03L, 8.22976828962407304914730770011736102e-03L, 1.49268961502975158975071505963565168e-02L, 2.53502658698472066372315325797964553e-02L, 4.06466974195663810865864410951160977e-02L, 6.19877276359776967830177840166714717e-02L, 9.05089155125712182450563511209635860e-02L, 1.27278213682114666289711516555196299e-01L, 1.73304699976842406023992088378438619e-01L, 2.29592410233034978491448000870038137e-01L, 2.97239599113018852567831136709176961e-01L, 3.77582948042641879160927817217899876e-01L, 4.72389555885863401785327685882008067e-01L, 5.84107138056041651067826639644019633e-01L, 7.16195243265456514286143145222900703e-01L, 8.73579162273458922635006193850777630e-01L, 1.06329740288293038148703202109279326e+00L, 1.29546076177954953883340629341283024e+00L, 1.58472055402981935372999954552668421e+00L, 1.95258275532953319986830507945836181e+00L, 2.43115638685977475925559253395572515e+00L, 3.06939317426312452000366876337463330e+00L, 3.94377618122435031881432297693345182e+00L, 5.17720373327574287465684980172077361e+00L, 6.97349551419502029130075958419090062e+00L, 9.68282046752329620408323930717367162e+00L, 1.39309131038991828857956159913232231e+01L, 2.08859990746605884557374483895633501e+01L, 3.28382897425881117409618357674054401e+01L, 5.45293246810142904942496502744410196e+01L, 9.63939781365248203122153852027923369e+01L, 1.83025185098871555179881958564576181e+02L, 3.77024517378370245776498953575447428e+02L, 8.52190226688445340278025693774183776e+02L, 2.14068512989192644263700461005007744e+03L, 6.06284853067739175777069687971114492e+03L, 1.96780457938951378915777196082473423e+04L, 7.45535092385462432927423608234859698e+04L, 3.36655497164547806089503954112397178e+05L, 1.85514609429466771541276069582993197e+06L, 1.28127256599195512602695379572162760e+07L, 1.14315867886785361488804976072737382e+08L, 1.36346329402339162906880444623714674e+09L, 2.25993073791019766670398383679728111e+10L, 5.43926612995997228479509745730508310e+11L, 1.99798484325959673290782033498623904e+13L, 1.18504970239150114123104110601445669e+15L, 1.20980370818215194207683618902723859e+17L, 2.28537992087984292439473774950290832e+19L, 8.67120977340450400779923403171032446e+21L, 7.25153649943518021867879355500893988e+24L, 1.48501435335333039333736586197814469e+28L, 8.39050326550867736343407650659898774e+31L, 1.49728470198356221256669260283197052e+36L, 9.83549601762784922530731490296260394e+40L, 2.82901352112032614706131527899887976e+46L, 4.33736659101971830974347248793299740e+52L, 4.42940467871587853569566546424045697e+59L, 3.87840248690238104186373399976301795e+67L, 3.87622435037312042010986878431609700e+76L, 6.11530088968567983241864570883470440e+86L, 2.19902986720444927672673080107769693e+98L, 2.73302501743809592753235404592828204e+111L, 1.88157705379416554346750034182897643e+126L, 1.22464500548199778033960287699262627e+143L, 1.38089682931886763280665214047107116e+162L, 5.35861724121451785967201429765672158e+183L, 1.55758090841089261682638940540906561e+208L, 8.18640878839858943416304034752205938e+235L, 2.11193471456685131226350980039759737e+267L, 8.29196100559631320106113784120111420e+302L, 1.78609329205356222554295903766141624e+343L, 9.02504022060557635111807879176244000e+388L, 5.55060710318615757165502584223064764e+440L, 2.68431690505806342057709029465018309e+499L, 8.45412788268345327632392585778624037e+565L, 1.90297947362180093404817251840979577e+641L, 4.62215189323912708971592873336189679e+726L, 2.62533210543270812917133055827838787e+823L, 1.13817822812561602537416032879617414e+933L, 1.95538622136936887385682087493096654e+1057L, 1.16937064578842112561072532780020718e+1198L, 3.88035117517281013054730623266703196e+1357L, 2.23743584154220985565150075331030128e+1538L, 1.50889533002797316376499137963913497e+1743L, 1.90641621776286179122749804749534564e+1975L, 1.93080249271305970633007359089743998e+2238L, }, + { 6.85586909881832886951451464772591878e-2421L, 2.92677267243682665120741515792112744e-2274L, 1.63242588944068781532732923861018809e-2136L, 4.10812064897186984969866413043968829e-2007L, 1.49435786878493820312929790405374745e-1885L, 2.34568268208591413691385316271709680e-1771L, 4.43925157300673395426635808699168955e-1664L, 2.65927633627471464278071651186161190e-1563L, 1.24859182507079754991269604284796564e-1468L, 1.07699173095552638424762549404812646e-1379L, 3.79889818022139862967145673157136925e-1296L, 1.16203657951916401289541501876509754e-1217L, 6.24572482158628957114104388658639197e-1144L, 1.14511680730607058597658427712436799e-1074L, 1.33557521045192075572641149916774170e-1009L, 1.77946124922921650079213398130306155e-948L, 4.69414096094237830969243170096712625e-891L, 4.11003931775404922019148615555751563e-837L, 1.94061218235885716000492708678051285e-786L, 7.79551077888128366830436599420622304e-739L, 4.08861993672760936738017704029701813e-694L, 4.18676490857955209780618740974196173e-652L, 1.22153592554301240722464717581112377e-612L, 1.44833892014264382948310395651753089e-575L, 9.74176764355703592877272264974985856e-541L, 5.08509650174353124708754662233746797e-508L, 2.76502760440391058924306176438285126e-477L, 2.06508450540542778211999232986493505e-448L, 2.74686348165461297466693117700925333e-421L, 8.30585680824802634886342521419101161e-396L, 7.18035163161661527310024383149797653e-372L, 2.20117367274887299835421816737413275e-349L, 2.92938701204713835430829657327314622e-328L, 2.04670856065666661814970623236244653e-308L, 8.97499107305077146284125789528155163e-290L, 2.92115595376553501154165826580135083e-272L, 8.26130614121671756652659688034185753e-256L, 2.35396777618554392325312768878283221e-240L, 7.76604519643439440768615254501273896e-226L, 3.38047616528897968517094694597452046e-212L, 2.19496817732884969215875687943120973e-199L, 2.38570033705332693932010529683394408e-187L, 4.83696042571616203283798802745975902e-176L, 2.02525789452808699182428060822541636e-165L, 1.92683544261267768613934270120773225e-155L, 4.55675928208753416426295293555087690e-146L, 2.91435926363522943509016642164959990e-137L, 5.45650834446039875776911937813876647e-129L, 3.22177915240208624055473617062236208e-121L, 6.43356918992122712617506763079342635e-114L, 4.63991207894245637238928734792612888e-107L, 1.28548526430585878202588260968441525e-100L, 1.44976784442529508497784801483631129e-94L, 7.02834477739882506904444529125607921e-89L, 1.54151343887499654318252629091310298e-83L, 1.60491367376894945627919582278915480e-78L, 8.29797555416253956153582009155421152e-74L, 2.22293580147262466985937857298017334e-69L, 3.21083741325090217758867273653191446e-65L, 2.59597447976318059491815288096285983e-61L, 1.21686551839843562559756380386148224e-57L, 3.41813412178077321753808876760492064e-54L, 5.93492497756373178397326564626159285e-51L, 6.55812810449229009165849681654564859e-48L, 4.73996462182817624913218344729897191e-45L, 2.29917713906026251753218108658989939e-42L, 7.66772810214285848709307613966489982e-40L, 1.79852699731596078211094021208953882e-37L, 3.03099351897543871174212829426305144e-35L, 3.74430827279655104510043134133803179e-33L, 3.45501893639921538125092697393537600e-31L, 2.42381852080187080923760278831274486e-29L, 1.31441976082623542058289755424927250e-27L, 5.59666006060409162050973561377317535e-26L, 1.89867556602582040862526655529336748e-24L, 5.20331508297836691753631952262461629e-23L, 1.16690464600934423260878649807673403e-21L, 2.16767714527916659623320357151600374e-20L, 3.37377643107659326572426331386135943e-19L, 4.44691383264786489190950322799097537e-18L, 5.01415830137739970673756811085508269e-17L, 4.88253693365386298188724591254681515e-16L, 4.14251016844320187955159569890123671e-15L, 3.08802476085892421415530065712870862e-14L, 2.03847832924953919920668690856932749e-13L, 1.20044498484990029827708442066317039e-12L, 6.35035779339988133329469515026722103e-12L, 3.03739182163512379493334464659410947e-11L, 1.32161843156591616383150953292325245e-10L, 5.26149741865431306798513845101472462e-10L, 1.92688222163920338777595529204662553e-09L, 6.52448684765263503483691364064710302e-09L, 2.05235608001812174069568432464532832e-08L, 6.02447248155606588490206026101601127e-08L, 1.65719156589179965185098196474263403e-07L, 4.28875221376115411615543853081272079e-07L, 1.04811127032430288440405169279023586e-06L, 2.42727195841237101271799656914039580e-06L, 5.34428013249275030874689017597357100e-06L, 1.12217116002251908227007056847369186e-05L, 2.25365270095215311537786875281660527e-05L, 4.34066412230525728790156860647261934e-05L, 8.03857428545025320920443714330221510e-05L, 1.43483273166998782632422720673552674e-04L, 2.47403670532944916561679376448099333e-04L, 4.12969671314554699465069528559056198e-04L, 6.68662248079464048176726608426967422e-04L, 1.05217959874444039957269021715673554e-03L, 1.61189482479878719591766861379534126e-03L, 2.40808122992764072147410965445120710e-03L, 3.51377854902820551940988678116833582e-03L, 5.01519359256763066459806052313013320e-03L, 7.01156300574609092374647377614547795e-03L, 9.61445020754398604050247376189537687e-03L, 1.29464977958074216006936641439568225e-02L, 1.71397050059386052582575161031849539e-02L, 2.23333418628568405596661137294311321e-02L, 2.86716433323270031012958633821643459e-02L, 3.63014455768061096476987670693482715e-02L, 4.53699316668876641396409342510559075e-02L, 5.60226467568397916052157799832294784e-02L, 6.84019250622201277408275217514564750e-02L, 8.26458460699460598611997466316916292e-02L, 9.88878087044773835985179298425629188e-02L, 1.17256783027063660721874825783310801e-01L, 1.37878272417301116163817842123251189e-01L, 1.60875997439806117261603052596128705e-01L, 1.86374297424717578638710069246872277e-01L, 2.14501238238148719030968730766268227e-01L, 2.45392415301662505713896222647369518e-01L, 2.79195449773929877272191161144448290e-01L, 3.16075192872379294294649481827620946e-01L, 3.56219678521249637323233310278349444e-01L, 3.99846897980088704601361036413251085e-01L, 4.47212512313163107391085998119621599e-01L, 4.98618670533294760818150011647972671e-01L, 5.54424164764947975414033158173924804e-01L, 6.15056231563286401803829984090534551e-01L, 6.81024404595688995229840589926798114e-01L, 7.52936943869155645889792590166619714e-01L, 8.31520518350208659550187071679434118e-01L, 9.17644012826577357641491486976575868e-01L, 1.01234758075340210126152790231895045e+00L, 1.11687839251578850642753265260268328e+00L, 1.23273496036260391788838218839806886e+00L, 1.36172249498191084612564077792923468e+00L, 1.50602251678823434544288956361434194e+00L, 1.66828098096960364511379075299209308e+00L, 1.85172058286684745279366828495999051e+00L, 2.06028483669890596285992438994232879e+00L, 2.29882417717996662881312374953444179e+00L, 2.57333802530471722160283306099247239e+00L, 2.89129193110240878387703249643229033e+00L, 3.26203621106764094357461881213752464e+00L, 3.69736290590815315504600654149629845e+00L, 4.21225284743951568672550404261498190e+00L, 4.82588633844219080687269426289849605e+00L, 5.56302277261292337309431040275971592e+00L, 6.45590163750149736955774273721315509e+00L, 7.54688784770818103174495320257408374e+00L, 8.89219103984228343085851433153285412e+00L, 1.05671517790393183669301386672470668e+01L, 1.26738407015152894733455767759949041e+01L, 1.53521137941817792315134763759132043e+01L, 1.87958986899048219790124225448671683e+01L, 2.32775055780405432294765542807163514e+01L, 2.91844233861930596156964126095351325e+01L, 3.70758319218904582325116346962442845e+01L, 4.77707378224399722392124081823831658e+01L, 6.24876734446863447811669818713989778e+01L, 8.30699342763174311126855611293197423e+01L, 1.12355321585737491915090874360361047e+02L, 1.54794728437631233369474093491065001e+02L, 2.17507985417556811263254275570301936e+02L, 3.12124586781855603508049115425717265e+02L, 4.58065302025763509177549206574829939e+02L, 6.88532496785780240326739257222869086e+02L, 1.06172181511411400423407908864360706e+03L, 1.68236894049421021674529061389284712e+03L, 2.74433484749143274695935635590635551e+03L, 4.61730673523479769409382001763470205e+03L, 8.02895513401715463422140861600391503e+03L, 1.44606187348593941052176609549649644e+04L, 2.70377620144727936743806059397776390e+04L, 5.26105241201059109738487092327866872e+04L, 1.06812531849740275922510876100737843e+05L, 2.26893075168541256271862004134549591e+05L, 5.05764404902608855969935895677933433e+05L, 1.18676186494579079987238943033223000e+06L, 2.94113264423683227561198247386975731e+06L, 7.72576514719998793452586494715302612e+06L, 2.15915178528480833880909472948132169e+07L, 6.44590226372788402030541979463995492e+07L, 2.06442545099697944602613003602586209e+08L, 7.12532948492900300739824830002676479e+08L, 2.66319659068655507734050368458244708e+09L, 1.08350636970002739580921292680640244e+10L, 4.82470799147337538737281851702596161e+10L, 2.36513804063572720852686335350104312e+11L, 1.28435637164102683934687705650167990e+12L, 7.77731246565628041938451985303773831e+12L, 5.28864903733985311795604320721713645e+13L, 4.06896744489041480369429188279659070e+14L, 3.57034809188328432417142254050169691e+15L, 3.60337498222976618360402297528737217e+16L, 4.22089025190487061069708630018503728e+17L, 5.79389086782171589014524617169039021e+18L, 9.41571436923218772663826142877596428e+19L, 1.83140546580432476725446560201754697e+21L, 4.31320926121717399384742067577025671e+22L, 1.24526713689819970862562132007699682e+24L, 4.46557396336452476527850690333252885e+25L, 2.01706317120607297931541128182425236e+27L, 1.16481109175988266234418168600383172e+29L, 8.73712441785116756599086490733480008e+30L, 8.65736270143027267976956887405444609e+32L, 1.15373549848396029384279199583578574e+35L, 2.10781669532016374773265262680619511e+37L, 5.38769637251502198497400987247791395e+39L, 1.96890474908610530032963280794536401e+42L, 1.05271764511336947295087542840771762e+45L, 8.43965629752558882239469624058575644e+47L, 1.04138369598852386365061187570128647e+51L, 2.03352356915167672502196854739506820e+54L, 6.47289125189110545523503523387311437e+57L, 3.46613548082834986367032599943319188e+61L, 3.22894792541599068853355143560944151e+65L, 5.42318759743953119742239523201238475e+69L, 1.70583228507675596981951702618714711e+74L, 1.04635953488687800354356406620895146e+79L, 1.30676249978604401490579288070545190e+84L, 3.47855004888451734894061507389280036e+89L, 2.07245356750112312931588098931095741e+95L, 2.91086857580213998298216107061151403e+101L, 1.01866939773917036897104863230086276e+108L, 9.42079727758602983661368103980660631e+114L, 2.45135270885215193905442997104007131e+122L, 1.91850621913423378510904034515156001e+130L, 4.84846348541576375648253727961523398e+138L, 4.26738728648259195430121429627940133e+147L, 1.41771213016857192102291892633345650e+157L, 1.93681124067818946208050336019146634e+167L, 1.19196764675833722929285298195873591e+178L, 3.64148488428297947856471515841164734e+189L, 6.12360784372861046853690882962104289e+201L, 6.32737167744109620998113270972893770e+214L, 4.51626866922887039378811138276232919e+228L, 2.52237535488279323839235752907864107e+243L, 1.25874430868722260548214869831621228e+259L, 6.46403890833514736730418683378673138e+275L, 3.97014109807165189460577113122885913e+293L, 3.42256445909004961984480518463414679e+312L, 4.91057220648194827953651882481242793e+332L, 1.40575745439889948649867992022706415e+354L, 9.73933590848593290516589462953654487e+376L, 2.00557619166308496177559022371882184e+401L, 1.52772859099735075822031580257311058e+427L, 5.43355654783039835976501066730115367e+454L, 1.15613726424969615026074606149058824e+484L, 1.91611396577413915548297095470351353e+515L, 3.27574835998524173295312535664414153e+548L, 7.78995993645646383749425447261756829e+583L, 3.54265432942533120234904548837850071e+621L, 4.32354359483087940297488323505450874e+661L, 2.03098786518797659659581103998046513e+704L, 5.39103916237599207670086450736143491e+749L, 1.21683151125684538902217928380735342e+798L, 3.60847574304211696962789044183995856e+849L, 2.23398800758266399217702784712099052e+904L, 4.72717380839903008268507408818545095e+962L, 5.77822208457179232925131147188581785e+1024L, 7.13289562956799416571309267253574621e+1090L, 1.61164858402955200792510210236524128e+1161L, 1.25521313739368945437360950048953572e+1236L, 6.61069623781251502357557332678377193e+1315L, 4.82362056335119095907952363185253207e+1400L, 1.04640496911016000942284610597050358e+1491L, 1.52131212817898241350510416765362487e+1587L, 3.52116090648535956154142297718505774e+1689L, 3.25907088535366768900129651211398670e+1798L, 3.21536840347133363006114569121938775e+1914L, 9.60165908424805663006527683476758652e+2037L, 2.63585872900260288034767508588870333e+2169L, 2.17048793513302111330851937361254536e+2309L, 1.88788443108195661060841368444711468e+2458L, }, + { 5.29693440729788041213142409892436291e-2459L, 2.27629257218329628557497350447858260e-2383L, 4.60725896612142987241524079465629916e-2310L, 5.17919364499500847985920034617781519e-2239L, 3.79383002964804382517930061580447157e-2170L, 2.11419993680434447426181517759297327e-2103L, 1.04148667561061807899012277964691785e-2038L, 5.24544425651958823988931435014729457e-1976L, 3.11006352777614281598465337503705373e-1915L, 2.48867462987012194623347147546568943e-1856L, 3.06835915872226280445223729961288427e-1799L, 6.62736493446143254705278263772087543e-1744L, 2.83997245953224047644578590378179268e-1690L, 2.72398780252406063855606534842103674e-1638L, 6.57327304158814917854156231336457877e-1588L, 4.46940189941144606938097964305720201e-1539L, 9.55652954181188776027715447963783638e-1492L, 7.14757266175076046071660887379600587e-1446L, 2.07313155515958333906901076011055929e-1401L, 2.57708633795358827890276221215294553e-1358L, 1.51269996990649935807792458579987758e-1316L, 4.60565435951356389119181468428252427e-1276L, 7.96677448800758121662225971905999717e-1237L, 8.55160853918795880988712436880140365e-1199L, 6.20482659749393290517542190337401836e-1162L, 3.30618935612498022733666989541183557e-1126L, 1.40195518332652973622801089378870590e-1091L, 5.11407919863367919558746085806786902e-1058L, 1.73063614614270605229830917360912415e-1025L, 5.84546019976429168954160400076820148e-994L, 2.11542888104356332114006186983662541e-963L, 8.78597020474401601699260325757052372e-934L, 4.47629976797445775500570938357786257e-905L, 2.98416839309444731431172458639558207e-877L, 2.77125321384854968458662765004085943e-850L, 3.80904190342493701536240175462301111e-824L, 8.21806462726393678491860107910281889e-799L, 2.94631935053803405188027155144659836e-774L, 1.85492994927395428856242032790235018e-750L, 2.16349445690590806097153640474491227e-727L, 4.92371233300030441739039250387920817e-705L, 2.29918059518632617935997695502963251e-683L, 2.31291758268743951509849171359112934e-662L, 5.25491742744220732604319355531444736e-642L, 2.82274223509188430651059911113688649e-622L, 3.74753227935082714244593814667510926e-603L, 1.28370364951438380618871579660566498e-584L, 1.18285412035024318029749091456416413e-566L, 3.05273754301598829645261576934311186e-549L, 2.29479910590203595225694928967822608e-532L, 5.21889625493118727969519850005753886e-516L, 3.72534255592436984201074827726301397e-500L, 8.64949198440528351465957047285602117e-485L, 6.76174414760667924982941341637985863e-470L, 1.84041518883114740241388396417281333e-455L, 1.80160472793323877219953443455302799e-441L, 6.54566528304067135832221898507534820e-428L, 9.10001699811829840956092860906810074e-415L, 4.98609828016939856686029944862830983e-402L, 1.10802830298400645391731986287163178e-389L, 1.02676405187821370308474571067658508e-377L, 4.07575091116228204031238856923140440e-366L, 7.11360268352693191010849541271753635e-355L, 5.59881168833151588006581688986986730e-344L, 2.03642255515559150564975951817039221e-333L, 3.50525657096789033370540964985470150e-323L, 2.92178573100086478331989127444273654e-313L, 1.20598734041934315977832234578459915e-303L, 2.51880216671823764300316483881856209e-294L, 2.71834421831894383133482530254389304e-285L, 1.54702039109098756507051056035620614e-276L, 4.73499485141563990358940703275480353e-268L, 7.94442519500188390796900278354012024e-260L, 7.44316376023327816606172273381802393e-252L, 3.96451700998508534828226048217863900e-244L, 1.22153684948784264379851755556819940e-236L, 2.21421725154084964507841507830563690e-229L, 2.40004857648572823842789487119416272e-222L, 1.58043505420313498164518700461984906e-215L, 6.42021223167302856767365812271085781e-209L, 1.63302423264111059580848381300534588e-202L, 2.63853106939137106330498547542524566e-196L, 2.74613250302397818664806479526069745e-190L, 1.86615306707995508392565990157579707e-184L, 8.38948945233194510175234920774873796e-179L, 2.52701050376399124391991347402621144e-173L, 5.16312575535157598596140018726440984e-168L, 7.24167062135448326922272784801743108e-163L, 7.05361814094865509813912299190351845e-158L, 4.82507740170943565549056875354725391e-153L, 2.34335421855805662819938218222415100e-148L, 8.16563163629951985655858859925168146e-144L, 2.06250908768935143871108361256064164e-139L, 3.81378121105029755974979453855090030e-135L, 5.21238862833226048821040688112783913e-131L, 5.31469066325781546457465599778122553e-127L, 4.07938032086884338695136986806703742e-123L, 2.37782434978024084372113156401306143e-119L, 1.06148128500673821430527965352560854e-115L, 3.65894930935314933069457000324241470e-112L, 9.81672760779301769095882197030988958e-109L, 2.06581729538829312212171371616525011e-105L, 3.43540071960972258090881112115251093e-102L, 4.54745983632894201410075262868047927e-99L, 4.82519857468149557373657687371350595e-96L, 4.13210577018135888633811621378125178e-93L, 2.87476099508953335771741680746804464e-90L, 1.63524251388290882625725240042223140e-87L, 7.65249997733887999623874860707951771e-85L, 2.96396516998940431058211305683891581e-82L, 9.55694449812711903241890069159516005e-80L, 2.57983003461536294556125432978470487e-77L, 5.86224102303822793749090237239965643e-75L, 1.12729666204663539107360352976065345e-72L, 1.84393400012961666333357387323541892e-70L, 2.57838118497774645351182154219344361e-68L, 3.09698398084623291081115732152399867e-66L, 3.21034639994569504125984658412826677e-64L, 2.88505745240234032993466930110171709e-62L, 2.25763973385675919792268556682148533e-60L, 1.54490468182644383657455478866541800e-58L, 9.28299236822216106223683331290050646e-57L, 4.91757270567151153434520348832876307e-55L, 2.30554641627582419897786323384840309e-53L, 9.60260856639165286607071389462405742e-52L, 3.56597785391661967741537394944785975e-50L, 1.18488237523747100855696221290216872e-48L, 3.53480106239996687790067585870262148e-47L, 9.49922331635571479300328969906674959e-46L, 2.30696251922047363681394459290289348e-44L, 5.07896585888252846067820035747838002e-43L, 1.01672554003146516218461940856820913e-41L, 1.85608083837358412341292426322275694e-40L, 3.09875103851653509802894724036653659e-39L, 4.74424556091727158516159565756659137e-38L, 6.67875654292885708009556323027970307e-37L, 8.66749789110265824007798499627002101e-36L, 1.03955806472296089132115323650013375e-34L, 1.15508617865206361238561969897526423e-33L, 1.19182362291753977427429758189318101e-32L, 1.14454132981883615336894355014782203e-31L, 1.02525602738123519983996836134381910e-30L, 8.58508308406581287405862446386142355e-30L, 6.73394164670453777712343530741256529e-29L, 4.95770293303240892202540668612526963e-28L, 3.43261200056988540268170912603591182e-27L, 2.23935379461627788150957730520597272e-26L, 1.37901808820501650857276186986911719e-25L, 8.03040544770876549232435915566049266e-25L, 4.42968188137908996064235843650469764e-24L, 2.31845927113168436195559586507393831e-23L, 1.15324161925721516540799043047625888e-22L, 5.46028729667908667672130073109459001e-22L, 2.46458926739523684644781998993375925e-21L, 1.06205430707170637462172218092564615e-20L, 4.37564008882607318443071720026076737e-20L, 1.72595587803323990868164488937090111e-19L, 6.52669144636334492287282783537910032e-19L, 2.36916844627434713681577417830597819e-18L, 8.26580372697482904251900693228762290e-18L, 2.77517606391661360182153963773908766e-17L, 8.97689232444592868369906653940499583e-17L, 2.80084735231662190309995026747244972e-16L, 8.43846463133099160645680685207593959e-16L, 2.45762595435789224473736552077118113e-15L, 6.92627769518345222522404766069340383e-15L, 1.89084205236464652796008005489924701e-14L, 5.00504297304156635993817971340426042e-14L, 1.28579120925883494201961228234875929e-13L, 3.20880531681575127155908954236910927e-13L, 7.78600100470787821926138878185058803e-13L, 1.83848331026111978204532135720140678e-12L, 4.22808302441074119355483439549639212e-12L, 9.47805306883598889922905503268261293e-12L, 2.07266429754356748908920713182886782e-11L, 4.42491437115776228499841800855357065e-11L, 9.22929507351999755945043065016679100e-11L, 1.88205258669115539986830146476840153e-10L, 3.75488615259231157512941964482754887e-10L, 7.33426418139309264953064008778652175e-10L, 1.40344387177481383433616336399570262e-09L, 2.63261606277390900911399983420396976e-09L, 4.84396275737187249536387241410506136e-09L, 8.74769197387686182490212973737486333e-09L, 1.55137319662316143322632050708021849e-08L, 2.70341183770391766500462033783635805e-08L, 4.63144836233962351361136455522914469e-08L, 7.80474058793106802102732603067941163e-08L, 1.29437017686516812026215434301661584e-07L, 2.11364219596533096486660492476571897e-07L, 3.40005066401716435610198303924157253e-07L, 5.39041104673862946543865026660608261e-07L, 8.42629030758144765430007132771995573e-07L, 1.29932702981307401261989221953085056e-06L, 1.97720517756199603296504985814152326e-06L, 2.97039557774168150435589567759708661e-06L, 4.40736236333866783037595222091818751e-06L, 6.46118993513603067322889724548764197e-06L, 9.36219732537340456332983881649283088e-06L, 1.34131848415120895981721422476655149e-05L, 1.90076038344927799241882635296823326e-05L, 2.66509095957072382671851701769041584e-05L, 3.69853096371186063639032612868033323e-05L, 5.08180543166657948433862427398171792e-05L, 6.91533341923576665290801314459185869e-05L, 9.32277498618928819410507284882673596e-05L, 1.24549207625185292746788896109936768e-04L, 1.64938971333376144939513069096604597e-04L, 2.16576471380809909291159455336007140e-04L, 2.82046340794006881311592802174739018e-04L, 3.64387021107897729238216699262593180e-04L, 4.67140162762043149791404714119969181e-04L, 5.94399941612237251611663813916878716e-04L, 7.50861330003505141341237132619730559e-04L, 9.41866302231455859084164368912569515e-04L, 1.17344692380002247672609547026883890e-03L, 1.45236427426188008347616119045966424e-03L, 1.78614218598655178612808460803997991e-03L, 2.18309484603519656221136749899809853e-03L, 2.65234740423109052289144172110269167e-03L, 3.20384885506921527761765779516587618e-03L, 3.84837661076576821141977260794172255e-03L, 4.59753235303186248996039969885789422e-03L, 5.46372893686621665171770797799402382e-03L, 6.46016831511747979221062326266402012e-03L, 7.60081065185419977059145624254178297e-03L, 8.90033498980204155946674089749748970e-03L, 1.03740920266168385556590451013464350e-02L, 1.20380497313706427480839156336456773e-02L, 1.39087326917827169960002061321148754e-02L, 1.60031562206455496475142539245814110e-02L, 1.83387563636593926316708603595489832e-02L, 2.09333170384958330449215168774593401e-02L, 2.38048955952869498234626954784270233e-02L, 2.69717481217077174816927863942958635e-02L, 3.04522558220532394622866431653207434e-02L, 3.42648537806332947261888782628446295e-02L, 3.84279633774899765386527022493279515e-02L, 4.29599295614980634381395647366200859e-02L, 4.78789641053477195533528647962166054e-02L, 5.32030958720316323100756360890520466e-02L, 5.89501290167188399227102430485391475e-02L, 6.51376099347951026087494855511522993e-02L, 7.17828036498272120091084808533476670e-02L, 7.89026802175633783409928711856568346e-02L, 8.65139116068936794825248092013403649e-02L, 9.46328794087702664882628072944679318e-02L, 1.03275693621920814402887268719345915e-01L, 1.12458222671938515285380933743314032e-01L, 1.22196134739810167085016527168685084e-01L, 1.32504950408621397326604347561435549e-01L, 1.43400106584199068783023171408440267e-01L, 1.54897031607657925984050586220533856e-01L, 1.67011231455784555526366713839660189e-01L, 1.79758386919258486031495958113778865e-01L, 1.93154461659030684603221234896514194e-01L, 2.07215821067763214460783254641335718e-01L, 2.21959361905993070139869913079334838e-01L, 2.37402652741481501585147220599178905e-01L, 2.53564085294908579555677649044302540e-01L, 2.70463036885576732351902861856168718e-01L, 2.88120044277091724111603906974976099e-01L, 3.06556989345224713687672375979413066e-01L, 3.25797297128632613090751563726807919e-01L, 3.45866146978355838846531059919780118e-01L, 3.66790697694818431455168590767201925e-01L, 3.88600327732532063221423261459050385e-01L, 4.11326891764317591973280272152569947e-01L, 4.35004995130479531888748830535836274e-01L, 4.59672287956338821101823148522366487e-01L, 4.85369781006713270719035870359289569e-01L, 5.12142185661796519744086646686900168e-01L, 5.40038280749567858894795821479236183e-01L, 5.69111309360283620800291297165821293e-01L, 5.99419409204557829271245298375247710e-01L, 6.31026080564853461281465428141943759e-01L, 6.64000696438865091754636398259527208e-01L, 6.98419060091622837940058120097784455e-01L, 7.34364015932103716685673325408458579e-01L, 7.71926120422450486565697123079450111e-01L, 8.11204380628463812996672518165491420e-01L, 8.52307069046258371120734338452652256e-01L, 8.95352624512219417238820469064741936e-01L, 9.40470650345508781665473144971561924e-01L, 9.87803022412309344664090567700404412e-01L, 1.03750512157160024916963789173178052e+00L, 1.08974720700214151578746902594297743e+00L, 1.14471594926501601899574650013187236e+00L, 1.20261614467922655880690394062840816e+00L, 1.26367263574296191533610775626416078e+00L, 1.32813246599542422597073187153380823e+00L, 1.39626730197278306832678497202104711e+00L, 1.46837615987297935465145703905241109e+00L, 1.54478848033412089590682530315276939e+00L, 1.62586760150092827681818702612923363e+00L, 1.71201468848349507792697792068680378e+00L, 1.80367318661869118602748089155898811e+00L, 1.90133387688644143294074965806611335e+00L, 2.00554062472320920559824403445004936e+00L, 2.11689692868996327728244730212683488e+00L, 2.23607339344688170923456651751668676e+00L, 2.36381627281331763524062140552607385e+00L, 2.50095725401825500385431630504625834e+00L, 2.64842468438767047986902883861439562e+00L, 2.80725647766353485711865991725063525e+00L, 2.97861498011790290399988989454287074e+00L, 3.16380412810114748721127771257562134e+00L, 3.36428929047159656773947338449998169e+00L, 3.58172026374255002938249218600614501e+00L, 3.81795797752670936449825238124466741e+00L, 4.07510557639156630320887778958143299e+00L, 4.35554467582358554514458856445852610e+00L, 4.66197774993613776113418481343338776e+00L, 4.99747780346124563910807301981274948e+00L, 5.36554671871496309147449064380266706e+00L, 5.77018396000583698718320188114380523e+00L, 6.21596767643453604333341399022283971e+00L, 6.70815068570623654464776592817234118e+00L, 7.25277436733040258314736650500251589e+00L, 7.85680416993879891697239876362854677e+00L, 8.52829127820429133135398118660851136e+00L, 9.27656603318338653224922387509018222e+00L, 1.01124700112272039114486606209390216e+01L, 1.10486353121876175190769261708382627e+01L, 1.20998216795271857764508697373482606e+01L, 1.32833246923912553882423938260725321e+01L, 1.46194715878299420711013972809323962e+01L, 1.61322254926408962729986594994585730e+01L, 1.78499242340404104179578536110600421e+01L, 1.98061868055245863949655128520558624e+01L, 2.20410294496835217815852679074305586e+01L, 2.46022447943980585927583897681190540e+01L, 2.75471123562893237374077750154320094e+01L, 3.09445280931970284883990775946651869e+01L, 3.48776660064165064038939228627010010e+01L, 3.94473180334351770794475603595764904e+01L, 4.47761023021425157569087608052893710e+01L, 5.10137878711900622533650986521384164e+01L, 5.83440613273984383402755554599355811e+01L, 6.69931638788863998843945524712655391e+01L, 7.72409663039404221632393248526916570e+01L, 8.94352363841359052286058140969269159e+01L, 1.04010107537438719134080196856970415e+02L, 1.21510103906665265646188258350644787e+02L, 1.42621552310160172951445448156836659e+02L, 1.68213866518508832477273582457732136e+02L, 1.99394097464546647941096853182355363e+02L, 2.37579409247584470819614691411159418e+02L, 2.84593916789823535562840880888980902e+02L, 3.42798827028127058717471147784029643e+02L, 4.15268383629255114718046929646589502e+02L, 5.06029199301683119404601716655559045e+02L, 6.20387871848170976858394304975149188e+02L, 7.65382367194376728088096731506729391e+02L, 9.50408087358179153450911943224019430e+02L, 1.18809220276011606595956628737466824e+03L, 1.49552334212407885347227350564427644e+03L, 1.89599366703067034325550411232806679e+03L, 2.42148532800683663374818194050951580e+03L, 3.11624674527423644655997407153581040e+03L, 4.04197721822739650017152639557046462e+03L, 5.28540456882764394198106919117899344e+03L, 6.96945349745478520211739265737692803e+03L, 9.26984863597541610825591719881066842e+03L, 1.24400169046144284609469034917486102e+04L, 1.68487804928219120974770366506141126e+04L, 2.30379493050689209894874317068326889e+04L, 3.18111749406368329678640732920395152e+04L, 4.43724092704038524997055436198884382e+04L, 6.25438880548229936896462817079707202e+04L, 8.91129656174671765721819893640615727e+04L, 1.28390011615567130356349325241374642e+05L, 1.87115939884978799395430373139032810e+05L, 2.75955654445572113231216194578725044e+05L, 4.11985149226574332956827494211875921e+05L, 6.22884543671150616939347176756608244e+05L, 9.54097172994412639791727921401626133e+05L, 1.48121323807100834515424707068495244e+06L, 2.33168052188078970586379639354686916e+06L, 3.72339779803011251388319470323527721e+06L, 6.03430539101169547235371451057106735e+06L, 9.92972861117960142404055815146657353e+06L, 1.65989636945226644757161242143615839e+07L, 2.82017465494921172861525124733558875e+07L, 4.87244883934161305263386031770533647e+07L, 8.56498776477185184074970634710495674e+07L, 1.53268758654909039217478083777958109e+08L, 2.79366798395238972059209786152271040e+08L, 5.18973079293501172198046128702649663e+08L, 9.83165082634482695230583899233702397e+08L, 1.90059962104050828804295224765625411e+09L, 3.75160395202091966289927262175925315e+09L, 7.56648043123273181762292360200563868e+09L, 1.56033907397856950198380769768232419e+10L, 3.29229832278164384876778685138061688e+10L, 7.11297379086385418813540334382875157e+10L, 1.57471442166507563544871664087516645e+11L, 3.57509888501672692207543566803978301e+11L, 8.33024430623979589172560805550927471e+11L, 1.99374509951525518357032637324282993e+12L, 4.90561996981418757143934103035069327e+12L, 1.24197379810188498181468317797399218e+13L, 3.23831600275722270184945604347174663e+13L, 8.70403769580874957196023586424815933e+13L, 2.41399528145469907607734183398259453e+14L, 6.91510620574880583944843529198735451e+14L, 2.04811558742607734304993874133785299e+15L, 6.27861397733698939186730156018167292e+15L, 1.99435267076689206564427715465056511e+16L, 6.57141971664513108413598657255436192e+16L, 2.24875056642273914367880154275296162e+17L, 8.00147401578245998412996372425512095e+17L, 2.96403754199235340052960592736049159e+18L, 1.14455803313869409862823561648962815e+19L, 4.61323311996821344548899222001480398e+19L, 1.94346926949906856258436939614621369e+20L, 8.56968050834200116120462221511753399e+20L, 3.96091566953282355348486677100761553e+21L, 1.92185171194284479900050386014427105e+22L, 9.80409181939054057802535035944011717e+22L, 5.26682924609986175842861032563925229e+23L, 2.98441055802829784200443452444088495e+24L, 1.78677995299228897649048545726173530e+25L, 1.13225906725879734647293567479653181e+26L, 7.60791970573697649080495794599946588e+26L, 5.43049485025884671542842347146701195e+27L, 4.12572142434645000681420526588413556e+28L, 3.34277767339287328803586493191472415e+29L, 2.89434014229221431295360965172883804e+30L, 2.68374761249850267614464943620131017e+31L, 2.67072026965642827232315722365639115e+32L, 2.85880373230063837155252556137517211e+33L, 3.29924822913520515079335032162581841e+34L, 4.11488570832552270061078474206882038e+35L, 5.56010558358231010262223361328066200e+36L, 8.16009266847150844693389287229450581e+37L, 1.30416726659952301962536120869903033e+39L, 2.27600481686142160023333409481863034e+40L, 4.34938214638271735275350443120721790e+41L, 9.12741493518023346499222172162825387e+42L, 2.10972038777434150864210644015160107e+44L, 5.38754491759583324556444810556121661e+45L, 1.52482535270240332398284822085798536e+47L, 4.79877533166358652838909903087275144e+48L, 1.68494126510508458862564987284302025e+50L, 6.62357573295543230261174696442002813e+51L, 2.92557273755841342556692584369563440e+53L, 1.45729219902900863678006319195819802e+55L, 8.21783496105748128055143975755446008e+56L, 5.26688130483523933792268242131450300e+58L, 3.85211799189653678380768112270880793e+60L, 3.22861432024885393800430464301385615e+62L, 3.11445231039438406261213455773274485e+64L, 3.47323481265477220985448691064609690e+66L, 4.49855546587324575105781665091655708e+68L, 6.79925746409737423822172568281133860e+70L, 1.20511321523280079626937861818322431e+73L, 2.51749264598597737693408358183917414e+75L, 6.23086472714522132176542446806460931e+77L, 1.83698604157213615145607828551975305e+80L, 6.48713124894846526923286444858655243e+82L, 2.75979764628924062898267004292796591e+85L, 1.42281010916783424894495664030511266e+88L, 8.94356583170635560730657498907040019e+90L, 6.89765608918172471716339680473639534e+93L, 6.56960382950241207669696237814704407e+96L, 7.77916346275648519460667580565807164e+99L, 1.15314598687748380372708686918514146e+103L, 2.15521325185955507170865064451154694e+106L, 5.11618164822064799451529384134754077e+109L, 1.55434716015270528126967279870385072e+113L, 6.09112777117402790869661219995564436e+116L, 3.10387507242519227183111245931080882e+120L, 2.07390189233940742293442790510784430e+124L, 1.83267382155701863417862737648022763e+128L, 2.16097258672364775058232219739796364e+132L, 3.43128595186527837599814654188046354e+136L, 7.40646244666625583794129098263179729e+140L, 2.19454208154239352969892199569722442e+145L, 9.01619836979155465535468945047889426e+149L, 5.18985678737597694246477524117862598e+154L, 4.23046985030263912409378392183252421e+159L, 4.93764276985086773495452256391816235e+164L, 8.34636422063293684495534346523864357e+169L, 2.06741406169751668845974997770098232e+175L, 7.59587841419400960682004001784651511e+180L, 4.19164127392101407920200382533221559e+186L, 3.51927711650483149002609005453729140e+192L, 4.55587470619707394753414927965798200e+198L, 9.21952142596023196043927688149872532e+204L, 2.95816314360706369484966684111893238e+211L, 1.52709952631709289803811134371908265e+218L, 1.28765668330017907582554622529315931e+225L, 1.80129361672056777447357282869624658e+232L, 4.24814651295030396772649227180907798e+239L, 1.71729703963558073111114105671039088e+247L, 1.21046234446012300929891454835993254e+255L, 1.51419519516367160890801105849993081e+263L, 3.42330233588160029564511697140750743e+271L, 1.42528129667493838632765543616342364e+280L, 1.11420723637564670686340338390175118e+289L, 1.66850212135837193821657370527462903e+298L, 4.88589347415031911318629107633374545e+307L, 2.85800617499362161237161192858659000e+317L, 3.41368346308455763011375953918857639e+327L, 8.51659564264685587821018369835222946e+337L, 4.54303089474615832686354150019925596e+348L, 5.30809578740740306246018975605923943e+359L, 1.39268945492416740550127311639881773e+371L, 8.41868946331338761333876333129653244e+382L, 1.20396970846759916705111332553270569e+395L, 4.18638285711073253556696402015828229e+407L, 3.64051583443686661335653674614037576e+420L, 8.15125707810912875910267388062325131e+433L, 4.84241684726444145079336201568928602e+447L, 7.87277386139003022204421580245435912e+461L, 3.61660042166407854517352456605683269e+476L, 4.85176905670774504900384645174873943e+491L, 1.96653101796028683463909850095858046e+507L, 2.49428344091357019569533852688763620e+523L, 1.02650775155921036180043655136824490e+540L, 1.42290670725613581153914997322741401e+557L, 6.90446128383757111350399979478971290e+574L, 1.22038031602184356762554212370154951e+593L, 8.18641498043102997149775477320992897e+611L, 2.17426427576810603662782427977182733e+631L, 2.38847898517251831173924452396821302e+651L, 1.13525581232092079165478024625033648e+672L, 2.44581305055310563196277332943189236e+693L, 2.50579201726264634501291514398286907e+715L, 1.28278958026597426545698815500879845e+738L, 3.45329144611998202962794722592107008e+761L, 5.15301310117757693898843758843439768e+785L, 4.50037434223155300664502702852727419e+810L, 2.43306674872992411217032796443919144e+836L, 8.62798204693025064663883932656343701e+862L, 2.13031523407691556211779361127399737e+890L, 3.89502853428849118703235846476912848e+918L, 5.61967843038535141183624496528991236e+947L, 6.83163157235897275355324461890504612e+977L, 7.48741060910847824069581635250382582e+1008L, 7.93319051954128205327740081284490051e+1040L, 8.73273358333231337767980404927541807e+1073L, 1.07574303828662898687276828597901159e+1108L, 1.60109519481842931883372467310550530e+1143L, 3.11621335415749303163841998134612826e+1179L, 8.60558107743722927550014656572137529e+1216L, 3.66811383278356514418007625117425117e+1255L, 2.63234220176367112942815907184016908e+1295L, 3.47859421502287448304146808910623408e+1336L, 9.28512235755776936781681374078562947e+1378L, 5.50718056653300293052467960576840696e+1422L, 8.00902248373521173018720630861185040e+1467L, 3.16115623922106492070773163357582495e+1514L, 3.76042153408120168432167355515647590e+1562L, 1.50211667261404150161306978400073837e+1612L, 2.25263196634448337432840054986261153e+1663L, 1.42290818050514650710172541634086053e+1716L, 4.26315122517229508281635793163851999e+1770L, 6.84787649140078417523090257285629098e+1826L, 6.69183748343427005004387693124220507e+1884L, 4.53246642529433183363157301179103704e+1944L, 2.43420309539903059914673692609144617e+2006L, 1.19096818482919681799422553000433899e+2070L, 6.12585236774593416353267428912127386e+2135L, 3.84000941993213246405245986391372004e+2203L, 3.41673273574541565248480628561887880e+2273L, 5.05031055516767284204610907378751985e+2345L, 1.45860427844568831785920214989842347e+2420L, }, + { 2.77668375956040189946826811680384390e-2478L, 7.15287685954868211386033128907477031e-2440L, 4.67658088132803463412188029644470498e-2402L, 7.92687480429971819654882242916691373e-2365L, 3.55705626445534513670485482702241051e-2328L, 4.31363186281767249198550472192046640e-2292L, 1.44267570824010102564476209762038016e-2256L, 1.35750289529472083929076668071298865e-2221L, 3.66520151899825097802289209374933991e-2187L, 2.89498463671553268274047707590333923e-2153L, 6.81807725541668247816231315716744273e-2120L, 4.87856900336985600073857171641568070e-2087L, 1.08033682307899983904972807875490412e-2054L, 7.53978658799448170922270322982561647e-2023L, 1.68836600150778453318616795534542245e-1991L, 1.23462709610862382392789185979644933e-1960L, 2.99986697918589103634446685042416531e-1930L, 2.46367649797140140439024370548377672e-1900L, 6.95479514251903643444688832919306991e-1871L, 6.86110776725256744693425828768272774e-1842L, 2.40431940102692787285034949159539178e-1813L, 3.04121511300162701514429163779115709e-1785L, 1.41065291642406553832784938505501922e-1757L, 2.43705806703985396362343530158481976e-1730L, 1.59233397078886467474093245165420794e-1703L, 3.99458646512746569553991304016076066e-1677L, 3.90502825544924862516415029425091730e-1651L, 1.50951212222311306420066585908781007e-1625L, 2.34075577961021270449149847209864885e-1600L, 1.47683791355252947630371426518876483e-1575L, 3.84433827968748974568829430827411882e-1551L, 4.18584678137447017460210584041562890e-1527L, 1.93235335361456340539919561054923147e-1503L, 3.83273493158460886555652388105220442e-1480L, 3.30931424971841824136873930746170663e-1457L, 1.26001001743526741988366704934436124e-1434L, 2.14254382108136960073063000869254434e-1412L, 1.64752740569760866428499059885288678e-1390L, 5.79997534765464443335232132612089697e-1369L, 9.46173366850636035136459393339314051e-1348L, 7.23844554700889711120024618879438753e-1327L, 2.62753543705293236920590575888507321e-1306L, 4.57825670343966465596419576070363442e-1286L, 3.87294895920776670416027972176834657e-1266L, 1.60856514992623900565886618371043785e-1246L, 3.31650403849378163469754348545840043e-1227L, 3.43149117215084179247503681795855710e-1208L, 1.80089379614922388608625914511562841e-1189L, 4.84469660937728881846012977552474102e-1171L, 6.75021934282781912062862469597524256e-1153L, 4.92120879530819746165015110941962755e-1135L, 1.89622303139680815547453480860411409e-1117L, 3.89999690124553358779083557357143651e-1100L, 4.32337852652349730363515343553956403e-1083L, 2.60812148992852188438485836891607672e-1066L, 8.64320507307309471921069873497971138e-1050L, 1.58817234955465364327662145482119776e-1033L, 1.63292822332387428570727069490856970e-1017L, 9.47965403932768371077126663738787002e-1002L, 3.13489123036525936535865202633924346e-986L, 5.95725324626422679969355089398557051e-971L, 6.56135449619885064132736333035718110e-956L, 4.22412947622465431737740854731813869e-941L, 1.60284936502012533605395043475391797e-926L, 3.61426009581007446214636991266185477e-912L, 4.88226731291038533672727194690523707e-898L, 3.98243859045531426665602764668150557e-884L, 1.97696254579881780215274246825324592e-870L, 6.01884829406232602469720991349044932e-857L, 1.13236358528056083157892195864287071e-843L, 1.32634602112101849951006383738692278e-830L, 9.74354258615429475261032804502093079e-818L, 4.52175713954583830576111594951110560e-805L, 1.33512020097306090853791018618669252e-792L, 2.52581092493362086952359277189983609e-780L, 3.08280454280630114861769351743791880e-768L, 2.44403095665612216421741893390173529e-756L, 1.26703351146649868905932200644776032e-744L, 4.32364746058654184636712625519962546e-733L, 9.77482453681545274501227529587168230e-722L, 1.47345296987795364063826018729590588e-710L, 1.49025749519107052339924056423862408e-699L, 1.01758543742056270682348949473524139e-688L, 4.71965368684349520914049336410150458e-678L, 1.49583331955342167906773277357310899e-667L, 3.25877112957152479296585133409409173e-657L, 4.90846979890405909332298369271733953e-647L, 5.14096775171769223933971053266547990e-637L, 3.76527319345060607553853872315139069e-627L, 1.93914103642113548742773247369930873e-617L, 7.06081267960685321695216552061682039e-608L, 1.82753922477698812695612565052211519e-598L, 3.38020931062714080731736679298776434e-589L, 4.49104974727379533831457784467988803e-580L, 4.30831017202845455490779426657646708e-571L, 2.99925774499663529105464847801180013e-562L, 1.52274525111081863903256031902733405e-553L, 5.66595073105051388454002533447155475e-545L, 1.55254034318111114885985765214004285e-536L, 3.14773091677700441775450360300498865e-528L, 4.74422214535871848463366092395468719e-520L, 5.34000677409012855851843363768904621e-512L, 4.50913961542719498094454101135511353e-504L, 2.86916730093441295609899413107663763e-496L, 1.38176315596895654455580263526098670e-488L, 5.05827668288972660188294275444103716e-481L, 1.41354423391013787396132813520577665e-473L, 3.02811286218415761503816814918528786e-466L, 4.99321587478833584968780076440597278e-459L, 6.36350378784780643105814130227578114e-452L, 6.29295581774659679570380847201393083e-445L, 4.84800776366962427166614895670077970e-438L, 2.92081155862662548270928062619807743e-431L, 1.38143568676341254642463548681208773e-424L, 5.14842432351503290408078410534655737e-418L, 1.51753560889290027005627901927469983e-411L, 3.55061704489050704368494163406172279e-405L, 6.61796042955880547227964893320004528e-399L, 9.86122308014976296151434619809887336e-393L, 1.17877481135241077171765329651013943e-386L, 1.13424833803992349974759003704486622e-380L, 8.81502377306393355822212968439637791e-375L, 5.55155950590484925963715579436840823e-369L, 2.84248729913659406224316552722434334e-363L, 1.18704719186027282879490304441234572e-357L, 4.05597847694543335354139081149132852e-352L, 1.13745052103435347539610354499759843e-346L, 2.62608432267715211136705119144544958e-341L, 5.00649221900861773230008659070798254e-336L, 7.90489841299351390278476450028383484e-331L, 1.03673095771954987567298480275353471e-325L, 1.13264118291164663653569719276217293e-320L, 1.03372554114991613828759256440083793e-315L, 7.90343344978986920403039115230438646e-311L, 5.07593758357543835739913968923721419e-306L, 2.74587297706393183600196990448758755e-301L, 1.25448043297991919976296583184269934e-296L, 4.85293287864597257977432400607091472e-292L, 1.59375532748424261820313240836566102e-287L, 4.45470192712163297279675529941780532e-283L, 1.06238236699788796015140463431038408e-278L, 2.16709025689586849941731617555370390e-274L, 3.79017494148388392555292862630176094e-270L, 5.69722642026139785964263462216321432e-266L, 7.37750423818818484376423187717037465e-262L, 8.24899816234186348122208308733670706e-258L, 7.98228295613681065404000331301407417e-254L, 6.69977627078532550007479609463315785e-250L, 4.88831026337525670264792775582398754e-246L, 3.10717465030331182564914656973440633e-242L, 1.72428695582194286916259157368370433e-238L, 8.37152419508690266695542791416172637e-235L, 3.56328545617913642798317603893755984e-231L, 1.33239745308069123170741398284986139e-227L, 4.38557307471736323357712547586541243e-224L, 1.27317190092247560042567075437905721e-220L, 3.26633944706575228492861971563886982e-217L, 7.41961719235926788479176390701225966e-214L, 1.49508892701036107375575902806187267e-210L, 2.67747004659594255579164687433346539e-207L, 4.26921971680475266131733781176106392e-204L, 6.07184376271449065521795822572065912e-201L, 7.71632746256793762696505755410742573e-198L, 8.77761527570739954686084893442788334e-195L, 8.95291300378341203683641755088969233e-192L, 8.20179011370862828929882403579221646e-189L, 6.75977978662441271172788792155811852e-186L, 5.02051176570061397957717306624573193e-183L, 3.36554863928813190587746679952307259e-180L, 2.03960573952427530884860135637723107e-177L, 1.11917598852847666035205866531172342e-174L, 5.56905039413988338846998023185739233e-172L, 2.51682459319287628531543936384778284e-169L, 1.03457507608575432785228105631849600e-166L, 3.87388309025221395194171192891040522e-164L, 1.32322812968423778281527114220160831e-161L, 4.12900297352082279106292344371557207e-159L, 1.17865546256954888181796214775388038e-156L, 3.08218900889320623074522540652758709e-154L, 7.39354283219941448656677403739458341e-152L, 1.62910064435532863938332952898952690e-149L, 3.30154552905982294134609461204752294e-147L, 6.16203139085424122701291732112343081e-145L, 1.06052819447098630885771547158633382e-142L, 1.68522575749723508863020213808775829e-140L, 2.47553409758226362888052187337950144e-138L, 3.36576474950758719210258297005317849e-136L, 4.24056268392402238294912126586145782e-134L, 4.95679422788561171460024764665358982e-132L, 5.38171636791416151987580045952962687e-130L, 5.43350717229498884938353606822409483e-128L, 5.10703124279431542010303665040364840e-126L, 4.47370493209864639350813176634174273e-124L, 3.65637694737788862889473248524269217e-122L, 2.79117002269425900051588497263773104e-120L, 1.99220023869241503219258818787712929e-118L, 1.33089435939378971755299967553769684e-116L, 8.33035676735989050287962245538521119e-115L, 4.89025663997024514599039877971897448e-113L, 2.69512893545116544669129054438916450e-111L, 1.39582960541563084355183973360376419e-109L, 6.79999752718808594213315829447961814e-108L, 3.11903776737903229329061449549842670e-106L, 1.34826013141921629130407145750369350e-104L, 5.49752601894399080415833353152482494e-103L, 2.11638467025119853304622111522504730e-101L, 7.69914871485806120880436816954565416e-100L, 2.64906534725059834511552809323827260e-98L, 8.62818926354972775334178389390317975e-97L, 2.66252094324836892217545797407595895e-95L, 7.79069862358288634135952568964046431e-94L, 2.16335486668307728100344975621110455e-92L, 5.70557673979722036138381850123515391e-91L, 1.43033819302856491333403076823625576e-89L, 3.41104078137232874664267449214467490e-88L, 7.74426807351644903668383259880558649e-87L, 1.67513656430343581317253830008450619e-85L, 3.45479581059570481569225182340141781e-84L, 6.79857313709947736278888732144820603e-83L, 1.27747470803378266136497077558029564e-81L, 2.29370213942630948295519765524670121e-80L, 3.93802170001517503024981641969166523e-79L, 6.46959393487630012362523872090477425e-78L, 1.01772526699091247125279301878345328e-76L, 1.53401952979332495111639447956817637e-75L, 2.21699988683886091607827589036641130e-74L, 3.07410074756280336185727691291524915e-73L, 4.09229533083754909228682061184080234e-72L, 5.23343417563653847061479912948387465e-71L, 6.43350607976335741808585356397544551e-70L, 7.60704267790136216066341175717356605e-69L, 8.65671438716342535748325493579430488e-68L, 9.48674605868548997400346985395655480e-67L, 1.00175672424828839701939548888991483e-65L, 1.01985394383485432972080334959114676e-64L, 1.00159110661066563005593773053264872e-63L, 9.49427782244426395210838765944495599e-63L, 8.69142291889189064854075883690819022e-62L, 7.68797704788744827616631661309525244e-61L, 6.57440810419660524782417308561229212e-60L, 5.43816250291842519145575247702512746e-59L, 4.35334083136300321175659843267140387e-58L, 3.37433876218124341053665144604385146e-57L, 2.53377092117304232961472206140287465e-56L, 1.84404892524861673828316906508664460e-55L, 1.30141081230848018402542829366785560e-54L, 8.91046674437447006307015773182167698e-54L, 5.92153838412413233143345637093941679e-53L, 3.82135613429770512672309553535220252e-52L, 2.39578065735303689149259651605329745e-51L, 1.45988218758182023631230626004517631e-50L, 8.65010547207677732721948607063784916e-50L, 4.98593355079719931559980617333925476e-49L, 2.79691190323743591605512918548961454e-48L, 1.52757011899350333194123701418929652e-47L, 8.12631404819699330158401537112269973e-47L, 4.21243636394857818219784558381591723e-46L, 2.12860405024256466240923390999711474e-45L, 1.04893835632343107182205383744844780e-44L, 5.04275314265368784163135845797922992e-44L, 2.36599922549416536405636377221603052e-43L, 1.08381346209104032486272733428199249e-42L, 4.84896336796031616924505606902108385e-42L, 2.11961287373765727720156892217888941e-41L, 9.05594713902200264778664561627827336e-41L, 3.78298719219266665046394564391309006e-40L, 1.54564984691757476458462458129485585e-39L, 6.17890975212602635731338783415082506e-39L, 2.41759755862594038624882497707942985e-38L, 9.26130599996633274587378852134765724e-38L, 3.47471297119465611529279266980333841e-37L, 1.27721589062918134522531144355249981e-36L, 4.60093813393547386396189442938777048e-36L, 1.62480431477305204386750726891935535e-35L, 5.62680810313792997206232926753677840e-35L, 1.91144242994708647057868821934329247e-34L, 6.37130041549818712538060098629118750e-34L, 2.08444453130944123746087664312229902e-33L, 6.69535606006557423430835320939136513e-33L, 2.11203843563779293148946583571749480e-32L, 6.54480290655151239305039275670085965e-32L, 1.99286493762398711426295964156611288e-31L, 5.96435881776415175461953820911435643e-31L, 1.75497323146494950021419641534165307e-30L, 5.07823155886177386317817053950871430e-30L, 1.44544786652825947518140437679267760e-29L, 4.04809975939166078604969666043969110e-29L, 1.11575287892799422088984788434321808e-28L, 3.02733416844233859190251989588495462e-28L, 8.08786849810622478767566085355596476e-28L, 2.12810654415185893615787768003277562e-27L, 5.51621011393022798460545237305226697e-27L, 1.40889092112486390607440977505465003e-26L, 3.54652073432677480700798349650597512e-26L, 8.80063648109636049392437478276758980e-26L, 2.15331950904398446525184217737998611e-25L, 5.19613654473192634598878003489200027e-25L, 1.23686905842220219027076147492586511e-24L, 2.90489167449091887312162206507161675e-24L, 6.73270731756325876275561922583341148e-24L, 1.54025360336139105521086193967934171e-23L, 3.47876572768722101871596015971992779e-23L, 7.75845007993303197586197585003227682e-23L, 1.70893932426983027624683633350310787e-22L, 3.71846701056881115177897268795618277e-22L, 7.99409437676902992032878645322876456e-22L, 1.69833677431834312305384300763198925e-21L, 3.56621446972400227479906082231485065e-21L, 7.40284853486635166159906810215851685e-21L, 1.51941171975529754933443555359007838e-20L, 3.08399399452860874024652960034823534e-20L, 6.19138881797445980861805317656851788e-20L, 1.22962598701058922677441904835003634e-19L, 2.41624594930841108357336910436255182e-19L, 4.69855181874941970642420918335722321e-19L, 9.04299297884852043932311013611381641e-19L, 1.72288019839002081694998146770641182e-18L, 3.24983285835411232229770728918949423e-18L, 6.07012059458645756189773861988245818e-18L, 1.12287188164609844099198470626937240e-17L, 2.05742923566420592156922015953543702e-17L, 3.73461320774281639944361675972781502e-17L, 6.71669436926784207473111220730444193e-17L, 1.19706302505504395186947411747310186e-16L, 2.11441966111566361680483324148539475e-16L, 3.70201713823102185303168392234499685e-16L, 6.42566549874633786044656050804228769e-16L, 1.10583090372698541886807277008925137e-15L, 1.88715605166056322365232100161599762e-15L, 3.19397901867912583303235022260119744e-15L, 5.36188197747320445907706025927166858e-15L, 8.92931856860669280901808059459161448e-15L, 1.47533056095858665971377793523064186e-14L, 2.41870863676582496406573146120828803e-14L, 3.93507835090405130222724885910838729e-14L, 6.35404709630865447857089142202307170e-14L, 1.01841666646650944181450881700329392e-13L, 1.62042378299930769318560924447489642e-13L, 2.55981751705612616590139075734652273e-13L, 4.01527388629421281039816262827476156e-13L, 6.25453235826176129082121714446163184e-13L, 9.67598102139418285827447083279565919e-13L, 1.48683211253456618620643979203627482e-12L, 2.26955737776048687888315587634986337e-12L, 3.44173600876636583230784574560493186e-12L, 5.18579385986065241250884484837407551e-12L, 7.76421788931400466314739807932612879e-12L, 1.15522810574654803550770552217628934e-11L, 1.70831312146426209744016210099566072e-11L, 2.51095185608620189710869551132160955e-11L, 3.66877697851095234075891821003426570e-11L, 5.32913181394174031371781017456930198e-11L, 7.69632539729948085558352466099257329e-11L, 1.10520072364372285498114055238330020e-10L, 1.57822184379603482492805668832205965e-10L, 2.24130967294097676646756319917307649e-10L, 3.16577320114495664158493107630920887e-10L, 4.44773051087161070439507137569795222e-10L, 6.21604166145516404864589081218699790e-10L, 8.64254490539598786804804563578215933e-10L, 1.19551930651665934901247256485043253e-09L, 1.64548212141718982285430677462884054e-09L, 2.25364361294162088274171207920306355e-09L, 3.07161057649675130982867546470369013e-09L, 4.16647469046044592666212503776391905e-09L, 5.62503650418518103546622761014447205e-09L, 7.55905963895399839577230243791284335e-09L, 1.01117741787649109183519733871956784e-08L, 1.34658870190626745425612716113453914e-08L, 1.78534009295770335027325069409745001e-08L, 2.35675936423533751929780865973963492e-08L, 3.09775637333761608808718626586210342e-08L, 4.05458117130271472976754716443074815e-08L, 5.28493928008555417314519862662075002e-08L, 6.86052524785416844753739601495847428e-08L, 8.87004371407679534565262439555179668e-08L, 1.14227959934028163656084297163993474e-07L, 1.46529195996537375677477289744322135e-07L, 1.87243781452025990276419175076674860e-07L, 2.38368096170532406236914962927186340e-07L, 3.02323520821923278406510621336929642e-07L, 3.82035773260694787625549171519571981e-07L, 4.81026746749616004418812011672214969e-07L, 6.03520391713916631448186742261762126e-07L, 7.54564302177565687477041747448625764e-07L, 9.40168786133714127970401442799808303e-07L, 1.16746531401927207818183968119629644e-06L, 1.44488634919934624164636989185786720e-06L, 1.78236866676220579646941432400191756e-06L, 2.19158235968382023977800841196782357e-06L, 2.68618781213700528587671678902632939e-06L, 3.28212298590973811003340670234049833e-06L, 3.99792341503412914858164425580814066e-06L, 4.85507733328388046876150511289283628e-06L, 5.87841836668756018708322083288294132e-06L, 7.09655820622938796350022322477138609e-06L, 8.54236163220623609743157219064928822e-06L, 1.02534661892020938105973895830986033e-05L, 1.22728487074863285519290054710280426e-05L, 1.46494407312787820235069142302801116e-05L, 1.74387947455200274155445197262654991e-05L, 2.07038028896765075538771239781158806e-05L, 2.45154696092443087426053206140339263e-05L, 2.89537394229808584415606234281235237e-05L, 3.41083806769492860360664819345743796e-05L, 4.00799258161539348751926239815464572e-05L, 4.69806683323287862163878784706404376e-05L, 5.49357161442722725101184470856795070e-05L, 6.40841007374651816919514989779193660e-05L, 7.45799409355181382811997812036059565e-05L, 8.65936597006977565440049012882777955e-05L, 1.00313251868244228486845169918522419e-04L, 1.15945600213690649557974183508671660e-04L, 1.33717836738558167374082301113276138e-04L, 1.53878745542570977882656611663357910e-04L, 1.76700203135100555424143059190915095e-04L, 2.02478651530284460762520573567302864e-04L, 2.31536598974665040190979221162493510e-04L, 2.64224142678798208257632362853594384e-04L, 3.00920507470608001324163745800874977e-04L, 3.42035593863725830721435182160899216e-04L, 3.88011528643900055031892572065609775e-04L, 4.39324210725794779827016989314436073e-04L, 4.96484844725809052233768108298280237e-04L, 5.60041454438256227059209260385185510e-04L, 6.30580368196231443658525282679749066e-04L, 7.08727667948158660008974296844527949e-04L, 7.95150593789209443880323604776955146e-04L, 8.90558895655812679363260602821822057e-04L, 9.95706123923012434268721813542918011e-04L, 1.11139085073953859292031598702982886e-03L, 1.23845781409454868818512091763619876e-03L, 1.37779897683285042761735605405503089e-03L, 1.53035449312115014435580213674818791e-03L, 1.69711357521498846993912286538919474e-03L, 1.87911525378240440542796943910703787e-03L, 2.07744902550331120940589303741307914e-03L, 2.29325538217982005624763697091003995e-03L, 2.52772621615854827916639591227331912e-03L, 2.78210509747707274118095565348853401e-03L, 3.05768741879849780665835354304288470e-03L, 3.35582040488560696306610399114125004e-03L, 3.67790298408396440888192232818825231e-03L, 4.02538552002609726985152127212337675e-03L, 4.39976940253081440732383904779371772e-03L, 4.80260649744698504497144153794077709e-03L, 5.23549845597384011114251649759318761e-03L, 5.70009588477421233645539752147845015e-03L, 6.19809737897730872540802302573847437e-03L, 6.73124842093794861403414763375789954e-03L, 7.30134014837421983438805473382268060e-03L, 7.91020799623995212524470914365122922e-03L, 8.55973021739730390294556694387596169e-03L, 9.25182628783344529797384941938652911e-03L, 9.98845520280948891334775899197118662e-03L, 1.07716136709355454400393298774895433e-02L, 1.16033342137295485601573254130151715e-02L, 1.24856831787362164573968971563345559e-02L, 1.34207586747535542664119568732591706e-02L, 1.44106884381354658508301066473916456e-02L, 1.54576276395086064771405090469805654e-02L, 1.65637566405583013536386920486874088e-02L, 1.77312787108013640215572254554956350e-02L, 1.89624177144726038238696005618612010e-02L, 2.02594157778067758841208537767709612e-02L, 2.16245309470991783928580857382458621e-02L, 2.30600348479769142051214039575544903e-02L, 2.45682103563102531782599654851478334e-02L, 2.61513492911411521698129655317611847e-02L, 2.78117501399057252267505437298152555e-02L, 2.95517158260815126327011961248970821e-02L, 3.13735515292012408141424535463840985e-02L, 3.32795625669450926962877709780283664e-02L, 3.52720523487562160472278601135978908e-02L, 3.73533204101223493795063079870277644e-02L, 3.95256605363332412560750462340568604e-02L, 4.17913589841622853414796289201462570e-02L, 4.41526928095348722137611194180899765e-02L, 4.66119283088387990349053837529086301e-02L, 4.91713195811071287202299070345370512e-02L, 5.18331072178645941782756741967663201e-02L, 5.45995171269784130156535121811973661e-02L, 5.74727594963965733729390200663376457e-02L, 6.04550279031945582526756917103894992e-02L, 6.35484985728882875351754365961380466e-02L, 6.67553297935098586459427868785125518e-02L, 7.00776614884864197850796119077335695e-02L, 7.35176149519140388651301532758182494e-02L, 7.70772927493804152471705586229649727e-02L, 8.07587787870652431694028348485017861e-02L, 8.45641385514373366852999925423097546e-02L, 8.84954195214754605679505353644207668e-02L, 9.25546517549672049628688665169818439e-02L, 9.67438486500890476543279055502732567e-02L, 1.01065007883142650157999494215339249e-01L, 1.05520112523018947242782060692540634e-01L, 1.10111132322684063185699908950501089e-01L, 1.14840025187730710332047574671488736e-01L, 1.19708738821816529269842068051324872e-01L, 1.24719212548617699381893630778769370e-01L, 1.29873379309762826940592292027774350e-01L, 1.35173167838079215925316604016895877e-01L, 1.40620505005381631636575206950501568e-01L, 1.46217318343962952595269565777364191e-01L, 1.51965538740906942447303428154167210e-01L, 1.57867103304335938296117505727756989e-01L, 1.63923958400730641095309983504562072e-01L, 1.70138062862515433149015694041321523e-01L, 1.76511391365190704205555387802167839e-01L, 1.83045937973413460592324819248629329e-01L, 1.89743719855578905138540205901925041e-01L, 1.96606781166638569017145529907938222e-01L, 2.03637197099104797388960830732662422e-01L, 2.10837078102436785186096324004787346e-01L, 2.18208574271279784343490287100076472e-01L, 2.25753879903336437885194071240289887e-01L, 2.33475238227987351081778389476348222e-01L, 2.41374946307146941036852686683657608e-01L, 2.49455360110240324117132946908862256e-01L, 2.57718899765617581970697551365699803e-01L, 2.66168054991183344330456451077482845e-01L, 2.74805390707512480349974276871498222e-01L, 2.83633552837247137560986852113493320e-01L, 2.92655274295126854671240651245542162e-01L, 3.01873381173592566247581847444990310e-01L, 3.11290799129527708372244037377423071e-01L, 3.20910559978356159579257040371157487e-01L, 3.30735808502408397196150346208941643e-01L, 3.40769809481195164806575214000604739e-01L, 3.51015954951993455453034437018576899e-01L, 3.61477771709954227353934951808660907e-01L, 3.72158929057786693176355712369457666e-01L, 3.83063246815962181179662085907016341e-01L, 3.94194703605313603549231284148895684e-01L, 4.05557445414886871112481166359816563e-01L, 4.17155794468930807411520974095114834e-01L, 4.28994258407995154251335647089270309e-01L, 4.41077539800245330879960121109734359e-01L, 4.53410546000301224452886670053661009e-01L, 4.65998399374169294389180835005701951e-01L, 4.78846447910166863084991969300289662e-01L, 4.91960276237139210883303640625007935e-01L, 5.05345717072748965861316155618037977e-01L, 5.19008863126178679451085258491885813e-01L, 5.32956079481237266942061435303847022e-01L, 5.47194016487605519485083198030599369e-01L, 5.61729623189802041293777914000548030e-01L, 5.76570161325406179304747155047028479e-01L, 5.91723219926146849096660434528676034e-01L, 6.07196730557664332661777342118343230e-01L, 6.22998983236085549221918733111272834e-01L, 6.39138643062032159550125999965534073e-01L, 6.55624767615316158435211030870214346e-01L, 6.72466825156381227156528472165863186e-01L, 6.89674713683532904728192023160169670e-01L, 7.07258780898180476422511449104598714e-01L, 7.25229845133703375815759935882969711e-01L, 7.43599217307171072603779249870503705e-01L, 7.62378723957005410057715275736188342e-01L, 7.81580731433797129025240842779308298e-01L, 8.01218171315894385869574690877526536e-01L, 8.21304567126092639185776756157030964e-01L, 8.41854062430796373280836243276360497e-01L, 8.62881450408419762754617604609421022e-01L, 8.84402204979573743001129336964073261e-01L, 9.06432513597781571704880022546834535e-01L, 9.28989311806106946360784332676954119e-01L, 9.52090319672203976394493741712123982e-01L, 9.75754080221945735296148718924093021e-01L, 1.00000000000000000000000000000000000e+00L, 1.02484839189454300830993201809676807e+00L, 1.05032052037278447499546563674080434e+00L, 1.07643864928417387084533130337621185e+00L, 1.10322609239912797847732993345442148e+00L, 1.13070726686292705163871994441376389e+00L, 1.15890774975714122929598339522250570e+00L, 1.18785433797464608445948646027899515e+00L, 1.21757511162904898441624819295410761e+00L, 1.24809950123526638608045628896113726e+00L, 1.27945835891516450038384515634984238e+00L, 1.31168403390070906172271785633240954e+00L, 1.34481045262708114284870961989593531e+00L, 1.37887320372983270957282413312613361e+00L, 1.41390962828351735195133854106565322e+00L, 1.44995891564449075379247910337230275e+00L, 1.48706220528789860745767637311307254e+00L, 1.52526269505843914812343336632313553e+00L, 1.56460575628650281139860620478932861e+00L, 1.60513905625597123057624111991440169e+00L, 1.64691268854754131266306691391994313e+00L, 1.68997931182218993728102497644674194e+00L, 1.73439429765359879279739907195277543e+00L, 1.78021588806633292063608039095887334e+00L, 1.82750536348865755482665463985323837e+00L, 1.87632722188546688075368971900486300e+00L, 1.92674936989830423931126850366320158e+00L, 1.97884332688633669446426238525349115e+00L, 2.03268444283491461260047065213162138e+00L, 2.08835213117755699197923733656794571e+00L, 2.14593011766347043193461156899167303e+00L, 2.20550670649671136552919447649838551e+00L, 2.26717506507558468055611786100163107e+00L, 2.33103352877266160486316503843066293e+00L, 2.39718592731780603672335804074417192e+00L, 2.46574193447982700411979376412836737e+00L, 2.53681744288793726408585573416385695e+00L, 2.61053496599332371109890452901649940e+00L, 2.68702406934518495604136651525501878e+00L, 2.76642183354607197859959809591833922e+00L, 2.84887335145994878054909245340497664e+00L, 2.93453226247492266642719969961850934e+00L, 3.02356132687313192268979888413460939e+00L, 3.11613304363510221142689168603250629e+00L, 3.21243031530752459841477997957148726e+00L, 3.31264716389468297553121493594219218e+00L, 3.41698950209779795665404010466511538e+00L, 3.52567596462684319748110900008331556e+00L, 3.63893880474980996700862087872826533e+00L, 3.75702486172927248744324880848351753e+00L, 3.88019660533026434144487775885161751e+00L, 4.00873326417229898631367723395410172e+00L, 4.14293204534786760904278361346846386e+00L, 4.28310945344664439881789918389859821e+00L, 4.42960271791643703960803985590050978e+00L, 4.58277133856704814714568853892203278e+00L, 4.74299875999107924880685634942448809e+00L, 4.91069418674686750664370967067014440e+00L, 5.08629455233503443708376995130700228e+00L, 5.27026665631483182008254527988202911e+00L, 5.46310948536451639599392689767712196e+00L, 5.66535673570814692696549699934052267e+00L, 5.87757955612834548026155780285696226e+00L, 6.10038953278194387910748891481975603e+00L, 6.33444193925698167042406747055218470e+00L, 6.58043927778222227422530564217212955e+00L, 6.83913514025466452585283059757581636e+00L, 7.11133842082084256614010724304296860e+00L, 7.39791791517290376256435527130893558e+00L, 7.69980734554450846886947561889535387e+00L, 8.01801085466429447369362846417322143e+00L, 8.35360901670240672837408029297072392e+00L, 8.70776541859238547329480193384508847e+00L, 9.08173387109914748403941266390886970e+00L, 9.47686631571637600605881026375055671e+00L, 9.89462150100714627457776733266750735e+00L, 1.03365745104567901877248523564151283e+01L, 1.08044272334084191011529376038077113e+01L, 1.13000198813377778114411160555843168e+01L, 1.18253436637533511507143176436936036e+01L, 1.23825547515605242739627815508172524e+01L, 1.29739896710116156250639129682527238e+01L, 1.36021822886130624460500072703793332e+01L, 1.42698825668476028925550536958145770e+01L, 1.49800772926032764371676872413981972e+01L, 1.57360130051385708102009640040308534e+01L, 1.65412213786631649993077912938609934e+01L, 1.73995473466468578424134221353716244e+01L, 1.83151802913268898058518900530921820e+01L, 1.92926886631898453200253754020840677e+01L, 2.03370584421782617230641820877704224e+01L, 2.14537359058448294184882229567324528e+01L, 2.26486752306089873609060295600452917e+01L, 2.39283915217729827153789982621787140e+01L, 2.53000199473141826806593837999123741e+01L, 2.67713817411801152928733734963681048e+01L, 2.83510579456049880498903420268116163e+01L, 3.00484718808548719519487088002485537e+01L, 3.18739814671361063943508266371074277e+01L, 3.38389826798966490384466465437407911e+01L, 3.59560255995953567185453470776520193e+01L, 3.82389447239249331007247241110692191e+01L, 4.07030054487934539563244342845687403e+01L, 4.33650688991795367943193597150736221e+01L, 4.62437776082326978417918860128324332e+01L, 4.93597649096797907147762266234322051e+01L, 5.27358913329271476516365756663547356e+01L, 5.63975117818677084656045931084727554e+01L, 6.03727778486785227486990377756623302e+01L, 6.46929802762275435095300960911126288e+01L, 6.93929373529211836464995846228029413e+01L, 7.45114359206196683576202953920800440e+01L, 8.00917327217667406576253702254103983e+01L, 8.61821250323685694884618177226323948e+01L, 9.28366009540655148012445479790749067e+01L, 1.00115581408296888990404128808417666e+02L, 1.08086767832535244787263306357432758e+02L, 1.16826111875294927859522500437909465e+02L, 1.26418926085804724017089848087642554e+02L, 1.36961157770833171464154963091055755e+02L, 1.48560851934901186551056930429681893e+02L, 1.61339833638593274264805190552029918e+02L, 1.75435645332062901686076817427004926e+02L, 1.91003780902460959044883635552383857e+02L, 2.08220265501991356519964932798160160e+02L, 2.27284638923300107785084254230641145e+02L, 2.48423410633602325676190041300652816e+02L, 2.71894066898304725754664440871201054e+02L, 2.97989725118823201634188484455430791e+02L, 3.27044548063367687799351246625873367e+02L, 3.59440051674122988480906333522906174e+02L, 3.95612465308733548542080237354845984e+02L, 4.36061333495907795272034066341690570e+02L, 4.81359584626980835451438312811051118e+02L, 5.32165335780833820345250001609436065e+02L, 5.89235755699686219555872484606593438e+02L, 6.53443371777544904545726289396026874e+02L, 7.25795284228401899442052568196334372e+02L, 8.07455844372956662653935015669559504e+02L, 8.99773467933970120032100931203892228e+02L, 1.00431239295794425220145278602443696e+03L, 1.12289036118559487702348487348886695e+03L, 1.25762340845977552983926843880669836e+03L, 1.41097920290752223402430410334039052e+03L, 1.58584068016657346033724860162595503e+03L, 1.78558210660144726153863412855453166e+03L, 2.01416017149982591387363180452914622e+03L, 2.27622328928316747879110750486628791e+03L, 2.57724301000797348481178480414602978e+03L, 2.92367232516280459791647074886201195e+03L, 3.32313675929073604672388801848045153e+03L, 3.78466551111357505023764578327774171e+03L, 4.31897162016023640570560918832525773e+03L, 4.93879227485091848874762796864624098e+03L, 5.65930305827336833061655557231992410e+03L, 6.49862329247639500380687922515090074e+03L, 7.47843387531893338609063539714339383e+03L, 8.62473434228616623771753210405507751e+03L, 9.96877263348459014531785309952890789e+03L, 1.15481895955939390229775103785535678e+04L, 1.34084311070264939001405447133999516e+04L, 1.56044945390858044276508880692505176e+04L, 1.82030939102313379306065080413190777e+04L, 2.12853506664968077681001285108385025e+04L, 2.49501459804837504640469288880047968e+04L, 2.93183077048218804714595369958899209e+04L, 3.45378531384547339729721217099269346e+04L, 4.07905708493105663079713795820150418e+04L, 4.83003052786320640972382415932704632e+04L, 5.73434124658699200382652517134835469e+04L, 6.82619915902214645340692561470062070e+04L, 8.14806752559419146429293810910586320e+04L, 9.75279950747873086720735652227979263e+04L, 1.17063646220480829492981340691767948e+05L, 1.40913379548158414250243653370073176e+05L, 1.70113785311182551164819299122255310e+05L, 2.05969942671050993972655988038600318e+05L, 2.50129853973569246335608225835338567e+05L, 3.04680843555537948624554921830727349e+05L, 3.72274788636036141079112881438654547e+05L, 4.56291316446017606669036491868612297e+05L, 5.61051155492184554128598135519314736e+05L, 6.92095956581034369089275407099645880e+05L, 8.56556497218119814922783780052161157e+05L, 1.06363880055232600043867227938165842e+06L, 1.32526810122628602501044472769613140e+06L, 1.65694484184724012086108587753064923e+06L, 2.07888647930116015575144959412983113e+06L, 2.61755592013006806905408032351706035e+06L, 3.30771485222622495472503881888885584e+06L, 4.19519229320262625923561042278599896e+06L, 5.34063130025074556576550111959530826e+06L, 6.82457849576702073415053978191461581e+06L, 8.75442405324883181776310371883173248e+06L, 1.12739015977226351727931535875936998e+07L, 1.45761434273968962478096940509724237e+07L, 1.89216932684193810033543675766077150e+07L, 2.46634598680066744212983509402346013e+07L, 3.22814282171121758797754478348568006e+07L, 4.24311457153986975423657329267444940e+07L, 5.60117371443408843149644877281459637e+07L, 7.42617250972307211179134697728146644e+07L, 9.88946135783012173106461237736151683e+07L, 1.32291587547042718239491966847893521e+08L, 1.77776624072745598074170059515038266e+08L, 2.40011058338983426258122648845724399e+08L, 3.25562103364198274177076500687162156e+08L, 4.43725882059376140276746390832793801e+08L, 6.07724621850487716521348005200021505e+08L, 8.36456587985737541719041767923031690e+08L, 1.15706659432645616854021468641216152e+09L, 1.60874082649874296139935339596050162e+09L, 2.24833765794868826938828602052210087e+09L, 3.15878597885133622780330724633488102e+09L, 4.46167708136391137964792211498946984e+09L, 6.33624483104820926953501466923377042e+09L, 9.04813015958867755955007060963155039e+09L, 1.29932136230997226464299124717687605e+10L, 1.87647826121294792855983490567276630e+10L, 2.72570397671288897105662591436709544e+10L, 3.98255345906428893971269386370983030e+10L, 5.85372779401741541532402802418687327e+10L, 8.65629908955310338465751817097315538e+10L, 1.28795973304189874698643530406628864e+11L, 1.92834506543009988305207298557577307e+11L, 2.90551046754580604436065170645660613e+11L, 4.40614548809848580878194871514169088e+11L, 6.72570891877849315226112306772636026e+11L, 1.03348693821219692992886708382137863e+12L, 1.59884055708669585428974649723976740e+12L, 2.49049013421827282502410713540807461e+12L, 3.90652846672458392086943060796482254e+12L, 6.17122514796135424360349149730712054e+12L, 9.81916373648510913725273324679675423e+12L, 1.57380010699156447495769482655375521e+13L, 2.54124546153003122065528612181733881e+13L, 4.13443762840798177552480089332110759e+13L, 6.77814197348597152801493367496981491e+13L, 1.11990628659588449226309821338662554e+14L, 1.86501680604176896658450602560601490e+14L, 3.13089094872498973827438463058389098e+14L, 5.29897884766906828009755247847186245e+14L, 9.04297389980418175348985287558326633e+14L, 1.55625903681899143890977078931637702e+15L, 2.70123006636820081209540843148166787e+15L, 4.72943010505471127882390119991674115e+15L, 8.35377903309658653016536824399814765e+15L, 1.48882760629319165095592517030838223e+16L, 2.67765346603161495578266855417246317e+16L, 4.86043448136949927032370428281054854e+16L, 8.90573551930099331171397006211491165e+16L, 1.64741372830687155232163226493215628e+17L, 3.07708132567301637697547718557883369e+17L, 5.80423410132909767997152626617023549e+17L, 1.10582857062809961361827765317796937e+18L, 2.12831535880807402614537212551250197e+18L, 4.13865153208523558147805437822414497e+18L, 8.13255421212392003487525754214292826e+18L, 1.61514650331257085505245767762340125e+19L, 3.24254846726071819306305572744455009e+19L, 6.58149458108070132105640205170170346e+19L, 1.35083136618309000260400853464983546e+20L, 2.80409383252093739584477712160125327e+20L, 5.88811368346756383731750279395970839e+20L, 1.25092343531246827629449550883330451e+21L, 2.68928027909821563456325160060548474e+21L, 5.85158282566447970019894650702188721e+21L, 1.28891723178894465997393609758461271e+22L, 2.87458276376899763123926200401593262e+22L, 6.49243733510921786856841605747277893e+22L, 1.48528660586708217722481671351080137e+23L, 3.44246915911330706635229848078895385e+23L, 8.08493019686043820711319325430367342e+23L, 1.92450677804809487818429003209217169e+24L, 4.64399266249147072865108838294493471e+24L, 1.13628145208359133428909996372167656e+25L, 2.81966489106069457125481864485455314e+25L, 7.09778155999185636739332722019170506e+25L, 1.81283885012768848640687277115301054e+26L, 4.69901285134453912350857508188703800e+26L, 1.23641970716283295078972799846710910e+27L, 3.30323626121041128601791088120844416e+27L, 8.96255809763889121781104645394017356e+27L, 2.47029485298622611738479511793982193e+28L, 6.91827096055594288255981089299725583e+28L, 1.96918944795841151009270119290336857e+29L, 5.69809260945398128927937198565189507e+29L, 1.67662615639692208356086898776485724e+30L, 5.01790152017155697028174057139776321e+30L, 1.52792989227983448898308499437330165e+31L, 4.73476231836671194909529913837515959e+31L, 1.49357254644677704024642645900767165e+32L, 4.79744116468190818427448048047019508e+32L, 1.56953829640099873205260260372105814e+33L, 5.23165115691024245360777615947271007e+33L, 1.77720651152529094086938101558873583e+34L, 6.15458729957691613373022022121395673e+34L, 2.17346978135660487165909974321640569e+35L, 7.82952989652658161590959525826590591e+35L, 2.87793555407307691688503613867678361e+36L, 1.07976132092345859199417272983750960e+37L, 4.13633773095120704247204289059445522e+37L, 1.61840848971118584374440265082561208e+38L, 6.46977064044782477057521822447781556e+38L, 2.64341365485931635830069155722471865e+39L, 1.10424672830852570286491286394819018e+40L, 4.71784264188126066477442678013103229e+40L, 2.06229646238932771079246843113076062e+41L, 9.22668000516125721911884540275100330e+41L, 4.22654407163273196344404760642122190e+42L, 1.98304372970706651824186968975247346e+43L, 9.53344869097015503904308238124562564e+43L, 4.69791457874020860581396665191487360e+44L, 2.37392310198043657407434802189623818e+45L, 1.23057021186853175270406146048991232e+46L, 6.54634433841169514665337805691594822e+46L, 3.57537181933580491356588477879121785e+47L, 2.00564245353833550563491221890112961e+48L, 1.15605526802890307768061561905701576e+49L, 6.84986780787031295787489135284280640e+49L, 4.17400481521895112076613271616259486e+50L, 2.61687203405285747164128861362318936e+51L, 1.68875034683729772513757434403804400e+52L, 1.12227566600968410062529607944214843e+53L, 7.68396874024867707105114297890426357e+53L, 5.42284961265427858271262866960101842e+54L, 3.94668670179953341522351651523862327e+55L, 2.96354358728813288396379337565903477e+56L, 2.29708639579893951580254665307105346e+57L, 1.83885641420855576075627699143076709e+58L, 1.52104947571124399594694864621286492e+59L, 1.30073229117507111236343155772481130e+60L, 1.15055959114171674001974091149754682e+61L, 1.05326599737372546052564481925643420e+62L, 9.98411420987902083614726789220470599e+62L, 9.80532561593869471877040903652671478e+63L, 9.98246356419911599549241472274732206e+64L, 1.05410221145791141007800297806625299e+66L, 1.15517268478078246328479789979967959e+67L, 1.31457130233411666326872185958326427e+68L, 1.55436240768545731029836466857749970e+69L, 1.91079120600264507732475085854133289e+70L, 2.44361640389071120608105036496582382e+71L, 3.25298382231882323170055543487798304e+72L, 4.51060014002013973693091388809534590e+73L, 6.51882183100190244682597556816883900e+74L, 9.82583446077426763261011103909194169e+75L, 1.54569206362272285597219332482212685e+77L, 2.53934608840816325270469005344260713e+78L, 4.35976399381183611739718946785420143e+79L, 7.82794362746440474440241447663834683e+80L, 1.47089687767430118295343594318257369e+82L, 2.89452707142067428998158759253431372e+83L, 5.96966254160791549191064067088778403e+84L, 1.29127761398105735746114390466172354e+86L, 2.93165653562687792342264563025180130e+87L, 6.99135354753146313546505095265922672e+88L, 1.75267119452597285220967300845626556e+90L, 4.62245013705602071519123099756702996e+91L, 1.28358193316956622609422743295635868e+93L, 3.75583900113839078839602923077406673e+94L, 1.15899172984597870198690174300625365e+96L, 3.77491631543886267838503954431054828e+97L, 1.29884489446238167309781708169537790e+99L, 4.72503894994338488909389270574194659e+100L, 1.81900003120328673954815570724729852e+102L, 7.41696633087690618810014849262359799e+103L, 3.20611699691059820440544154944066069e+105L, 1.47058877007197519318900335321912402e+107L, 7.16419823823864105738627712719272912e+108L, 3.71039762456707726983380527316097819e+110L, 2.04488245427970937306347337109290828e+112L, 1.20042877865473022461473385597117568e+114L, 7.51374437003017211432960701498996352e+115L, 5.01957574634341063561427626174780847e+117L, 3.58272692766569831842277681502801710e+119L, 2.73494777587724855953563379276564479e+121L, 2.23528376407894424768162839028330791e+123L, 1.95808475111824332331314972422066776e+125L, 1.84043191310930565706137359879906765e+127L, 1.85814326069283110784535066904520512e+129L, 2.01743294965577713629069559518257063e+131L, 2.35817761588810149418319514273035811e+133L, 2.97109297417860360975602176456436124e+135L, 4.03953232143581630156016504419988399e+137L, 5.93392306966113219484352196331202218e+139L, 9.42926369344495323976110371737768721e+141L, 1.62284145693287387206611282820134815e+144L, 3.02888447606769418009867639216690630e+146L, 6.13835617501533947725917198648160556e+148L, 1.35253155719194264809220346207577825e+151L, 3.24444736229558294520810049145898860e+153L, 8.48424354492815185029440589500302573e+155L, 2.42189217690801196639615731788461939e+158L, 7.55727585868832926111996462541955391e+160L, 2.58138920742415528768470662656564452e+163L, 9.66580408821980500452620634685578942e+165L, 3.97326060268422220330874023543806264e+168L, 1.79563826725695454978311213353995983e+171L, 8.93514523408268859940137248520982995e+173L, 4.90290834459626229428863642680474223e+176L, 2.97128375542216561281658377940574510e+179L, 1.99182881480698947977101116086872463e+182L, 1.47933813166325570382207702423402678e+185L, 1.21924602572867713843112063103440147e+188L, 1.11695489454371994985095225835122915e+191L, 1.13926159735841086544690160419235263e+194L, 1.29595329494635946555823051599904183e+197L, 1.64694619802426865078234124605721432e+200L, 2.34234840634634342775071057533872554e+203L, 3.73486904651415569743903039850576755e+206L, 6.68856535510325485878978796153529680e+209L, 1.34777842855531871957592541417095863e+213L, 3.06153116112389690978003658017819254e+216L, 7.85439891718825136093879357578783886e+219L, 2.28020371103825909996341632353690860e+223L, 7.50526802410090668256555773098038714e+226L, 2.80639879206390242816779047164860586e+230L, 1.19452560453314111686916354242681346e+234L, 5.79949872394246778903337432628166035e+237L, 3.21835787345388969294352208047085465e+241L, 2.04569666433064103875712173825120783e+245L, 1.49258715453013675730747996991557044e+249L, 1.25277443244629163588528004740184593e+253L, 1.21226842377681326200203984685187270e+257L, 1.35547194242695069046025865235623225e+261L, 1.75524005232377336464776480479935346e+265L, 2.63840064228932918271533450220126376e+269L, 4.61448246937529975889164745570586249e+273L, 9.41280682985947960778964419634581143e+277L, 2.24481910655275049981565977905948653e+282L, 6.27448882996682532882323387040658757e+286L, 2.06060958394918535923518047482752655e+291L, 7.97142764215603564227622164969231434e+295L, 3.64182905892925111147897309560503282e+300L, 1.97007938638916489488880184999451702e+305L, 1.26527287963256941162906241681573766e+310L, 9.67374762635351109418734649102546799e+314L, 8.82892141913231571338896445110187498e+319L, 9.64570405228039780469604907885256630e+324L, 1.26503839487205882730553259131731653e+330L, 1.99740647993660386944495280559643123e+335L, 3.80795083906732148311558637535145760e+340L, 8.79159120777085501704319293452205335e+345L, 2.46549631780369377584312978131661447e+351L, 8.42426490586997547506062762517991909e+356L, 3.51804562259170040261749407236406336e+362L, 1.80129565203500398450083781286924107e+368L, 1.13442688952887433720702641069844446e+374L, 8.81641141946113920681847478154293508e+379L, 8.48338453086470297056624825970987040e+385L, 1.01407299264221993702531525534230006e+392L, 1.51103955764611037180263766796269076e+398L, 2.81641187251957701963969414170240418e+404L, 6.58963120298401361748098859356824253e+410L, 1.94234184512060662929742463444500478e+417L, 7.23884585856411287896767410403126131e+423L, 3.42370598009480301692521696476539260e+430L, 2.06270296737946127496845017607144670e+437L, 1.58907837423540569213464552634511445e+444L, 1.57146131021351822368954401625918115e+451L, 2.00271733703560402612457677241115831e+458L, 3.30238681816736073809946856032462582e+465L, 7.07441603885154545912376402781538965e+472L, 1.97695789038711346120868489115303627e+480L, 7.23713029747673018134344413894888363e+487L, 3.48533178833568221019229567888827162e+495L, 2.21771798011905249239941207476859498e+503L, 1.87265680045956064211817379705948563e+511L, 2.10782709864946331624669282953979957e+519L, 3.17689162904658562291907841456392867e+527L, 6.44105645558316603786838285606330189e+535L, 1.76492886625329297926588753856751673e+544L, 6.56708664348495439553998825816543384e+552L, 3.33415826521812264992257180271069504e+561L, 2.32109565019822213867641474306217000e+570L, 2.22665090852540791532492989207079877e+579L, 2.95839667933009412312396349376762019e+588L, 5.47183877884770709370953901555429409e+597L, 1.41626756773793934414234479620392920e+607L, 5.15692247865370682523431517094128585e+616L, 2.65584978465684945355727442801669402e+626L, 1.94515906011252752522390088574648572e+636L, 2.03729480055734573550624444975610288e+646L, 3.06864139959250122576234946830893261e+656L, 6.68523683038794846390318553081110530e+666L, 2.11879952715090010307995150421897875e+677L, 9.82718465915609660920397095265955939e+687L, 6.71024976037303477285708646634894987e+698L, 6.78677922161865926117102990656018413e+709L, 1.02303626651674990928162545434962304e+721L, 2.31286202012488077377232576408525763e+732L, 7.89245107528823830762373616398932534e+743L, 4.09160120200842896534230185492282146e+755L, 3.24379955366775267129216830328274275e+767L, 3.95912453354472811300573118431549283e+779L, 7.48996232152866120855530906466249236e+791L, 2.21152965349315333956435853596087911e+804L, 1.02632075670404876010930426472294612e+817L, 7.53951068632005171876747821502928323e+829L, 8.83108581906785992138514068848879898e+842L, 1.66144742506056069516088714981068146e+856L, 5.05826477150550571129779691932628665e+869L, 2.51102428144577988853257771418346819e+883L, 2.04822869357369644800523164159313000e+897L, 2.76681803049890115118755008828029448e+911L, 6.23888945414058934548223953019542236e+925L, 2.36735167714072318956060511661796446e+940L, 1.52407555570930344049434626852406921e+955L, 1.67862596848152559342541655995681177e+970L, 3.18990333799710745664618509349355327e+985L, 1.05489081758823555970428507172122908e+1001L, 6.12396788613568122227472934597131896e+1016L, 6.29654583950170379780496166626637403e+1032L, 1.15697821762367329197002183707451842e+1049L, 3.83417721859040383986075244204614475e+1065L, 2.31300589079836393970996707559294268e+1082L, 2.56410460141809897241834340099170971e+1099L, 5.27364125127925215166604640933456487e+1116L, 2.03202107773477151599346823269715856e+1134L, 1.48143334195874803524122054239589157e+1152L, 2.06411274147574456351269054783640404e+1170L, 5.55279829459270893053136130201212587e+1188L, 2.91418497041682586483964699073577480e+1207L, 3.01522322419410790036838054063732694e+1226L, 6.21672053535323172221442203567173233e+1245L, 2.58201182234158741299570291718541207e+1265L, 2.18423750518116545391544630374143187e+1285L, 3.80584781426053416091532316078175593e+1305L, 1.38151208502663182821551093570287278e+1326L, 1.05688876376696945875455031156325640e+1347L, 1.72414525934903045436623350959611871e+1368L, 6.06970176363513871871663291361433633e+1389L, 4.66734911165218107635353767855185961e+1411L, 7.93644483902981870648608149469983212e+1433L, 3.02177407323915414129348065742188333e+1456L, 2.60910294567790325670373269654248928e+1479L, 5.17503694719938298503446121278113303e+1502L, 2.38900287619137048290055040441414741e+1526L, 2.60122790255932170291515511953064757e+1550L, 6.77122378037074355003811222286996596e+1574L, 4.27212445104598645308010594377100889e+1599L, 6.62465696881760614600007097777440709e+1624L, 2.56080093301387999855187759148833996e+1650L, 2.50338804461975863168260136920269977e+1676L, 6.28008959392222170902165204120090502e+1702L, 4.10330805623617785960247879181409818e+1729L, 7.08891597895639626581466081525369401e+1756L, 3.28815937986385053022460003637061243e+1784L, 4.15918117856089374793600707142802802e+1812L, 1.45749058887095094990047184214707565e+1841L, 1.43785687357830444275837543949503093e+1870L, 4.05897446691318032347020269164975282e+1899L, 3.33348114079172166390364845912603682e+1929L, 8.09961164105229487950427444532606992e+1959L, 5.92288638308847934616085992236628536e+1990L, 1.32629748644648493533560071181408206e+2022L, 9.25637244456745511366766862807596139e+2053L, 2.04978139964660371723728495327865680e+2086L, 1.46668915962420498068615471735159780e+2119L, 3.45424976463618489443831684054473314e+2152L, 2.72836294216453749285575709798797945e+2186L, 7.36646679330208627221413509790840381e+2220L, 6.93156469113828331566714060809446921e+2255L, 2.31823213431754954747032929849642953e+2291L, 2.81131341663812436900512315439163404e+2327L, 1.26153121461887745230804891576437417e+2364L, 2.13831434840067269117435765818454673e+2401L, 1.39803888650069112961026818896691495e+2439L, }, + }; + m_weights = { + { 5.90801545776726515999184015930013435e-2494L, 5.43034121836882538817369981204760444e-916L, 9.13645323997978810837635266947225189e-336L, 1.38026921250443161275979571515063966e-122L, 1.95473329586235063070470724741264116e-44L, 5.89765053810344838395474502424100508e-16L, 9.65083022671853583721482039321815318e-06L, 3.18674406396319375693901804428127016e-02L, 4.49940993129051317388425885244478941e-01L, 1.85250678576020588686470383628874232e+00L, 2.14751816323261845650556006802974073e+01L, 3.65018587462837432006103692095515092e+03L, 6.47212478751933019554592655468556643e+08L, 1.92641646488982742563851849719109881e+22L, 1.38994758402678387868517621844463411e+58L, 7.26879966558078977021348471744247141e+154L, 1.04765280279857897745141662958802655e+417L, 7.83837589244484743057347089777048838e+1128L, }, + { 1.10316126712058491420201654940763610e-1511L, 9.01600613495532057799091391040663772e-555L, 5.11904332497495239643103179971390500e-203L, 6.89671333890943322248923557636362424e-74L, 1.17634110503454704251022002576839267e-26L, 1.50757351778282569234155861289206864e-09L, 1.64896113239222241299157252910603817e-03L, 1.70348472687044679146785418051347199e-01L, 8.92604116485216943737039962090086924e-01L, 5.08107015469559685466563888116585167e+00L, 1.70322410074360164066883311173278799e+02L, 3.99580125020294769314748785515084392e+05L, 8.97859410735688933722745437703783632e+13L, 7.52866673518542859464441779223888455e+35L, 5.14816023241024489763203760058639816e+94L, 7.76882384415261869036597544471920535e+253L, 6.83649581024319385239349778375109740e+685L, 1.71685218299087881635674367971803808e+1859L, }, + { 9.87925015299918398144785423598176370e-1942L, 8.71533681693018261767494097538810486e-1177L, 6.57384046217461429576867660255037671e-713L, 1.22572352048272001483240603010122094e-431L, 4.00210488905354704066065300402901994e-261L, 8.68831861142192461329723188826285819e-158L, 3.39344901437582485256542967096807177e-95L, 2.56737317400303409399563341354938201e-57L, 1.99325419812798016097936249998766075e-34L, 1.25616316381741439662336351160566326e-20L, 2.43090464171805920109733890177176767e-12L, 2.14048123340650521217897512392567060e-07L, 1.78351176282128440930436365965135303e-04L, 8.91532759780500845110690795259481658e-03L, 8.30018538939149499579790988285111688e-02L, 2.93820046590635175209882488313404811e-01L, 6.42167019459198241099164736507367056e-01L, 1.25676009815264777866804196778444950e+00L, 2.93241842564261090318837326991751597e+00L, 9.80176974669959846616864231368773370e+00L, 5.49217006325024175243162209529224299e+01L, 6.74415210957129787494085872629636299e+02L, 2.95093734929150449033134748913572566e+04L, 1.05011160163132749880805450719595372e+07L, 1.19276753677448525725842377258604019e+11L, 4.11976276783133288599595346140932524e+17L, 1.77581149088770071821845041850345600e+28L, 4.35594809668394640823177135833505819e+45L, 1.46965529638197726713059781629071505e+74L, 1.14872217888121999297587395528584026e+121L, 1.70677996026663975507589457654701634e+198L, 2.11819696469088836247505505584030188e+325L, 5.33443484802698043954530255107399872e+534L, 6.76327254647744376095801434158695958e+879L, 4.65552684789936854337398747780741866e+1448L, 2.41016379900581970812596189341460931e+2386L, }, + { 1.32133547680717018679108130408012819e-2200L, 2.77712159414975738481258376000179218e-1713L, 8.84696668578869367896605187021695554e-1334L, 3.02118052104884375490712624043751719e-1038L, 4.14765218378536031502305059306013033e-808L, 6.68597993758855914851785488336018106e-629L, 2.33347816130102648013054297856813910e-489L, 1.04733564854277330060008344877597147e-380L, 4.11557211597596026781639255888321135e-296L, 2.96892493585484037081544967750602740e-230L, 5.48318261457236849627593775240447695e-179L, 4.37952763140247483545256113532792419e-139L, 4.93764851567154537678682785150822008e-108L, 7.12882559733493186476365592485215882e-84L, 4.41155760043873077928273281441139888e-65L, 1.80163734340122138141929999274331671e-50L, 4.08343162992111053691005442960554881e-39L, 2.69713878716183124254075973537323621e-30L, 1.88906085681027307067677306620940234e-23L, 3.83661096593349300206254286709601564e-18L, 4.94655966889556498072463502849060578e-14L, 7.45399353944412484667368844933083088e-11L, 2.11213594306352633431635806968088815e-08L, 1.63019937992045999824523554635197574e-06L, 4.57540432069617055539176306478504351e-05L, 5.85085995568316321646161156635372880e-04L, 4.06605991446724517473851752061784970e-03L, 1.76336759267286733236155605055701792e-02L, 5.32246038588641268382381208383524691e-02L, 1.21978563400315778588175663550724559e-01L, 2.27813822026525499121180105863893077e-01L, 3.67880940693987971581072989565083693e-01L, 5.40739096387634225611080390746760034e-01L, 7.57649154875166910544734982341932295e-01L, 1.05508672843049871100505526038205526e+00L, 1.51442893723856346518379289394390563e+00L, 2.30704471829033068051765367243404246e+00L, 3.81265333029628098807578829102732392e+00L, 6.95531454976623073962406546394064472e+00L, 1.42580921706810654107345317832413199e+01L, 3.36149768965581810654207836598212633e+01L, 9.41442967189932119013509095554254321e+01L, 3.27468727748159184559404098660493044e+02L, 1.50134197286985544688570624625182907e+03L, 9.80710571996542847233767661790386013e+03L, 1.00962016775294251580231030319396563e+05L, 1.86536785996695038528848904417900709e+06L, 7.30953564053636331147337800282574617e+07L, 7.52773592822324283583724791889200862e+09L, 2.68310388335555167663870380176682102e+12L, 4.71267149903232936486329698993101877e+15L, 6.42020070484263570170339986066376457e+19L, 1.21445858766272510022421711137530603e+25L, 6.73690008798356003301023318149224184e+31L, 2.86191858315711641955678894569568040e+40L, 3.19319569382394077525802448772198805e+51L, 4.55425948316978466116193749735949380e+65L, 6.33381334198036002776230152386194807e+83L, 1.16685549796591838612114357506921339e+107L, 8.11568192390745193863805331868574764e+136L, 1.57270137093366013936347867540038862e+175L, 2.12621037868720966375758237292361135e+224L, 2.41043281776111273672384537919910315e+287L, 2.06426392024598778796244702435819107e+368L, 1.59767188945824373238194899871319514e+472L, 3.70147206080013271017541277477470426e+605L, 6.04524081068361649977908949693985827e+776L, 3.91244551907499740549590413818514135e+996L, 6.37601410091330839292544093678958764e+1278L, 1.38423256121282951104859278958281990e+1641L, 2.29003319158044389177689218691755697e+2106L, }, + { 1.06947516637266850888077780365944975e-2342L, 4.00222795925000100954191256688394740e-2067L, 6.14269929806784835508930822317395965e-1824L, 2.47129563578700314331274388349812780e-1609L, 5.94856549925636496124140508697277691e-1420L, 7.88155582901689454838569820447222612e-1253L, 2.37169815411747688234160253328737061e-1105L, 3.29576869517934854144272957025066495e-975L, 2.30295331039392476672974731888405196e-860L, 5.07778539549297920546786995561355024e-759L, 1.36309792114536681315299788580123700e-669L, 1.11902249499811588919802641601624761e-590L, 4.83171643219834730998170916090452646e-521L, 1.35092956692688343220060283908963635e-459L, 2.24199581450623280210827812157346751e-405L, 1.56044428013608715771945922727966521e-357L, 2.55762668699602425668170610426828633e-315L, 4.52598451420085229059456309653543845e-278L, 3.31498525601312348031091223503291312e-245L, 3.28982733272263633196035888826313749e-216L, 1.25979671796942324763554469354410763e-190L, 4.68781195667796137227478889031902638e-168L, 3.82963817403632291960149514795452273e-148L, 1.41008655666469634743601323447962987e-130L, 4.41480300426527477757453266178330825e-115L, 2.05796976085320113157119878898298467e-101L, 2.34167766563934625382241547560196138e-89L, 1.00611330011990340950410787621048434e-78L, 2.39886979987338732623660845760149501e-69L, 4.45828722999844038302160563656015401e-61L, 8.71674689717785941226626165471518297e-54L, 2.33608458451638324303027615256535578e-47L, 1.08390303338972947113853753614820116e-41L, 1.06995151808257796332112367831607337e-36L, 2.69524358925375181073032551986305924e-32L, 2.03423384800497240894806821496090050e-28L, 5.30019940271628291011490416486872002e-25L, 5.40212919469588209381281396175343198e-22L, 2.40511019215192441365347431063245533e-19L, 5.15573611643522185168933155470786681e-17L, 5.79902272788904112815174301897601165e-15L, 3.69205735629667547626167545850806392e-13L, 1.42267754195891351150562998109337966e-11L, 3.51991945554992222676432065045765653e-10L, 5.89117093052592385410771587163177426e-09L, 6.98414016831114732860587596174055273e-08L, 6.10836626587512983932161479872803914e-07L, 4.08537274605429873510095058624689151e-06L, 2.15678250632197565791431535444473324e-05L, 9.24312223411418671168580362381399190e-05L, 3.29629252828970123413244980995397823e-04L, 9.99865029818046920794114062146177746e-04L, 2.63018698849220190957883149658594289e-03L, 6.10412221855424181881652487802655548e-03L, 1.26903202004975552477255319538074005e-02L, 2.39564299641088688046037610330961560e-02L, 4.15643030399701933649627965940349917e-02L, 6.69982939046328122378009075425825174e-02L, 1.01314761859197945164098555651429523e-01L, 1.44998628043994675224702383164439509e-01L, 1.97976367297349804840344474368395293e-01L, 2.59785494162963270697436696871054011e-01L, 3.29861530130123082323166204892104315e-01L, 4.07887707779851847083967462215852975e-01L, 4.94160808801609892592520472039421040e-01L, 5.89951040448037491768065148251882226e-01L, 6.97865729437412689560491745121349024e-01L, 8.22260217393657822959055682985146030e-01L, 9.69774604378855851935565350832453271e-01L, 1.15011795553624730201138456447827419e+00L, 1.37728513637309570900453193107529701e+00L, 1.67149809630206531099733950813918712e+00L, 2.06235275406513270776777022052056344e+00L, 2.59399765677200896819549138553557629e+00L, 3.33381238373592320485907218391630985e+00L, 4.38727553184963415451944389447389070e+00L, 5.92410234721624433989387409845478071e+00L, 8.22555400895276009470529071921123608e+00L, 1.17728847794365554942833299884164414e+01L, 1.74186946732944479219083797984245546e+01L, 2.67321347727075416316453470949013980e+01L, 4.27248599090065202592682231550667436e+01L, 7.14514957498311763066605425195361350e+01L, 1.25726649744291050649669245834238885e+02L, 2.34268740301195719755233273502547873e+02L, 4.65674501968291917847819643280019736e+02L, 9.95892168086429019721630255623709337e+02L, 2.31370536252976840857940169336286210e+03L, 5.90416785827987120394897587933071506e+03L, 1.67574959687797819327588127121232764e+04L, 5.36589048987894263464971617898730248e+04L, 1.97001995592318850388501435517959975e+05L, 8.44594440147401724253246450884183480e+05L, 4.31706343383048349864263584742746589e+06L, 2.69343047021169619975848244859698568e+07L, 2.10656056871936774519731164741615606e+08L, 2.12865839525415045164207708849921266e+09L, 2.87579863694102104115679841861873156e+10L, 5.39962441480030320721171298079837788e+11L, 1.47228407211216271679535227733468003e+13L, 6.12702071280434890818621133461421119e+14L, 4.11734705402761288562221821245591184e+16L, 4.76248383365979073253985584808588348e+18L, 1.01935525113816768714253607040570786e+21L, 4.38231774892874881629281035002570378e+23L, 4.15257812330163302032181919338837514e+26L, 9.63578634121366174238646117049249945e+29L, 6.16903528716345189143890155825118447e+33L, 1.24741073700366469803472774007991980e+38L, 9.28495127856215607061013544719468024e+42L, 3.02620640278402325128627613072607942e+48L, 5.25740318414851642612290423653366751e+54L, 6.08377705676929998408087326671143748e+61L, 6.03621188684706784050917948535663342e+69L, 6.83604430657324601596912909835543184e+78L, 1.22207736059289881632444543839493409e+89L, 4.97963284347586492335598341460012283e+100L, 7.01286464121514720750130754209620950e+113L, 5.47091248474436718447273702781160082e+128L, 4.03491215911361460129480089373280294e+145L, 5.15550681905479930138211789209766809e+164L, 2.26698817812971993667638253759384337e+186L, 7.46678442214100282100191345089453705e+210L, 4.44695748246229233245164503407419774e+238L, 1.29997993210113625215904908209705899e+270L, 5.78362417210637255304620183172670719e+305L, 1.41167148054040165920786770540444441e+346L, 8.08286570061195033556699134866983755e+391L, 5.63304784971987527997364020512160855e+443L, 3.08690662195072763023845781932813249e+502L, 1.10165417416868743288711300669064477e+569L, 2.80994196635775688984524212097397961e+644L, 7.73382325928152223721046490397169922e+729L, 4.97761231747547736253787393388911251e+826L, 2.44530978920516083381477794744261645e+936L, 4.76039467365174741738996705683688855e+1060L, 3.22588883912409917905940907837482370e+1201L, 1.21298392121243707893541014829026239e+1361L, 7.92540396126882607375372502759559361e+1541L, 6.05643048475311304903673843949239315e+1746L, 8.67085957383156175019676264069447501e+1978L, 9.95105409544177778456070528537389733e+2241L, }, + { 3.82052466785182332086738926018596976e-2417L, 1.53216690964008904863800245911834695e-2270L, 8.02799618255145245433991916259679940e-2133L, 1.89790062782857972828467648673787073e-2003L, 6.48547054333991583933133337347105329e-1882L, 9.56340910858469468709935501045338939e-1768L, 1.70023842699605420504066989530814298e-1660L, 9.56797730413407205631782708332785103e-1560L, 4.22020698781412857368210883093245672e-1465L, 3.41965451589094380116779072034053750e-1376L, 1.13314142099471085666864638284317139e-1292L, 3.25613842818879565325184054056113549e-1214L, 1.64407833236659941146136019432680305e-1140L, 2.83169222847758408789499219075138705e-1071L, 3.10256729477751738834780026930224437e-1006L, 3.88327366035249790364432313659702349e-945L, 9.62325937366412073215674752789621450e-888L, 7.91532304589191166500084311712723764e-834L, 3.51089649105332123383908279313304145e-783L, 1.32489192907121558509586493733802170e-735L, 6.52783588426344440105254553576625446e-691L, 6.27953766456679638940801082204333268e-649L, 1.72112316179301192237697323835800001e-609L, 1.91704593421434794371085034440245942e-572L, 1.21131389706331685590249812201530647e-537L, 5.93984004695174374389288417212720344e-505L, 3.03411224655952005849867823710301306e-474L, 2.12875962525689396085894169728448953e-445L, 2.66000529174336615171418420545198600e-418L, 7.55590515004675433995195831838744150e-393L, 6.13626926542527991664012204881781789e-369L, 1.76713467741974813886350949888126351e-346L, 2.20926972666826146585381131914638666e-325L, 1.45005559535857920730397373363607727e-305L, 5.97336892939272666152938174641382891e-287L, 1.82640350668529645297131829899777179e-269L, 4.85229717585781075750778298691866187e-253L, 1.29884069259764069953465811099712413e-237L, 4.02542740473423831131996110176920188e-223L, 1.64606390223494048083381164318527223e-209L, 1.00404640707773475495017963404550319e-196L, 1.02517549226209525963922466256750740e-184L, 1.95259262992798399878532201786889482e-173L, 7.68026595299128847616027073204274409e-163L, 6.86431799704342420135947045710241387e-153L, 1.52498555897006686273111644122247925e-143L, 9.16240838899174700108797638312124662e-135L, 1.61152978600632900525315532785259119e-126L, 8.93873956545614240431663830324423008e-119L, 1.67683199253457467411487735035598912e-111L, 1.13606831265305889540738444180574550e-104L, 2.95677983624992268135074874283992128e-98L, 3.13261928574067484199912376683710488e-92L, 1.42665699792617318967988994714464344e-86L, 2.93948527551792820481373266955543872e-81L, 2.87496940202324055984269030763057181e-76L, 1.39640503864001278539518135367012235e-71L, 3.51418022897052500616248358954553443e-67L, 4.76840843576304417158706032926840904e-63L, 3.62171076308676895946675701059866747e-59L, 1.59482985688579594373676029076259231e-55L, 4.20842453488002122572360942178919587e-52L, 6.86443229233076886165541867675398494e-49L, 7.12571665807519317291983672203309613e-46L, 4.83819502081497047116760866720006226e-43L, 2.20465542430951342610708115485440884e-40L, 6.90709560806486502312714752170868272e-38L, 1.52197218506174728353062647705743598e-35L, 2.40955219490267088425869662208370235e-33L, 2.79630904534258562440727543829590381e-31L, 2.42396861904265607424793591553560695e-29L, 1.59749866280800688175296781099864391e-27L, 8.13840485655638493122774039812902482e-26L, 3.25536762868063353648331484818545825e-24L, 1.03750216774182187079375467840556085e-22L, 2.67108014795025059201469276708831348e-21L, 5.62745845137509901846677188959226735e-20L, 9.82072302589238577426509279192638536e-19L, 1.43594941796544038692542800708134381e-17L, 1.77810682024353573557752337941414159e-16L, 1.88354537738694939365287613122504842e-15L, 1.72308010102740811988992770129939744e-14L, 1.37343705888395103661321882765344100e-13L, 9.61866975437486408023966746429500914e-13L, 5.96531965279554928068743818930854269e-12L, 3.30041201040702869600996143071210790e-11L, 1.64031748053937249488182380342568737e-10L, 7.37124149693192472685858181626175497e-10L, 3.01344400817654411848957462000254023e-09L, 1.12717586759651920251576226824261590e-08L, 3.87857240586881913126338809706852880e-08L, 1.23397923410236586482402725064781148e-07L, 3.64729321175679321144258676923993113e-07L, 1.00602028308961790056200899477538690e-06L, 2.60043020837597212496425152713721292e-06L, 6.32419483196640694034831908133223537e-06L, 1.45245521130769448827445571183003177e-05L, 3.16123436155465446648693209598810124e-05L, 6.54176706996526406822348966226430775e-05L, 1.29110196844657112529538619169285993e-04L, 2.43733749771260888436783011892865212e-04L, 4.41314232710451843972392755372463603e-04L, 7.68377076370070526296257588743541811e-04L, 1.28957360159046548970572233319638690e-03L, 2.09099199558542466132447951593809118e-03L, 3.28264889533211879885382599961585359e-03L, 4.99964828308048181967481389975237633e-03L, 7.40157019965966236427260197490815304e-03L, 1.06698107000950941317328124490909795e-02L, 1.50028172314973599445873815719412949e-02L, 2.06094173096225141746698709598883056e-02L, 2.77006834377238972506888931261097291e-02L, 3.64809756186562309685025492261970114e-02L, 4.71389254316798953989957737554750583e-02L, 5.98391571230828379216832783213494747e-02L, 7.47154814906505012222514984217472816e-02L, 9.18661612946071289937159187843364627e-02L, 1.11351656134035569001793372114249223e-01L, 1.33195038632804266520840073116724199e-01L, 1.57385060631367271607409153973946866e-01L, 1.83881661881487488373471043449811640e-01L, 2.12623571664368840241407884037664753e-01L, 2.43537565151706738569000265542366947e-01L, 2.76548903119165441078310983457425711e-01L, 3.11592501651099485071285279910294521e-01L, 3.48624439429573943493094167043683901e-01L, 3.87633503629295959856799538075546008e-01L, 4.28652590594010568395685064250714546e-01L, 4.71769904763931628640496795425394984e-01L, 5.17140031351419396580841715288928105e-01L, 5.64995090385812394527782017926592446e-01L, 6.15656310347513453519162300561374394e-01L, 6.69546490104796171397630195486014552e-01L, 7.27203952634969644713241799501762825e-01L, 7.89298740343220248874987146571520149e-01L, 8.56651969968232039115451358927023892e-01L, 9.30259468685761614462731685806948992e-01L, 1.01132106970032064396659635282297935e+00L, 1.10127727814330022383089577768540741e+00L, 1.20185545627576044892754956074556492e+00L, 1.31512826035991923618357153643853889e+00L, 1.44358784334344214073911010244139658e+00L, 1.59024039033833533691274024525328135e+00L, 1.75872697808494229887678505228447105e+00L, 1.95347868511083813992081514830258545e+00L, 2.17991652311273637078595706271805585e+00L, 2.44471039181719695746189348680321367e+00L, 2.75611627927753518177812012686624980e+00L, 3.12441791418753602036992277268322970e+00L, 3.56250886504706839116501560040688156e+00L, 4.08666490215568913223544572173213403e+00L, 4.71757610938540508471197077535051869e+00L, 5.48173646271881799502596740262131127e+00L, 6.41332945820485042568468273867868285e+00L, 7.55680806548694121454415120092330575e+00L, 8.97045530296518503588356381213781124e+00L, 1.07313427967993620782556935698599286e+01L, 1.29423018529722651121181556330024768e+01L, 1.57418213494311260952898800974816324e+01L, 1.93182476307453478113061967921720372e+01L, 2.39303783823625958630927317369382100e+01L, 2.99376708353783067254755016259184880e+01L, 3.78450834852449540061461594823397372e+01L, 4.83704762272558588741438572877597086e+01L, 6.25472526597377774327448466299291048e+01L, 8.18828352821743059070051234981039846e+01L, 1.08606901707010877244713106575898588e+02L, 1.46066165572767230787668444759129144e+02L, 1.99362305840947908376533577788614663e+02L, 2.76400238552833065835531188582929358e+02L, 3.89641361583293015149089847924625396e+02L, 5.59090899610510721528958323850657754e+02L, 8.17488717203324414010281686447524861e+02L, 1.21951707162988010780952106506178041e+03L, 1.85849349228255485567535180727353270e+03L, 2.89733723527987926224598061281533634e+03L, 4.62742546807418291953673117361684539e+03L, 7.58336312821976325886140349375631572e+03L, 1.27729327383211423049145373221610484e+04L, 2.21512103826316975884795094360035657e+04L, 3.96282043351341952537133210137390141e+04L, 7.32802430573798143066819092764851057e+04L, 1.40370956832174099704802040273767653e+05L, 2.79169596050238213326100612230710484e+05L, 5.77851587758831222006931720166846758e+05L, 1.24809297513500168708148829224766608e+06L, 2.82070529249367448006501528915158547e+06L, 6.68996112716468438709724989481100128e+06L, 1.67032788479232576626369550400657265e+07L, 4.40490689805489416603930530460183080e+07L, 1.23130681270188214533524272282450985e+08L, 3.66207397185135919222246119544674802e+08L, 1.16348659359258561581772655083768774e+09L, 3.96573293875598360514367483348534276e+09L, 1.45675716212887953801924286655056170e+10L, 5.79499965416005488651946885694232582e+10L, 2.50933409077965035999243371354527615e+11L, 1.18927611174028691004735513584719908e+12L, 6.20525591975150642720259081452168385e+12L, 3.58662837399254785268923887857175768e+13L, 2.31171019709164125040709702173384790e+14L, 1.67323267937848597801576240028274938e+15L, 1.37027502568098828908714302508292741e+16L, 1.27982243687884271019103805104886411e+17L, 1.37488860693662981360604951513000987e+18L, 1.71428840498039054019366079813545633e+19L, 2.50480806231532255799256901000499530e+20L, 4.33295295852175693203040531656862705e+21L, 8.97105957110885650118812876460940777e+22L, 2.24900305994354872692347113786351015e+24L, 6.91168391281314093810281357471213740e+25L, 2.63834638817928808592115398804015843e+27L, 1.26855240154452496477895137567276885e+29L, 7.79793937981300078349411089481829644e+30L, 6.22628875244383647460445596438511369e+32L, 6.56725010457698317225350638943220187e+34L, 9.31627142136562734426709726532855891e+36L, 1.81178764804393998725363596058882739e+39L, 4.92965709962256757369004572197380439e+41L, 1.91768799703732643541855471608092309e+44L, 1.09145348658581711775073448931123050e+47L, 9.31447898399194268806130290915959528e+49L, 1.22344767896866261290498650189275522e+53L, 2.54310892512613676637994972961780173e+56L, 8.61698733620595754888079045068786616e+59L, 4.91184107780000171015313299477683427e+63L, 4.87081518596258225878777239561036595e+67L, 8.70837775558769802630502082888045797e+71L, 2.91582292448921588681558819522688100e+76L, 1.90391730055994678151666350663451590e+81L, 2.53108226877386875309925515429807108e+86L, 7.17216745327677632991407821508792163e+91L, 4.54861980767233963821254711174889633e+97L, 6.80080274478233195724672872122891978e+103L, 2.53345776553427904264312812304869400e+110L, 2.49408335416956941404546574182091219e+117L, 6.90831393215899350999406217643925461e+124L, 5.75535983268412076946168827231484587e+132L, 1.54830478033444708124258729693098368e+141L, 1.45063275961171552593742069490051326e+150L, 5.13010920252030309322157027524520131e+159L, 7.46051857949218271625227134136784373e+169L, 4.88752936708905952864518859469811383e+180L, 1.58944916201304126296752123375100638e+192L, 2.84523891966215233479427916942262824e+204L, 3.12952175960493682046861415263020503e+217L, 2.37781288259852734112773228061886887e+231L, 1.41367934226264567696479785830917722e+246L, 7.50969021632501856297416076380790606e+261L, 4.10517599617698914085666788248374635e+278L, 2.68396648103470580650904518179723689e+296L, 2.46300967872463438914762759549033346e+315L, 3.76174998591379278617806685202641214e+335L, 1.14633505463399943022299924904504898e+357L, 8.45422653379120782973725460577460520e+379L, 1.85322036769366179986950823638998209e+404L, 1.50271794914844405931928670543344206e+430L, 5.68929995100375677797682848265066614e+457L, 1.28862756145762463302669091988538860e+487L, 2.27343599851542201859662096966470860e+518L, 4.13728378647859018626664278751490836e+551L, 1.04732962553987345589103224110962753e+587L, 5.07014442635227334186619020470235649e+624L, 6.58680466182542570069097938912153401e+664L, 3.29371230247950075139843014589562364e+707L, 9.30666782392729638823808617314515754e+752L, 2.23612238313938342458217832467289997e+801L, 7.05882324392654993625063412318352329e+852L, 4.65192550274585790446586136162724180e+907L, 1.04784460655109112066824552095698697e+966L, 1.36343029663707923380723270729436320e+1028L, 1.79162856963805080764174564008589158e+1094L, 4.30919215868732016052648412277675057e+1164L, 3.57261639332919274471338835639300206e+1239L, 2.00290113950626521919894557483624467e+1319L, 1.55571074565195195355910058210877816e+1404L, 3.59251763773431142332284400696144078e+1494L, 5.55982146221013438636549073847422510e+1590L, 1.36984614652427999087777938149635656e+1693L, 1.34965612662661283517635152647662065e+1802L, 1.41743602676194002368496649429520279e+1918L, 4.50570145843130891260063218260174869e+2041L, 1.31668432261399763150332726270146708e+2173L, 1.15414484031205360166874295729734758e+2313L, 1.06861618403043050305720276519487893e+2462L, }, + { 2.99827136671822203139659705254947108e-2455L, 1.24882827026046387418324170521821293e-2379L, 2.44988423001973909940876922057761351e-2306L, 2.66927540888423924256197676379835451e-2235L, 1.89512300782142727523964560129359997e-2166L, 1.02360851047736978252291085443458258e-2099L, 4.88730957021167285814599122540648196e-2035L, 2.38575973739960063984613176811112623e-1972L, 1.37101430897591401677957283544539320e-1911L, 1.06333264218828160158212770967007648e-1852L, 1.27067801926958817891969964688113127e-1795L, 2.66010333678426336904594890897508436e-1740L, 1.10484167956085896672647638913688653e-1686L, 1.02711572445228877679664077673865962e-1634L, 2.40228312498468537472913439313888633e-1584L, 1.58314329557188545251248547330891601e-1535L, 3.28094781159949863603124081342946968e-1488L, 2.37840601013012306745513950331950428e-1442L, 6.68624945754691841776166731458196006e-1398L, 8.05587986859135128455444199209469004e-1355L, 4.58316096287519065423952255855034306e-1313L, 1.35248343166964409448147921555689922e-1272L, 2.26752160966952001157168922897574770e-1233L, 2.35909278572023604645731071940961914e-1195L, 1.65903351294385543451470844717805067e-1158L, 8.56804094411838080986008744972959423e-1123L, 3.52140713988280887124946897137042691e-1088L, 1.24502439015653832112887580419259567e-1054L, 4.08361208615792538039018647193947162e-1022L, 1.33685935274460284904788097419890160e-990L, 4.68914584779066055505548198640894341e-960L, 1.88761464755010821415650640440428715e-930L, 9.32118389977759099804089947706407268e-902L, 6.02287072293155834327191570771930380e-874L, 5.42106639858656175956621834625906078e-847L, 7.22191826970524227339284882890548040e-821L, 1.51020072122639353372149509671977024e-795L, 5.24775126181523166368024963040824842e-771L, 3.20220580014087429159629013136223785e-747L, 3.61997704502523196516304924921584345e-724L, 7.98492800624004092804929885145612391e-702L, 3.61392988815279171930655913638563273e-680L, 3.52366894930304180660437805611575996e-659L, 7.75941790954346674475792064117877807e-639L, 4.03982705605992279012386676527754690e-619L, 5.19834669028776461984659088482903679e-600L, 1.72588931588477933787290173538689408e-581L, 1.54137268468058258004178745033532316e-563L, 3.85562019823508006565291873935904091e-546L, 2.80916830174896024691081755907263354e-529L, 6.19212992045820718698085583700822639e-513L, 4.28406369726641450642830646435371014e-497L, 9.64070107276137860266813577293097959e-482L, 7.30474502980487251348070249880206420e-467L, 1.92703875472217605577664104239882285e-452L, 1.82836317722867439282495454446115074e-438L, 6.43850535226391166629598797094394826e-425L, 8.67564527079512826366041439069686406e-412L, 4.60732378382987117665981750506044471e-399L, 9.92355019653945096209219622811507181e-387L, 8.91282113369599082908019662526444168e-375L, 3.42910268669860807072991706793596262e-363L, 5.80083861220020883214825204353252963e-352L, 4.42512315593917892307328787082985460e-341L, 1.56000404760553377203351190297454435e-330L, 2.60259125151860978088621742839596354e-320L, 2.10262994916038774260354592873630300e-310L, 8.41173460487346663387701675407432002e-301L, 1.70280612724644563266907394311476267e-291L, 1.78116409086610297225917597830385624e-282L, 9.82480313804105048460709403983300504e-274L, 2.91457791899830525764575140294420231e-265L, 4.73965774855838520901565109021450612e-257L, 4.30398176296336788976377718753404885e-249L, 2.22193567988028967419035853512154624e-241L, 6.63553772275767193165934337486647504e-234L, 1.16578412206922730540647811503608703e-226L, 1.22474675486304476176402962758102117e-219L, 7.81684108965031293490823429466674471e-213L, 3.07774321188900147460180897292349446e-206L, 7.58759251414243265302591311385078772e-200L, 1.18823395876906229284835410783359514e-193L, 1.19864235179097517931485807315756884e-187L, 7.89484815058732018316693655376229205e-182L, 3.44001585820470930356951346759790116e-176L, 1.00429282413458278190733306028479555e-170L, 1.98881516262612704197372631141044676e-165L, 2.70364023416269358290386889178454878e-160L, 2.55241036356528886321774073237366662e-155L, 1.69227628517124062919375344585284149e-150L, 7.96587271931569005985245219884752131e-146L, 2.69038016965415710141558028398178580e-141L, 6.58640142296301821553052201959182941e-137L, 1.18042002159083828066729019346791192e-132L, 1.56367343741949029569249898774237153e-128L, 1.54531048534737740803236941099285613e-124L, 1.14963627239221457328345144952502533e-120L, 6.49493107141223206477306791588740146e-117L, 2.81018975962531457950258683552245790e-113L, 9.38876009983047538463236277234608306e-110L, 2.44144614978077332940218030178369234e-106L, 4.97967380423964535764132428105410190e-103L, 8.02629250855504170950085275141889693e-100L, 1.02975774422556528975197839046564511e-96L, 1.05903428462392788554333849690582167e-93L, 8.79012224539705420215807394822091933e-91L, 5.92725904620589386119574720007659266e-88L, 3.26785695641876626125438772016710733e-85L, 1.48222090912512196733576972776187035e-82L, 5.56431172687041304333655416134228735e-80L, 1.73894644850180973193834439393406052e-77L, 4.54974501627115811330277659341709811e-75L, 1.00204791018402181301004224966380115e-72L, 1.86763466487726841127561204857118883e-70L, 2.96092907372076963741238677845263773e-68L, 4.01290356278003207547213477434374557e-66L, 4.67174973180940285995675266523420122e-64L, 4.69376738484344030975102668254954324e-62L, 4.08839867480777582716177965835471551e-60L, 3.10086294017966876521788239138705860e-58L, 2.05664262860193002265928563040484563e-56L, 1.19777269867460483717671801459380654e-54L, 6.14987857896674930479991965502306936e-53L, 2.79459594105487367405294144558243202e-51L, 1.12814222153195027375952194262805170e-49L, 4.06053088698370288660361299969573584e-48L, 1.30770277764601303984357205166621959e-46L, 3.78118998998858848129267831928491324e-45L, 9.84875712554165931773609676827898732e-44L, 2.31826871061275836674260034702071180e-42L, 4.94684766719278736886703293137447413e-41L, 9.59814033368779163526953048426266162e-40L, 1.69828465632158908850726775955673984e-38L, 2.74808806067694979431131601699073400e-37L, 4.07794734980576448596813627579221148e-36L, 5.56417400808680411162969051547065270e-35L, 6.99889732124326604821939972498753725e-34L, 8.13608686966403922600365716655177400e-33L, 8.76218322965140584555660990677761542e-32L, 8.76276637192578280309577248461260176e-31L, 8.15628170980170063345810303188191933e-30L, 7.08149199986036059275640615879247609e-29L, 5.74736606938180421303095720610698091e-28L, 4.36944079330436317602800446372377792e-27L, 3.11795190731786551713306066746724497e-26L, 2.09240762901978141675541589343048983e-25L, 1.32305299259448285811442078319939693e-24L, 7.89691997711578359267081292526106870e-24L, 4.45716605711992632203887297614028920e-23L, 2.38302054707699751676620265710858837e-22L, 1.20889613263470803214753580918237251e-21L, 5.82833462566546297036431040060608322e-21L, 2.67469784973934035752489871481337927e-20L, 1.17014393860453605367131279149462226e-19L, 4.88739480774243667158625429475089610e-19L, 1.95168062031382677617975635339602042e-18L, 7.46163208304186839076058133462415646e-18L, 2.73485791500251557979443670181385630e-17L, 9.62223074873981898938153222962813147e-17L, 3.25389617800670808719193210653774700e-16L, 1.05888451003262711834291997535706834e-15L, 3.31989417456924550647348023471492055e-15L, 1.00398818028880718004903688096398433e-14L, 2.93186753434992804142094819281287207e-14L, 8.27635883877837412701034478711895464e-14L, 2.26082510653047710401828799240495861e-13L, 5.98228146965673437508140635644104873e-13L, 1.53484657642706271558550260287175188e-12L, 3.82185576688620308819449258941130914e-12L, 9.24474797424185856221360345157220406e-12L, 2.17427909729908200066806520833424743e-11L, 4.97635090813511876195380613765617708e-11L, 1.10929412007484858271399815868498117e-10L, 2.41032585809105707126681740366639425e-10L, 5.10905559690208602233885434283852003e-10L, 1.05723928928894498681155298267174319e-09L, 2.13744795688281626795384543565327267e-09L, 4.22492806022042378177884800843897317e-09L, 8.17046853836402216132200964074977087e-09L, 1.54693324186061707441588930749976281e-08L, 2.86930859292637487108510416894642893e-08L, 5.21722334965282980403485300265738444e-08L, 9.30518593041943674159836371480799295e-08L, 1.62889442240265382985512933741863589e-07L, 2.80023159222713498193152226335713707e-07L, 4.73011069732904671695491353591017402e-07L, 7.85526363421471709139200654941264315e-07L, 1.28318979177475296348420727772184965e-06L, 2.06292423671439573062357518920248604e-06L, 3.26552286428871054459476770292453844e-06L, 5.09222413107163744070769490625113325e-06L, 7.82617466349549247600633222001776503e-06L, 1.18597235737360853531010814128200937e-05L, 1.77285167845861097132511756107809923e-05L, 2.61533347347083551795448324767635695e-05L, 3.80905294601878233958593851046717171e-05L, 5.47917574609632216617322114415284106e-05L, 7.78734661207721580410532787755478685e-05L, 1.09396271310786841597436260479638662e-04L, 1.51953965111990518244589142984584154e-04L, 2.08771424329052859462812228725402767e-04L, 2.83810167897154635400111152886276561e-04L, 3.81879755641776745662197699923565149e-04L, 5.08752658539288473040921063606067979e-04L, 6.71279691879016478989727452815073290e-04L, 8.77502619869410964596211481799673429e-04L, 1.13676014562695660388935295197579588e-03L, 1.45978322435393926290231969328136083e-03L, 1.85877550576562291461373383997358853e-03L, 2.34747474413929171623192976971642926e-03L, 2.94119122257973574562047404684570218e-03L, 3.65681962518947136825693675506580632e-03L, 4.51282135037802008049500003706382224e-03L, 5.52917497487431572466643627095469859e-03L, 6.72729342693880289247231232743320046e-03L, 8.12990737739402925191380506695287882e-03L, 9.76091537148098089988167779205704956e-03L, 1.16452022628003896766716791241908478e-02L, 1.38084285310255098081489577923406060e-02L, 1.62767940269060299249627834088541599e-02L, 1.90767805535439719611430291452241110e-02L, 2.22348784290424057418829018676115193e-02L, 2.57773027557106041232220835190089403e-02L, 2.97297055256785242037107379259364943e-02L, 3.41168899105681014303940274877700652e-02L, 3.89625331103873045168982262850032695e-02L, 4.42889239784348614272085648656341809e-02L, 5.01167213062401896725837060595306942e-02L, 5.64647381631055655160905842942135176e-02L, 6.33497570613638646379858081046281019e-02L, 7.07863799874088410337603891340254733e-02L, 7.87869165286187403201277486249691639e-02L, 8.73613124671846027274852311959507760e-02L, 9.65171203330026184766273626679604986e-02L, 1.06259512537229504582581766840088037e-01L, 1.16591336871525032405196867775170242e-01L, 1.27513213378027801743713746335418149e-01L, 1.39023670890726644461647310110564995e-01L, 1.51119320935163034926767802526948718e-01L, 1.63795066161333054101624624583286900e-01L, 1.77044340081249140375155906842322507e-01L, 1.90859374591070988709995096163492901e-01L, 2.05231491577749618625157075644473454e-01L, 2.20151414838427133582099008248376327e-01L, 2.35609598571509171617873703655361587e-01L, 2.51596568823441496049692748064095951e-01L, 2.68103274485319808338763876413696112e-01L, 2.85121444718080293120944366000785895e-01L, 3.02643950033175240463650928525241062e-01L, 3.20665164656273759511495325736015581e-01L, 3.39181328243896232934423095526947639e-01L, 3.58190905496894238632513262989320923e-01L, 3.77694942711148444854921008885136613e-01L, 3.97697420816736709936441112125746846e-01L, 4.18205604975383785180004107895309545e-01L, 4.39230391326913892071217294036947977e-01L, 4.60786651994838310108569244001462874e-01L, 4.82893579976783682783259082280697090e-01L, 5.05575036056380615456191240843198089e-01L, 5.28859900380164343616138823034844308e-01L, 5.52782431848141026163801711629569094e-01L, 5.77382638973537667728623589540847426e-01L, 6.02706666380887845415163251209767664e-01L, 6.28807201638412861233038059400000985e-01L, 6.55743907668438480076422889144751851e-01L, 6.83583886557560546105565188637319809e-01L, 7.12402181207131050122140520074497354e-01L, 7.42282321936634874071712163942668772e-01L, 7.73316925891616774766609626518222875e-01L, 8.05608357929825762678392686079844024e-01L, 8.39269462582114444255866071824225817e-01L, 8.74424377728731780655872302934188327e-01L, 9.11209441820152654384317758539800255e-01L, 9.49774207830947999703385257169606442e-01L, 9.90282578695719860661750084965348602e-01L, 1.03291408077266220499949941381670461e+00L, 1.07786529395310786342015831094913754e+00L, 1.12535145943113425409772316889306152e+00L, 1.17560828892019106387681852443264510e+00L, 1.22889400231711865029290591255755794e+00L, 1.28549162454200134646596760738351906e+00L, 1.34571157661211478758710729669915294e+00L, 1.40989460104228631141154693756330089e+00L, 1.47841506752326819907071392253335661e+00L, 1.55168471165732988584072993312632620e+00L, 1.63015686749586045646523839878119043e+00L, 1.71433126392888582869445858515841385e+00L, 1.80475946586097450583979351681595524e+00L, 1.90205105385821569910651758727035418e+00L, 2.00688065090883085704250790253631297e+00L, 2.11999592251508776978462701922381176e+00L, 2.24222669701791864392841075957133612e+00L, 2.37449537743872890090165532424204567e+00L, 2.51782884491687412950125924770996677e+00L, 2.67337208788498443977901451698681543e+00L, 2.84240383149636938582597352632467033e+00L, 3.02635448975787151687626271616744396e+00L, 3.22682681985641084640836568780538092e+00L, 3.44561972615851906798292101239468486e+00L, 3.68475574257857058166416238846674883e+00L, 3.94651281922700641882215705186324970e+00L, 4.23346115586300426882702466682124288e+00L, 4.54850596485993372358839139642384894e+00L, 4.89493721528314838282250644869812537e+00L, 5.27648761361579143482640951008870741e+00L, 5.69740032348777653019331418706396336e+00L, 6.16250822618479874280298612217822529e+00L, 6.67732688781902305621720870171254858e+00L, 7.24816384288680618425673773908490765e+00L, 7.88224734633420137754997440176783259e+00L, 8.58787841076847338040196250304371454e+00L, 9.37461076170556588083589376387132811e+00L, 1.02534643490360208202755813725095827e+01L, 1.12371792943596952958405098972799626e+01L, 1.23405186912073323038589589843390563e+01L, 1.35806305843369735705552654775963352e+01L, 1.49774818320198815684165550755584428e+01L, 1.65543795252306978072060668000283508e+01L, 1.83385993586213963662082373601202455e+01L, 2.03621450242974894275535474068497776e+01L, 2.26626685943754163096516986406459795e+01L, 2.52845893136112912405786286347442878e+01L, 2.82804576829875229843082739941801350e+01L, 3.17126237580911006574531329780573620e+01L, 3.56552839704483033860162655552985983e+01L, 4.01970005016327611735412627281826315e+01L, 4.54438126123299012690083228854751285e+01L, 5.15230920902650058925899224137885947e+01L, 5.85883374425407037894686827319101058e+01L, 6.68251567023112069515824430636222454e+01L, 7.64587608768192360600680527705062884e+01L, 8.77633846894782777864438965135974549e+01L, 1.01074175868700380244224060820937268e+02L, 1.16802258994842453002226105258170771e+02L, 1.35453898714114297683765730207366657e+02L, 1.57654978967903747896778920825912898e+02L, 1.84182405906460887204718250035971904e+02L, 2.16004568481915370203941996632993398e+02L, 2.54333702516246823953928460722661707e+02L, 3.00693971336392029288524445812313026e+02L, 3.57010397089553597741305454749296236e+02L, 4.25725590115811669827894375931285872e+02L, 5.09953725643224718975881101989299450e+02L, 6.13684687521816216675628323432708789e+02L, 7.42056139017496594867562213902074498e+02L, 9.01718069398279102081695287947885045e+02L, 1.10132394119371945146169423670051948e+03L, 1.35219615071533062822615520086342752e+03L, 1.66923291068630661586092129359067647e+03L, 2.07215152332054272741081984137877196e+03L, 2.58720328209038570262408045410782795e+03L, 3.24955382874419473343636700904469745e+03L, 4.10660860213453501373964026030452875e+03L, 5.22268955795277619388623264624171874e+03L, 6.68565726355089669998707553230747827e+03L, 8.61635357331041935557199135249564277e+03L, 1.11821636876213398227716019227207708e+04L, 1.46166395927660444135310088609126834e+04L, 1.92481111548503807855046302083949422e+04L, 2.55417294787310992653570084425920733e+04L, 3.41617486573493312682855974958999477e+04L, 4.60645561151339657587241032816274431e+04L, 6.26388222783949624156629031841856307e+04L, 8.59184957335087735876745002390386986e+04L, 1.18909441895224029432207119296169161e+05L, 1.66095033938427884484826987675525104e+05L, 2.34226252811038979343276539537003434e+05L, 3.33568602948986258437654580586715228e+05L, 4.79889988962864687601246140266254885e+05L, 6.97663061660509733330079420786394691e+05L, 1.02527964914474052697145671441285507e+06L, 1.52363581455429196593138247075709981e+06L, 2.29042801548317740734746692037333714e+06L, 3.48424008370597272699707163872949391e+06L, 5.36561882022124111785765119998290944e+06L, 8.36799594465384427071057649003523823e+06L, 1.32217203482688374239659605009398927e+07L, 2.11738506478689471767346755297403608e+07L, 3.43829654204789362343598103327212044e+07L, 5.66383460344826705635075490736605924e+07L, 9.46890531446099216978642309212033877e+07L, 1.60736860537955754766368401888105613e+08L, 2.77184337816824251216810756452423932e+08L, 4.85821891491727553231947839400706241e+08L, 8.65895043719996967916785083318862010e+08L, 1.57023595787763814315717820663521931e+09L, 2.89877916582589084595240112564380085e+09L, 5.45082862939618857716273065316347458e+09L, 1.04462776299019818355322697028773431e+10L, 2.04161928476231748290058801874576093e+10L, 4.07167362508726715447348035164126587e+10L, 8.29154750329098975446073110291771593e+10L, 1.72524569678310615987347680670953976e+11L, 3.67042596452982637114653516749325639e+11L, 7.98985690430384590881851382687868095e+11L, 1.78088199348481822130071407591775159e+12L, 4.06753710066430378340194042741373814e+12L, 9.52719664341172412580158176782396629e+12L, 2.29025392291311484677517351429897325e+13L, 5.65517100257158446400477892790807623e+13L, 1.43556057453169991412842468344287817e+14L, 3.74966777273576618576956864828262686e+14L, 1.00868013060119404846072345341681988e+15L, 2.79711270328189457750729359218050034e+15L, 8.00353033476527491290557180677857043e+15L, 2.36538022352308798092653239020367364e+16L, 7.22793756862980926623333746953184515e+16L, 2.28603237125675384523138361921766753e+17L, 7.49169357670736182787260118136384206e+17L, 2.54681528722697062733706069581540403e+18L, 8.99167123461421679854681325569917778e+18L, 3.30088716836331393064955543786333400e+19L, 1.26155602488854061815298573346753948e+20L, 5.02601059129997078887664234449072840e+20L, 2.09003840003334609133024432910535654e+21L, 9.08427629135679092557541630988833736e+21L, 4.13277307337650905633261831455054852e+22L, 1.97077591472219550165099701845426740e+23L, 9.86567192878194333593095251120628263e+23L, 5.19253827231351201624600034890440225e+24L, 2.87797813261600767124658244003026900e+25L, 1.68253103834271529795445964171621893e+26L, 1.03930300492804406447430223922613789e+27L, 6.79491179196076158722692150701779494e+27L, 4.71054472298412825215699352759734253e+28L, 3.46906218798171940969795067049186910e+29L, 2.71919469298029646397308102518695120e+30L, 2.27308597305997987201797057125811269e+31L, 2.03060816941963451979890589753656719e+32L, 1.94261454794602808054773809715560372e+33L, 1.99453642796409945684693816457728868e+34L, 2.20275757078165507105373401305070760e+35L, 2.62280693187648585243154230451397289e+36L, 3.37503469494102278406378324431267258e+37L, 4.70514262885548973786602859197635105e+38L, 7.12449819522227214155183099218285736e+39L, 1.17479491699687500984526531336188586e+41L, 2.11529840618171125644793575486664802e+42L, 4.17057423654484355854313046574264130e+43L, 9.02996402249218455912158145716517353e+44L, 2.15344195364580091650722699472214395e+46L, 5.67373854091156226750041136308702235e+47L, 1.65679493344512341491651081156308385e+49L, 5.37959274142567387437479000715431452e+50L, 1.94883090765131732574822421459033340e+52L, 7.90409930117048365355172083360408902e+53L, 3.60198039300535878643618051284879761e+55L, 1.85117602089555214211892984185617326e+57L, 1.07703344015399312416171835284404207e+59L, 7.12190311508435674119313111798381629e+60L, 5.37418888386167437844586074702336014e+62L, 4.64729650833728307491157079699691435e+64L, 4.62526710582644946748054017004844382e+66L, 5.32182077764493049141810605179622557e+68L, 7.11164697902038500579051989777466680e+70L, 1.10899515910236266304919828966923200e+73L, 2.02799605144484652148788128416483129e+75L, 4.37097775363901059074163853783972656e+77L, 1.11616878412036714566047843287003825e+80L, 3.39514715649439557125494531010505893e+82L, 1.23701982128373508607730444611285161e+85L, 5.42965793175551379743384549971838572e+87L, 2.88810817234216647705316265060164148e+90L, 1.87304637361264791993354548498385904e+93L, 1.49042693797246054384025095285834884e+96L, 1.46460222682423294988692623274219021e+99L, 1.78930667727185631768641895397399502e+102L, 2.73657637241785643461962451320315667e+105L, 5.27697387534476684848681508483720442e+108L, 1.29244503566283656061209233007634805e+112L, 4.05121786788653633019340698712667656e+115L, 1.63797303768105580759099639209855651e+119L, 8.61161786816897952522273022842847467e+122L, 5.93663320306070547376727413186770748e+126L, 5.41263435338015569490052234550484999e+130L, 6.58482575653621278094067557171475624e+134L, 1.07875660982114746476517100137547561e+139L, 2.40241992462133691284825971033750350e+143L, 7.34435324696612505273925787730222850e+147L, 3.11318307060514113999896732347290570e+152L, 1.84887752009365552806348833513339683e+157L, 1.55493753489569904210242587934359215e+162L, 1.87247311840034398087857290386878308e+167L, 3.26561398822344966034897508874934342e+172L, 8.34577318106206521818843721578177275e+177L, 3.16365209967032443701802479913075857e+183L, 1.80121863573431611955949232303314972e+189L, 1.56029746814154042157436181814468250e+195L, 2.08399815409632719398233238905315693e+201L, 4.35116508686695844690078637651674080e+207L, 1.44042594283375698824917457557971547e+214L, 7.67198578340176495038072549202750984e+220L, 6.67439909212164301008970795489093574e+227L, 9.63314810388083227111873828289832687e+234L, 2.34398517046722427869034729305744960e+242L, 9.77625325893464652861772945740140456e+249L, 7.10967843958998030041427991161778060e+257L, 9.17597441867286774623146964891772219e+265L, 2.14036206544827332284805812358315196e+274L, 9.19420612380519250234059644495148895e+282L, 7.41568524413971300723452081581189161e+291L, 1.14573384520235218510170025456065061e+301L, 3.46156619789802557007367290577360329e+310L, 2.08912045049233012342096277237544009e+320L, 2.57451388307699184873778115477509299e+330L, 6.62688893229567984520960366416649465e+340L, 3.64721218233974203748299012650543732e+351L, 4.39668921699312866048896359512324981e+362L, 1.19018091828589034728575506532863164e+374L, 7.42292147631996488193728378356566879e+385L, 1.09526098640141261390128648437627728e+398L, 3.92927734436557751277903528467662194e+410L, 3.52539958718458390412925405124992174e+423L, 8.14407380085561132671651242382158564e+436L, 4.99172864167925991508434677916290384e+450L, 8.37313822543668537823480408319630674e+464L, 3.96855771450749046728173847477197045e+479L, 5.49292894873452993989300213358944271e+494L, 2.29708122354182613470710687416853220e+510L, 3.00602816347641813806476628260504686e+526L, 1.27638345565474398023933739505382139e+543L, 1.82543785151714558753981850731109273e+560L, 9.13886193903951047182967076404934097e+577L, 1.66659166393902754183225415655293639e+596L, 1.15345182570915755941253059732455874e+615L, 3.16074696483848527092291852149349249e+634L, 3.58237065512849118228300807716046934e+654L, 1.75676845140981179589000705343726870e+675L, 3.90495239094757591264933748015965848e+696L, 4.12771024114613858596256966986824636e+718L, 2.18017473107123494465764845328386818e+741L, 6.05537171542030830962660182644895823e+764L, 9.32267445280349135813949292533678488e+788L, 8.40039310752404384099688064836067109e+813L, 4.68572386284109286448290494678984852e+839L, 1.71436621216433181556756205470621080e+866L, 4.36726894564208691170045669145775062e+893L, 8.23850494545149522733960578619372006e+921L, 1.22636833130359811940229369518492693e+951L, 1.53817446772510796133546119401337038e+981L, 1.73934010579080275675622752667739992e+1012L, 1.90139542390828308944919910797818652e+1044L, 2.15946649839694693874583032395369802e+1077L, 2.74458385322614086037916005350795661e+1111L, 4.21460437827726866824631065747020388e+1146L, 8.46327678591246014474308263680903354e+1182L, 2.41136671056709946500959023526115708e+1220L, 1.06046799402590770086828664893536628e+1259L, 7.85179239227989671195411257856609735e+1298L, 1.07053761782523090834371225181245647e+1340L, 2.94820375013014518743449818159813519e+1382L, 1.80414267837505733123417059421507186e+1426L, 2.70702818749460407693598763878577805e+1471L, 1.10237898995725987663697548890315962e+1518L, 1.35298567513553498909522877321159185e+1566L, 5.57611902405430874175886881037679558e+1615L, 8.62760618106732185887902244008862925e+1666L, 5.62274836328861658358184936480919820e+1719L, 1.73809780706704538846353037945373733e+1774L, 2.88052131688282318513745853191288493e+1830L, 2.90423838801873888374451692095277096e+1888L, 2.02951924440811805047282880080209219e+1948L, 1.12457154445459099155545223242406413e+2010L, 5.67678101812548596682420412619518564e+2073L, 3.01259124479996611916817067093268060e+2139L, 1.94839799990442184578594656275869899e+2207L, 1.78866123976568468449541367729975757e+2277L, 2.72776450570640988722564402903756955e+2349L, 8.12826724972980545013533499964424395e+2423L, }, + { 1.58403833597397609272337637131715304e-2474L, 4.01729907956437307269377706375953438e-2436L, 2.58580645701935131155084366864422406e-2398L, 4.31502895023559220093536948165386274e-2361L, 1.90627959218882483095663188951084330e-2324L, 2.27589955667507909301636117518932802e-2288L, 7.49364095876812027654477175001110624e-2253L, 6.94191154236392933887288062436725643e-2218L, 1.84522919671267474043685120983334524e-2183L, 1.43487104640347241520251346864979221e-2149L, 3.32692243646438795745471365264644590e-2116L, 2.34362088307498827836613435573448115e-2083L, 5.10938037262713942693655713913568198e-2051L, 3.51060735754549615330960873223686009e-2019L, 7.73934046950102664330281533900661264e-1988L, 5.57169465236073520583741860201801676e-1957L, 1.33280818206626290524674045358563098e-1926L, 1.07761463878385909143899244627194248e-1896L, 2.99487219016399829947920738111566372e-1867L, 2.90872283894068508271645083240599458e-1838L, 1.00349314519658897817146360011284604e-1809L, 1.24963603019269210233323055704536134e-1781L, 5.70651178926661193581089363715896182e-1754L, 9.70578293043209307574192077696195294e-1727L, 6.24328278846472954410732505740796953e-1700L, 1.54193058035632514209035337344023300e-1673L, 1.48399119945730121895709095048379728e-1647L, 5.64752158032889554103477750567193685e-1622L, 8.62167301557505164690437370018957398e-1597L, 5.35528299764763984143338000418037832e-1572L, 1.37241462764951847155586335894427418e-1547L, 1.47116444020541724843474277134735959e-1523L, 6.68618803692998895772448346916660911e-1500L, 1.30561453192449212967328116730742424e-1476L, 1.10983482751594629837009226116529299e-1453L, 4.16014518377810797736243906294304347e-1431L, 6.96431413050131379947014047903616964e-1409L, 5.27224320695995707920555229340409925e-1387L, 1.82727152085917578757399986780345619e-1365L, 2.93468712490571136931409720092296819e-1344L, 2.21029656493081556265677595112314098e-1323L, 7.89892460822856456312620943162424218e-1303L, 1.35498246922475851477828612647429926e-1282L, 1.12846854910106323887966343965144914e-1262L, 4.61424330893765402182473137993848704e-1243L, 9.36605095127672178405946589653781928e-1224L, 9.54054141854710811663726016692763275e-1205L, 4.92938100391460828476769674596652859e-1186L, 1.30552448174985025504800286655378847e-1167L, 1.79081395504489298673122868237542862e-1149L, 1.28534148947828407343141932678878641e-1131L, 4.87584961151572559819046616829450419e-1114L, 9.87277629967922144952427945151885497e-1097L, 1.07748800964228010206356572218732211e-1079L, 6.39928058051557015650179754550910965e-1063L, 2.08781638937389821580749246439535224e-1046L, 3.77684590339710704264469235045684970e-1030L, 3.82307555361237861173188661605677525e-1014L, 2.18500494285229212661260038960152445e-998L, 7.11371665672211288079530438419393765e-983L, 1.33086590459456967821090511427946680e-967L, 1.44309821421378874919204882407008472e-952L, 9.14647515187060050796469146648366553e-938L, 3.41683020290309632448426799765730462e-923L, 7.58515118221027874504569883083804726e-909L, 1.00874302140725085602226074835782694e-894L, 8.10069400524047548461447004237480370e-881L, 3.95900210017885619699714022194103898e-867L, 1.18662867376446832171113003401601030e-853L, 2.19786739893484213511853337557279548e-840L, 2.53446665772094387684997171428381901e-827L, 1.83299289701163579779687245566728015e-814L, 8.37462324951323786164578010773011160e-802L, 2.43440349985894963165438833576050630e-789L, 4.53405919015746926984345204895280285e-777L, 5.44811780296147933680587250736719556e-765L, 4.25227509910246244055269284525208521e-753L, 2.17028567518979939311612851867355063e-741L, 7.29110293097611082922276966606966112e-730L, 1.62280402409213923291155004693280799e-718L, 2.40828308813354260030814303685712546e-707L, 2.39798644647022706006083856285038692e-696L, 1.61202006993232554271262188260349029e-685L, 7.36078014307223356522361505691981658e-675L, 2.29673595120013740585571409952171287e-664L, 4.92601668045549547120303143586093867e-654L, 7.30469847326532782734592211727680659e-644L, 7.53208483045812497621524949105624661e-634L, 5.43101457218649885434844485451114112e-624L, 2.75364547737132169841544376328974616e-614L, 9.87114363624257039419731807833639141e-605L, 2.51532230246971379761137727536103954e-595L, 4.58020252011364324634687161502454437e-586L, 5.99105224430269595047395967421408836e-577L, 5.65817475729598864582006398104320790e-568L, 3.87790653215945353008449656152626419e-559L, 1.93831767408426944576894121111160849e-550L, 7.10042999124518145073529096418920675e-542L, 1.91544155185588660392537613901890409e-533L, 3.82329460613706944718834058784982843e-525L, 5.67308558344799642959861077485254353e-517L, 6.28651971015047054176370541889652534e-509L, 5.22608309691007325295015732741277330e-501L, 3.27380385796518526996963624688451015e-493L, 1.55218880567110686358214096387337744e-485L, 5.59406715134492552797785887998506288e-478L, 1.53903555561583129370612427064103671e-470L, 3.24582771097869247388161880434215690e-463L, 5.26923908371102477241383694074670819e-456L, 6.61116543964979170247326465662672578e-449L, 6.43651161747399650924315876123367361e-442L, 4.88172530890739153159755873311503383e-435L, 2.89552772291014307121494513337008901e-428L, 1.34824561713159645449381177450374044e-421L, 4.94682830703508395886779775564904786e-415L, 1.43550778574773554814450699757551163e-408L, 3.30662278156545301906789072182270217e-402L, 6.06763076341882342375981845143813941e-396L, 8.90102295078976467641802004915383639e-390L, 1.04750026993369008379812665328207076e-383L, 9.92305977697594285442750520712185343e-378L, 7.59233047709729007268137313555513461e-372L, 4.70739644774061079459196244467224618e-366L, 2.37289471679140773116577190541471766e-360L, 9.75578189470698031776059091702014024e-355L, 3.28173795958592945075990020191630023e-349L, 9.06055778471501819614486253220513415e-344L, 2.05942153439035557149195606898627504e-338L, 3.86530964740245225250791387282901296e-333L, 6.00843270324960642367292431619041056e-328L, 7.75791717613089963209182313649669073e-323L, 8.34421688870272754369905134347321346e-318L, 7.49743392110895125137984446953806518e-313L, 5.64335493091932417079632230402715339e-308L, 3.56822312364224796215751885944182157e-303L, 1.90033575264131712027297219010231489e-298L, 8.54728045366493643486236298588028833e-294L, 3.25523625801393911932111212124054975e-289L, 1.05248047241632062076489482718979111e-284L, 2.89617776712893256185087414745466351e-280L, 6.79988531580997322799099912957691248e-276L, 1.36556351036663137564575797911341140e-271L, 2.35130154856703817933308580165070895e-267L, 3.47957918602140446743207712996488528e-263L, 4.43595246742156897562714682208015764e-259L, 4.88306826050902558584812739817346803e-255L, 4.65192688318894071322199120456680912e-251L, 3.84397217698170104458131412518090261e-247L, 2.76116826189849718252009792299798034e-243L, 1.72788148193695597819524956747708857e-239L, 9.44000021446169518374327174980091189e-236L, 4.51212554821909958969480138145008725e-232L, 1.89078188020015147413152497967774898e-228L, 6.96047357819953940988624584998189879e-225L, 2.25551400000095886908107215813083451e-221L, 6.44644677476230409449870129589571800e-218L, 1.62820413693305623578289570883910133e-214L, 3.64118898140332008867604954881435445e-211L, 7.22342104300488240353501601432620632e-208L, 1.27354621995150979542739771832851778e-204L, 1.99918407175965223164864543465886820e-201L, 2.79923301669228713128194864334595626e-198L, 3.50221902155243103789141550909762023e-195L, 3.92214264392110857739154085058742459e-192L, 3.93845056335503285763060194710496279e-189L, 3.55208932101704820479562248595366349e-186L, 2.88218576501349132033303488025583146e-183L, 2.10742246561673617325867420889217990e-180L, 1.39082883056909297835969428096996258e-177L, 8.29809184041509702782403322046680024e-175L, 4.48275079028324875908925844854947607e-172L, 2.19604664947993546897548946859268970e-169L, 9.77074245531826439290686011595488065e-167L, 3.95412900034836577575737163397063382e-164L, 1.45763752143522946134851229157315125e-161L, 4.90175908594770144816169627656347413e-159L, 1.50583242362081439890282730822964005e-156L, 4.23187210926299952258468916772463829e-154L, 1.08947970178510600143883902241342972e-151L, 2.57292238715065164920970933548863818e-149L, 5.58131105433415694107142145348480095e-147L, 1.11357590012697004029170524556205260e-144L, 2.04616505133228608383036998688279538e-142L, 3.46699488500477063569923373366652510e-140L, 5.42379540407350192206120227447952764e-138L, 7.84383327240284700975116490839187822e-136L, 1.04992295793319441478934809931921214e-133L, 1.30230107195741860304672567525213181e-131L, 1.49865973782839300796909511415792928e-129L, 1.60190662241428628230308870106117967e-127L, 1.59224861840198356125270425396669689e-125L, 1.47337534591643627391632824044256382e-123L, 1.27065155139400959289502878067800521e-121L, 1.02240826352576620907328663762929630e-119L, 7.68376260232956278119400404906698852e-118L, 5.39926812723337318582425048609813182e-116L, 3.55107427485349467569160645183534302e-114L, 2.18823540951912101048500342930263842e-112L, 1.26466751543081693428147968135946762e-110L, 6.86180756673724371219029573988488620e-109L, 3.49869168682520996337772693940273721e-107L, 1.67801680739837515692197356611469711e-105L, 7.57743943144193148982405002124429739e-104L, 3.22470377015938680899710533122019572e-102L, 1.29448709067770596337952427228314258e-100L, 4.90613325096345413914934529363944533e-99L, 1.75712131798815332550332783841135938e-97L, 5.95204249145432038279376449394263726e-96L, 1.90856665328641726356485393831448064e-94L, 5.79822445923642921233565089484060205e-93L, 1.67029323997833472695510332615399040e-91L, 4.56623667339808303761814383193281614e-90L, 1.18561734279154794522720467403607684e-88L, 2.92616002780129692916694825399426567e-87L, 6.87006113412670713749912656047162470e-86L, 1.53556578350037994526862611062995548e-84L, 3.27003673677840125658578850353789865e-83L, 6.63955800720658036202444029681088661e-82L, 1.28631975096739859347518450406626244e-80L, 2.37956658113902295790875474474928153e-79L, 4.20626823139888342521923162463424944e-78L, 7.10971923783337943250783648529172174e-77L, 1.14991510411537277718541841100610582e-75L, 1.78087620125559422021122815240864113e-74L, 2.64270379617932988289762938432353092e-73L, 3.76008537594171932684988546369276565e-72L, 5.13292095112425199264463076393673633e-71L, 6.72710027460142769581137467118289653e-70L, 8.46958562134769749810317782657268756e-69L, 1.02503238267223284787859415412841523e-67L, 1.19321912755786334798650299344282298e-66L, 1.33681693038130658171632078204446788e-65L, 1.44228347967979838541089585366023007e-64L, 1.49937455500479399063651651865716553e-63L, 1.50279720313350143765006477517598013e-62L, 1.45300596931848530329429215240805653e-61L, 1.35598044837786253974814702268132430e-60L, 1.22207241221255212718220407758970979e-59L, 1.06422318027052015901612579353436284e-58L, 8.95966739607563684498250506056071091e-58L, 7.29628880807929410507791279851435148e-57L, 5.75025529619018115782221236649660618e-56L, 4.38801166482901351758297994035262224e-55L, 3.24385245129183239778054564241318804e-54L, 2.32423935766553880551312730791561599e-53L, 1.61486977620302644603098163288002715e-52L, 1.08852460554527484166896264813585652e-51L, 7.12175557419282904469498440847683331e-51L, 4.52464766254906707378983948806266105e-50L, 2.79273071581879303547665803856393705e-49L, 1.67538487960386422664995380528599268e-48L, 9.77311432877767609128920687351148833e-48L, 5.54591076684762708155258243373876422e-47L, 3.06280970562787364526087771025696151e-46L, 1.64686211803826623376300968100335938e-45L, 8.62510851388715584666563483664725226e-45L, 4.40168766386889070104410967553191993e-44L, 2.18975577884764674623829698191429056e-43L, 1.06234533644926588892221744026505121e-42L, 5.02803666348568404922856964957017674e-42L, 2.32252463571724922291588384046952088e-41L, 1.04740659389834130621977678673036650e-40L, 4.61343838844969816849890851044847674e-40L, 1.98539744511816200515536891243051363e-39L, 8.35102736745462834322783293199882340e-39L, 3.43444090348454338873945310910863585e-38L, 1.38148913187719664577281415801326678e-37L, 5.43705120131022522415564030011104834e-37L, 2.09435754808064771674030165617400032e-36L, 7.89867661859200690211003183623252601e-36L, 2.91753687094747127218152557081492503e-35L, 1.05578888602271659701510267800456427e-34L, 3.74433381216033081152946793044225824e-34L, 1.30180118525195729018565371931285108e-33L, 4.43834621689338776826444391843192077e-33L, 1.48434826895181654234585115302567433e-32L, 4.87100112984983697071424260901079389e-32L, 1.56890300074251394167498791840311009e-31L, 4.96129531591793523529868958902224169e-31L, 1.54077391002799082070667599670892752e-30L, 4.70055802217201491012415527477898338e-30L, 1.40911523071894959581827729743208189e-29L, 4.15191310395569203370171887252329295e-29L, 1.20273761371542774812275721780834541e-28L, 3.42632737493449673556641936029297478e-28L, 9.60140535939702601155477307042148556e-28L, 2.64727864203377330130778700812469317e-27L, 7.18344222056514710304108009603342664e-27L, 1.91885054598149404233254994607045127e-26L, 5.04697477945599249407828848720385551e-26L, 1.30739479992591170007499101639277446e-25L, 3.33634219823695708156517864262133521e-25L, 8.38925958113626219399750986165640649e-25L, 2.07905181351354860827899559955891196e-24L, 5.07917896724376528007260946058158296e-24L, 1.22350179435783727784530143589061714e-23L, 2.90665491105754953014975765085018324e-23L, 6.81166860609501546977145188171063268e-23L, 1.57498593823802530267320052674032470e-22L, 3.59379678896934832551131875550134077e-22L, 8.09418541120521256436201968800902213e-22L, 1.79979618323748172103553749785052354e-21L, 3.95175890164101728455789689950582204e-21L, 8.56958006805086577463240518925283894e-21L, 1.83575348651729869648335347322858802e-20L, 3.88541433996602231722399876322981769e-20L, 8.12661397289502178971121801417655470e-20L, 1.68000718288950314093575786904308274e-19L, 3.43336935156396282804714345750464903e-19L, 6.93769555039942749928599832442683686e-19L, 1.38634563100898175510110455954156138e-18L, 2.74008749775923088060873199170519103e-18L, 5.35757028868338662612872498580241047e-18L, 1.03646493302280378406673184005440162e-17L, 1.98424944201008499240310250250687800e-17L, 3.75978800606000340899396301904932318e-17L, 7.05221126182168479511704811938887205e-17L, 1.30963564152954622082996853685780292e-16L, 2.40827549610918052797562865726934570e-16L, 4.38589880961171155211843738902302126e-16L, 7.91175868684912128549216604428547791e-16L, 1.41388359787718387270571947224924145e-15L, 2.50347753664468021020115723250325879e-15L, 4.39263786655070582741822344903139686e-15L, 7.63871030696057461236914444427999640e-15L, 1.31670336037747604093705380830550144e-14L, 2.25003102727544891850217684727399098e-14L, 3.81223973341221495282227985716493129e-14L, 6.40502166019136347918960755019998163e-14L, 1.06725053827031948353711195948826425e-13L, 1.76389749378472101040375240485184047e-13L, 2.89198756533454775599767608849931393e-13L, 4.70424252036995808470327107927435060e-13L, 7.59287827351269198973041796516049688e-13L, 1.21618333837252517178450702971971531e-12L, 1.93338859343662487903047794738683986e-12L, 3.05082685244229075126272877890267121e-12L, 4.77908002001763665704541557372044375e-12L, 7.43273471338542509759247990082208445e-12L, 1.14783388812587366578078714999164060e-11L, 1.76028616037242275427822154657272751e-11L, 2.68107110162395316788540367212924769e-11L, 4.05602375429596543728262134893310443e-11L, 6.09544349224153722159236648112669209e-11L, 9.10055012961606421079182569690846497e-11L, 1.34999345213696765153127846451643325e-10L, 1.98994391239515605127817880646635584e-10L, 2.91499607361905978799020781323598840e-10L, 4.24390078141221962088655373293736779e-10L, 6.14135316267139108184909214050184662e-10L, 8.83436579589479851125156253066831718e-10L, 1.26339559402593316965102282486280599e-09L, 1.79636925005171604673781604814805685e-09L, 2.53970414332648086166213535713251755e-09L, 3.57059249828789049877331667413514712e-09L, 4.99234840315053910682137402914672922e-09L, 6.94247187048993148295924434414634261e-09L, 9.60294960016456137105057353194608309e-09L, 1.32133371276166677672139906194961059e-08L, 1.80872790163534638977965561238944112e-08L, 2.46332536476779151638500763225429049e-08L, 3.33804787013687049574791297244907192e-08L, 4.50110842610850506871431532628603516e-08L, 6.03998541333325959410060827223996830e-08L, 8.06630537452609783391065479881400036e-08L, 1.07218105901889261435737857618298194e-07L, 1.41856144379535399139351236825663488e-07L, 1.86829769983638330491745888879438028e-07L, 2.44958653917297200861483891225150109e-07L, 3.19755978044276083153634882857883309e-07L, 4.15579069086754433405340505039048729e-07L, 5.37807971332554467827633744547482376e-07L, 6.93056106477668619385798002644561466e-07L, 8.89417585250212245375810218669817408e-07L, 1.13675615786872600638029106996132895e-06L, 1.44704121253473089806789252868181132e-06L, 1.83473664533283350419063698449974520e-06L, 2.31724882235425364363184937796552995e-06L, 2.91544022582530391094107183656707013e-06L, 3.65421570986355186992807571629053921e-06L, 4.56318857677376015133362727471956847e-06L, 5.67743390948223287752620793591929613e-06L, 7.03833674730757178417069911600525632e-06L, 8.69454275808306722839276847105496531e-06L, 1.07030190270275985848630609511672890e-05L, 1.31302324393740374972736712543053054e-05L, 1.60534528678907389671161995891497537e-05L, 1.95621879772878044903047444244351033e-05L, 2.37597559155521886172243888058434365e-05L, 2.87650014695436120790473222143336354e-05L, 3.47141604126307620878569429267584729e-05L, 4.17628757618591523872557240511914786e-05L, 5.00883684896740377264076716570754303e-05L, 5.98917639018173037280503906445049523e-05L, 7.14005734028021322676450426011314791e-05L, 8.48713297304976003620620060812799411e-05L, 1.00592371962099993408798498455907607e-04L, 1.18886774688549697317681023800631139e-04L, 1.40115413739806927896468824589692520e-04L, 1.64680158738873124934815777767252928e-04L, 1.93027180590427177790609959505517465e-04L, 2.25650359795433055575151925625868196e-04L, 2.63094779253370712822446127059315509e-04L, 3.05960282998094618038061759727754321e-04L, 3.54905080142515530273890819014315333e-04L, 4.10649371213184272695586730470455583e-04L, 4.73978972070856543596623702324547537e-04L, 5.45748908769705106925744948564871657e-04L, 6.26886955037988466777589811218012335e-04L, 7.18397082597597367255394668144143647e-04L, 8.21362793308292890121036733909194916e-04L, 9.36950301151796636389593916360605611e-04L, 1.06641153138572518429387087881256567e-03L, 1.21108690381909541715522898126065244e-03L, 1.37240786710764633931488483556773354e-03L, 1.55189915125250562428574475103346186e-03L, 1.75118070611954731846143391024982058e-03L, 1.97196929478447094442182021751059029e-03L, 2.21607971185090897097885205424488147e-03L, 2.48542559858177963603431553204765315e-03L, 2.78201982871899325746660736300345366e-03L, 3.10797444123022017600460098808123935e-03L, 3.46550009889599377554207066240202628e-03L, 3.85690505461395961880575720620871256e-03L, 4.28459361052363939313848682793859897e-03L, 4.75106405851509722505038175681427297e-03L, 5.25890609434561842084606413815284753e-03L, 5.81079770141443579933464319447926318e-03L, 6.40950150419891594280210549702450453e-03L, 7.05786059539697018633739598386855559e-03L, 7.75879384490912344645900750924930976e-03L, 8.51529070288836937235862937785994511e-03L, 9.33040551314529952303815524992440065e-03L, 1.02072513571791257196870650265821749e-02L, 1.11489934529722276019901656254303012e-02L, 1.21588421363983657377673415921445027e-02L, 1.32400454566162946339651246079183099e-02L, 1.43958814201171884975897081297216705e-02L, 1.56296499211348507284307663166667625e-02L, 1.69446643988840458394481431193257832e-02L, 1.83442432645398203334614155955590374e-02L, 1.98317011429883687012533532738687781e-02L, 2.14103399761506788853091011534572156e-02L, 2.30834400360906269037251797223442256e-02L, 2.48542508971601536767883257823339293e-02L, 2.67259824171004266947925047187844041e-02L, 2.87017957773082030971446046374914401e-02L, 3.07847946323935695276863138190467659e-02L, 3.29780164187051571955970986393933287e-02L, 3.52844238706916706398930809090405599e-02L, 3.77068967928172889046621767464058045e-02L, 4.02482241332694163505581270228186661e-02L, 4.29110964039093677010619866631701642e-02L, 4.56980984888413264034413616112869595e-02L, 4.86117028816359215545912812117182378e-02L, 5.16542633886674445449455067720287452e-02L, 5.48280093332349644585895096278308003e-02L, 5.81350402921654268021994051667911914e-02L, 6.15773213934700546744487567673172633e-02L, 6.51566792003733016470332458328988615e-02L, 6.88747982036856640340840950741077307e-02L, 7.27332179410771208959941663503595393e-02L, 7.67333307583556615050326531083587939e-02L, 8.08763802243933982425303227000944183e-02L, 8.51634602078983074689360505021182257e-02L, 8.95955146208286742294968393977769930e-02L, 9.41733378299144489750576704343915921e-02L, 9.88975757345080247656478735188449399e-02L, 1.03768727505857796722978821461546404e-01L, 1.08787147979900856678514246787241454e-01L, 1.13953050692823999603416543952272158e-01L, 1.19266511545960614110252460361458099e-01L, 1.24727473084088741556780346524879069e-01L, 1.30335749368884349581460099687500407e-01L, 1.36091031427173401966757170543046798e-01L, 1.41992893251724361991875167825655695e-01L, 1.48040798330635148304426193810368709e-01L, 1.54234106679899202351157467338543629e-01L, 1.60572082352486356465237071613156643e-01L, 1.67053901396246033471214692284653203e-01L, 1.73678660232131774208044201415508905e-01L, 1.80445384423654491197811595430697492e-01L, 1.87353037808093115326776430258837481e-01L, 1.94400531959820109714578533182084599e-01L, 2.01586735956129211498107459964096125e-01L, 2.08910486416176267158329341893267875e-01L, 2.16370597784052818695266702661187610e-01L, 2.23965872827597104489240738884195628e-01L, 2.31695113325298676464455224512869174e-01L, 2.39557130914560734720290079897448420e-01L, 2.47550758075638008786996132954185789e-01L, 2.55674859226756791227887436442350007e-01L, 2.63928341907236639931045094151784107e-01L, 2.72310168026859366788753574972476498e-01L, 2.80819365161259349748148678323641718e-01L, 2.89455037874729232565423711864655899e-01L, 2.98216379053536250342702367445487260e-01L, 3.07102681234616603556790972526892770e-01L, 3.16113347916348760019249138447488231e-01L, 3.25247904839992014226666657864488014e-01L, 3.34506011232305314043635112310304911e-01L, 3.43887471001825077739424147442217492e-01L, 3.53392243883271879333889785572599272e-01L, 3.63020456526567529072712529376719554e-01L, 3.72772413528969943076239230990758849e-01L, 3.82648608410867702369280704118517439e-01L, 3.92649734537814481801171047048544340e-01L, 4.02776695993421447225756159687866121e-01L, 4.13030618409759875566958499890031988e-01L, 4.23412859763953990585030832527434639e-01L, 4.33925021151663415382683548295156320e-01L, 4.44568957550164552554831720660662401e-01L, 4.55346788585740186021655771168112611e-01L, 4.66260909322076961243786064631384911e-01L, 4.77314001088352176735947056292312804e-01L, 4.88509042367666263602229097070513234e-01L, 4.99849319768447906973686731056178972e-01L, 5.11338439103428142948352352152044385e-01L, 5.22980336602751811729499672944460101e-01L, 5.34779290289774015573364455286468490e-01L, 5.46739931550080955287380242064660003e-01L, 5.58867256926284616744877484869191055e-01L, 5.71166640173175841717312971842336611e-01L, 5.83643844609887615578228626088462787e-01L, 5.96305035807827889758567710635182685e-01L, 6.09156794655297569062821736349343099e-01L, 6.22206130841923771587050175584017347e-01L, 6.35460496808321163697317796410781296e-01L, 6.48927802208755868138883757264025330e-01L, 6.62616428937038679525110869491604161e-01L, 6.76535246768429422677267756666823087e-01L, 6.90693629673005399383708050292572666e-01L, 7.05101472858747991895757442966727674e-01L, 7.19769210605547537680146085503476253e-01L, 7.34707834954433431482100014962668745e-01L, 7.49928915319620942104629439591963551e-01L, 7.65444619094446439133009723643838630e-01L, 7.81267733325957766141060146767846541e-01L, 7.97411687536856786535849810135961905e-01L, 8.13890577777678436208431256995493454e-01L, 8.30719191996558177068293937598919209e-01L, 8.47913036818712374055336621201445842e-01L, 8.65488365832860347537655780480228440e-01L, 8.83462209487281076620051655836621909e-01L, 9.01852406704052162112602532863159232e-01L, 9.20677638326296314246112109641174382e-01L, 9.39957462519996315051517977272639457e-01L, 9.59712352259170728365681565566195274e-01L, 9.79963735030970038685207606899372777e-01L, 1.00073403490559993309000835270230984e+00L, 1.02204671712495200986974494164817378e+00L, 1.04392633537347289336664619627296763e+00L, 1.06639858190518516071876464455235265e+00L, 1.08949034071194662751500934725633506e+00L, 1.11322974393006216402411430386892104e+00L, 1.13764623169531331372630723630321340e+00L, 1.16277061567042026013306680494416940e+00L, 1.18863514648397907083703649648730714e+00L, 1.21527358533611238960293477132347556e+00L, 1.24272128004352904999786719958821158e+00L, 1.27101524581551079885511358011134290e+00L, 1.30019425107264471110982901454765895e+00L, 1.33029890864201997125110745686528366e+00L, 1.36137177268624019179654148863686280e+00L, 1.39345744174911173037014751038646328e+00L, 1.42660266832841175766232711333173310e+00L, 1.46085647541588835802048454309412779e+00L, 1.49627028047678533760134362560179034e+00L, 1.53289802737592016874439144914426210e+00L, 1.57079632679489661923132169163975144e+00L, 1.61002460572564642000849608863176067e+00L, 1.65064526666943143532240244567555108e+00L, 1.69272385721798833166204038375277879e+00L, 1.73632925074497773069781144176863796e+00L, 1.78153383899165490255124499430464714e+00L, 1.82841373739108738124596203605065226e+00L, 1.87704900404072044775471792428672248e+00L, 1.92752387330408763463712892863710673e+00L, 1.97992700509947708650365975965257989e+00L, 2.03435175101694043322616088522632134e+00L, 2.09089643849576621383396167595935906e+00L, 2.14966467439309042108153883973067514e+00L, 2.21076566938140221236799358744093376e+00L, 2.27431458472911392711904220601704565e+00L, 2.34043290314497023966214961240421096e+00L, 2.40924882550482707578395780381837657e+00L, 2.48089769542928804270777308901824137e+00L, 2.55552245384400165592583716337259322e+00L, 2.63327412583237088656291310907475315e+00L, 2.71431234228441160768610076838330351e+00L, 2.79880589905706635256578441640292763e+00L, 2.88693335659214188612865513175227518e+00L, 2.97888368319007786718164917079966461e+00L, 3.07485694541305021056656397487876403e+00L, 3.17506504939176568339259231884822943e+00L, 3.27973253713925527986226523992226922e+00L, 3.38909744233483410200034132396842728e+00L, 3.50341221043527586541966899038246748e+00L, 3.62294468840159570502872359754361586e+00L, 3.74797918980246258518386393043115941e+00L, 3.87881764157340380510220562013091253e+00L, 4.01578081927931267029397913978942025e+00L, 4.15920967835153616848634566919310171e+00L, 4.30946678945578836835486232808829311e+00L, 4.46693788689973689723986043138805888e+00L, 4.63203353981649359057533901265089751e+00L, 4.80519095677036072684883899803335247e+00L, 4.98687593543289697160079921623416533e+00L, 5.17758497008053768765855285400689531e+00L, 5.37784753088062976076034128768012631e+00L, 5.58822853027308803485444007033170411e+00L, 5.80933099323364005938466841106588229e+00L, 6.04179894983708948784718604678234941e+00L, 6.28632057034228591922334730387683243e+00L, 6.54363156501365266125399451934329088e+00L, 6.81451887309858260791767579514605499e+00L, 7.09982466781971868191373433617700078e+00L, 7.40045070694293100845796745008949286e+00L, 7.71736306147578881407568826714170705e+00L, 8.05159725837127958401987584151171259e+00L, 8.40426387679538395058384455428283593e+00L, 8.77655464160750010892022612040926275e+00L, 9.16974906224756520705691589269677116e+00L, 9.58522167027699388874228356777329920e+00L, 1.00244499144430070386099274885141050e+01L, 1.04890227783960385614814296197680936e+01L, 1.09806501931649260624015170997236345e+01L, 1.15011733242716998455210622743445835e+01L, 1.20525758220454727952816341992419823e+01L, 1.26369961333845432419384699684768677e+01L, 1.32567409840433238017603739136360460e+01L, 1.39143001526287336814820956823084828e+01L, 1.46123626710408671221171338391349055e+01L, 1.53538346012683753120053442509520620e+01L, 1.61418585554581184591279187098492208e+01L, 1.69798351452575852400510409025135738e+01L, 1.78714465678460133882677098961576727e+01L, 1.88206825601317848442892749807248071e+01L, 1.98318689796476498521560439791262319e+01L, 2.09096993011184544989073368255312499e+01L, 2.20592693519609552724995680207860407e+01L, 2.32861156486188168325833440616926330e+01L, 2.45962577392286013760094208279475314e+01L, 2.59962450073299827601794849672397508e+01L, 2.74932084469488923833030086627802945e+01L, 2.90949179822819598429999086944366938e+01L, 3.08098459764107671506384842333391345e+01L, 3.26472376541418040006352140116179211e+01L, 3.46171892555432186128355184008936311e+01L, 3.67307348405744306653537849794079228e+01L, 3.89999427831545697992227880433189487e+01L, 4.14380231271361842696931290595974334e+01L, 4.40594471293014233018696008435982161e+01L, 4.68800804884035743932352319123055757e+01L, 4.99173319575866229822636583993237381e+01L, 5.31903192638729836914160122380617184e+01L, 5.67200545170346581087003708738282234e+01L, 6.05296515859483113978235132985845589e+01L, 6.46445582591583649124780712968047055e+01L, 6.90928163944313177415529394071665670e+01L, 7.39053537072521168719419511314839173e+01L, 7.91163113594234348927381617490387462e+01L, 8.47634120965947230809397578710282148e+01L, 9.08883743598215272174601093484125344e+01L, 9.75373785753325382322893051705294986e+01L, 1.04761592725164736089639534479074532e+02L, 1.12617765338655419662606911403899284e+02L, 1.21168895243741881709481972315918511e+02L, 1.30484988804359382802013970413388238e+02L, 1.40643916977370870089294791135734370e+02L, 1.51732386386376598946153144686407135e+02L, 1.63847040773982427929709267988083986e+02L, 1.77095711710003361983546853982729852e+02L, 1.91598840361277588527216638598210664e+02L, 2.07491095540949726522855395012839290e+02L, 2.24923217236106119394568010864647153e+02L, 2.44064119463086993590008673999888577e+02L, 2.65103291739026696423162894476095053e+02L, 2.88253544828036421249450783362468048e+02L, 3.13754153889742451327114437895012151e+02L, 3.41874460927761232190324931320648150e+02L, 3.72918008746121432097478949634992228e+02L, 4.07227290759381879033987273956073881e+02L, 4.45189215310338987815842929936219157e+02L, 4.87241400038863092710563840938907565e+02L, 5.33879431809824993154116113611340152e+02L, 5.85665251340011311718653543776253641e+02L, 6.43236849676682281579530292235801252e+02L, 7.07319496933657861116096423723089184e+02L, 7.78738763222127723625961426334336958e+02L, 8.58435638777040682657342340030579928e+02L, 9.47484116394459954294416631122613257e+02L, 1.04711166630196929712820316594777632e+03L, 1.15872311371927743485840786701904690e+03L, 1.28392852534970775486315470390457819e+03L, 1.42457582618936343671625036189352836e+03L, 1.58278900639377570598543689683858411e+03L, 1.76101294444545923486104598108258215e+03L, 1.96206607357312178755673700966218336e+03L, 2.18920236070835422209657734442941355e+03L, 2.44618436034955965177471357752869960e+03L, 2.73736946076118709316717034422700237e+03L, 3.06781187080876763823587584403262657e+03L, 3.44338341950996275353420062305895100e+03L, 3.87091687821820770548262640961099474e+03L, 4.35837629346446550811483742251576785e+03L, 4.91505976942026055884439891778599977e+03L, 5.55184130321696740425893724460092414e+03L, 6.28145970445342612877221303833900020e+03L, 7.11886438520566571043900024525721790e+03L, 8.08162996762779959609851789890726579e+03L, 9.19045432173859727983153055486718404e+03L, 1.04697579405183570171054706781681133e+04L, 1.19484066394624731955974446656465043e+04L, 1.36605846306210479280006137726608390e+04L, 1.56468513163780927299848865296760921e+04L, 1.79554229917996753910020302361418910e+04L, 2.06437304374408251386790990436920728e+04L, 2.37803156373267080705808819875316658e+04L, 2.74471462199565095258711815725505419e+04L, 3.17424455248072273922403695999752070e+04L, 3.67841605073133622632674187774059283e+04L, 4.27142203777350805091608476572382608e+04L, 4.97037776810032398127125994364568099e+04L, 5.79596727313857616360132420453444344e+04L, 6.77324248460879259253530791773167141e+04L, 7.93261334694994276050922426242412735e+04L, 9.31107739715691545023768199956003639e+04L, 1.09537503053637222429417759669716212e+05L, 1.29157755673566952599086463851912376e+05L, 1.52647130160874158565239969760504587e+05L, 1.80835335096964828910095096138515211e+05L, 2.14743829477016418053483721316277484e+05L, 2.55633251557399994754680946686048161e+05L, 3.05063334556209750218324509503461449e+05L, 3.64968792666585395419705030588899790e+05L, 4.37755686685748537981529230100717254e+05L, 5.26424122294320873553623779329790816e+05L, 6.34724899010831940960718793968560727e+05L, 7.67360052654242646579956157559309383e+05L, 9.30240305033750278572545038832724621e+05L, 1.13081650266645184495081585123306969e+06L, 1.37850753115552374245055838415718322e+06L, 1.68525439396416227539607702063253047e+06L, 2.06623977016863939032179814240740936e+06L, 2.54082527022935491763036651163297626e+06L, 3.13377596203641663047341272710642846e+06L, 3.87686514827580239293595658539782774e+06L, 4.81098405401834942973721071475737211e+06L, 5.98892408953467866424875864774796159e+06L, 7.47905792960806092396497010475870265e+06L, 9.37022569869340886743682668142431718e+06L, 1.17782423097751066120254539266241595e+07L, 1.48545930143258061872721569284540776e+07L, 1.87980927038339810411221199415802492e+07L, 2.38705733443634639976678131975655720e+07L, 3.04180655225860320213756009749555241e+07L, 3.88995004684326215069338023547372206e+07L, 4.99257437458669601662091946924574592e+07L, 6.43128750449561321017861557895848463e+07L, 8.31551851992585813643149605060553440e+07L, 1.07925566470411796107305712037505869e+08L, 1.40614107339003511498586442587195365e+08L, 1.83920178567730560673713663331917338e+08L, 2.41519711690497536458569405379734816e+08L, 3.18438601538111228132801183275722771e+08L, 4.21576501892968673592102667497462836e+08L, 5.60444635691511454953230090792878868e+08L, 7.48209439804691157215633476755723997e+08L, 1.00317512966824615144294234414110893e+09L, 1.35089891899748286951692285814894218e+09L, 1.82722216505349159044967968934424570e+09L, 2.48263348083176093300905605774694855e+09L, 3.38857763723491971892999484076543171e+09L, 4.64662006529910564426883234085294096e+09L, 6.40182180156629712154379147661940269e+09L, 8.86235203805325147258573091932997831e+09L, 1.23283860285919681076337828978766266e+10L, 1.72348929748018002343932808836953853e+10L, 2.42153052846944737603768649152219024e+10L, 3.41967381320806302529104945578396652e+10L, 4.85431236462260654032773006433818623e+10L, 6.92714904376034267631798991329824532e+10L, 9.93804949018620361644641133903513098e+10L, 1.43352142475985414523266188918663249e+11L, 2.07922173448308822669953899424734201e+11L, 3.03269524182010815814751345567548609e+11L, 4.44863150372771043146060595057040363e+11L, 6.56345864647790105139454816812312939e+11L, 9.74063569639891097956397109813490533e+11L, 1.45422052005965615789962842879352220e+12L, 2.18425068889862732017431485970855335e+12L, 3.30099910475756075681442440083420253e+12L, 5.01997048502274901150163921982195024e+12L, 7.68267629901760783371009641842522603e+12L, 1.18337659600398387182686793240868246e+13L, 1.83474885355703531496992152648661997e+13L, 2.86363931245836358559523100954017414e+13L, 4.49980389271503995761664922194406313e+13L, 7.11948687698915449751693845544920647e+13L, 1.13430701798012234619458399048221594e+14L, 1.82006578236361839541514524597276231e+14L, 2.94148450061539403705926461420998342e+14L, 4.78870730589093038221910605812495108e+14L, 7.85402503692862355090784993078672085e+14L, 1.29789430461986025113447366376693514e+15L, 2.16127995478242564041665605678872071e+15L, 3.62710214703500383377916061381597850e+15L, 6.13534293344095037788551479051826967e+15L, 1.04617000636224450596060724147477482e+16L, 1.79847735783966568554234927670508824e+16L, 3.11747341233233147536151972501734499e+16L, 5.44944507304918422218082921598846642e+16L, 9.60751550501797821243248841373822216e+16L, 1.70858922445267785163471612163490444e+17L, 3.06542975111022866531582625971692938e+17L, 5.54922743745114951066953816028814728e+17L, 1.01373023277804631428305560194491190e+18L, 1.86905989587640582429259395332686294e+18L, 3.47854955238157842413369108802590798e+18L, 6.53599224597546376326701108631484361e+18L, 1.24001927226106630812645719537154550e+19L, 2.37582886691093662903464587039857427e+19L, 4.59768243360443262528520790447211677e+19L, 8.98810681683712842794124622629411311e+19L, 1.77530237939363226330723906827319437e+20L, 3.54341330439097348610370779591666976e+20L, 7.14806139767552532748817894789979543e+20L, 1.45762051057718630539520752847120279e+21L, 3.00513712487982979744944726506420716e+21L, 6.26502486163325069730377264873611059e+21L, 1.32097994109028381590144585332181800e+22L, 2.81748753590214622077676014001554368e+22L, 6.07993304142980523101356268020373032e+22L, 1.32765885364721208288263553578233241e+23L, 2.93431175918364131820516218129002628e+23L, 6.56508721680713002578214496043109168e+23L, 1.48721227343793765013154051597710086e+24L, 3.41184019607678812819334291291332010e+24L, 7.92818992879701876208212761012395842e+24L, 1.86645187702970485690987148720542546e+25L, 4.45252185988673954885155645168863932e+25L, 1.07654543517497766241465472692681594e+26L, 2.63868568119069758552386276646714408e+26L, 6.55790847024418649820013325410592483e+26L, 1.65295224373558572055534033842757998e+27L, 4.22638339591491619855432610245411904e+27L, 1.09645039426808014848951068590561771e+28L, 2.88682208299928608019375692651426610e+28L, 7.71548038934401592468282155249032740e+28L, 2.09372878930996484632394470400138705e+29L, 5.77027578944765503685743525710220950e+29L, 1.61546384539178114004658391605197219e+30L, 4.59547005579560869055708560274363012e+30L, 1.32862939268652325541488091880021431e+31L, 3.90507968153078421921910800039715306e+31L, 1.16713402427199725201363486127342874e+32L, 3.54805853865427740256789009746696294e+32L, 1.09737805935804615955239963430188272e+33L, 3.45410297806444559459316674852385198e+33L, 1.10674539370165232283645935543266144e+34L, 3.61089955913906999391756229494586894e+34L, 1.19994699928367056689901878605794596e+35L, 4.06268701419087879160332452792716198e+35L, 1.40183522389322451388311239745912475e+36L, 4.93108552733316217324966630695184171e+36L, 1.76881239328491949973951925349674313e+37L, 6.47214829394519996070845864216337266e+37L, 2.41645372173921192231147151489004683e+38L, 9.20894472039812386191245000342688835e+38L, 3.58329702862212667598998865894252598e+39L, 1.42409748259669944005518449916929857e+40L, 5.78262783342641152433806724533524027e+40L, 2.39986220408436318313990705343752378e+41L, 1.01829157204230545960231903208713235e+42L, 4.41910541482203453093956062976933998e+42L, 1.96212611768049931065065590432043620e+43L, 8.91674242406125370712417447773466783e+43L, 4.14888247829475772044491476179936724e+44L, 1.97725652955827692966670149947470575e+45L, 9.65530023387540108044378286001152781e+45L, 4.83287889833559892166961276593618835e+46L, 2.48057587822309805808523773881299449e+47L, 1.30610280975765470571043683527277027e+48L, 7.05756571728956923233902004974509542e+48L, 3.91527652222961861840270351783060925e+49L, 2.23089898094339331762072829615745302e+50L, 1.30614133449630930559423540813368509e+51L, 7.86102128665639262739828585146248224e+51L, 4.86558375853845110678814792824481696e+52L, 3.09848742591570467373735298285106117e+53L, 2.03103761486256390140847277681645261e+54L, 1.37099964760826020030246335833308722e+55L, 9.53473627432500152782873935909970826e+55L, 6.83495992316641540715754654005899263e+56L, 5.05273354632478901960113633106144814e+57L, 3.85381099728215997914445000026608173e+58L, 3.03418310785320829824308157124864982e+59L, 2.46716192600983889917114272951924381e+60L, 2.07290103981358059329932171745274528e+61L, 1.80056398057961538305615630314631614e+62L, 1.61776402789534425695658193709805813e+63L, 1.50428302825068832904492692640561694e+64L, 1.44839320652542717214779500803249160e+65L, 1.44485551098011579855868939330990133e+66L, 1.49412042885502924277326734308483245e+67L, 1.60256656610701572194891345599497651e+68L, 1.78388050415394298763315503064430164e+69L, 2.06199924057276073839995264039101124e+70L, 2.47652179469857271457600275335452230e+71L, 3.09234991415349735847967247784284417e+72L, 4.01692723830598581004567643058591262e+73L, 5.43160754522649738742682321649737815e+74L, 7.65008682404282275932608294522372170e+75L, 1.12301798411434928750045233045701052e+77L, 1.71938295296605200401018803799684912e+78L, 2.74733571869068667385885336550518795e+79L, 4.58454501055768412308971248876333874e+80L, 7.99508204153925025226317876728470146e+81L, 1.45811990936589904392804782726885652e+83L, 2.78300117867960017490532778932474629e+84L, 5.56281223196619462795860275879049153e+85L, 1.16533876898240457849831832137567995e+87L, 2.56039912643283822420817604614012086e+88L, 5.90454964185909819164533268125527979e+89L, 1.43027847474983870988836419822056214e+91L, 3.64204612295693256305339371887263313e+92L, 9.75669857120640229967783787120452211e+93L, 2.75194604427588305129487979774984195e+95L, 8.17916479364319727936284803066665955e+96L, 2.56370473508682589047202009616066313e+98L, 8.48165649612825587957771293185197099e+99L, 2.96426025440398100674466172613133159e+101L, 1.09534297003120888620652471421812455e+103L, 4.28314854758487062838465336068295133e+104L, 1.77395435294431974409395342323139198e+106L, 7.78899108189422475969140390458031321e+107L, 3.62893172105682135159715800277136586e+109L, 1.79572927251602059220958063790243562e+111L, 9.44668515148283533862523011302496150e+112L, 5.28826317961448810089554134850695191e+114L, 3.15331123674140136231493452577546350e+116L, 2.00480707968382766860514611914082879e+118L, 1.36040719266523771611516008331762962e+120L, 9.86282560980781051743602195410395887e+121L, 7.64755178859112809938428139017982021e+123L, 6.34880222487173008841344329862213996e+125L, 5.64906236198001909791959175488227229e+127L, 5.39324800352378478055022039572371179e+129L, 5.53089719191570391565414448432944942e+131L, 6.09959864464089433289271654904908851e+133L, 7.24209843349196450391058906977712497e+135L, 9.26808305363737556950784175210077690e+137L, 1.27994270241604058214925694813276489e+140L, 1.90979662696062130244831484512150929e+142L, 3.08254030066988503957988563764712878e+144L, 5.38880973238417965706179354197373928e+146L, 1.02161025105662653467101460483765248e+149L, 2.10300544007279065014421211807768152e+151L, 4.70675399034872557015773705065650223e+153L, 1.14683412812524899101968167573148610e+156L, 3.04620262376779901134561159740015427e+158L, 8.83255301555740088857655282843830654e+160L, 2.79951315833790052768515917244690507e+163L, 9.71307000884329724595836237775132776e+165L, 3.69425449543187541186652254254454177e+168L, 1.54248755204034481247092284401752383e+171L, 7.08075007659653083674442572183052884e+173L, 3.57888569536270290704774796012385631e+176L, 1.99473765641034107285413476042860568e+179L, 1.22789700989638770500092926180435793e+182L, 8.36095001442791620159284429240141671e+184L, 6.30749438488829733664127973626729614e+187L, 5.28039699582730274851611343025005913e+190L, 4.91356459266260178144685151251583280e+193L, 5.09061556382806163145943155929283695e+196L, 5.88195913486315120755496558081929324e+199L, 7.59272859182451584412681161192886089e+202L, 1.09687154447604565252927157604063023e+206L, 1.77650105264457177914887205035954057e+209L, 3.23153511879574325299022213712900198e+212L, 6.61424415330008555964088497876375007e+215L, 1.52611134962392865764465743843181152e+219L, 3.97691502072254861067816109956158434e+222L, 1.17271592685350180601663411607927347e+226L, 3.92076851079784438154800269803529292e+229L, 1.48915601904650135853122181753421959e+233L, 6.43831323019893638007682069747894997e+236L, 3.17506717851901774760997889290937204e+240L, 1.78970981603629426034165602936202663e+244L, 1.15551435950001094003467361479483663e+248L, 8.56366431033316582912879348191377839e+251L, 7.30093770528170061921940254565023758e+255L, 7.17613138815551609337504025522760569e+259L, 8.15019404042552378087870259624107791e+263L, 1.07201229194901841245742935320285314e+268L, 1.63677814658507005123653360340510968e+272L, 2.90775562270833690431514296460636317e+276L, 6.02476179304325236422526103127046739e+280L, 1.45944561364291559252990517774206937e+285L, 4.14353248208966528107409825739318649e+289L, 1.38220972739972368321976302536673924e+294L, 5.43125471568796436605394023488404770e+298L, 2.52039989595272682474151246524004609e+303L, 1.38490332203279628724542169932072504e+308L, 9.03453415480179250943103381623811201e+312L, 7.01620311300324094081813342355630834e+317L, 6.50430483422567669743617206850738485e+322L, 7.21793562600493199951776097195343971e+327L, 9.61542788471746566451160668498411528e+332L, 1.54211655565340209996546117001243607e+338L, 2.98626205265198316430063943341329432e+343L, 7.00309320577422492544778192980108604e+348L, 1.99486089518136492496460973366880635e+354L, 6.92350663128275446878446973158773950e+359L, 2.93684755383592258491626945473185368e+365L, 1.52739293250863294426010436780725812e+371L, 9.77075509850276765943058812672579852e+376L, 7.71310608088780517993569363011828070e+382L, 7.53863036472313339350939561575995488e+388L, 9.15331385155864163687518059055937567e+394L, 1.38538605697398143363179835422022577e+401L, 2.62287133256068615930266548676255190e+407L, 6.23343982286571042809890547122705804e+413L, 1.86628588041890755929921756251934723e+420L, 7.06492694188791912037300528166794228e+426L, 3.39406886800977749230458579824930803e+433L, 2.07704891812976483907563047536681219e+440L, 1.62532865525590176989706193358042030e+447L, 1.63262112354994112352218911327913750e+454L, 2.11342684365334123128646755974119857e+461L, 3.53982137873383101244091847412793714e+468L, 7.70246700302666062188915359100825615e+475L, 2.18636422788338230254129077405708124e+483L, 8.12975261672049081897166938196495657e+490L, 3.97686557044826916151646962242652853e+498L, 2.57033035969007091507617008526033295e+506L, 2.20458407348036235529376715504150602e+514L, 2.52051509380683369529400145083533353e+522L, 3.85871376898138292734730034828559871e+530L, 7.94663225793828689108907007781152553e+538L, 2.21176541223395827472447113026924253e+547L, 8.35931033048630497134082029598865726e+555L, 4.31091797212556485985662056018893390e+564L, 3.04833317305882254988404372326531988e+573L, 2.97034828681146526635277450855709161e+582L, 4.00864404566992526097179834506253327e+591L, 7.53113144131492631353410204171028663e+600L, 1.97996763586022811207860344830247407e+610L, 7.32300332662100885299893727481183608e+619L, 3.83078680906847773947984890776183687e+629L, 2.84987258373806149506606754536239806e+639L, 3.03186631046306534459943952897407369e+649L, 4.63861318260680959360747724936035922e+659L, 1.02646622253495677529633262335412306e+670L, 3.30448344760519942319105428211388701e+680L, 1.55678514244926540491694986676104766e+691L, 1.07975219247204914347510266773073325e+702L, 1.10926415409608640204268413223928121e+713L, 1.69843188882084389205231670587156933e+724L, 3.90025209215096037836224226547246383e+735L, 1.35188796159061122898267917047667153e+747L, 7.11881895741722013661309086794573765e+758L, 5.73263787962641176699015570741387791e+770L, 7.10698682909851371094390920546530663e+782L, 1.36568905751347705631533710470350932e+795L, 4.09591384091714486453161283605440034e+807L, 1.93075428208975454032168180693618424e+820L, 1.44069783794868490577087909226154603e+833L, 1.71407451380697883211569548277738601e+846L, 3.27557874564463748685767424892341420e+859L, 1.01295195987435253561137255728975319e+873L, 5.10768437019276174029340754351596177e+886L, 4.23191986113702770379280941046346950e+900L, 5.80664714178397794019307157189161329e+914L, 1.32995815980583547946711112525038194e+929L, 5.12600842672542100652183507817331030e+943L, 3.35203762278831767267193293263751763e+958L, 3.75009417204153826893896307870937057e+973L, 7.23855050824188975713471018223024339e+988L, 2.43146178229439003194650931378387467e+1004L, 1.43376736234835679429446577737976919e+1020L, 1.49738681485939897351147361037410278e+1036L, 2.79474808763788045317059787958854766e+1052L, 9.40752795141195895210630116566470676e+1068L, 5.76455681194134988563523968421696548e+1085L, 6.49098750070655215612470119412325218e+1102L, 1.35603677524062211064037225514112165e+1120L, 5.30731596106421482379267500594247426e+1137L, 3.93020043869734370491941322540535807e+1155L, 5.56226722613029149136813618379760709e+1173L, 1.51990408820680241841102181882025951e+1192L, 8.10228003417607034858018290055212984e+1210L, 8.51521180721994744419289716417963237e+1229L, 1.78329495296502824223674285976432097e+1249L, 7.52325725334531880022021234450122858e+1268L, 6.46447702663797449769360764507187142e+1288L, 1.14411796435953528891736478925455547e+1309L, 4.21851818337788742448241659152628519e+1329L, 3.27808619028067308419286053048979085e+1350L, 5.43188779501763188996015031600338462e+1371L, 1.94236185576822902995555282219996135e+1393L, 1.51711647857248503907031482339088565e+1415L, 2.62035716514505778741231466041668281e+1437L, 1.01340333806343444348385264050569250e+1460L, 8.88786410219005270769408353397020687e+1482L, 1.79062851327433476234422894649930707e+1506L, 8.39642792144232596950658702528918677e+1529L, 9.28628794761707451127390451820966789e+1553L, 2.45536895088636462839367313490581387e+1578L, 1.57354562229875356978426356241845302e+1603L, 2.47847583619098850454983740131691503e+1628L, 9.73157119375940175602769413110414643e+1653L, 9.66320447484532719750186034583884499e+1679L, 2.46232109538721189753853963925622165e+1706L, 1.63417596934387293040006746046570718e+1733L, 2.86767794799456586471233013913198039e+1760L, 1.35110548955493375904544893914917995e+1788L, 1.73592152545700077097814839827674920e+1816L, 6.17893831026015926230407301367680801e+1844L, 6.19169576655007716364858612984691562e+1873L, 1.77539961419331109157892833779912252e+1903L, 1.48102931564535770775910220632570312e+1933L, 3.65523833138677287346435504279580939e+1963L, 2.71500576533505130343548298805675281e+1994L, 6.17538661057993294979124427622665421e+2025L, 4.37773911614056336228335278244614535e+2057L, 9.84696637606677900175890481086698860e+2089L, 7.15679932872021171306956409599896671e+2122L, 1.71206538074954819527676482193571839e+2156L, 1.37358203471630226464631105286036694e+2190L, 3.76701670663930120912543386433302245e+2224L, 3.60043887764831236838085599723119708e+2259L, 1.22311399177140229476034440208616729e+2295L, 1.50662485913882109231872682750679813e+2331L, 6.86720031172136555587682118613084257e+2367L, 1.18233110675109495729851537371527994e+2405L, 7.85186218386652904615339091354671418e+2442L, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -8.8984375000000L; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif +#ifdef BOOST_HAS_FLOAT128 +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 2.239451308457907276646263599248028318747e-2543Q, 4.087883914826209167187520163938786544603e-936Q, 7.764136408896555253208502557716060646316e-345Q, 2.569416154701911093162209102345213640613e-127Q, 2.705458070464053854934121429341356913371e-47Q, 7.491188348021113917760090371440516887521e-18Q, 5.198294603582515693057809058359470253018e-07Q, 0.005389922804577577496651910020276229582764Q, 0.1920600417448513371971708155403009636026Q, 1.140219687292143805081229623729334820659Q, 7.806184141505854070922571674663437423603Q, 497.9910059199034049204308876883447088185Q, 27016042.73379639480428530637021605662451Q, 172966369043668599418.5877957471751383371Q, 1.061675373362961296862509492541522509127e+55Q, 3.811736521949348274993846910907815663725e+149Q, 4.031589783270233530756613072386084762687e+406Q, 1.857591496578858801010210685679553673527e+1105Q, }, + { 6.38192460297577997296130116084380488004e-1543Q, 4.553284218142424152191512347101108073691e-568Q, 1.937062162895195937060002998269756423851e-209Q, 1.660126625033739077374114876720390220712e-77Q, 5.725718222547734673080418904622339594753e-29Q, 4.168381624810496871907721134250128161942e-11Q, 0.0001613301975005046953323705477328478299103Q, 0.0474713399587676291203429066086137662056Q, 0.5099627601758401314316521881645115690603Q, 2.636240582466121690921186199130019570689Q, 39.05613529229837860979125052359555007623Q, 30990.22477506600812220045610450185310364Q, 1857609984963.014390268032888333743476748Q, 2359106700485891760372588191034580.237445Q, 5.305502438164240038024865289303441329929e+90Q, 4.153264547632969989660655052675878016131e+246Q, 2.39549808558050342461418974153843135261e+670Q, 1.907821628968714220362207148967088886146e+1822Q, }, + { 6.057903324174675880054786918700573277193e-1981Q, 8.656190904067090962653034260124195755274e-1202Q, 3.301911576596318022491539142850442018161e-729Q, 1.425485029898429297758878823810205941516e-442Q, 1.016496544573331920304016689793414356743e-268Q, 2.848036810989534605128535426330975462895e-163Q, 2.581928872313165828368701686010678577144e-99Q, 1.601590227152633400640250804848713890905e-60Q, 5.423190544363659530944338243992687682219e-37Q, 1.016381761828840448285257216929561921503e-22Q, 4.635725075794601084424604353869125707077e-14Q, 8.3498615886950739967156481568160331201e-09Q, 1.303868885475613415062833232828648525669e-05Q, 0.001153300807253218344728159062725073079949Q, 0.01814288911244882236930497812936819917973Q, 0.1025656071886267491128524112054469619388Q, 0.3242301173345578897587341005053281543043Q, 0.7688636442387784234265303257286061242944Q, 1.704936145319479582718350104944998619577Q, 4.332223509891009397137256165478273534279Q, 16.00424777396788542203662195209964219854Q, 119.9894477197320344196270723637925628186Q, 3053.206094606356294417950881488718170062Q, 602365.2553559583292243897621777047334194Q, 3550455773.201059364690484967711333425091Q, 5733723619916794.008354021149856937812556Q, 97490164875869638451560588.97182161070984Q, 7.132097466952214251618865223622602893458e+42Q, 4.527309308592487932893086561010303870042e+70Q, 3.115319987396348432317683626917454615693e+116Q, 1.165082263946878699920850154957972424971e+192Q, 4.61868993445541953416660351754288757642e+316Q, 1.235693446874006572643670815583618997533e+522Q, 6.085142451732094001360716852852249745666e+860Q, 1.561268268167538223129534325473369675815e+1419Q, 7.15416720524977809484490807341332912337e+2339Q, }, + { 1.316397640984446973307154953464589633275e-2244Q, 2.91103714441677346374884778987181929964e-1748Q, 1.041515112823364264288004198932170597134e-1361Q, 1.163952866111770553035180609992941917098e-1060Q, 3.331010008037941781256743115855292034324e-826Q, 1.311012824977050544924978303237678019851e-643Q, 2.102714428828884821953890862683078649826e-501Q, 1.181154283940326231672292577754503055478e-390Q, 2.109394497146605580650701202262455040085e-304Q, 3.142026651033038465813811858591067955951e-237Q, 6.481721750272378322539690406725748230209e-185Q, 3.583598691717140876356841025821167196821e-144Q, 1.92664353411734602269656833786034601971e-112Q, 9.922976982058019429687317584840590274898e-88Q, 1.74739966510164583390419990770953521763e-68Q, 1.70290143918426077776224230568679054616e-53Q, 8.030136878691961276301034231071221582072e-42Q, 9.917365028053524354476145352392235487451e-33Q, 1.195101660603996715429218637550950454647e-25Q, 3.914005753291886226833591030642884022779e-20Q, 7.736530260670029404731999770065344717989e-16Q, 1.718208187412490487060798651160186368903e-12Q, 6.957606467986766668781610852908826758303e-10Q, 7.490494532575157167666978009034915042833e-08Q, 2.876694179706214244895454007509365858007e-06Q, 4.95621623915248246930633393189624651192e-05Q, 0.0004580885614011081480136084266758386238991Q, 0.002611973650987327972015238352563580017097Q, 0.01024958074171405301707965287545674192198Q, 0.03016224300141855969532721437631887510999Q, 0.07123470770339354612512733126593011802245Q, 0.1425077997714610113981393440866519718873Q, 0.2522461348260661654197754128666648295859Q, 0.4094768120120717375909393632502588445701Q, 0.6284517616579117758312487536756803604881Q, 0.9367868281384272374009925574604673700344Q, 1.390682216155298525280673341216151282237Q, 2.107722788359705067834932911785748508994Q, 3.347673174455422472577549274497972709551Q, 5.736410541438001909256000925370163885819Q, 10.96982957507422942804757729955529934671Q, 24.38435887010115093181364909323819215825Q, 66.24753699117985966148476651092908482621Q, 234.2315029073004369735419071058951676162Q, 1166.800705234530212373324266823192926477Q, 9058.072807556345123303399558638850050032Q, 124646.6048080201712485538680062639558529Q, 3584819.86746951378682172637961966062923Q, 266100993.7796082691768128807430671558536Q, 66825052601.51570420440082629824643725379Q, 80338167537283.97995953411028754151943899Q, 721934731984192713.8330181471216700501392Q, 85912332322414837303920.66199595232277841Q, 282145179878388664670389842403.4386259681Q, 65637349877520123390370406122266056686.38Q, 3.628585210946194380811829731899355186227e+48Q, 2.255004287064249520310520131039130736102e+62Q, 1.15869387156744556281317453901581151608e+80Q, 6.381237955604791946525597400340497294869e+102Q, 1.010840568769200528470714372039635841864e+132Q, 3.146392870507528140666504475776071670543e+169Q, 4.36361765578710599110918832751720492273e+217Q, 2.853414836089672424680428668400813268807e+279Q, 6.729793209488189821208480033926845423686e+358Q, 5.551856590995612599330193819104783525931e+460Q, 4.052255999971348848790422668447727946207e+591Q, 4.359321017798455720139540978196326313327e+759Q, 2.491143253847753891477290704847758735118e+975Q, 2.715360792058091922045750051250504657e+1252Q, 1.435205921116767351962933143664802808424e+1608Q, 8.210855869756939741458957539090139842153e+2064Q, }, + { 2.5206619423030582050540170122224114428e-2389Q, 1.172863116157072894734245940044946298728e-2108Q, 5.723395259249713010169313313952092349583e-1861Q, 2.197389499531280825740095933047095895838e-1642Q, 1.745161518126606205352284095182052308004e-1449Q, 2.988322581168499697535468502285209728217e-1279Q, 5.082152338298280900263082030896703594299e-1129Q, 1.923568771941791888696041505006148197297e-996Q, 1.922376701708619531115877054556550086857e-879Q, 3.43354234203261313677968607194090162681e-776Q, 4.520976144958693723499608471428644204377e-685Q, 1.16924290517103592239484417171431040132e-604Q, 1.076080723321413327903675953550818303011e-533Q, 4.542643147897936251189382845876349248208e-471Q, 8.39641135188984130629872933142091374729e-416Q, 4.975865312177024229863027999897167556333e-367Q, 5.478993165227465768218836546574553849014e-324Q, 5.284390536217028049162677728277890870188e-286Q, 1.753997013998162369603538709409426038521e-252Q, 6.702720150152123722417807613786063904275e-223Q, 8.560241294360251079054160391146097054699e-197Q, 9.357825403471029128412705980972206582797e-174Q, 2.008012274394970040775210542988145301135e-153Q, 1.759362217490417244193766476411245146585e-135Q, 1.201323068157632801024303577546837842597e-119Q, 1.130871751114348441263036859622267361614e-105Q, 2.427952702329304891356334984001160462099e-93Q, 1.853857010064827708666752242673457462783e-82Q, 7.450531057316733181973526587285947355417e-73Q, 2.227578113196083858417625605575495347595e-64Q, 6.723847629738657283145680261671783557431e-57Q, 2.682661571058473846237236792137934196058e-50Q, 1.79453195451344128721262062986439838442e-44Q, 2.482641507616913094034333751341582768753e-39Q, 8.548433311573474998083868427676274583188e-35Q, 8.62683103876914985130407106643678050193e-31Q, 2.947486044786180737441798148453414409162e-27Q, 3.872329992960205091594692590987101453023e-24Q, 2.188786812967355018227938536553422999502e-21Q, 5.877663279328016310239105745938007253203e-19Q, 8.184245820130904480351031879568469982524e-17Q, 6.383596940050023404498310185052683420494e-15Q, 2.985846320564205038037745987061543784625e-13Q, 8.894313235339439363097219119871323774239e-12Q, 1.779353851443023403734921943727167209889e-10Q, 2.505382916672247087749339155220756062847e-09Q, 2.587725630426792604401006002267344237741e-08Q, 2.033572921227284576438445719455687616491e-07Q, 1.25575991824042977482635039643574244403e-06Q, 6.269440412694030058863353111989674862175e-06Q, 2.595085881599872954251937862499883118425e-05Q, 9.105996179813948353400602282697524464869e-05Q, 0.0002762392802117902551874788776118764135082Q, 0.0007371672770779048357858142458553279273489Q, 0.001757270507480588460625943761648134470357Q, 0.003793199741311863237629531234477439491776Q, 0.007504045999882254423903408991718678739289Q, 0.01375129203357108795095672207425737042887Q, 0.0235648806669815705789256424396565511416Q, 0.03808206546757287312410400667727321525232Q, 0.0584750515250823575509888778022876539008Q, 0.08588741816168257779870858476342798002897Q, 0.1213974127142878083976184138280395303104Q, 0.1660203958235870922656132735987314987822Q, 0.2207560463670208437118557853737734158601Q, 0.2866810915284543028513192158997575835338Q, 0.3650869474810520258950775181589457153731Q, 0.4576643646397673926152716166562185990355Q, 0.5667441269218995998913739139298550489509Q, 0.6956144754295223366640533077595837863928Q, 0.8489536783030172130335775282473784663229Q, 1.033443510885548859219360552937381026851Q, 1.25867327784678000729733451594597097337Q, 1.538517555075041016346761652863952793208Q, 1.89329890876468636135161330299058554312Q, 2.353277301351851558487347974576485001412Q, 2.964435360444065702141420592598446485362Q, 3.798346361008385380944705678431124418709Q, 4.969527598464384372784681410687225436954Q, 6.666989125776029897025551678183749955099Q, 9.213721071361445027221262415929619540222Q, 13.18345690989291972865182826932610004922Q, 19.64024062230142947772459448354624698294Q, 30.65462770756782675694978623368074494086Q, 50.4779893046794926285039124793115175055Q, 88.37993660346673602047366921902538163011Q, 165.9803667059984169730050649489153421943Q, 337.6706631615823036132897955161926139609Q, 752.4698775446966859930160294870547655096Q, 1859.895753721088275783900471462382585879Q, 5171.784242569678351544419777453466412916Q, 16439.68224920392428255829998472244941314Q, 60828.28772762458714202245676717324350873Q, 267403.3214912122110256002506355191499137Q, 1429347.933351015204306617447897972413452Q, 9536926.621626306980484309643305423208196Q, 81822783.86938234780551399066229800198692Q, 933554751.5321686629929819185460517560829Q, 14714528933.55367564194257696642197219325Q, 334526819004.1342316058283621780777931756Q, 11519120972470.51332962127585805147042226Q, 634977429513554.5866778047103885859990833Q, 59661154851781618.71469833139627374808833Q, 10258566668268483666.87233774788273411671Q, 3498782351548458269054.698064372699628001Q, 2593041167054462009490911.107406772475519Q, 4630891728517314272789671037.133056823687Q, 22405725198422081640863565993885.01556046Q, 335382887519057371346768487572597807.0471Q, 1.805229891096869056758012265512553255292e+40Q, 4.143352671969591623813814524116221876304e+45Q, 4.918933828381959415593488120823071981949e+51Q, 3.759479884167637531775066458674648098607e+58Q, 2.370354252414880186596684665159418630029e+66Q, 1.632887662723346042746203904027271808135e+75Q, 1.689790288382573271901196765672215169737e+85Q, 3.768157678554177644154419456918439518135e+96Q, 2.725167569380753976402510741556225451742e+109Q, 1.01581121689650812980198251914622703178e+124Q, 3.298856991576337284158560413886137181497e+140Q, 1.691896320782650875076203269043188495403e+159Q, 2.688862164597444111407738620805399395688e+180Q, 2.842157259124605697187795386218677216391e+204Q, 4.747639199403024362447283672125852826296e+231Q, 3.341705701165246712607275760771067534333e+262Q, 3.011199583815608630823405186037102754549e+297Q, 1.223690427483633883424913552261079866419e+337Q, 9.342435130798085441244782123257085986706e+381Q, 6.75013277944506940788764281864974376778e+432Q, 2.883587060602951466391472557821367572471e+490Q, 5.807295241013203323828534467621397444726e+555Q, 5.796152105409012013566864143195753032862e+629Q, 4.122626017834653186081615813053037582347e+713Q, 4.285202011931086479539142857463076440052e+808Q, 1.99573761404250032069947440682788052405e+916Q, 2.014079397178923658633495910333688587014e+1038Q, 3.570148522918403340320830841666908310066e+1176Q, 1.617637477295168349967593280814302779633e+1333Q, 5.291797544280981679311029646634340608003e+1510Q, 7.48399182023635266336559154483155451479e+1711Q, 6.420118348194716283591292220766712713315e+1939Q, 1.230075220167288536615919838362095973387e+2198Q, }, + { 3.795390672070017300753231208972661157463e-2465Q, 7.779777553755136439657877267977245651568e-2316Q, 1.433306323222013275209083063019716735198e-2175Q, 8.384206893282840565983221028480116073658e-2044Q, 5.095877570390321573443926231967674337647e-1920Q, 9.801617117780997982789217759593347992677e-1804Q, 1.698559621973235103207681863307358445538e-1694Q, 7.086325399079152707198289787557526167382e-1592Q, 1.791883740278245862466944715145415778126e-1495Q, 6.537977048684207893536199493437969077762e-1405Q, 7.774908468832649847178339204899627179575e-1320Q, 6.478864602726321305200912515898143930486e-1240Q, 7.765090574678907306134193726947577898876e-1165Q, 2.630326119433748477458706343770434986992e-1094Q, 4.749906839546177165095241119597567665718e-1028Q, 8.299891364005248930752542816259554461453e-966Q, 2.456886121616923290433040931702106673987e-907Q, 2.084975105306165421720621792298451738582e-852Q, 8.314863021917642918260981455060899893804e-801Q, 2.479012812294721526368945086473772161421e-752Q, 8.54646964556090357402612014431012525116e-707Q, 5.132368733352036821103684616515224808065e-664Q, 7.889147927418897398294379021877366424811e-624Q, 4.456089988888074476694572824088806782629e-586Q, 1.298990194919558378495326736351729403923e-550Q, 2.688838750505892128510794226187763931399e-517Q, 5.333514036446538787793518253409262489744e-486Q, 1.343530053903156890860347423384825206649e-456Q, 5.599542549782115166174708028896712747121e-429Q, 4.950559812998042896188584647263206419909e-403Q, 1.172571121690289764179956681265097018287e-378Q, 9.265119487981539529767577305990761378789e-356Q, 3.000980062420973867973818880845860478641e-334Q, 4.835349309746179020153748142870208251803e-314Q, 4.648418165203187459537829054831654604148e-295Q, 3.162795591358865058002374567318379344286e-277Q, 1.78816495446662412891655575761768850823e-260Q, 9.767303242094807115508406532983731924042e-245Q, 5.938359770701310949887981802571491225734e-230Q, 4.590409820668175251596766385949902266971e-216Q, 5.112083272880275136834520713890140902382e-203Q, 9.223299886181076841150224911038916132471e-191Q, 3.010290465213103549498805131683068042409e-179Q, 1.971306978618734683067074267607013989575e-168Q, 2.854882401768039470681434737764403097782e-158Q, 1.001876004164187257589222479116755961481e-148Q, 9.28388368884304519736248927049010830097e-140Q, 2.462486108028708927260440395734488837617e-131Q, 2.016795400360833462215017065421366863426e-123Q, 5.476652622966367615032292053884484336876e-116Q, 5.272077566455494451788521546425408136695e-109Q, 1.915797835762559722934275003970166064824e-102Q, 2.787748791718769345895186833164681898523e-96Q, 1.717019969783925469381392688568931486586e-90Q, 4.715605767411004441260107716554911215983e-85Q, 6.064460188117978272108174292717305809528e-80Q, 3.823876411447123854401459917711732557741e-75Q, 1.234319419865795919459380852955199024887e-70Q, 2.124134488829505900467360579059303439811e-66Q, 2.024503330684819834315108532844110559563e-62Q, 1.107606713747660145231851458239388162059e-58Q, 3.597409197676984675677984057726546424488e-55Q, 7.159009669672532506246206967901639058717e-52Q, 8.992186046439948861475628942520087991718e-49Q, 7.330545657183168686891287840557389031978e-46Q, 3.981455458584870683744497436520506933176e-43Q, 1.476619713772285254431130454584176200133e-40Q, 3.826978431809928214389355447519902726264e-38Q, 7.083290668359386861447966477541586360608e-36Q, 9.555768999319788426431775086087349112968e-34Q, 9.577913087935460160539269489276067690914e-32Q, 7.262226384946935038838885698096620016918e-30Q, 4.236504491274396853110321383504675317874e-28Q, 1.931901576598121874499773676395841031276e-26Q, 6.990113865391778138743200448969517839792e-25Q, 2.035144735566841718413904303195536680396e-23Q, 4.831023993941522980447473400007455319995e-22Q, 9.466523297160036536447434637997160469953e-21Q, 1.549167405525432140925565313051159250563e-19Q, 2.14045496241922041961398056320914332322e-18Q, 2.52272497168145963445164392470656925743e-17Q, 2.560802965559051560381760195943725944933e-16Q, 2.259216301270926387212069708862804061239e-15Q, 1.747067697308661614911229837784633703426e-14Q, 1.193721953493877730136777069023115375804e-13Q, 7.261048647211436110012409981162064070343e-13Q, 3.959698354015994423003203648219445875559e-12Q, 1.948812140821042423838293141200645234893e-11Q, 8.710185284512708238528405205689273543106e-11Q, 3.556110511389215106439363864587680913673e-10Q, 1.333523995015433973303869945509054883231e-09Q, 4.61686492197482306467363712069697375051e-09Q, 1.482933777652652086397921165904176062922e-08Q, 4.439201256433602926738671445859281174894e-08Q, 1.243818740024104315795359265865889061391e-07Q, 3.275118138216200625243866640518155922026e-07Q, 8.134998048703182572861795938492429107642e-07Q, 1.912901137346598024841188094682606222964e-06Q, 4.272510974451733112955668057488366672288e-06Q, 9.092705525753037851717167450560202933918e-06Q, 1.849285862719977729368018635153610374012e-05Q, 3.604297979179478770170349465262021708134e-05Q, 6.749560699636067367111827124793672270975e-05Q, 0.0001217399530093589052755709255552137501214Q, 0.0002119798092857219716784092724070184838165Q, 0.0003571089874396016314441647628669192562085Q, 0.0005832262433970766235214764926219826111953Q, 0.0009252003173231862125410074191993584583236Q, 0.001428170271956024371431271278148622938591Q, 0.002148851705929752880377989456676968462357Q, 0.00315651924059648003003554910164669437379Q, 0.004533551347666632228987100190172196497749Q, 0.00637545404570481802455455747608672403478Q, 0.008790321915333871574458792947941344568964Q, 0.01189774328782595914086895004343189328045Q, 0.01582720561441695890844807688765959236837Q, 0.0207161013778195777697553686569837390476Q, 0.02670746991923049288761134463020449829739Q, 0.03394763323356885770625642676679074309901Q, 0.04258389292974886627325746268496237602011Q, 0.05276245167659283110092436309489567698917Q, 0.0646267074882549485198639150918873184786Q, 0.07831604604644478869244426161876162156255Q, 0.09396522829516283795223827995446661844768Q, 0.1117044411973961766270728271802225526835Q, 0.1316600519131492902561052263967199098344Q, 0.1539560822924166257732329883435248756687Q, 0.1787164033620456734893640543344657244889Q, 0.2060676396490745147451195395209975563699Q, 0.2361427713798308598187043784963620082981Q, 0.2690854290511355532204052693921342602242Q, 0.305054889564183700169683815016292291199Q, 0.3442318059586820108521538706833283481062Q, 0.3868247338279828413933661340378205138754Q, 0.4330775570906081008567360156110456811268Q, 0.4832779647893183186516132108214191589339Q, 0.5377671905201770169268895537332680002311Q, 0.5969512993956263711392546315972859565671Q, 0.6613143977169219977516694158659088783811Q, 0.7314342528824741733839807656432757716107Q, 0.8080009525815161840183243326671240353006Q, 0.8918394127469408385488364196441967124333Q, 0.9839367763604760603196459906151607884336Q, 1.085476048188192123075453739251218510212Q, 1.197877708796906199452119329245639014272Q, 1.322851579124039222603672663798567463376Q, 1.462461912120810364685968380183335243894Q, 1.619209637172122692401303406940860411898Q, 1.796136969870131896910672473813146944781Q, 1.996961357255571143394600289831227589373Q, 2.226248146939811707460599481581870837544Q, 2.489634721575354120682362651699549592949Q, 2.794123526213803146198014666678951074308Q, 3.148468019138963709501537343168779075746Q, 3.563684960811185116871444598190714785818Q, 4.053739911052914262319668034399529246027Q, 4.636472277732791639643132400229354301411Q, 5.334854715994749316640865062595471476959Q, 6.17872368062665629230474100549748115302Q, 7.207180591667347287378567828702938758294Q, 8.471957573781362650788882585164992019564Q, 10.04218590197794227217933794419470785519Q, 12.01122789383119269588876734679450310228Q, 14.50658104373764159548493669863074310088Q, 17.70441458362279065247583672815995486735Q, 21.85118425006810320690011043664488062523Q, 27.29621402684115092380778363288585647847Q, 34.54152056424679099285119102536330748543Q, 44.31916726839142090610996062523724345462Q, 57.71328886751774892234123495651961475509Q, 76.35584358152632016598443699081343758881Q, 102.7462505675411480105538524612024044409Q, 140.7831585666643225193757393741867278968Q, 196.6667474964623927249971506170398178841Q, 280.4619631485236195196797451233228262752Q, 408.8670610980933975199031744038678580601Q, 610.2321623589824189265508610689128858198Q, 933.8829465748849223717127266358476602503Q, 1467.899351682072654265261818303420805692Q, 2373.963552496782925146643131635919487713Q, 3957.687993737630371024277051314012548134Q, 6815.00440544869246329167423844268111282Q, 12147.029345299389687784126723105779578Q, 22461.26315451801667607728249765542982297Q, 43191.82899503864990448351842350310452323Q, 86592.83261029074596023553700403258785224Q, 181491.2182721628267997397771678482115802Q, 398821.3304282950694957160947337961449181Q, 921693.0297755253718437997165579403685837Q, 2247506.617072129871513449059675893778703Q, 5802766.090658016747854717427934875572966Q, 15922021.31523087692433670991497122820894Q, 46612597.19331592874262340584944675431461Q, 146208710.2792678645398232830462812342502Q, 493569143.2307066662432772490674353132498Q, 1801740337.558116631147349810980444999904Q, 7148307411.399254959232794464956561182284Q, 30989869934.39066958068626939662791860663Q, 147649151381.9059927972205500145326440175Q, 777832651058.2373318671672047663996869845Q, 4560424603708.565710249815401144391564815Q, 29963305946767.56842972520633089879873266Q, 222246149150518.6507762919150981008140173Q, 1875596126838825.642644233007895386015597Q, 18160363350835773.74516009756645868880786Q, 203536650090248516.625043706634545368859Q, 2665597720841305548.302450333304699400882Q, 41204608037903156475.39985932734062136376Q, 759876113857935028362.6764948416534507389Q, 16909538504875626556689.12599202687620857Q, 459597465298806307001750.7749444248692729Q, 15455560145468796199738255.29643411074339Q, 651956726139185886059458642.6456024667082Q, 35004988031596951754619312735.98599420651Q, 2429841273655890598216891207245.641906802Q, 221696165758096369653709633056729.8232721Q, 27060150789216850631109638704372698.78322Q, 4502433645750365138830615513311327089.375Q, 1041810120339429976002448865021784801526.0Q, 3.424464587101762111451481470694312381625e+41Q, 1.635664057519152851238683474567057668695e+44Q, 1.162951256027565131290956161943290374314e+47Q, 1.262811761284799086503405611252635233656e+50Q, 2.15222560299770182282455885090384256002e+53Q, 5.927019921206890317429173453836477496214e+56Q, 2.720358070414621904927945205493061176651e+60Q, 2.150628379545567079384298592862480655326e+64Q, 3.033091903463971517881841788307963107317e+68Q, 7.921368611331628081248063379573761382456e+72Q, 3.986286626077744941375852361406984714748e+77Q, 4.032391864691712851313014198621042119742e+82Q, 8.577090029838120212166000022366079871587e+87Q, 4.024562204594671053503828454684257308668e+93Q, 4.383891452457096911537927453770180399861e+99Q, 1.17045217400342154196646591119629085978e+106Q, 8.115437734907537955622095521768803987323e+112Q, 1.554052969362240408421903236953148739051e+120Q, 8.775471287453444844276638439036590213222e+127Q, 1.566809482709748107234370921913935232618e+136Q, 9.526797160697136847557977555249000344472e+144Q, 2.134941756221901106176576424675977193162e+154Q, 1.918097035157483285449977841564367744648e+164Q, 7.556035740310529929570454851394128435238e+174Q, 1.43568170802240136103830216945338188904e+186Q, 1.456247124841402286711771880936055458401e+198Q, 8.784946928360920634616223064741925447928e+210Q, 3.535985278478868333807046739582226641175e+224Q, 1.073272343888237444965783157773143482544e+239Q, 2.798511671365241100069292950756398438599e+254Q, 7.201139159763991347976972479464073241141e+270Q, 2.119612470693949634980452377127889982788e+288Q, 8.35127608501017199036945672484210550293e+306Q, 5.206581076471599138927368603976642437135e+326Q, 6.137683072504159519093566380150676073848e+347Q, 1.65365713226976909024057251840993190236e+370Q, 1.246014506033140843421606944264692466847e+394Q, 3.254899241867217111629780947123555165675e+419Q, 3.705154796788819306114372374954229956351e+446Q, 2.344512109211865118416887254717997725603e+475Q, 1.068605521510729219385296658425410620874e+506Q, 4.622755758626722510337274875488262765949e+538Q, 2.545829350236663337500678416947756636394e+573Q, 2.439795178088938120765822649335193091201e+610Q, 5.675175497466395228662107439123139188123e+649Q, 4.565969620548043353061100880184463647516e+691Q, 1.852513557834463914074257089792125292744e+736Q, 5.66202849023276763425686777537095814147e+783Q, 1.99854750515263372338536180455239032501e+834Q, 1.28382276856928079108725410000686060447e+888Q, 2.435560683565767075089527065866036912278e+945Q, 2.284607066895124809009946752542339634883e+1006Q, 1.83397327367455896295290053298361055471e+1071Q, 2.259224958362616651797923330046896261405e+1140Q, 7.952136569405401937718403408277221799385e+1213Q, 1.550067830025464501251949158102360769822e+1292Q, 3.384382591693685484610769271259590877811e+1375Q, 1.751941236491613044496278886964352885248e+1464Q, 4.776645267343470319209453110650570993652e+1558Q, 1.604349526201221298891650145582936076751e+1659Q, 1.640044957411376610973353671546593593977e+1766Q, 1.336396861851325699943323623799172110962e+1880Q, 2.41906808317407675203923811685143697444e+2001Q, 2.896081860693974086066933470505539001816e+2130Q, 7.324861191361713354256739989104536795154e+2267Q, 1.347469525914335579372969347338829120074e+2414Q, }, + { 5.892170517318086666953925258259606259061e-2504Q, 6.117305974456569837115715631749111865698e-2427Q, 2.712084481257778798750223761957629870515e-2352Q, 6.073058710711633857519284698655949914024e-2280Q, 8.082266197142077119564887639840911869565e-2210Q, 7.484561995997071530501984781691501485529e-2142Q, 5.619352370681200188347816270904791694455e-2076Q, 3.966702009117964995668129237954360954774e-2012Q, 3.039160829008980709281446092761564330808e-1950Q, 2.904674120638887918188905017568583344857e-1890Q, 3.963146206792477443213856482805096904006e-1832Q, 8.797489265002916895750145490206360737566e-1776Q, 3.606480170760138398954756486565543243608e-1721Q, 3.087106294302307871196417216617493649868e-1668Q, 6.215254538498038663143380180158422424065e-1617Q, 3.303019263067666624863250674838244790295e-1567Q, 5.181698126897362137508517547147366721192e-1519Q, 2.67430990687042667343737270909643193877e-1472Q, 5.04372736336949773835965501524190461252e-1427Q, 3.848661455852432413566576255164564523954e-1383Q, 1.31142543929451988746108502161155545923e-1340Q, 2.19579728467028106786956369019004703621e-1299Q, 1.982058966544355958671442714446925470899e-1259Q, 1.055209826978095633677671490164298051898e-1220Q, 3.614769981710764510469969660128911079744e-1183Q, 8.669620657522813613476248440368886020077e-1147Q, 1.579891518706792342061627603531973101382e-1111Q, 2.368095394608974529044007666148227296087e-1077Q, 3.152777809486329357349922837512146182733e-1044Q, 4.016616422152767475043768845311040445394e-1012Q, 5.26326734348874427867160923756135577274e-981Q, 7.607975954101774669220742789343028025992e-951Q, 1.29824601484856651321515822364389494584e-921Q, 2.792983144744856624041340061025572588357e-893Q, 8.073725811606752551798005890821023071973e-866Q, 3.335750915317738167215040711158938700374e-839Q, 2.091325277547992586470359739628205949321e-813Q, 2.108397879487823636845683679666452461287e-788Q, 3.615813848673697494437203912271165602689e-764Q, 1.113910390544133206836910834129616648114e-740Q, 6.4986798192866207556531928681508001505e-718Q, 7.557269790334208193064600070845678835738e-696Q, 1.840855696857568526152225936524612005631e-674Q, 9.855455540318692459000160450736088444298e-654Q, 1.215011181806807883503024417928187082906e-633Q, 3.608710810907620387125789818961584561518e-614Q, 2.697801843128551517722534747566806678326e-595Q, 5.296475656590678792057661014274729741598e-577Q, 2.845434351853293221694274145766127034931e-559Q, 4.353222210388104546768744275969919162466e-542Q, 1.971319605306481685459990202413649319882e-525Q, 2.743178579713549537232332748108356050045e-509Q, 1.216377484217057669321200590511760772754e-493Q, 1.780251054144349041585891833770135353931e-478Q, 8.898235527618745551411874254333308519164e-464Q, 1.569971597631697176571270982246834173433e-449Q, 1.009621902698559076723839592135830897456e-435Q, 2.441127896800545725696080663751581711874e-422Q, 2.286956623983843351692168480046548829067e-409Q, 8.547313231231952263389158526373469384726e-397Q, 1.310945121043115854537489288344750585315e-384Q, 8.480544215952584120219210061556976886891e-373Q, 2.376195750145011407949988906500690280959e-361Q, 2.958966552359701613946778776076028444187e-350Q, 1.678932905454870490485103352086229292909e-339Q, 4.446975873193618582040505313291817509065e-329Q, 5.628775440009246798411151001673301275784e-319Q, 3.482949423243256460469329466445523169403e-309Q, 1.077028836057387184891418032453579279292e-299Q, 1.7002900687661497411099945611064888079e-290Q, 1.398999859111998929669400205107302068455e-281Q, 6.120943065868598204199619385636695886373e-273Q, 1.451991886477035314124154356864543161856e-264Q, 1.902982255891018605439736483173910116321e-256Q, 1.403323668038955827632944226103034802753e-248Q, 5.926761782297548008111802847112709911628e-241Q, 1.458347909530007582053409207558183402751e-233Q, 2.125725921886845166902485753056081233894e-226Q, 1.865314922085840081035788849150941346294e-219Q, 1.000868211285321086917874293102058243002e-212Q, 3.333910189116025062392204887682742425462e-206Q, 6.996057797661723564465529622684508232394e-200Q, 9.381010137682393061723297183966641053728e-194Q, 8.149422206570198614671737034056664431133e-188Q, 4.648204050438648295729958742208519419602e-182Q, 1.763382028599735618950597430260750127679e-176Q, 4.505668549509372875334714365466121837689e-171Q, 7.848827451015741343516636376339472039698e-166Q, 9.43195366733317557432496852652751112836e-161Q, 7.908807675712522422612568989783146337138e-156Q, 4.678874056808388547490695440890043150363e-151Q, 1.9740277150406416393472265914784118132e-146Q, 6.001555992890612428801571487780317935966e-142Q, 1.328163079397065385327925289264731361735e-137Q, 2.16052535040165176442153814630687031217e-133Q, 2.607958591114470705414120473406600483036e-129Q, 2.357554701561926760029134769773337306267e-125Q, 1.610298469201024515879430894257744042905e-121Q, 8.382612222355548760233942491367020639525e-118Q, 3.353593586452915832569674072223525081046e-114Q, 1.039483344045928327813782782292714015733e-110Q, 2.515998899367231336786588220014789800163e-107Q, 4.791748526296684859820071480335168052638e-104Q, 7.233882041344577328694643371681697761091e-101Q, 8.718610699523506537449879798515202197214e-98Q, 8.447548935303423092983492501963432028328e-95Q, 6.624273312846416599106412803691377974126e-92Q, 4.231522609903937390394156663719438122666e-89Q, 2.215877847430570570445630383685921708396e-86Q, 9.570645508139853996549884935016352405711e-84Q, 3.429704850295633161024952993937464831207e-81Q, 1.025621270026085677651647893549391716655e-78Q, 2.573652733661275222317639633213733692478e-76Q, 5.448651668530820565916001089395037924061e-74Q, 9.783082745893052744363715374110441645141e-72Q, 1.497309317676946956551112800447843381192e-69Q, 1.963044966272704772659454700492703707982e-67Q, 2.215134209071674982471098815066195747706e-65Q, 2.161351710643442010301494126693960145476e-63Q, 1.831678748421095089762102375383001016554e-61Q, 1.354112410172168136765883516840229885915e-59Q, 8.769338472449643538158092836793899993759e-58Q, 4.995220388929997584669700704804630257962e-56Q, 2.512654423616951714204235999520576210629e-54Q, 1.120373918708649945843283688366357025889e-52Q, 4.444839111284013899725922216127704158823e-51Q, 1.574610283663527272755009024582427877567e-49Q, 4.998356543932294904480136169985894236427e-48Q, 1.426543666359685133441221136496707150912e-46Q, 3.672552882913553274555845097712520647132e-45Q, 8.555668106587513479048141229067260955288e-44Q, 1.809164391396441253762162140556144646538e-42Q, 3.482848907447103497527032821217257422686e-41Q, 6.121786687311889688191400930566012176179e-40Q, 9.852003787026362774618836477823750001228e-39Q, 1.455634124991238896963167344925482788243e-37Q, 1.97971820691572088676655895385912176617e-36Q, 2.484763679339334966581765721767085024748e-35Q, 2.885163212704360732431320706076695613523e-34Q, 3.106699707341279253390630094501492545923e-33Q, 3.109422822659254173295015828730415582971e-32Q, 2.89927169617384850488285791262825714268e-31Q, 2.523908691785325135732629051255895540275e-30Q, 2.055662367454969045111364012501147940831e-29Q, 1.569686619252582684425332361542007327513e-28Q, 1.125950740133316431064044128614537744957e-27Q, 7.601631416668137779752584924274136228738e-27Q, 4.839329824239351623300558838123321724376e-26Q, 2.910313243115431255504236289416347158316e-25Q, 1.656270635728607887892216630334576640507e-24Q, 8.935060024907100301565336660347629000551e-24Q, 4.576707115860143299317717947737094283786e-23Q, 2.229416062319399778753562461794880093428e-22Q, 1.034387027477115751926852078057580744105e-21Q, 4.578042956879664176157371046309566421989e-21Q, 1.935585802011138180920578591072504780355e-20Q, 7.82874713340001580345661045705345964109e-20Q, 3.033277065605609148877308443530255995764e-19Q, 1.127317776163823415957278474207966592424e-18Q, 4.023943777604203957468025053851953375997e-18Q, 1.381237707255244482658044701824585586376e-17Q, 4.564771324569693089113904466531252814338e-17Q, 1.454155094221294167906504269767636729648e-16Q, 4.470282536710471999548738623982417075368e-16Q, 1.327602585336672326909513613982506297883e-15Q, 3.813043588615643039554788734257898537102e-15Q, 1.060213952169345190463001465764618351972e-14Q, 2.856716038659232860437047136982049015392e-14Q, 7.466427670055988494705277475545414724545e-14Q, 1.894690957825474964952696780154361710946e-13Q, 4.672384910216859631300636349537565265528e-13Q, 1.12071812756145590573088420248213396768e-12Q, 2.61687402991139925388375152212065210662e-12Q, 5.953297123549162859512430130852786699602e-12Q, 1.320593807517838934275904504842136211828e-11Q, 2.858616138334039461868692599012329142624e-11Q, 6.042892454052515960778598669683992803927e-11Q, 1.248400183635724584150334059943405909833e-10Q, 2.522263563011319493898997487611481739084e-10Q, 4.987157614461502802573237722321997830104e-10Q, 9.656747028650146543937534093622969648656e-10Q, 1.832331394688612391225223960799760892905e-09Q, 3.409135584469323144465616190250392759698e-09Q, 6.223217073156115395989075884572438588064e-09Q, 1.115247649492127150742015804014106309015e-08Q, 1.963183124650189164476211317711594899641e-08Q, 3.396434861673153782630952753806077604247e-08Q, 5.778182457384419293379609496198444309124e-08Q, 9.671416228982645764923638776870390962876e-08Q, 1.593449237146444753348807411708714457653e-07Q, 2.585517662865383112572981730106266058425e-07Q, 4.133550070951521580893927841763124264506e-07Q, 6.514248621964041568573631795492153402393e-07Q, 1.012427229350996242277648936990123957075e-06Q, 1.552418076257223144547466550986390138311e-06Q, 2.34952602641015445771098161766731932897e-06Q, 3.511189688643888344939790080074685439225e-06Q, 5.183238423526162260514143683960468112835e-06Q, 7.561120127800534234406303171206800351833e-06Q, 1.090358470741065211245882025263310466461e-05Q, 1.554912473916646049717055292677270916341e-05Q, 2.193545319541190180132126849766958008055e-05Q, 3.06222602906776706081463783690640463254e-05Q, 4.231743641829304472292855191854823789729e-05Q, 5.790687550406990902565521591693920007089e-05Q, 7.848788357413748318766982611145815627101e-05Q, 0.00010540611257998968044433245343227694598Q, 0.0001402958222219341832876712273516369371858Q, 0.0001851231462878728337021449981301377043921Q, 0.0002422319093235441278154323469294950222567Q, 0.0003143914093490438255880506656627154706713Q, 0.0004048454583005453349179317740247669036001Q, 0.0005173618594864548959363227919828100894997Q, 0.0006562814060075758768591696157433266343571Q, 0.000826565410738786554070676706609189056012Q, 0.001033840731308778310338356140134352910286Q, 0.001284441235784871207845599117337491899893Q, 0.001585444668572432724602460096818027294236Q, 0.001944703922220064726230693092127144593237Q, 0.002370871798930369738140358404690161441277Q, 0.002873418453883568229680512273971543105615Q, 0.003462640848071487344380174768378455826004Q, 0.004149663697254268694341620803700341750894Q, 0.004946431581083455931123013841676887080885Q, 0.005865692066950994853071296376232848181214Q, 0.006920969900914144932733040132020845317402Q, 0.008126532517174807372490261340953247192729Q, 0.009497347312238993901379897831447122259424Q, 0.01104903131457044980845293838495748749764Q, 0.01279779405034133941458833907237333363064Q, 0.01476037455652850932760949389411325141064Q, 0.01695397362067762139688900226735864675142Q, 0.01939618242962242870635025934401096038724Q, 0.0221049088856914002071081720488716917237Q, 0.02509830289776780112805635044533390468242Q, 0.02839468197618069143809622830333154887549Q, 0.0320124584557903256913655927231054414679Q, 0.0359700696425036189719041085926788664321Q, 0.04028591212712788918860989829800630773938Q, 0.04497828143973876450915029065019924359699Q, 0.05006531813074977860516026316034857684728Q, 0.05556496126500436200205406716017085842229Q, 0.06149491020595281000433614073726129327576Q, 0.06787259545181476041214035595974238651884Q, 0.07471515916795304445597861763291341835026Q, 0.08203944594271127811857339386627258498639Q, 0.08986200418066622980078648563566282224339Q, 0.09819909844029617176185091362429719527247Q, 0.1070667329248230597757363001969375241841Q, 0.1164806862474626034039483986386441378342Q, 0.1264565575171798280651520372849367286188Q, 0.1370098237296297712334750378458162735435Q, 0.1481559084012775089077514714455506672378Q, 0.1599102613534637261518838984992924699938Q, 0.1722884495378824340287769605961068745877Q, 0.1853062587958232506234706761849695009517Q, 0.1989798064606889145314525019971032049343Q, 0.2133256647466923920312841051185874306084Q, 0.2283609949161532287902785133781001020772Q, 0.2441036922833063452109012049830089929543Q, 0.2605725421938823788428344541510908353441Q, 0.2777873872168545776842997093342357199644Q, 0.2957693058977194666949060616013919036907Q, 0.314540803551686309784195942257876965052Q, 0.3341260157205896645805580249519520659416Q, 0.3545509250798462409040234122490482411371Q, 0.3758435927622725725468195175697635639615Q, 0.398034405265314932316721128862444377758Q, 0.4211563383288478074934410968315399023713Q, 0.4452452394142342112037530159184743482082Q, 0.4703401306843622192334129067026336438633Q, 0.4964835346819850264796402305352446730944Q, 0.5237218252336346706380944300907573589031Q, 0.5521056064731078009809290745112694671355Q, 0.5816901232873094490876115456900045021105Q, 0.6125357069442992091785758987915348842459Q, 0.6447082601760031328793606429195360515171Q, 0.6782797865647680362323450787747425231422Q, 0.713328969733718924338199106505237313316Q, 0.7499418085773880637774140766639953164695Q, 0.788212315604926068652626105954826754308Q, 0.8282432864192821691838855987970085475654Q, 0.8701471494406427668515580696378217925631Q, 0.9140469062229000024305084421371343630326Q, 0.9600771741334760715452351166072128160259Q, 1.00838534479936281872807209462051762564Q, 1.059132873600894629208311701835194786588Q, 1.112496717660920861077933361693898250256Q, 1.16867094227945066816119751095978153848Q, 1.227868518660106499246607081659705290566Q, 1.290323339132992663775546769881462628908Q, 1.356292479979645252281439522534913259788Q, 1.426058746505517983625962591713495225332Q, 1.499933540298130677282755870691604857096Q, 1.578260094790658487921066515100833894383Q, 1.661417132483943299505861369104724515305Q, 1.749823005659253477628797946998754744417Q, 1.843940392372990799011473838158344835204Q, 1.944281631243440140888093759695373064805Q, 2.051414792356401944565998126314287654597Q, 2.165970597938875077463390429124692046136Q, 2.288650325771052401031013101683478825601Q, 2.420234851224610202981214703922557385267Q, 2.561595011055991143556009719659165225042Q, 2.713703504531639625308909178993926233509Q, 2.877648586197607034469946831006043902893Q, 3.054649850949549132212265433115461142545Q, 3.246076467630962399436086307607401933516Q, 3.453468284179391156036568854332710135444Q, 3.678560307807365503436950354477030229407Q, 3.923311160880828226841460125907452693619Q, 4.189936230801589469617865272423738708942Q, 4.480946374981393187300478594675727821553Q, 4.799193215730075888059881716590645860452Q, 5.147922271834676155907768264245273184096Q, 5.53083543288162221496812953064514469904Q, 5.952164600404323232077176105485527849396Q, 6.416758711130580646140459867054801191736Q, 6.930186840165860423056959159766792880846Q, 7.498860678961496459112702551699237411072Q, 8.130180423734335306085749550103992889195Q, 8.832709032074082300727064239431431565972Q, 9.616380956728658660414523916466345275065Q, 10.49275290755319395568272810318760233957Q, 11.47530600467060827560328905529268264146Q, 12.57981097060251303632608403301195351732Q, 13.82477089961782960432916836171863837498Q, 15.23195981221925849222231128916108185324Q, 16.82707987825682774784083335591634330807Q, 18.64056617116082598920083983139151178565Q, 20.70857549023794489237616151245562272887Q, 23.07420567642830393820713431967151913949Q, 25.78900463811922691101083889080485274776Q, 28.9148449161628874745824798436978904724Q, 32.52626128158058523332927382231420046858Q, 36.71337723086835603588917836258932717836Q, 41.58558355922287803881354300264233692755Q, 47.27618148799234762359952749427981866286Q, 53.94826824081686119518439858327130711346Q, 61.80223017903425916505790434588652768438Q, 71.08532543748765375968161551984797388555Q, 82.10399526567024554009049181822069349031Q, 95.23975602759407986028496155380257658111Q, 110.9698130973400470540296126193574357698Q, 129.8939333056630349651209392273740185622Q, 152.7696559979070753474928332485084782731Q, 180.5586736654304805091404612770078232022Q, 214.4882566244919977674795470939882573586Q, 256.1330547928231665447618178646818628868Q, 307.5246605111580416738693948713410626594Q, 371.2992177645933210815236774130885421247Q, 450.8974935685650228046078237680058220481Q, 550.8377451977232828330837131651153630988Q, 677.0902520413471880139625478638325464736Q, 837.5947742574322093884729471574161023545Q, 1042.980321750999312487850573606895531864Q, 1307.5733034982828412757582490221559987Q, 1650.819716406337706482714876001490076974Q, 2099.30620694485704616911531094921965624Q, 2689.653973155598437822589731884479684238Q, 3472.694809575007863005294222892497677728Q, 4519.545764387058601035451090692543677268Q, 5930.518674537505346737826216472633987045Q, 7848.298777884479316137628839872663776205Q, 10477.60880021856385719693056500458608465Q, 14114.81490684772176680780085987142294843Q, 19192.91511707047090505808670817300989283Q, 26350.55658560455766181799432059631325487Q, 36538.95917947214240512662756429322004361Q, 51189.24577374136230581311094854349469585Q, 72477.04375863379234457839995727856619466Q, 103745.4088649592973810191411342407199099Q, 150188.3023295660326508494811677648122358Q, 219967.7689573534473575008039486504545042Q, 326061.5312826027320414954398576839826327Q, 489355.6392353288320496416362546119688476Q, 743885.9518644993361121112473990653166511Q, 1145836.036325291912608215672199749248507Q, 1789188.875939868458022703843462472987756Q, 2833325.749624631317608641966061077100245Q, 4552379.001085143560456970771255583862215Q, 7424770.417957557824591303777367273905285Q, 12298095.03339192649792224192475818198456Q, 20697452.44203504870297806084701641515662Q, 35411226.8516228589720639754465162495418Q, 61622293.99369810009557886781288436597997Q, 109129592.8013237346517088038973951906807Q, 196787450.7962188394120339001790074555393Q, 361536817.7448103880188348963209149691119Q, 677120423.3172777856818760349805677342992Q, 1293610983.587362779559465518324962563345Q, 2522553846.524246174668941309214199618138Q, 5024113345.110335633272773596127448087986Q, 10227108739.74671955289688604133172938803Q, 21292284646.64136897396446520065098915002Q, 45371028957.31826747857852788334895849181Q, 99024543993.49841576792491248942076110007Q, 221536850748.6098276622557044178585207827Q, 508428097361.1528634995551255940374716653Q, 1197969892671.581974824369525928975612373Q, 2900404573426.685665196180358330599181008Q, 7221752811472.8261452649181134184825247Q, 18509084887192.97335916615093951559742913Q, 48874773784843.78193151762381145841529246Q, 133092599678780.7333556849381274648911595Q, 374125489089124.7353802139430677423910378Q, 1086709109057297.928444101014041776257313Q, 3265082931979987.87258453753276410350238Q, 10158431261326011.13015097449733816116137Q, 32763630132737586.73603276260407811351189Q, 109669789016956903.4218400551929290532534Q, 381438095770944157.1825584777350889364541Q, 1380167765463284502.013487398318939323096Q, 5201827105102251430.265183068342299790134Q, 20448381076785180341.12205914023728031402Q, 83950163624094898393.20723287617699714777Q, 360448148933858058712.8780057010771531487Q, 1620842171484886876913.030704922900840775Q, 7644568543274003707654.86412953245584887Q, 37873673540062878009627.31905351817669446Q, 197411676069663987218840.0240738763140198Q, 1084325020587868871264672.520110031271041Q, 6286658480253412511287686.688273773230383Q, 38538910676114933268850065.09568308686941Q, 250246069563561293270298335.428341967445Q, 1724315963019082925322914110.810919837136Q, 12631846969813248447320347615.40596832151Q, 98573898949291986323285198444.06078824566Q, 821057436212784005347211084495.6470514358Q, 7314771694696635838311419333295.781697573Q, 69850784256841570597712958391316.64699117Q, 716542825316038193448406387231039.7325133Q, 7914087099643693963542803664017844.382529Q, 94333533130664349347695260353580343.22749Q, 1216435546693629689320962786816870882.161Q, 17011958605833866533697726617718628547.07Q, 258690600784654078952220563714511508113.2Q, 4288668870669264476726242241367007368436.0Q, 7.772683277942945071659438262429071791914e+40Q, 1.544382512235139127663329049916790285448e+42Q, 3.373976769284500300734994475431045918708e+43Q, 8.129067158063592169546241812179625219138e+44Q, 2.166707895024819458966336780455558086535e+46Q, 6.409342911265172948192363235629813592865e+47Q, 2.11113881388279400077857147982308514427e+49Q, 7.769489188265480790835175082006376830908e+50Q, 3.206046642709239701586971551086164010033e+52Q, 1.488767022066119144919510543596148902267e+54Q, 7.808922278980110020262281481276188465084e+55Q, 4.644537901374006010236471698605630713765e+57Q, 3.144950967272856447107269590955178110167e+59Q, 2.434406581339142831982748698038217920141e+61Q, 2.163340477883997759822400087483427153e+63Q, 2.21672786608733211115932677066290250184e+65Q, 2.630990323276199330190674194077357004804e+67Q, 3.633887175234243651387984912585415628364e+69Q, 5.868933738481309220339956552275711759159e+71Q, 1.113881935382029622721131804445852357116e+74Q, 2.497102482962287596897815758971572470222e+76Q, 6.647318918269159316328027335371301086625e+78Q, 2.112701640474565422443496783512143837923e+81Q, 8.062227970535759114418981877150220612432e+83Q, 3.715510945470852711992858932101873544354e+86Q, 2.080318971829832954182086119453113044697e+89Q, 1.423879211015686994319095889875168247666e+92Q, 1.198994853251729786241539016492183220468e+95Q, 1.250315031722350913764230284966245816961e+98Q, 1.625650765546514480342676962699164400174e+101Q, 2.653884334781796076676164446838709276364e+104Q, 5.479254529900215518677997546263114530318e+107Q, 1.441395352908079823636049242510235987341e+111Q, 4.86863361476434656481400139271483745093e+114Q, 2.12833312729333131375593175762872072427e+118Q, 1.21404908713874757399814333397205765557e+122Q, 9.113086201114220747023518622031943166454e+125Q, 9.080551093105764581019426693667161701282e+129Q, 1.211941011117902121307375621265384771229e+134Q, 2.186766004105621881376552252876808934254e+138Q, 5.38556910852742084096067183800770753047e+142Q, 1.828345237093990030193445995904159522714e+147Q, 8.643847849099259259500488986422077930261e+151Q, 5.751005573557285468834049974868214789523e+156Q, 5.443504786034121401705823847908344635578e+161Q, 7.412615573089797094999326113074735280293e+166Q, 1.469049957199636824011402378332059557857e+172Q, 4.287925258882100461704570569455556092359e+177Q, 1.86612597273239616433526329447208163512e+183Q, 1.226379273064859017878285487689272510739e+189Q, 1.233049565517510525925233460318642472664e+195Q, 1.922517526428740240240358644220410694808e+201Q, 4.713487477409130845748812106854860817482e+207Q, 1.843473550328897809072120079994782769412e+214Q, 1.167326323244523228495462028700671117392e+221Q, 1.215209473429451036393049722893853863007e+228Q, 2.112842179547585374156273626907120728937e+235Q, 6.236071889607844243851741551378727798154e+242Q, 3.177451055527403166573000715118191400606e+250Q, 2.843789662251339660082577053201078673614e+258Q, 4.551274163789384572783760421480072175954e+266Q, 1.326777353683208009714512167729125836305e+275Q, 7.180580831932836542699287247744355850507e+283Q, 7.357782423625700430160947985743321252389e+292Q, 1.456666945043501567602541946073259416498e+302Q, 5.689564305935835027168129397847037147749e+311Q, 4.479926117516288195408691178143032272192e+321Q, 7.271111854603264703485967993610910737998e+331Q, 2.489090968193354380548052924828358593712e+342Q, 1.840259455673651866750330218300534783335e+353Q, 3.011137976393141155355678072396774678908e+364Q, 1.118272080174129693400170486739725992216e+376Q, 9.674512812796990597042138943041164545638e+387Q, 2.002782451702786557677729337022040139776e+400Q, 1.019975709385264179139063366965306494318e+413Q, 1.314944448797276383473642068489831668351e+426Q, 4.419677641026319174030519840041897734792e+439Q, 3.99254597036251358494799314361445177128e+453Q, 1.000265470725239760396725325941353640132e+468Q, 7.178755898102847579865186247347092072963e+482Q, 1.526021248325894848024962737690774582006e+498Q, 9.945324366407757254373767427512829534744e+513Q, 2.059059865446383839574552066851830041917e+530Q, 1.404900555375285454167524041392893443542e+547Q, 3.28087400282783259859618499821459956325e+564Q, 2.726864333586723754092688809912622716001e+582Q, 8.397859952756530445475213030730928168291e+600Q, 9.989908058973658294250311845442889852856e+619Q, 4.791505060970806776913551234159590878002e+639Q, 9.685481388431718626736865995988280327726e+659Q, 8.636556526427388714908536450441882235051e+680Q, 3.561156350974507459594142999610151752871e+702Q, 7.128248594017258005827215297412602656911e+724Q, 7.282768106798628819284639720336581389678e+747Q, 3.999482831186451968486716727260797908428e+771Q, 1.245346192388408435509525415668547227356e+796Q, 2.323145626677791462828372939022836177037e+821Q, 2.748168511226474189368586386876360779693e+847Q, 2.186023493982995850536763861857306300187e+874Q, 1.242175899551683170518300129644162776195e+902Q, 5.367034878872921573200381477952443794382e+930Q, 1.880509201665102918165168525840432579628e+960Q, 5.71032298577717938785953523302892142655e+990Q, 1.609386767501025736187596845183892280095e+1022Q, 4.518456557906832340328523403801389575925e+1054Q, 1.359377662008135474569503940329073679828e+1088Q, 4.725054714693428263295803139291895421729e+1122Q, 2.050805649400987593085939745846976951509e+1158Q, 1.204198867740810318663452249425780180773e+1195Q, 1.039053471866655386979552860107322907703e+1233Q, 1.434806667444463356971054485869624191903e+1272Q, 3.462506506934504077751858039898243011211e+1312Q, 1.599075147408129408091474499525357970819e+1354Q, 1.552099255551750227826769263306876457274e+1397Q, 3.487589868124137333898596626836045551213e+1441Q, 2.004482475545019114512171871841999807838e+1487Q, 3.266184291106132543681912795564641088147e+1534Q, 1.67783763526057060563518018773882643864e+1583Q, 3.031816590403436442474526312463549597677e+1633Q, 2.157658535793961571985216784676001134821e+1685Q, 6.795640821072482146198361520303941544851e+1738Q, 1.068303525733467960295743735204898069971e+1794Q, 9.49035887175352239368277676528910660383e+1850Q, 5.415177775755778852952005549339515155762e+1909Q, 2.265003149514209136521685690794152242451e+1970Q, 7.958960851406909431550138661401662745318e+2032Q, 2.704333418922120675152324269895601692782e+2097Q, 1.027316567877779588221212575606512955238e+2164Q, 5.067724711353594001952616900450932235233e+2232Q, 3.788567045328638236731381566671647412124e+2303Q, 5.033943905367906070883711379852229702017e+2376Q, 1.401291904868944410529538867922103039787e+2452Q, }, + { 1.371514866891850860580147671247114055774e-2523Q, 1.78059151397248974751721161286837911487e-2484Q, 5.721785888758699069103456365589770844687e-2446Q, 4.65054375815005991582966268522321514424e-2408Q, 9.766439188577561460790237859691768982479e-2371Q, 5.411793370039458455354990385284371780101e-2334Q, 8.077731109845845920201388563994532085669e-2298Q, 3.314457987808662239136747203944447166213e-2262Q, 3.814216774420151193012892981499696410824e-2227Q, 1.25553244197497295620771570706808273245e-2192Q, 1.205334248405440130028736096195044170071e-2158Q, 3.439859219242599171410929107063382097289e-2125Q, 2.973688352410262055813011490243478241374e-2092Q, 7.932557138399171381451724757235015551226e-2060Q, 6.64983139985567616753784650800300435522e-2028Q, 1.783535197590152574181620799985394198187e-1996Q, 1.557756177066760347798671232037746675342e-1965Q, 4.50835586041040533232716428603770260743e-1935Q, 4.398198753548687358528653536680048897554e-1905Q, 1.470927315235637240331266456192550898399e-1875Q, 1.71465008838880964348190523555111145902e-1846Q, 7.081482877179836131442059969229644646902e-1818Q, 1.052988868679756641461550070454780113115e-1789Q, 5.727332034022694687284947570371705183098e-1762Q, 1.15739462236578863659656148034953454216e-1734Q, 8.824245880938427131911655080026958855498e-1708Q, 2.576937902674734058187379364472798379884e-1681Q, 2.925647070385438309955468564014371260538e-1655Q, 1.310366516627749970196906908155253601244e-1629Q, 2.348978983105517007632719018468710632253e-1604Q, 1.709410997728098633816935547350434401855e-1579Q, 5.121118377662292204023170356055225918098e-1555Q, 6.403389635343425663631591782183715749097e-1531Q, 3.387388606361687519127880900479628129084e-1507Q, 7.682845028338649121205296292580122279028e-1484Q, 7.5697800616719066342183600003671550179e-1461Q, 3.282179766587278495544847128493743606877e-1438Q, 6.342874576272782317964383704289390519493e-1416Q, 5.532171052437858139242350241105314679303e-1394Q, 2.204689812211625778588319899320164116602e-1372Q, 4.063642231251649808970064588651411033634e-1351Q, 3.505834447518969518509518528849945942891e-1330Q, 1.432473887091513447150492126342839296652e-1309Q, 2.804358628632567232199952351415702630343e-1289Q, 2.66063964253518984171287821553517135124e-1269Q, 1.237147739109782914114766326315518993064e-1249Q, 2.850636185934696156243405262161503937397e-1230Q, 3.290591833059237434920108388995870213671e-1211Q, 1.923411531080387875303980530941562752132e-1192Q, 5.753315949676429219782768882380932643224e-1174Q, 8.898623641056617385925239335507072432457e-1156Q, 7.189967416446551570306795185549101380576e-1138Q, 3.065508239134858139768522765991406123598e-1120Q, 6.965523591486903308426760175908956871108e-1103Q, 8.517620034923183484809399729544114465539e-1086Q, 5.659365953962467848177766816717617097698e-1069Q, 2.062573530337046406767250567348179248901e-1052Q, 4.161852659707982830572968592800051957069e-1036Q, 4.692241159119044484191107448210417118604e-1020Q, 2.982698522097636407260213300060948041181e-1004Q, 1.078529659466679650148712953327103511679e-988Q, 2.237932571204419329079179415438119299158e-973Q, 2.687779604401946022373571466662866987864e-958Q, 1.884315707424963927641532671833587240912e-943Q, 7.775916115101539973101721787430845628126e-929Q, 1.904389083833778231092894380474362030062e-914Q, 2.790480743212439217722761443513185676356e-900Q, 2.465926648913378827209569812194001932794e-886Q, 1.32453666225889852923448237001268368176e-872Q, 4.357954169067029764588892111614304541975e-859Q, 8.849858929503900331905076375159876230295e-846Q, 1.11756825414017856890835286188725247492e-832Q, 8.840858072027483686200027831373682346404e-820Q, 4.413127527092704801352846086655418413121e-807Q, 1.400007801030484767570446402553494180345e-794Q, 2.842487154347560114907190046795915809722e-782Q, 3.719250938565689181624101685057377159049e-770Q, 3.157618225591420085512645965965929848638e-758Q, 1.75114987148442787873596419431088305131e-746Q, 6.385777873090946474243531008881328150137e-735Q, 1.541181822234902334916632441949848277437e-723Q, 2.477550690731270781011321116596617085026e-712Q, 2.669658787248566306163138309021034924058e-701Q, 1.940202333546917439202686680187380693786e-690Q, 9.568593524722134826709740856677698073001e-680Q, 3.221585461382583247710139618437253490996e-669Q, 7.44872342769648167389430455225675065663e-659Q, 1.189638501771902231424740243250726099567e-648Q, 1.319958393938916343886322409809694440374e-638Q, 1.023222353884721296290441353639395656224e-628Q, 5.572611912350442469781066985285379073621e-619Q, 2.143895457167286509138836925702305298852e-609Q, 5.857935768286961997593913967879706360256e-600Q, 1.1428406852843012490910945546556940254e-590Q, 1.600276538368249091681352691119548348521e-581Q, 1.616611439295194955625093231898724105017e-572Q, 1.184175055644738174748521286561285618321e-563Q, 6.321063094448832167707046445620734055392e-555Q, 2.470922066459568011770971566970048936919e-546Q, 7.107557665424030425852285003920836370767e-538Q, 1.511608590010936014341479674633899001101e-529Q, 2.388081265694744511448096326055442541688e-521Q, 2.815472550702340688172542879041232967279e-513Q, 2.48837919000401445219744804980784920927e-505Q, 1.656093914015468497737181055575250483141e-497Q, 8.336168624615487443627885419612364814439e-490Q, 3.18743641956695605041303086533386108674e-482Q, 9.297395544527448592830333338764436959721e-475Q, 2.07753500427579145364603881525582257654e-467Q, 3.571058202658373821694558210889151485115e-460Q, 4.74103867173240490413388040526375091844e-453Q, 4.881093482481361236762660159636286975458e-446Q, 3.912369974092201956975825460350308122387e-439Q, 2.450910406106052551255344761044302587528e-432Q, 1.204589604960650973911895984080791492458e-425Q, 4.662390512096548320130183079581954524186e-419Q, 1.426410136108239271628869933927485152397e-412Q, 3.462022295520875568887679396389873321599e-406Q, 6.689965361959539507296200940776906225983e-400Q, 1.032906866888844460363965234571578480766e-393Q, 1.278652922107423854922242620018460855558e-387Q, 1.27346175112717053239090655930858052069e-381Q, 1.023823977719212384301250664189673152317e-375Q, 6.666725705084252678150326635220070780096e-370Q, 3.527501141911259771256602680376156110087e-364Q, 1.521550619725659440989624157338581448637e-358Q, 5.367178386399065173689709539892711842253e-353Q, 1.553103594884899144778901074836122484754e-347Q, 3.698136866653946571267914019652083161444e-342Q, 7.267857666274321583558053878456127222792e-337Q, 1.182396378403029271255116700338342272541e-331Q, 1.597075112277586427731638320619803585259e-326Q, 1.79616310417311168251812691532499891895e-321Q, 1.686776580430614870136341368549220295438e-316Q, 1.326400820923694839828868126921386634198e-311Q, 8.757752605603787086889457335226509690784e-307Q, 4.868418990945228081453886254928167861293e-302Q, 2.284646841932174244279967147270918463565e-297Q, 9.074580740097597152261098447164420165217e-293Q, 3.058674426405965026102952238688104005e-288Q, 8.770907787988163743413755834970410859751e-284Q, 2.145105864999992209688483122610527442958e-279Q, 4.485565646931315043637211169200810850942e-275Q, 8.039051377155100634170607610838242458239e-271Q, 1.237798459140634245394855702707316430846e-266Q, 1.641250849228685733321328948635354163602e-262Q, 1.878392643839145475948645114851275314888e-258Q, 1.859837819346807234979384520727903936856e-254Q, 1.596675206199588015266237522224100758227e-250Q, 1.191163300889329440492988307548134854255e-246Q, 7.738998457363138650763594103272910530358e-243Q, 4.388214066152685197969849610034490383905e-239Q, 2.176190276775343886183543527108804962112e-235Q, 9.458323390405043573268776062741642547043e-232Q, 3.610172183979709423096064193965398866308e-228Q, 1.212586127555234921919768098823882915843e-224Q, 3.59111324401453575527963023293455049051e-221Q, 9.395610112642259280459967294233090545081e-218Q, 2.175878640712952864616203692811262231176e-214Q, 4.468683812013515731337379575375451666765e-211Q, 8.153960491495333836272380517373862616232e-208Q, 1.324334834118382614778205714074964422865e-204Q, 1.918010969227594967076007862060402474386e-201Q, 2.481419344431850431832642008478325717022e-198Q, 2.872795934722793405682347917373434018734e-195Q, 2.981349523066067914025266431304396865241e-192Q, 2.778183214184428719494018536521280699548e-189Q, 2.328486353991385450908858723725291527882e-186Q, 1.758186943224971219517752327685010699026e-183Q, 1.197946966638678929592039684664547722208e-180Q, 7.377055951967901897864941596001292223249e-178Q, 4.112278669973440702181315578462285064667e-175Q, 2.078291415365407917218825890865740908413e-172Q, 9.537067910130183878871726206163401272743e-170Q, 3.979767266831748046536551531606993002857e-167Q, 1.51242767258917389289465209587647895879e-164Q, 5.241982224408838742535027808527238690516e-162Q, 1.659359739042905225047790447024360734017e-159Q, 4.804189190171438209477354610578302798335e-157Q, 1.273899629641974768294696288314250406176e-154Q, 3.097972570039967409381197695536388439631e-152Q, 6.918782676203354501696541281574674135727e-150Q, 1.420905061393621836184825537780939096116e-147Q, 2.686880053196812186383269222572644952966e-145Q, 4.684197364933578819900414372355690019325e-143Q, 7.538292842090449394366060991929379034132e-141Q, 1.121244892108977725124030722189671879955e-138Q, 1.543291602455658629065990737883115515276e-136Q, 1.968057200151723062214416934507209947162e-134Q, 2.328003983334060978647728261009904175111e-132Q, 2.557361370195688062969068207425233275233e-130Q, 2.611927488619706964609586759095304201419e-128Q, 2.483026158243640437503808965978985775636e-126Q, 2.199558726962169679083120552270215159747e-124Q, 1.817604357772346797279295638966528051203e-122Q, 1.402622308618408240781121273710706375183e-120Q, 1.011860243749717496597643469830115242708e-118Q, 6.831127536515730097540183118129885433187e-117Q, 4.320191100696367801967874719856844820374e-115Q, 2.562075564358016827111173141097650600476e-113Q, 1.426238694588568870687238604039093177163e-111Q, 7.459848026168321089493030639864685607272e-110Q, 3.669651340262246286048534626216288397075e-108Q, 1.699377066420368081652375575263230646377e-106Q, 7.415347269378738772554757519265950805265e-105Q, 3.051760076915455100351083762051342894307e-103Q, 1.185606536701726646160124184282201673383e-101Q, 4.352012462292932218666289630132342719673e-100Q, 1.510709811312352716016896845640521276349e-98Q, 4.96351624265344783282463142301615005161e-97Q, 1.544847436576855907745798135714872919059e-95Q, 4.558626702124257235752569024006245964769e-94Q, 1.27642008479453751639667439563273882791e-92Q, 3.394045905392319665569519214098169750653e-91Q, 8.577369478664050327841008779377881642778e-90Q, 2.061794113305408627205942105505921160903e-88Q, 4.717678942214176175585291907504765989603e-87Q, 1.028336592244877396499367499530170373412e-85Q, 2.136942248611699065366375204560555442768e-84Q, 4.236649816605452806608538404381400553183e-83Q, 8.019390326869837302318803327925687368548e-82Q, 1.450310328118094376720023212297234378891e-80Q, 2.507773447443639285811131422971779815463e-79Q, 4.148830024850719085252858854502549378537e-78Q, 6.571590494079647834460655487488465170869e-77Q, 9.972769081433910894391809784387965744944e-76Q, 1.450941240511938754819526746862952160298e-74Q, 2.025147121753812973462197585271955311494e-73Q, 2.713410648449319341394062293702880697709e-72Q, 3.492221881468832071574769247806205619972e-71Q, 4.320026314957986074471025977887938831804e-70Q, 5.139678044302121691257432248649865135314e-69Q, 5.88454602498027835646853308660089711635e-68Q, 6.487480038582780094962826210870660500257e-67Q, 6.890958196370926220424217725022443833687e-66Q, 7.056254711010837638169942940084550044742e-65Q, 6.969579804750282059291393905862236832069e-64Q, 6.643844951482205349397989109640847868486e-63Q, 6.115782049052550927522596994851724693213e-62Q, 5.439255920241588910635386169168650069713e-61Q, 4.676421881589679071462973437280331165559e-60Q, 3.888684381216725595659573659632893641487e-59Q, 3.129184103756304830587115921877252345851e-58Q, 2.437923355425183366110025852517458902153e-57Q, 1.839870139530736605717536567889553740685e-56Q, 1.34569546099067802857678564027627409864e-55Q, 9.543548354590505654408042421857208818407e-55Q, 6.565747142552830887480211819288562501447e-54Q, 4.384035908945419864942715257281219621436e-53Q, 2.842372851943162821895168269638503020572e-52Q, 1.790206722551992369372815691219096572315e-51Q, 1.095810962565634873096014895603262248904e-50Q, 6.521845700716095054692872802045308924929e-50Q, 3.775695339986648388305396192552307067105e-49Q, 2.12716464152594887189778742590835609859e-48Q, 1.16671910540040391992253760579220008166e-47Q, 6.23265403559085987542213498720205905273e-47Q, 3.244134896678645746059576473240602899384e-46Q, 1.645958473231714974889173810016645441791e-45Q, 8.143388031734858419182189130653533970639e-45Q, 3.930313582465246907302843363611600709482e-44Q, 1.851194263290435234938417283137103119568e-43Q, 8.512239336793202359069241917584798017519e-43Q, 3.822649348695211790804635671865758360444e-42Q, 1.677154859408228776678271851575940954557e-41Q, 7.191619924152852038442032565761535379094e-41Q, 3.014945807169869323963767145635796967345e-40Q, 1.236185040650714236792933080415503535797e-39Q, 4.958933233628030587234303679158088010029e-39Q, 1.946888752775509918760428023552746596113e-38Q, 7.483195996266222208010017837398543174827e-38Q, 2.816884085832008440862888918858326739866e-37Q, 1.038788790311983532626498647875866074014e-36Q, 3.754052366421776972298304402899627666075e-36Q, 1.329916636449442293929331165948166178563e-35Q, 4.619911398476589889287822018098556733235e-35Q, 1.574200500535886072240446156960489377595e-34Q, 5.263002870105818624051575346548509593314e-34Q, 1.726960099078857779289991292495256114725e-33Q, 5.563295479027593276363106515909903530738e-33Q, 1.759977498646924128925619156060635503779e-32Q, 5.469270261898178500979414281790390666607e-32Q, 1.670010326740456896177958676237975226683e-31Q, 5.011812229140459292937572098984863834087e-31Q, 1.478675283612228924576755629362483876746e-30Q, 4.290105197670639434248708745588052583008e-30Q, 1.224314847204857214288128441827892216884e-29Q, 3.437633138669099008098353177172696586855e-29Q, 9.498972745536045125708605102671240382972e-29Q, 2.583760349139748372190785203361264056883e-28Q, 6.919781634353028415062110558967966606871e-28Q, 1.825162674340331350492593059731827245464e-27Q, 4.742230202003700799981525062649235524325e-27Q, 1.21405061359099326936056130057580569356e-26Q, 3.063118047519658846943846604881668640376e-26Q, 7.618361643983062409286968372813904975471e-26Q, 1.868215421385976931437156399023912819061e-25Q, 4.518090735445957461893059448531246001478e-25Q, 1.077802555101032018001573196795959603137e-24Q, 2.536716415287025987243332057261521203556e-24Q, 5.891743572611456938581645671099702613624e-24Q, 1.350654629696238651479692262614635184919e-23Q, 3.056759774717924539419358796200729285625e-23Q, 6.830955143743892705466065819320427714946e-23Q, 1.507613243104685126205368805198220832115e-22Q, 3.286781089426561469078764502160043788401e-22Q, 7.079565101495153315614280736442313671788e-22Q, 1.506880116178374539920205157221361054724e-21Q, 3.170058264327805606367536705343862141049e-21Q, 6.59251402755243003297452378499013462071e-21Q, 1.35552580917224613064763906748000530126e-20Q, 2.756219881083391006714632017605268608876e-20Q, 5.542995422751507991815595112925511099095e-20Q, 1.102741830357026668509228710940474564193e-19Q, 2.170574924791608623404819767053535761174e-19Q, 4.22784562521684419969566703381613825383e-19Q, 8.150374391610149393088547569573938943941e-19Q, 1.555319761370903112941040411557418768911e-18Q, 2.938421091239191486965897394716220785884e-18Q, 5.49702918186578726899982577419496597386e-18Q, 1.018422840283521980646891608411447224077e-17Q, 1.868872525702349874003525110232409264092e-17Q, 3.397402939502888626915671597580544282826e-17Q, 6.119185785264468750269400946381512507862e-17Q, 1.09214879924426987627392659888533333755e-16Q, 1.931848224257484115187021666194486246113e-16Q, 3.38709738113457021746601978090966428654e-16Q, 5.887153893766801191455922107519234664868e-16Q, 1.0145296263318078248737176573311390616e-15Q, 1.733657986531008282841829763437819666348e-15Q, 2.938043850581996177822909658510042042154e-15Q, 4.938615471781692605915992715954874017254e-15Q, 8.234918562531385917858203857862277957338e-15Q, 1.362306331265371396596294694423173800976e-14Q, 2.236170869424733841320751737542100923557e-14Q, 3.642524554580435163120663045083577493864e-14Q, 5.888694392313571271396174247706099778175e-14Q, 9.449427618501157548166373911244332310801e-14Q, 1.505261978665752624561018591391102066314e-13Q, 2.380609441526787810264512243714771106257e-13Q, 3.738370022433227086384575475381090947548e-13Q, 5.829648161155620359106976280093017981524e-13Q, 9.028496600869498357963548235512457258829e-13Q, 1.388826357069473033794159652839122295033e-12Q, 2.122196240029301709491138513135360364986e-12Q, 3.221611506135842421727691817477971674495e-12Q, 4.859091658706136214244133527025696573555e-12Q, 7.282405996980113883706062207316493538397e-12Q, 1.084614626633106462843146164014369523503e-11Q, 1.605458327457498641880369613222255948306e-11Q, 2.362039805046516326689547929276742382626e-11Q, 3.454465994486121845661011103063064511645e-11Q, 5.022506107218991611053939202358149250568e-11Q, 7.260149275135915690391382052565097178099e-11Q, 1.043506651266876142022178805768372845923e-10Q, 1.491447438205217428990418540357559180095e-10Q, 2.119930450717337762893944880079093620671e-10Q, 2.996908529590102178368349845632326420577e-10Q, 4.214055822301332409818763610781801512466e-10Q, 5.894380163761400407235801747311008727447e-10Q, 8.202054377127916232711329106917380504757e-10Q, 1.135504396304516014422645934598193894471e-09Q, 1.564123926801416152345998562700717501364e-09Q, 2.143895532536103685135640602614991156305e-09Q, 2.924284555594605553671769414519942616402e-09Q, 3.969649003737127932344749476989177485695e-09Q, 5.363316892671581077171752210602991068092e-09Q, 7.212662081948228982393580259053449241656e-09Q, 9.655391838969175725217005148400887863888e-09Q, 1.286729736245160124986798102409646699924e-08Q, 1.707176162884067575027148124091659866518e-08Q, 2.255136756706215921832547171587286426381e-08Q, 2.966200406055540209232028685038397255741e-08Q, 3.88499279165752963245413637224838028982e-08Q, 5.067230696631395898391507929991299499358e-08Q, 6.582184302397294059244050027864020017102e-08Q, 8.515615360415210982691891965235105797731e-08Q, 1.097326780309156415388972256670220023435e-07Q, 1.40849966698634516338474292825860882904e-07Q, 1.800963114520075404035053726417815773279e-07Q, 2.294067798711577907333029492475997054264e-07Q, 2.911298260373502821242208979104064808447e-07Q, 3.681047642935816556705697739214988768386e-07Q, 4.637515095891270700500412168316111896075e-07Q, 5.821741069987161473731830875047390436438e-07Q, 7.282796925275399454511805955028073483488e-07Q, 9.079146457486250991458577609594710846256e-07Q, 1.128019810375338411661718812277807260419e-06Q, 1.396806769576530095637743385965024634296e-06Q, 1.723957266560495308759186180749598884135e-06Q, 2.120847955410992129415865076137962702185e-06Q, 2.600802749963756201636001826403410052969e-06Q, 3.179375107191397469591646715949441120489e-06Q, 3.87466263359623762618892933003290214722e-06Q, 4.707656435964015050950934858654955898129e-06Q, 5.702627649010476273062734021720688061299e-06Q, 6.887553559542152392628913331393954866062e-06Q, 8.294585707464843920777395442479020873788e-06Q, 9.960562276198518660710860857487330693778e-06Q, 1.192756698691180898016628898883173906339e-05Q, 1.424353658086394053028809949739212752112e-05Q, 1.696291881074835378827238882926582147741e-05Q, 2.01473826643461040251220418003491119867e-05Q, 2.386658231149715001671441877242307172678e-05Q, 2.819897599830005539475352694423628206838e-05Q, 3.323270081093726790471346839279300126957e-05Q, 3.906650389646304004580423055599671571497e-05Q, 4.581073036065455323829979901479633510731e-05Q, 5.358836766549172709593068062566350767259e-05Q, 6.253614592338064003449893584965224320815e-05Q, 7.280569303474707324470305244376804359753e-05Q, 8.456474314345314007150181097613624934893e-05Q, 9.79983963944311971961128822060083281438e-05Q, 0.0001133104274741962557808980829717804420132Q, 0.0001307246399020691600023526497292212020485Q, 0.0001504862625229124093013402201618646645292Q, 0.0001728633841361022292487807700747299013219Q, 0.0001981484216856842586799572772305180575132Q, 0.0002266596169386652242612079138639764750973Q, 0.0002587425560977173732352397172201132721704Q, 0.0002947717063367408829161595331713295059784Q, 0.0003351519628181797614281622077674269794528Q, 0.0003803201993549968241927643417622446554493Q, 0.0004307468155228297461815381992767059891142Q, 0.0004869372727138194050273920414562891311034Q, 0.0005494336113573051545188073238892334141672Q, 0.0006188159413179756137819623192609947043238Q, 0.0006957038973226249969676643754938554868505Q, 0.0007807580511653439670770907738372309905166Q, 0.0008746812724001532761340934353267577792467Q, 0.0009782200292515512336811027407457153376092Q, 0.001092165621558351789459012058646682104199Q, 0.001217355337715058924188958933421742595571Q, 0.001354673527787729173843430392365052760195Q, 0.001505052585257047138767616555691474176257Q, 0.001669473830178774238569756010944073496615Q, 0.001848968286948808422945347651594893384821Q, 0.002044617350314201919025518009463240807713Q, 0.002257553333779458717720728149390573426284Q, 0.002488959895115589901221858059759895342055Q, 0.002740072334283588362025959812292414640791Q, 0.00301217775972961953607413014104144464497Q, 0.003306615119691370083379454518010740369845Q, 0.003624775095868402689060121197344456802957Q, 0.003968099857548535542156097701394553950805Q, 0.004338082675041517295499039588623167374938Q, 0.004736267392044797255794242147281512023857Q, 0.005164247757348130579312969849265866446317Q, 0.005623666617068244685007554336227354330017Q, 0.006116214969386021858860229251854316110788Q, 0.006643630884530937776730154149339974333344Q, 0.007207698293515321895878348292456453654359Q, 0.007810245649859081048265134316584789895785Q, 0.008453144469258828274121626639448497149435Q, 0.009138307752839171316702467004395243791217Q, 0.009867688300273872669999644933745875091601Q, 0.01064327691967670787558472076910092093735Q, 0.01146710054173253851741408239999923619768Q, 0.01234122024606522527074289502339224210353Q, 0.01326772920831782112966648361938182825161Q, 0.01424875057684974543947505353952098867137Q, 0.01528643528833354419122626389892565090942Q, 0.01638295983185904916112164488898195461532Q, 0.01754052397142437120423950233168880720244Q, 0.0187613484369107615886167354070274590455Q, 0.02004767259380194441465699051526802405725Q, 0.0214017521020184759779667849902676587795Q, 0.02282585657429483535407508444593379094269Q, 0.02432226724453248297751175594886236631783Q, 0.02589327465651758066521453776794690161073Q, 0.02754117638329931218995431551143369605661Q, 0.02926827478738593898790451312106545224234Q, 0.03107687483173329787258745383633763611989Q, 0.03296928195127705906828026282057099308205Q, 0.03494779999449857988040032623857920380255Q, 0.03701472924421765093424302565538084301254Q, 0.03917236452647701857524610316723537907177Q, 0.04142299341602656982308246993170945227151Q, 0.04376889454653285699001801294927841574839Q, 0.04621233603323564126441668379095446930966Q, 0.04875557401535079589039921987184194521511Q, 0.05140085132508167562704906922303703496827Q, 0.05415039628965234886880735200235133638008Q, 0.05700642167231927160453898977060771401466Q, 0.0599711237578563573226915069629858708525Q, 0.06304668158754517366223858841179395265763Q, 0.06623525634824027829561347043735130048892Q, 0.06953899091962247509330580436971686102996Q, 0.0729600095833028746833811927601826713891Q, 0.0765004178970007835650709418899798676114Q, 0.08016230273659117141990270524388318621874Q, 0.08394773250840516467839177192606243584909Q, 0.08785875753377190721656428075049332888429Q, 0.09189741060741426847468433104579159465809Q, 0.09606570773095614670505424425466367647119Q, 0.1003656490224672211409706019834699207746Q, 0.1047992198026634931898508322163299556015Q, 0.1093683918581001987330424053206431223269Q, 0.1140751248814388848942142458106393021799Q, 0.118921368088643682516754028336251837472Q, 0.1239090620127639775785842545955310252687Q, 0.1290401404737925560843903638541851287801Q, 0.1343165327239504988585911849315540274307Q, 0.1397401657676431414586481908138076263638Q, 0.1453129668552556812547539926611835917781Q, 0.1510368661499127946794457281180654907464Q, 0.1569137995663141144619238369429012314605Q, 0.1629457117807767176524264957760589252385Q, 0.1691345594116669265838074234685207817681Q, 0.1754823143694867020605796895050649984246Q, 0.1819909673759946372926833537044279604056Q, 0.1886625316518879311352366885204737593347Q, 0.1954990467727495928713431543594207025934Q, 0.2025025826931743565802835311741625023285Q, 0.2096752439392272067845965232957417681348Q, 0.2170191739696598929453619381656215678642Q, 0.2245365597066132128474132532044770980417Q, 0.2322296362368660795566899971447466971694Q, 0.2401006916850564012879982901404429833251Q, 0.2481520722606935992655817236397629937298Q, 0.2563861874812082306191368162104739675875Q, 0.2648055155737408114457597739460139210698Q, 0.2734126090588597747267265038277637879757Q, 0.2822101005199178701881044007666032408543Q, 0.2912007085623076464160082864035019623808Q, 0.3003872439674604947757906906819067257233Q, 0.3097726160470507530279833066428086671434Q, 0.3193598392035173757684907470415069603046Q, 0.3291520397037016404193916534806228825185Q, 0.3391524626731213938587717093791470119821Q, 0.3493644793191617507885033680278723282202Q, 0.3597915943922604099274241916243743202498Q, 0.370437453895004534297809334142470200637Q, 0.3813058530499373333547650352661480737284Q, 0.3924007445377981971755919946678712021003Q, 0.4037262470188928140903475071101821304505Q, 0.4152866539513117540688677957021817444604Q, 0.4270864427207903916573703120710338501449Q, 0.4391302840981329322252234037536723604273Q, 0.4514230520413121575982986672983445970989Q, 0.4639698338606081117511470803776773172719Q, 0.4767759407664674418491476565985386456096Q, 0.4898469188211550036177946416809944701631Q, 0.5031885603167355385407471102006047496143Q, 0.516806915603471063813928672429989712329Q, 0.5307083053943548685833492892416658817756Q, 0.544899333573231952763791571381569604648Q, 0.5593869005357851707458483857026244359117Q, 0.5741782170946036051801186516793426995427Q, 0.5892808189816027518756369857764771391118Q, 0.604702581983243549890321938796860532609Q, 0.6204517377463084432584827945463463628564Q, 0.6365368902944475668239615907758418765269Q, 0.6529670332983176740767048675459263366619Q, 0.6697515681449123115252066782831174608566Q, 0.6869003228546366803792541107869900910128Q, 0.7044235718978283242079024020772563155241Q, 0.7223320569657800605984787123162765141079Q, 0.7406370087549004552020459754059890701261Q, 0.7593501698264669376016144620943539451727Q, 0.7784838186085061098494460842596828305091Q, 0.7980507946106951600027541869735333876082Q, 0.8180645249278394856280467667607579883538Q, 0.838539052112468382179355150589367966048Q, 0.8594890635024286468165380673473754166204Q, 0.8809299220950730124913003197007267091987Q, 0.9028776990657666058321606844017813194226Q, 0.9253492080350027908463731668841887468309Q, 0.948362041195465249909046760063799591795Q, 0.9719346074179343990949614066840423597446Q, 0.9960861724630549479302366473419980629626Q, 1.020836901434702880136038002335887532136Q, 1.046207903620063540423272538165924635641Q, 1.07222127987161131376882927117522964634Q, 1.098900172697023686488065817678959243028Q, 1.126268819234731483687699755105102346279Q, 1.154352607305371556205746104983985376446Q, 1.183178134742943008313040704876221217254Q, 1.212773272224054755535396679944804822938Q, 1.243167229829379630892649667118722042897Q, 1.274390627588395280696510178366946433511Q, 1.306475570276800356042211803401477660985Q, 1.339455726755761299090854776902647953055Q, 1.373366414163496207916696260993796460505Q, 1.408244687292775319638246256496434465626Q, 1.444129433512862820237418019195005380596Q, 1.481061473621406240583458987854889421525Q, 1.519083669040977329410710130907067249025Q, 1.558241035806578679235039044308088638575Q, 1.59858086582466888372299852743006758704Q, 1.640152855921361574402265538231040950074Q, 1.683009245237678957954559946017992411702Q, 1.72720496157337210647316008484511209382Q, 1.772797777328169495475491773850651572118Q, 1.819848475740723857449237597299307993606Q, 1.868421028181370689596438549208663232364Q, 1.918582783315502273584026310535185025955Q, 1.970404669020352495193731841217502411354Q, 2.023961408009779237823690539642994612898Q, 2.079331748199772156275287309535810282094Q, 2.136598708932509466936874733788968855942Q, 2.195849844269505061444090956894789562589Q, 2.257177524665462326226386344962066768299Q, 2.320679238444695114506969192065453102806Q, 2.38645791462228535018090911257279622728Q, 2.454622268743510472485802015585977538477Q, 2.525287173558586284686837252134214325026Q, 2.598574056506641565930469422296652514342Q, 2.674611326154408827473590731512070423928Q, 2.75353482992286323949072031864016601102Q, 2.835488345640611439999643200601877219861Q, 2.92062410968804449738926309215771882388Q, 3.009103384743144622541911200865882785674Q, 3.101097070410615431476383817233400114544Q, 3.196786360313181016135882778770461391366Q, 3.296363449550237677932901170344316738063Q, 3.400032296787622239428000634643997693337Q, 3.508009445636508188824397561413278832782Q, 3.620524910413170580217782044901471996699Q, 3.737823131848823954579745937371900624793Q, 3.860164008844675289107469115579416301802Q, 3.987824012947036166619438121661763719179Q, 4.121097392856712044775558016541559733901Q, 4.260297476992532330650222886374288981273Q, 4.405758082908183742986369820036182319601Q, 4.557835043222720229607343330179101614167Q, 4.716907858677493920666662718003679310707Q, 4.883381489986147028731324484181342600844Q, 5.057688301311346413080048955955133931764Q, 5.24029016949517364937262385119050914101Q, 5.431680774604152215414745576056569940993Q, 5.632388088941263530838944426647235216134Q, 5.842977083444493240346088159010481650856Q, 6.064052672355303324054387062420722913264Q, 6.296262919224426838182742506396326825866Q, 6.540302529753004778869174624673669076774Q, 6.796916659674200034444948632350283775015Q, 7.066905068897762712353177820799890200225Q, 7.351126656505704724688125273958015673903Q, 7.650504414944385662659203665642040258745Q, 7.966030845955723910764349890266531446913Q, 8.298773885483222221468214739217431908518Q, 8.64988339003973506101525205018928180163Q, 9.020598242904561456999601751592885677702Q, 9.41225414510834360246219690427427333296Q, 9.826292163557269466732689978189811368073Q, 10.26426811694776371632533698438878780078Q, 10.72786288944826916813779631601409495717Q, 11.21889377261159001879701043038476676713Q, 11.73932694778443388521894681581610807556Q, 12.29129123457708270319215970282226419194Q, 12.87709324594766765515402048038669536198Q, 13.4992341073735758693176219364211695767Q, 14.16042791669191291271234624934713958783Q, 14.86362214279527089719453736582722220018Q, 15.61202018581665142041991318996024972122Q, 16.40910634912836056677912139837144777988Q, 17.25867350487402177091782658858013283139Q, 18.16485377037993024884452690977404455282Q, 19.13215255326167571891757955195233291448Q, 20.16548636905761204079359120396764800875Q, 21.27022488759428859211729062248302615527Q, 22.4522377239586858934126372942580332999Q, 23.71794655800352070106437529670545349828Q, 25.07438324400214828555529944234238427945Q, 26.52925466085620535573933853306193868668Q, 28.09101515483378720655301379661763173245Q, 29.76894754314429800021170138650587944439Q, 31.57325378002474417516854433656227175023Q, 33.51515654008411148311829427781923077265Q, 35.60701314953242130913508492608130123385Q, 37.86244349823339441594775773078079072641Q, 40.29647379850000394194999154115502761761Q, 42.9256983251566106568287701460452580677Q, 45.76846158142580776550763193789732785913Q, 48.84506369347253555255562043759063132523Q, 52.17799225094995370120933304290316705891Q, 55.79218429104484234314704060801385871774Q, 59.71532268038649506093311149177789765018Q, 63.97817179581388359256889501956078693274Q, 68.61495815679731739105182558138869817295Q, 73.66380253749173597579807670896348619996Q, 79.16721110650937730648828736138186887037Q, 85.17263433307891488469075132237625329786Q, 91.73310378961365450775367798895117611798Q, 98.90795860885862893373285703593128717067Q, 106.7636752615840049170921108192673039159Q, 115.3748165593138360964739919439025091047Q, 124.8251184167753335307884813481639551181Q, 135.2087360034668979739408892961618233969Q, 146.6316745601551591194184766080855899878Q, 159.2134344587212366502738176064757447706Q, 173.0889051680280399896165817677088786851Q, 188.4105488051885127906807545886516889139Q, 205.3509210823754434115791536392044147463Q, 224.1055859231269818834237202833297797781Q, 244.8964900834929361072626079301082497614Q, 267.9758760923573609795202757856526348931Q, 293.6308261096512585408835911644003226435Q, 322.1885463616083343430004234487963961674Q, 354.0225222209357737235698701666059446378Q, 389.5596984536108548077096261370629689439Q, 429.2888685030152394865736640219954342317Q, 473.7704919649917121515120988699951309401Q, 523.6482018956150921567202779251009371071Q, 579.6623148461239013729943303289916476255Q, 642.6657184518196254250998988603877103213Q, 713.6425863708155629919908359659403656033Q, 793.7304612802721925539978576829847118829Q, 884.2463570816121896178880212311454053258Q, 986.7176658841189012219850761458912237512Q, 1102.918819235722927744600414498283892661Q, 1234.91485329233271555981062082910716546Q, 1385.113272678479813634206124518231808971Q, 1556.325908312681685889992739657400589827Q, 1751.842833722475850243498798265810061319Q, 1975.520858975176784025953476571497190453Q, 2231.889682153460941507453429511802304092Q, 2526.279471529220797933682942282042851813Q, 2864.974510271917778566334688829570063707Q, 3255.398601385836981477327248620625297302Q, 3706.339256395488116333757365893728426179Q, 4228.219344042120788684028024525844687474Q, 4833.426940017626186335966263047791170787Q, 5536.716703957542012803288988529189752554Q, 6355.699353968381047550987173727520146629Q, 7311.439889033664714224839534528824153203Q, 8429.190352986375103659917942017957926758Q, 9739.289432574560082947218291110012238598Q, 11278.26941314174344865137745573539892162Q, 13090.22146527840192121556643882459793329Q, 15228.48353487758171912583592356379328602Q, 17757.7320759574131111084450686688920391Q, 20756.58056610832124979302179467528465881Q, 24320.81556946305416172004101150345528677Q, 28567.43688194010189078069185484468040728Q, 33639.71439652637892339557022075773032754Q, 39713.53390468433874079018761656799775516Q, 47005.38124868024276685194436174326123161Q, 55782.41454199081637721033867971136148933Q, 66375.20485467430976973616358391303682894Q, 79193.8964938789379080716557565128034655Q, 94748.76170569987926525384687205818258294Q, 113676.4185559940932985204557366937966947Q, 136773.3680937188787119816424376976346549Q, 165039.0188597090674337643015699657079395Q, 199731.0454972745979834726788415446981803Q, 242436.8306898628098527456078336958599012Q, 295165.9433837847718878457262129156537747Q, 360470.216849401713189605803840830130373Q, 441600.1519609350447724924713683024637015Q, 542709.2821490186584727843713857298955628Q, 669122.0692964885772249581763409255402396Q, 827686.2306514269967440238425057279466219Q, 1027237.646882789325395582817310098557766Q, 1279215.895361419046267273339768020024791Q, 1598482.001556073532061028566697317627191Q, 2004408.620417117903795710233263888056879Q, 2522338.537369602352689507222089859240384Q, 3185542.919287081047719844672603141954191Q, 4037860.118619087846479116022793787786343Q, 5137264.677480395599355604531997862929495Q, 6560712.534410318823827123644450645854025Q, 8410743.816776810796186473145045665937148Q, 10824515.55167440362485947269849464346556Q, 13986207.0209941330011779611362296564843Q, 18144124.90810505888082603159947148053492Q, 23634384.14477576245174950890211078768079Q, 30913826.95526480471448531540531281854327Q, 40605974.80378620661399473672299346895625Q, 53565444.57194199699651310605468978876294Q, 70968636.24955794350712584988752690989393Q, 94441963.80814532650216822140959524198571Q, 126243974.7954442094362911310588557317417Q, 169525168.7850776244769108117739517771857Q, 228700356.87037444467813945668623057383Q, 309984784.5945555486083699955906100203021Q, 422169676.419180296016038169604584024776Q, 577749487.0572079949357000884472359600731Q, 794568313.0307992201611056824664049192603Q, 1098236421.762334787107796693264193432183Q, 1525694882.086440344991905250910993556676Q, 2130500495.120059079142618634577471253541Q, 2990701697.368017711932087176125951177033Q, 4220637207.300671772783188221463829109696Q, 5988705306.551971098215414885650107897243Q, 8544269831.256129406510727541315985651644Q, 12258624497.59786938678183477943433708635Q, 17687708717.87495022845789287135040109813Q, 25668668250.58175914698250404635555840049Q, 37469379954.19249045788058580631395531215Q, 55021343701.47808222508026520305320946865Q, 81284573532.27450168954709280528031053888Q, 120822745771.3775527576541346782807310412Q, 180715302267.838335501258406348057915531Q, 272012900590.1587130429230121721901216984Q, 412074536897.799430443190475733419879223Q, 628344476944.1102285263714030386188019936Q, 964495715735.0823164995071629655123849865Q, 1490488802770.178852807340536150510230426Q, 2319151911693.03458420159878138301523182Q, 3633696221434.767157940890063426130568906Q, 5733695051202.934582494404097712673960175Q, 9112456759035.915558166110123534722925733Q, 14588156299469.85634878641183406469644201Q, 23527688830199.31431035896968138608336931Q, 38231623421869.65920594006767147759897662Q, 62601148428700.57299425483735853656627404Q, 103302358246928.8009047174017863251012655Q, 171814437520724.6796302867876243617578789Q, 288061024180302.6161380295256724616742758Q, 486899765795412.4945381221817576577795721Q, 829813516235357.2103923602912762213670883Q, 1426145535118378.951436282855348913815501Q, 2471991716108467.32565238550997265888506Q, 4322035403914148.133894111391643664621752Q, 7623370258751110.720304855446748890981251Q, 13566982446241751.95521593184313390214595Q, 24364538372998839.52259047925399940945603Q, 44160488249011501.98104668800830603643765Q, 80792929771140742.43357941688344049205352Q, 149224697949752140.7521990836163135293382Q, 278292163684832283.4160185479779845769773Q, 524107342845571057.9422283074584384844101Q, 996932213799835680.2597235801377919016134Q, 1915602123000823970.720466166997119896796Q, 3718848909517183870.143410573120269761073Q, 7295341760671302045.79313255542545772809Q, 14463988874285003035.94795686945931464091Q, 28987343448958931323.92810967706919677816Q, 58732754016747867529.00414398132271998153Q, 120331353070098168111.7390056337252147883Q, 249333004651588596284.035650776923709372Q, 522589314039917315810.223473765572860708Q, 1108152490641109934033.695782020580839626Q, 2377806308974776290281.711859341791971914Q, 5163834591017950405285.437821374070986535Q, 11351919331086858683918.1471528319768618Q, 25266839294442588226428.14778445717345898Q, 56951087826914109485973.59712623726588378Q, 130019587954518449740095.3405587711864565Q, 300717519321186724087928.9334487675138871Q, 704759216153309067051260.9313241944492729Q, 1673960445141169113758368.533624129723397Q, 4030544681474698805788178.936542366860127Q, 9839874954742709853120715.064425551442631Q, 24362247286979856257114998.8851952578909Q, 61184747201856950895364042.72498565866937Q, 155906667317075864701083324.9662928828906Q, 403163381047100871402409124.3779546257991Q, 1058261703628742425795196097.781097890238Q, 2820350066022680574530026898.432274605051Q, 7633343819011512595414528317.564843598457Q, 20986212852402084422748799314.66573670249Q, 58622994393166625667380328459.97406430494Q, 166427664782698297064027054016.028778848Q, 480305184367245946020952931414.3791654892Q, 1409469365276921639465057297415.183634189Q, 4206828103520948090625832005794.726896427Q, 12774108355248748130723515474898.16566641Q, 39473069418353402635694598912188.38756518Q, 124161027690416153525104720861908.998726Q, 397653952879188213452568013972672.1030911Q, 1297132481787798328222051462390494.77497Q, 4310699555554472364755479606514636.156607Q, 14598993032148232561844107749486020.15753Q, 50400995750152781199478648570188199.65257Q, 177430297054928348810918273327463082.018Q, 637121612274118077063576067207035125.0567Q, 2334308965896898251996924331341478060.108Q, 8729180311556704261437649253450972488.832Q, 33327870616504618405564608012803778253.06Q, 129957903565849452378953312970336477735.3Q, 517729777059756948461298024741483523105.8Q, 2107926524966039348251307533209594312777.0Q, 8774220406124443178237235835845685677777.0Q, 3.735197486182661954245100743924203262568e+40Q, 1.626762487644328121630687997548095289162e+41Q, 7.250973083083253199813538117009829490246e+41Q, 3.308936766532937115392827811529721364519e+42Q, 1.546541710130421473312439401601868673846e+43Q, 7.40592482120371542929543531360322220966e+43Q, 3.635026031346881800840788950800319505007e+44Q, 1.829426656802615545872238734711353926354e+45Q, 9.444371789843923777637569744583527921544e+45Q, 5.003291237038170466229131882466362255907e+46Q, 2.721071221382007933686249890911655353165e+47Q, 1.519865012090974117520450692809027707605e+48Q, 8.722349830799754316439247817774896336592e+48Q, 5.145299088117885927493542339522712625349e+49Q, 3.121221357870235693712216180124753139813e+50Q, 1.947899213175479452601623772691375555644e+51Q, 1.251210890644544336971252377162948639877e+52Q, 8.275874252588801763359933928249349963411e+52Q, 5.639192260136006716215984701965648621599e+53Q, 3.960436391373705651016231231787112634959e+54Q, 2.868130988088678181245153419409706139055e+55Q, 2.142864200359822342956549874731614126884e+56Q, 1.652506898141577776885280365380983877969e+57Q, 1.316016911424751010713227742852141936317e+58Q, 1.082852293820816389551974850072957597624e+59Q, 9.210644097586007954427562608847664200089e+59Q, 8.103092543855791898793790566984390085005e+60Q, 7.377040625432060608603217790009391493107e+61Q, 6.953737976979336176051071972961556866238e+62Q, 6.790427544984841974058656827100518158411e+63Q, 6.873219181285964966158787851203582418495e+64Q, 7.215276426549123743710202700699375386347e+65Q, 7.860040014854653238667256601459176244687e+66Q, 8.890552747510091206537761704842097735846e+67Q, 1.044773624845274406484242278763368099107e+69Q, 1.276339846429009678960092217254464675556e+70Q, 1.621909127730099101805179595189446592997e+71Q, 2.145222394949960636229309746712382373349e+72Q, 2.955136434459451093496393852873201995357e+73Q, 4.242484540386949293381593892190632931659e+74Q, 6.351598024216824109918004371203177858677e+75Q, 9.92322140177664793970985646435161664601e+76Q, 1.61890271292950503396982867447926469379e+78Q, 2.759835883031589426581500726726160092292e+79Q, 4.919725873480647138764805641435572041821e+80Q, 9.176966237443589394573048534481159624452e+81Q, 1.792537273106479512876232436227020228235e+83Q, 3.669131046186230038886281886697486654081e+84Q, 7.875974781863151481036630208790721389981e+85Q, 1.774257356669981483122646218784038073379e+87Q, 4.197883435791273747898935670006279670148e+88Q, 1.043953267600508611098731312756290706707e+90Q, 2.730922684509572139458179237102505154696e+91Q, 7.520756432311812479890602823961473367093e+92Q, 2.182171967918410224403041849327447242523e+94Q, 6.676499874620453543521727162652420305871e+95Q, 2.15577712365339698532597721844522720139e+97Q, 7.352286858278690688211435664926977400268e+98Q, 2.650811394091442291944564779047695087348e+100Q, 1.011237437351737388842116147030761121751e+102Q, 4.085370846206046405618971495958243394368e+103Q, 1.749468216493498166826699346132752537997e+105Q, 7.948317737498821871893743988852477827924e+106Q, 3.834807905023328863904941873118780424971e+108Q, 1.966628145855798245790683746091198936573e+110Q, 1.073071382517194531106278746912479484857e+112Q, 6.235722205835566650286247548113149395924e+113Q, 3.863024178163167333304337408956273310993e+115Q, 2.553807346093603757684677622217281376351e+117Q, 1.803488116000817634417017746648676518796e+119Q, 1.361928450409064286412411844878753266407e+121Q, 1.100955256966107712671861853615099298181e+123Q, 9.537293602323983258485510982542318832086e+124Q, 8.863266567274260063217354687374780337612e+126Q, 8.846188009560533969578546259096076506511e+128Q, 9.492930504934618253491690898644663173544e+130Q, 1.096533723415061531099016187787740114349e+133Q, 1.364975382571658955656460305314460765583e+135Q, 1.83324407540524757214204989774594748268e+137Q, 2.659671328312756196289158101058876969403e+139Q, 4.173261608816937493963987661707928522151e+141Q, 7.090865759140765750724147023181213198843e+143Q, 1.306301517030177176840321148170710506396e+146Q, 2.612529401702028055207351907664884448583e+148Q, 5.679555052608604602193055928305941291992e+150Q, 1.343920076232017946109889611934747955765e+153Q, 3.465917231693894339164893985895951010068e+155Q, 9.755225071272572958983312664175060577847e+157Q, 3.000742824526763344250019563325005284778e+160Q, 1.010183025811355809743868197177095335303e+163Q, 3.727075264673607112752380094424316792648e+165Q, 1.509245115418270293863342682538256987299e+168Q, 6.717559128302317419502861311585313379321e+170Q, 3.291318624734529160385171919931022097846e+173Q, 1.777836662264190438042312066790334422342e+176Q, 1.060338236589004151924947254106146518332e+179Q, 6.993672005277206691006295921013624374732e+181Q, 5.109315035547664200818831784655767554202e+184Q, 4.141101118954695995671586123417157559749e+187Q, 3.72970841944231900038690832200877504406e+190Q, 3.739049036766599115557194117114820248566e+193Q, 4.179336859308613161688286180307722723544e+196Q, 5.217443685257035669045459028493376857319e+199Q, 7.287327710700167211508944666212719983552e+202Q, 1.140792958868983691957356818511196462798e+206Q, 2.005179807700415852613810846388560032405e+209Q, 3.964605794076837186229454647465847803719e+212Q, 8.833882400656291129175201471618046038197e+215Q, 2.222416827262079161857013529468675017992e+219Q, 6.32487549000714259166529546382487457952e+222Q, 2.040207496855183891566222509116467026066e+226Q, 7.473933116405018227487255858678429348372e+229Q, 3.115635824480421807822417339161885727878e+233Q, 1.480984764640258342704597085687274914994e+237Q, 8.043751353020125109686268526532207882345e+240Q, 5.002449229484107509386335537403342295815e+244Q, 3.56984178603255912889435086930227079813e+248Q, 2.929532238219821490211564778591785188182e+252Q, 2.770679238026050606746236624138254643707e+256Q, 3.026798751595984436030709186683228573466e+260Q, 3.828036992387459381535969017271019185191e+264Q, 5.61778964283159075488466212754593198112e+268Q, 9.588901159209185095148527450244489057512e+272Q, 1.908180733385590686815575451459150865076e+277Q, 4.437792706543634540204526150192117697146e+281Q, 1.209142348425346993959353491937811099331e+286Q, 3.869310908075061490991368493783003476499e+290Q, 1.457926108247910333143812619546225873976e+295Q, 6.484855807244582773591724274648851980582e+299Q, 3.41399505989190389306038993462293155821e+304Q, 2.132926581369322983520027356423327793664e+309Q, 1.585660584493898360074791847406811357495e+314Q, 1.406549923600311781623297490488487143692e+319Q, 1.492858644861812662236576139363443931014e+324Q, 1.901200330136325650182339443918279093102e+329Q, 2.913594428067374876548048333381454532825e+334Q, 5.388753660372153318353497639257238947787e+339Q, 1.206400501839513571365268204575078366491e+345Q, 3.279025639761489754823013616224251826114e+350Q, 1.085362944039382532594119322284810147467e+356Q, 4.388637237003440512107759837586104007354e+361Q, 2.174591860496217544769291320830048605672e+367Q, 1.324675896729186199114724714897773943058e+373Q, 9.952624718323993743049191691571236891758e+378Q, 9.253292674624468877275054471751609753538e+384Q, 1.068175944610869281850017361625425792553e+391Q, 1.536233415754634782761541232392152383885e+397Q, 2.762122556175579381683600950713322858649e+403Q, 6.230559998086773008127784731120178792412e+409Q, 1.769541482165768371365926657095877950287e+416Q, 6.350669236692242487355167861453925877634e+422Q, 2.890704406534452721026792565610887691737e+429Q, 1.675092854792031970707972331086271904052e+436Q, 1.240441432963222229677830128231516291098e+443Q, 1.178400682719307171825255815152530484263e+450Q, 1.441758860787715996316806330169292187636e+457Q, 2.280896618995616398207821385872558406154e+464Q, 4.684783854898512240077048801484626654414e+471Q, 1.254382062452529400606345787473880256453e+479Q, 4.396832097929432333029382171843947213338e+486Q, 2.026103867409562112292321652086245531169e+494Q, 1.232725336259010710705619694645169566278e+502Q, 9.946131815388102167901949874677079252691e+509Q, 1.068946029136854556187731919763529005914e+518Q, 1.537205154906196455751501587209923504936e+526Q, 2.971488523144685380967551694691249695223e+534Q, 7.757209184017428909949567668621317830698e+542Q, 2.747774426890260234248395195407097655093e+551Q, 1.327052327970207303024364376423737858912e+560Q, 8.781052085532532513351576329773639941121e+568Q, 8.000370822300190275739495419036959668159e+577Q, 1.008709656376084238928867250812980114533e+587Q, 1.769035798555775145353374205587591814306e+596Q, 4.337887865267566149881332153701156202295e+605Q, 1.495146308822926755798228719893196247343e+615Q, 7.282512724193076983982833247777530464559e+624Q, 5.040065527191122347567048286402290970361e+634Q, 4.983688801691864935789903752926384680408e+644Q, 7.080529129251182167249954898842537768423e+654Q, 1.453648046373413551924040968198898941338e+665Q, 4.337598065643236527071167033605358927725e+675Q, 1.892313991275571732367620521996379213332e+686Q, 1.21419543901635843212963487739041197346e+697Q, 1.15285330851746771508587852221532721288e+708Q, 1.629782553411954975244284837756441953593e+719Q, 3.452055344385303141542795202545813325143e+730Q, 1.102512410379851438348571427232382982861e+742Q, 5.343866508694911882201645974783260583839e+753Q, 3.956826871594873007934411028424676095123e+765Q, 4.505631958696195386104188270723354358589e+777Q, 7.943741724189032271630373120507187623319e+789Q, 2.183459428673567948307965032840976723479e+802Q, 9.422208350325892638463546770197336134876e+814Q, 6.428840148770315798651380658113045680139e+827Q, 6.985833940158525432315159789439527191548e+840Q, 1.217845786540958113768113810573137032862e+854Q, 3.431528187148182849659646421877006421135e+867Q, 1.574663673077646155008069202772850496061e+881Q, 1.185846444352357252836601236236570671829e+895Q, 1.477057769851258028567499039349533232523e+909Q, 3.067158420904043177984085593633988645838e+923Q, 1.070385336228404234932902688736321198149e+938Q, 6.329361062260066695035899075868249670335e+952Q, 6.394430084983455208900711505672291428547e+967Q, 1.113087578022601582658889275733799715846e+983Q, 3.367156528651748518226447029503966911755e+998Q, 1.785596416013840188999074654317069177638e+1014Q, 1.674666787802858038890787260817621087922e+1030Q, 2.802838925410915198948806997205672228095e+1046Q, 8.447990981775688253045681606083551485684e+1062Q, 4.628258681649599746452829731806526694326e+1079Q, 4.652403352165737018608017815748357654583e+1096Q, 8.663306406163595964182894618845167463798e+1113Q, 3.017539509818074238591225328432214956732e+1131Q, 1.985491468553870196235393755910025018348e+1149Q, 2.492752117595816975254019948962503474621e+1167Q, 6.032605363101356373534719772171116367884e+1185Q, 2.843372909557441218412153608274974657095e+1204Q, 2.637696488690173901807892313463663992925e+1223Q, 4.867530936012666839215995814615900274247e+1242Q, 1.806297364908140811504547249661887475385e+1262Q, 1.362837915337647858769963651184997835872e+1282Q, 2.114105420285786331665845901133892184208e+1302Q, 6.819711630204384971623932887265931684823e+1322Q, 4.627744947987752918797524724541973729474e+1343Q, 6.683790011169256329679542877680372823771e+1364Q, 2.079180492288020730425138467537817647695e+1386Q, 1.410019079371984617158725525463202947604e+1408Q, 2.110334082726406632374960613564821609635e+1430Q, 7.058051491521915345419574349236726710823e+1452Q, 5.34226016580829579370410286869019558134e+1475Q, 9.269528949293586385450920959869061167858e+1498Q, 3.735566704990213502991174185370143251359e+1522Q, 3.543110166674891301675102145543023739261e+1546Q, 8.016707380888655159273391286811616288477e+1570Q, 4.386687461900889475748897922654392224916e+1595Q, 5.88635362961734378190669011184046381302e+1620Q, 1.964535219211330834129077713169656935329e+1646Q, 1.654278142010004007056058777791069121274e+1672Q, 3.566334264149844792966289257255345995689e+1698Q, 1.997696914392470061226774302379611252801e+1725Q, 2.951628334862652832836643008558957759962e+1752Q, 1.168023508080063514319067026006763505616e+1780Q, 1.257294797191357963612588713158077979814e+1808Q, 3.739918694766242006670350085465955624472e+1836Q, 3.123765125844391073468466650907077237401e+1865Q, 7.446408993561740205402068952680263307098e+1894Q, 5.150389021579176147263436232288928749684e+1924Q, 1.051097717221735323089186284217633448457e+1955Q, 6.438075549979749353380206207123056465567e+1985Q, 1.204191338766423126178080201430624216758e+2017Q, 6.999971798174361940960129565044032866623e+2048Q, 1.287400224651680358272160086786311987728e+2081Q, 7.628245018212267544254965199020501367005e+2113Q, 1.483306035186298578810854793693026754937e+2147Q, 9.644046259875525824373227005626744381049e+2180Q, 2.136807992154677198095425726464162609443e+2215Q, 1.644881859879540417424569583091022315341e+2250Q, 4.486258285656428254910735253711445952652e+2285Q, 4.422477869652754055735874573990613824885e+2321Q, 1.607928077696045804457995352614731652546e+2358Q, 2.200965498515380898569903830116828659581e+2395Q, 1.158169679831249142228245049215974628172e+2433Q, }, + }; + m_weights = { + { 1.311124362501499644235686793936615689367e-2539Q, 8.804534216807813314757104329326588296303e-933Q, 6.151866113634416819256167600386076492591e-342Q, 7.489561872273541742689179537030908098807e-125Q, 2.901271904710770582279868424530636078955e-45Q, 2.956328411110696011133881227129821807172e-16Q, 7.566001300199861545999807860317199813659e-06Q, 0.02939829736944376661348111575241831549228Q, 0.4375314491139458627156716229106118956143Q, 1.797291527801965779398851915787147159794Q, 20.19084569885298758559779466541998891553Q, 3190.204004406569421821255762141757969656Q, 464240600.3151569718431815049204268434463Q, 8064746494304895107671.373051861760453278Q, 1.345267603784213433366506701434024787812e+57Q, 1.312864386644320246962258704304378039761e+152Q, 3.774555882479308671780101506364300541449e+409Q, 4.727526321376723657695030280786783264447e+1108Q, }, + { 2.266244194795986437688029480753454536709e-1539Q, 5.948198448973651573057290957613527891511e-565Q, 9.309165866973257982306900988767978877e-207Q, 2.935089536156722196786549328771374738603e-75Q, 3.724520625101352679705795925568729252173e-27Q, 9.984303520500369046645618946072879096604e-10Q, 0.001431356453978288648029393232888019996234Q, 0.1627612496098382979023134567209341094245Q, 0.8715578869575546863808265846496354994425Q, 4.866023145010624995980060168572588092579Q, 155.7337423425961768825532940518427467513Q, 324159.1075527578458688529527151875836096Q, 52559121164917.31725683197728293103939879Q, 181320101439002742278180646071519946.3143Q, 1.108358234190440710092732108743944497577e+93Q, 2.358481112878241907590525258624871004068e+249Q, 3.697706182598331996489023917650042511899e+673Q, 8.005136174837239155367039692394787566174e+1825Q, }, + { 2.762173700981399765618908933145320277069e-1977Q, 2.39391240206587981734693603632697690162e-1198Q, 5.538595991089672359026435602811151013816e-726Q, 1.450273233250857905077679568886962533672e-439Q, 6.272581042589046274956826312460762996165e-266Q, 1.06595762540573348910987779005613885572e-160Q, 5.861309595694473480177550103363514588648e-97Q, 2.205278730651401402935850497892571252242e-58Q, 4.529434469306552018275201007754555774945e-35Q, 5.149496065541224290846694532009922569098e-21Q, 1.42514032948545940458919452929629803818e-12Q, 1.558687650051216471666230916065939291762e-07Q, 0.0001480770730060221114876366833392461280225Q, 0.00800978386203168352857804963031419632516Q, 0.0781267934470234464218464002858630624883Q, 0.2837432722671675969293700817591698892949Q, 0.6266921805102975877365600915734732725014Q, 1.224519291305484855806028685503263380562Q, 2.828371835589717993286260875443918026645Q, 9.308530387014651096841645763883748667386Q, 51.00340931322451024765452196424930212962Q, 604.5686663559257609710666271339665397866Q, 24963.7894862358300483813083168580513256Q, 8072295.599338304211683309182738003369921Q, 78274670038.30925761297829268300403781939Q, 208243829479833121.9614650100740045614524Q, 5835995851993422640885142487.353759023593Q, 7.038358981684021693676871973997393903892e+44Q, 7.365871905585280499359762130717295092668e+72Q, 8.356559316758425271433369887928065115855e+118Q, 5.152598671967255958872374447108140847196e+194Q, 3.367711726599649783722226912309479425978e+319Q, 1.485503800735698079387410309977283298303e+525Q, 1.206093277935111329439185628983764517497e+864Q, 5.101934496467121392771497579825667303128e+1422Q, 3.854461007601356020735662570367145309928e+2343Q, }, + { 6.801466297807648263832928079249921030841e-2241Q, 1.171357838472361572678710519863396121111e-1744Q, 3.263877177177999549213672495546362918233e-1358Q, 2.840730424450322878168790929290006130205e-1057Q, 6.331359514114723653384308531115955576826e-823Q, 1.940682122137038336501816556640832563117e-640Q, 2.424120579853831996718550176595436495523e-498Q, 1.060491186278820392276664616813055045647e-387Q, 1.47497560627560557171208231533307889666e-301Q, 1.711053655951593201729320308363487612571e-234Q, 2.748977044034961560163018702370375057024e-182Q, 1.183661289657511405743956059634031695806e-141Q, 4.956069833269360409024211595600427510944e-110Q, 1.987957235263791766538675534206288734102e-85Q, 2.726390196575204566967127968691492639624e-66Q, 2.069277780420174850386325233097351936186e-51Q, 7.599593796102130947873535802397682362576e-40Q, 7.30986765636526911109545189857700652429e-31Q, 6.860826488850009000152917649714036190099e-24Q, 1.750137476813662935088831237226143585691e-18Q, 2.694698939685357192909812465408615672038e-14Q, 4.662399523365191039306448758212945866003e-11Q, 1.471147096470191077279866117408849945112e-08Q, 1.234588382988672174156726122838549322181e-06Q, 3.698047527501062909973755871812833332555e-05Q, 0.0004974045204857426689718493339751312553248Q, 0.003594744266562108630858602906463214186729Q, 0.01606776382707240397141574634561698324885Q, 0.04963226590082011795403845149528264747534Q, 0.115744254393794946820912074463938084869Q, 0.2189395796674687235327095676147418958643Q, 0.3566541233572264162152813601314252592465Q, 0.526976767182178399604596779203609072881Q, 0.7398541068159815990923143586965891134531Q, 1.029425785377785516113796863012575526595Q, 1.472772244004991739780066538168681045534Q, 2.232105810859563539773192829947722929989Q, 3.664852093836574055260421484415211997792Q, 6.634229039042487667472625010842259069012Q, 13.47608350422833149354320757617644730575Q, 31.42073749047538137686874567762943831435Q, 86.79141791656354041821488779088943576306Q, 296.6528186585230549314029606641812360007Q, 1329.946577806955206827993564277915367892Q, 8441.344633114675813741927901407789834969Q, 83749.32841027025051399559911280792540265Q, 1475556.123428945995692670896358851704835Q, 54395134.46210963278883974741024860672763Q, 5179091016.902155867702113242034208944851Q, 1668941700142.962732014338449363262585953Q, 2575302232826040.930983214056263444447065Q, 29708121106264252782.32997718334559128081Q, 4538831967003783409536690.268981265379605Q, 19138023153446381738359211515557.27962435Q, 5716447050875173187782003939002192529233.0Q, 4.057627687752827735975516066653569584098e+50Q, 3.237780711010981929311620914986172494341e+64Q, 2.136177206956376829298160177481616436455e+82Q, 1.510581027396811547515066542591252259814e+105Q, 3.072511300612383685659247652666898751003e+134Q, 1.227994026803117836885996853139658018152e+172Q, 2.186769076188247553183183888358166072813e+220Q, 1.836091623107666564777188149335650549888e+282Q, 5.560380603618894755889563902333421267615e+361Q, 5.88998929678686832672515862440158058623e+463Q, 5.520096462216289192193975675075507876736e+594Q, 7.625041435865992600228986717464906255015e+762Q, 5.594942726633317888883469851113674080397e+978Q, 7.83065490388354698017246745548709611393e+1255Q, 5.31445051505238075828831366993821695924e+1611Q, 3.903967482555967268768154031672119092969e+2068Q, }, + { 1.386351840518308620839358763554215551931e-2385Q, 5.692714192122587749075617787151443181487e-2105Q, 2.451539999979072363325054695825688359483e-1857Q, 8.306259271201342345210834094714244365054e-1639Q, 5.821665674291993981062416504099267133283e-1446Q, 8.797358828459107177088680667625679647909e-1276Q, 1.320339777528218308293628576902954472032e-1125Q, 4.410206727121778476048579405149038344619e-993Q, 3.88958196740022428105997715246477744601e-876Q, 6.130840948743111294681197948959379863932e-773Q, 7.123986226444013036571903990814705244112e-682Q, 1.625956113900887259810636803089770478958e-601Q, 1.320572219097695369155247708778376474798e-530Q, 4.919706191404226525652134855992684547645e-468Q, 8.024860788515940296029723266854707311236e-413Q, 4.196871666597654619740159911562644470158e-364Q, 4.078224492411775554465972303455630373728e-321Q, 3.471191735147190701990574841139180851673e-283Q, 1.016777466021579755362597082466363719898e-249Q, 3.428953269503642726569674461101922799622e-220Q, 3.864648202676556945364513945878444511873e-194Q, 3.728313820662828523155813829174568160454e-171Q, 7.060208962235322129955144096761424864627e-151Q, 5.459090052012602911109845817641480236032e-133Q, 3.289567436086836109824643192921661921896e-117Q, 2.732791746839713887573903753808368756806e-103Q, 5.177831303085066219526632688623608474071e-91Q, 3.488982337185646306130499469791616370131e-80Q, 1.237442719251520028774158417551455658724e-70Q, 3.265026914390933861191439483297654102176e-62Q, 8.697379457734148653851179446161666064837e-55Q, 3.062345454155899894309388140629758140766e-48Q, 1.807833865712730097166039383871617541987e-42Q, 2.207201696331440225776336883273569215095e-37Q, 6.707139727572063961765308933879986454628e-33Q, 5.973483508300898776044037837138168377527e-29Q, 1.801180330026864986720562202650526101338e-25Q, 2.088388852078546115498528757421004935053e-22Q, 1.041793934618658976817408586406414722965e-19Q, 2.469049789233468018627633841281746668405e-17Q, 3.03431128584851438436540057561723628081e-15Q, 2.088889617504309972831708178248147497735e-13Q, 8.623861415427504342372142475897313432992e-12Q, 2.267520372707251092440673628855405207403e-10Q, 4.00434469899471800715993667519323799359e-09Q, 4.977449132259217603976612506935174810782e-08Q, 4.538968536823238628996215667606148804058e-07Q, 3.149630614091772394558558562673475357209e-06Q, 1.717661473089050710545820269467478657391e-05Q, 7.574967445230185640392007893916198017214e-05Q, 0.0002770384430817457004866373769076558592991Q, 0.0008592108153443758806376553027674462916736Q, 0.002304786360384424941771740344312552340356Q, 0.005441591917762328024217837565230797608769Q, 0.01148476167871522792645105471040075981536Q, 0.02196880253506076514443020083930138789152Q, 0.0385580396241706814351187454685124783203Q, 0.06277963108370615709268692244350221567785Q, 0.09576417409380607071669368828518626179562Q, 0.138082557357984497226918290243355129549Q, 0.1897351225141586893050983199373491867744Q, 0.250300181057554914230385878710297182992Q, 0.3192072549340042296492537721124960062069Q, 0.396080991004725824096103192363252504017Q, 0.4811067283954872948453453712777813856497Q, 0.5753914212017839181691468501697209245687Q, 0.6813248900530810118122761999613914470522Q, 0.8029798764915732889204873132214024785571Q, 0.9466241690181529814186874932394712810199Q, 1.121459300786612962966621888726574321557Q, 1.340759770715416009855754942434691146603Q, 1.623685219275531793982555905075386133233Q, 1.998211867629730384451407887613604637669Q, 2.505945399937510299544212230648723518997Q, 3.210163252219847883424432406111812852927Q, 4.209545478359448265983333053772635907905Q, 5.66221806820049392832515414216772490616Q, 7.82907923127299987879349586024812222669Q, 11.15440493963298675553174073341979600985Q, 16.4211729806540229459496343813231359463Q, 25.06213770772527921496874748041503923662Q, 39.80978364672011507488440928948335379928Q, 66.11905910269892631335237996583005145737Q, 115.4457061347595208831507793665792395105Q, 213.2410176092965330662887355382883213788Q, 419.7120557571478853925219015922721611943Q, 887.6243135338711385094394965082742389353Q, 2036.238442676944269983660634200868066177Q, 5122.12118711641868483849782862313248795Q, 14303.35249071777352807141644058493109469Q, 44963.76130260101727056610981483402829768Q, 161663.2341506202839569087583140422782503Q, 676850.9723274654978193458405608046555229Q, 3367904.732808158041991176278715985757882Q, 20381802.16891396956321794820770471285557Q, 153995295.8397188853456063357628382678262Q, 1496346599.741648156545891158553037248226Q, 19337797241.59405032267466119941485090523Q, 345272551967.2971484701102656571183717568Q, 8892537034918.26248560562610432170784198Q, 346910103925605.0063359353787631024771918Q, 21665929373961926.83928088004026581385863Q, 2306463422111622435.159433532385337024867Q, 449354136203242773092.5076776439573953522Q, 173650044978624626843389.7841238775680088Q, 145824377672837353076484945.9978156022493Q, 295089268707089209706730562239.5084852565Q, 1617782033479254791489149862949752.883819Q, 27439572735237674391627347457895077206.26Q, 1.673581697645403781224841542729295107102e+42Q, 4.352574542916664269993023807339615740421e+47Q, 5.85526745037344881314210199157273247914e+53Q, 5.070912889594583530997734588104227692577e+60Q, 3.622890387747150067406910684081678682268e+68Q, 2.828020276513886515649564791275027220768e+77Q, 3.316223981675888394574681086509262116403e+87Q, 8.379640459516602540499988839245270269136e+98Q, 6.867127982641854377436000349122572176257e+111Q, 2.900553033863247559187831400899198198647e+126Q, 1.067375865552333626918616370451069994481e+143Q, 6.203172809995726788998131622890100236377e+161Q, 1.117107695601654791970655214011701045665e+183Q, 1.338015284560800822144968909259062165181e+207Q, 2.532661918076356979939863944652000925382e+234Q, 2.020013699747769556918589976882904336926e+265Q, 2.062587137093633738153639964961537739828e+300Q, 9.497974733972601205199439097559404355421e+339Q, 8.216866861631646227849070101465292350345e+384Q, 6.727368363173988690006109427672655451647e+435Q, 3.256512214038182544092657678379570013082e+493Q, 7.431565554497628535696075925669517436095e+558Q, 8.404907826884863403395059072909982751661e+632Q, 6.774135867874352304403519336536368216792e+716Q, 7.978808683551832748089548367396910285319e+811Q, 4.210726051563171486361372753281330825868e+919Q, 4.815228807107039224016318021511536231054e+1041Q, 9.671936246443378281031357192551408517124e+1179Q, 4.965867685385961630088948794046462865437e+1336Q, 1.840788819983942185751345185174055491455e+1514Q, 2.949992127934753413488342242442835124216e+1715Q, 2.867592218659729126785338974659499305745e+1943Q, 6.225766615806442563214766060198378536369e+2201Q, }, + { 2.153709119065749047384536448355900579318e-2461Q, 4.147193855893089802932480896953837816201e-2312Q, 7.177658143381361090563844720372254951009e-2172Q, 3.944230945173987596102529995072916187169e-2040Q, 2.25203912532665129298170461102995236498e-1916Q, 4.069220991977459613504377433271627793079e-1800Q, 6.624466915659053303929653909407578699373e-1691Q, 2.596257880517152044266679980520189262305e-1588Q, 6.167272854034828267808038080246702477106e-1492Q, 2.113894573656814042644120551594507889596e-1401Q, 2.361521019353054468674145270219814329078e-1316Q, 1.848638669607253145389026119290761323843e-1236Q, 2.081403374877948007964079565701350764113e-1161Q, 6.623322864975529287136776279985505657405e-1091Q, 1.123590402158471434808995896499952788109e-1024Q, 1.844386514552891233533174646984024640794e-962Q, 5.128863718401367724889431337204044513391e-904Q, 4.088778734197102430329137280909077732089e-849Q, 1.531808371245169100620963725103848604027e-797Q, 4.290270905663487214153817815995887913095e-749Q, 1.389470421615532710115733425126799271732e-703Q, 7.838573060838659894518309211959299615802e-661Q, 1.131894291662080350703257522413580097058e-620Q, 6.006013929171556301601809240766812579204e-583Q, 1.644730968816111080320183371646275297305e-547Q, 3.198235005771726926394885789029782957714e-514Q, 5.959580309220240991340412270300143677861e-483Q, 1.410282910930590862816529755134883532288e-453Q, 5.521639312156930309110023768183565612495e-426Q, 4.585919516068868264280071563537738119217e-400Q, 1.020394119171727799567503936464494713616e-375Q, 7.574193909699610751429039846221563484459e-353Q, 2.30465092047628633493403784334464415825e-331Q, 3.48840220106323577890775923236785436425e-311Q, 3.150362661908098932123515245864546345115e-292Q, 2.013646164447659311144825526346127296191e-274Q, 1.069488936705677931335190498151163915494e-257Q, 5.487822844726864148884830007464470454824e-242Q, 3.134358187858381633591525778137729124473e-227Q, 2.276094570183129948569188857932257367076e-213Q, 2.381186996817690402995924843601642222159e-200Q, 4.035883965482480555809472106926843581355e-188Q, 1.237421125633634931787014328143031219326e-176Q, 7.612375248238611100167693433869538644334e-166Q, 1.03564517628310003846110294483553771263e-155Q, 3.414236525557816532714159962618179505079e-146Q, 2.972119191338884471738932645163613310679e-137Q, 7.405719578144237005638239996632269176066e-129Q, 5.697866971705411033338967165291329660286e-121Q, 1.453525650405010719093063409530168655253e-113Q, 1.314457042747800101250951995075815763416e-106Q, 4.487158944338714399472937522048625338578e-100Q, 6.133843010330477776911218592616869418346e-94Q, 3.549046569968448258108761477312785345444e-88Q, 9.15653736236172677846014482979591035913e-83Q, 1.106225007418683312537695601355577902976e-77Q, 6.552587618068599134320545512491211688749e-73Q, 1.986983959037010776999444552000407292986e-68Q, 3.212231088872538685545630958926283760161e-64Q, 2.876083037850198316572209488005734896643e-60Q, 1.478178451855495397755100020343123782752e-56Q, 4.510136913310968612160348544104344875802e-53Q, 8.43163306904015048294468768978670757577e-50Q, 9.949086338757522362613734399563150733015e-47Q, 7.619276387894797233552143024117256466731e-44Q, 3.887578603118804834388263706442887467952e-41Q, 1.354460425113896086794594963709153546321e-38Q, 3.297725535994022163897040708255026760814e-36Q, 5.733963913755196694875643096843980384457e-34Q, 7.266873043332808557472765774887708816006e-32Q, 6.842512280140593238694695887751428976356e-30Q, 4.873916238663169821502515125384510350419e-28Q, 2.67104044733090831863661929906177082711e-26Q, 1.144256425448742318630686443479692876226e-24Q, 3.889460608664331879375473469924970903769e-23Q, 1.063820968032088980245479855177643924172e-21Q, 2.372368187184684696934030650222501693836e-20Q, 4.367217234531848441087274222392461828198e-19Q, 6.714072048307672526701746503229203872406e-18Q, 8.715038929084108149220868369670810108493e-17Q, 9.649643353371338291949150921949043262283e-16Q, 9.202344844399561245249616317083794701473e-15Q, 7.627186782202012373857140553398508834043e-14Q, 5.541204897019768922378105161812644362096e-13Q, 3.557048030298498992879234830353226137603e-12Q, 2.032744001755231421592520905157658966757e-11Q, 1.041471970221369125727527396501651131028e-10Q, 4.815746961815888878707719559623238827298e-10Q, 2.022256033241840308293815584933936990392e-09Q, 7.757232961240456606859703523066518529705e-09Q, 2.733153775260544423882242088236116026231e-08Q, 8.891028969222217122426771244264445123634e-08Q, 2.683363699682823512352273715923881225589e-07Q, 7.547938347293146072138897896472002448211e-07Q, 1.987288087784999305724389158395024503401e-06Q, 4.917307260739981850972488313550395223813e-06Q, 1.147818087877776831871382182250485611551e-05Q, 2.536555822777680979640072567746984012303e-05Q, 5.324700805639575159848486238104008083539e-05Q, 0.0001065104593011935929690181523071874981403Q, 0.0002036201878041754169927401598406684761513Q, 0.0003730694572042112135642393073362991994966Q, 0.0006568041021168438789081239759748902651433Q, 0.001113856082390590315261750066635645853531Q, 0.001823795394232129061821994378958654853165Q, 0.002889513200651556198315930630030358001876Q, 0.00443881718224362291889374527793908773704Q, 0.006624370653018100869035486094303324374562Q, 0.009621643058168115506980743618776762488547Q, 0.01362474661061153688659710974159152873711Q, 0.01884028247930917278703173856744540683895Q, 0.02547957164901951276515984657668580178391Q, 0.03374986101820444134410850985898380264724Q, 0.04384524214597866779829228667526980197901Q, 0.05593807863817149350657574675807048756849Q, 0.07017170405513801042331008586630568895795Q, 0.08665503552527451253277350683009212070597Q, 0.1054595702235363867702301829785070516777Q, 0.1266190201109432391014527348400287053881Q, 0.1501316236075107886549638372376816417809Q, 0.1759649767559267732358948485233780510425Q, 0.2040630702512586485268749964249806985555Q, 0.2343551140988592187593366563877467767717Q, 0.2667656825843397368908190937623121671946Q, 0.3012257161225960732129884529500197323181Q, 0.3376839660798721233949233310785147371681Q, 0.3761185538003348421564742944823413913592Q, 0.4165484249847702522138862767113120553465Q, 0.4590446052165412998498906468918623478646Q, 0.5037412936922832954263365540046003893023Q, 0.5508469646129002757560299007304854908847Q, 0.6006557767190285077637253095947053526367Q, 0.6535597216576629891101800604144093765709Q, 0.7100620747737523822947126492473382788423Q, 0.7707928539773253442669973879355051153215Q, 0.8365271529352029829410941379841014207074Q, 0.9082074065630153160377196587855263177763Q, 0.9869708859999779495240452237028540164333Q, 1.074184028070142953846864518403663449244Q, 1.171485608204366918201829258479912815044Q, 1.280841302284684089954497564743618220051Q, 1.404612900635889239243367403680911038359Q, 1.545646402722480240247150802269938467715Q, 1.707384525263588509493128753610327227915Q, 1.894010926394097993786557902090588409739Q, 2.110635862415512116963868587235457795192Q, 2.363536303994741366574252227951115976696Q, 2.660468105686482827350797681159641534679Q, 3.011074164792230193113510360086440090828Q, 3.427421374693910835751367912941632897681Q, 3.924711673248156094377006203156860892723Q, 4.522230229488088770843806386045851485116Q, 5.244619212432280978773017572378093632495Q, 6.123602261918423455989664041297732186797Q, 7.200338212985471642696378036338100824922Q, 8.528661194163518647522330556738826698585Q, 10.1795808762825588115943699640538350698Q, 12.24759161182228183403936919987651507813Q, 14.85960439206079152354924082757358017039Q, 18.18772191639285225095582240934142331058Q, 22.46770693694438266788875673089834602979Q, 28.02598205678222312613627998636443255805Q, 35.31956839472836281617942063648805057637Q, 44.99589554931519875089171176915038299167Q, 57.98353389704885773969473673566367683191Q, 75.63171444720726311562293227564655477314Q, 99.92794457932308971895066190493770890577Q, 133.8425463310492883248985874380676641996Q, 181.8827841191322574272154105586756787384Q, 250.9989324790227325886260498692066131692Q, 352.0918043504840829713899165834496626436Q, 502.5673566776629477114581049222602222154Q, 730.7499663518253779065498110894726399171Q, 1083.663330851425621044011145629560752149Q, 1641.046090832866443292991561052478814981Q, 2541.175762543968047856727653734497274005Q, 4029.599963686451454823862824886660792972Q, 6553.444953601904053410984310275852939506Q, 10948.86156286092590781924054035970530589Q, 18824.24374198598947610407231104290274273Q, 33367.41042050707651941057262323589633578Q, 61100.32354761251643555142022778509780639Q, 115823.3197846099760624485067753700173466Q, 227800.5457979967285916898520734037878755Q, 465969.5974491004469600643539676692051643Q, 993823.6909873690422590985961324603809908Q, 2216084.13887947517519343506597373015701Q, 5181319.208019180282856303518778675455354Q, 12741027.34261421733969396616504794871165Q, 33059572.27383369273787469213830373668452Q, 90829891.07592666063192392492529195135112Q, 265220148.3252427142260298939914110596375Q, 826306755.697721615496224609055395381065Q, 2758381134.661518474947496017030009788597Q, 9910232200.243379934059362806886397274158Q, 38502881176.3933830609424901403318575962Q, 162584306967.2409325858164161316957369788Q, 750200992664.4359777908609835343088972969Q, 3804332487983.017078667225707645943133264Q, 21331904145388.14541475895031884650999707Q, 133122127507568.6787760048949572564123711Q, 930981675711560.5951829624728938156318722Q, 7350153770761857.738195134172081040509941Q, 66026171483511004.7598867374102237079003Q, 680486183952492003.9301399387520437691261Q, 8118174386406923586.599284563850167447239Q, 113170692154432424494.5216550607269731604Q, 1862134669947114232653.554228443860527992Q, 36554098616406740302516.43278601897053952Q, 865874280308076835063377.123348611020615Q, 25051406060214820093412273.85482035896521Q, 896751349474731244620492756.553903238626Q, 40266150489696916288472196890.64603620807Q, 2301369891996757289277873261787.184011061Q, 170047604983476347340915854457548.9867628Q, 16515349691975204027920973406952496.46185Q, 2145840986564667805146832484762675859.891Q, 380060769952839016072137090687963445752.9Q, 9.36123788558646358041896426324843981817e+40Q, 3.275494655666609981890875995623135434569e+43Q, 1.665398964860299545930184928911155962074e+46Q, 1.260451270788760156928310522092797529604e+49Q, 1.456947463601543501128002522603116571534e+52Q, 2.64322484187098185929268170588521133587e+55Q, 7.748613855444798667335906195147663845602e+58Q, 3.785779083813673709321393618005760329985e+62Q, 3.185930864211325729228980901011835019191e+66Q, 4.782979453124504957283130866796373448924e+70Q, 1.329705018427327910312331135948617996847e+75Q, 7.123048398653137809481237992377055295409e+79Q, 7.670126414228475157968011203109185943474e+84Q, 1.736689968283312998104946874213525703289e+90Q, 8.674483167127152572569881489730633083479e+95Q, 1.005836714694543802062236633293787516259e+102Q, 2.858670971133756835312878104822468805959e+108Q, 2.10991678144106388404020677820688045343e+115Q, 4.300927613568567564219321356837370605967e+122Q, 2.585292935715111244029099744261209770699e+130Q, 4.913585796022096573751225283239803494319e+138Q, 3.180331244781653863975221219946227781431e+147Q, 7.586729353605128898799633596174131151075e+156Q, 7.25574965577103086678452273743481928488e+166Q, 3.042628328617140159795776439859957241227e+177Q, 6.153982813886310112559054012984291284066e+188Q, 6.644716047129194946546223989317633525216e+200Q, 4.267010798047279459873744815427996740364e+213Q, 1.828261524200837793682416150708346778824e+227Q, 5.907192142855374833372550253101759665385e+241Q, 1.639613866135475410081422748292467992288e+257Q, 4.491164650248633394149160267786964834797e+273Q, 1.407205628682664127895373663193013840779e+291Q, 5.901973736086548723127533540481678230101e+309Q, 3.916881285333542675097708234397993801965e+329Q, 4.915136487337420126024738386450372286475e+350Q, 1.409678081844840550729970217105440686499e+373Q, 1.130683199310898290102829283325964896298e+397Q, 3.144117419652964064273526900880035236365e+422Q, 3.809876833653423585198167012150253087973e+449Q, 2.566258698784507090567153515899784014397e+478Q, 1.245112941213262053730574272447559130313e+509Q, 5.733709207713561096504201724939408030947e+541Q, 3.361300877024088016576478175807523211916e+576Q, 3.429058193604769142012855254783863281583e+613Q, 8.490713211274685176663921590498405237032e+652Q, 7.271789265612590062970363082306633017878e+694Q, 3.140603098783297467974052202677879991934e+739Q, 1.021802837240605643483742627625814386292e+787Q, 3.839307747037610497370639615169236613499e+837Q, 2.625348245611878921167180568009691832465e+891Q, 5.301810468703271471934335911636282471403e+948Q, 5.293953933728338458359735330414432271415e+1009Q, 4.523817161069727277868688722993321639055e+1074Q, 5.932188169476821247963196653927747373431e+1143Q, 2.222709326425237855173602817006726442049e+1217Q, 4.612038732897790803740603080628674002466e+1295Q, 1.071926720490530830314342236668609091118e+1379Q, 5.906749883873223055044444836570422088279e+1467Q, 1.714334001343939494661025595853170112809e+1562Q, 6.129355935256855944674667471697766641354e+1662Q, 6.669833729539525050372787353801005283761e+1769Q, 5.785462791059143624731094992917802825231e+1883Q, 1.11479279343352711500828293815386828494e+2005Q, 1.420693188301294963083799946944540546516e+2134Q, 3.825007293467971681545785259893286155041e+2271Q, 7.49023122288057767110049546000007822061e+2417Q, }, + { 3.396187965591260438897244230849252949133e-2500Q, 3.41747159490076194366166435197892344024e-2423Q, 1.468507678341085936510631686027018193702e-2348Q, 3.187196102551453055654175541511540035227e-2276Q, 4.111144618799882938247446443042495922138e-2206Q, 3.689982379249148439178153280533053022001e-2138Q, 2.685174204657092092067226298561204870573e-2072Q, 1.837147705508098860673717768368232067662e-2008Q, 1.364257907967552000423094508893268899947e-1946Q, 1.263771364208497251750238943339938928533e-1886Q, 1.671242563857819954841665799077012782254e-1828Q, 3.59572473348901442338115273389639464694e-1772Q, 1.428695046663295321301312704790120159931e-1717Q, 1.185320708968814213894285445648910693797e-1664Q, 2.312978025972053806095540476447810494724e-1613Q, 1.191384629114553103202392185340997162652e-1563Q, 1.811512325837822942229802348315430051691e-1515Q, 9.061690335018066855688935640999855840642e-1469Q, 1.656446393553325828143168688464980737559e-1423Q, 1.225078144907203399772561902982205963608e-1379Q, 4.046000991642731324022030505096438995941e-1337Q, 6.566030925389917368793803468023222144906e-1296Q, 5.744543867554393981259543937791978449595e-1256Q, 2.964190466284077618451217948796617398864e-1217Q, 9.841838762797010428171966754803344043532e-1180Q, 2.287831175258608392805748160775135819389e-1143Q, 4.040912495622704041470131809505159517349e-1108Q, 5.87056189991253569332657105113103824038e-1074Q, 7.575340244592727205322278379346787745011e-1041Q, 9.354001575325859412659652699978018590336e-1009Q, 1.188011952293188317901713987657283819367e-977Q, 1.664419563784475798800943375399832441798e-947Q, 2.752827383868394227330239571429534681919e-918Q, 5.740088624159127463245451711190174595819e-890Q, 1.608246374016315723402165607871082117057e-862Q, 6.440216987884563060048094831994625373593e-836Q, 3.913422837501277880548253194801428546448e-810Q, 3.823983955989560074096123125871957896214e-785Q, 6.356204437923014497781992143867806067066e-761Q, 1.897887002136970233209553057528902481451e-737Q, 1.073182396417440952923883248248820918596e-714Q, 1.209599587842878172907735383699977342323e-692Q, 2.855780038744229524130906951698839053919e-671Q, 1.481869691380590340606688460267010905665e-650Q, 1.770687381130960661518257581666080736263e-630Q, 5.097321233667122918955939586473322120615e-611Q, 3.693416425056334731671036194098592621278e-592Q, 7.028028538800977471757544285347858958102e-574Q, 3.659514003462772290514441124205917047976e-556Q, 5.426427278796883021042905920496694956698e-539Q, 2.381707918869144677895468509571771901592e-522Q, 3.212283372523687089209961685271370035808e-506Q, 1.380563704271665131614814775099207204703e-490Q, 1.958383048574468276677385071723507356519e-475Q, 9.48743029982518591875701010064880276966e-461Q, 1.622425672258543869160313396312274060462e-446Q, 1.011253624597190818422622302876493852764e-432Q, 2.369846278374825178509948199829322673406e-419Q, 2.151869280186648519304900103376776987149e-406Q, 7.794995966503254880771477408719032168903e-394Q, 1.158774967764284452774587235820678160811e-381Q, 7.265518880056698052413196249715572214718e-370Q, 1.973119772438811666557920176657054992131e-358Q, 2.381439826231545597543020603431153384525e-347Q, 1.309668015497819382164964970820775932287e-336Q, 3.362180147598881535117942142551368440204e-326Q, 4.124757840732051332008577708750119570912e-316Q, 2.473774062046798241443322474966268652708e-306Q, 7.414272202331839719973914818818580322732e-297Q, 1.134468775996673043912791038078875526892e-287Q, 9.047228020735108713214081674437370270152e-279Q, 3.836582522644715763942703819520627288712e-270Q, 8.821018545646132764191081245790014964075e-262Q, 1.120514881106390681395171052626683473171e-253Q, 8.008830218793913153208169453114674961091e-246Q, 3.278363148993695291288199990793809607438e-238Q, 7.818601615846121111349439345713965603164e-231Q, 1.104596257773265868270077717696885587749e-223Q, 9.394568230893641749287701746065205133818e-217Q, 4.885735162640535435890107738269252106649e-210Q, 1.577376231155234084689651390459997701678e-203Q, 3.208212741662475033190349289840478119199e-197Q, 4.169536264702376953290079421852225148214e-191Q, 3.510697043108920771297336971888026846695e-185Q, 1.940796992053920703808111564711495526893e-179Q, 7.136244685320035109754945708241458423185e-174Q, 1.76730280063163466059025249772515470605e-168Q, 2.983904480026560548776384248696357376925e-163Q, 3.475443323448652658867118439684844230342e-158Q, 2.824541702249354041220922001046298716151e-153Q, 1.619596258103472503516391027755171126672e-148Q, 6.622883213895051670195179932778951351576e-144Q, 1.951579126231643346975253911702685400056e-139Q, 4.18602835981743857108590756268931043387e-135Q, 6.599918926269709459823212257675014743931e-131Q, 7.721619700426055982173615669852719657832e-127Q, 6.765470266069447535409496863264786718304e-123Q, 4.478897242147858909930672029381816582225e-119Q, 2.259813587851430691340478359494188813328e-115Q, 8.762584216656783897599480439549782669278e-112Q, 2.632496848689131735621784382242972332592e-108Q, 6.175744762125928416051254264663305408061e-105Q, 1.139991187420054499517789858269823323244e-101Q, 1.668043996811119184547324447087614691957e-98Q, 1.948551942896453232736618306447207462772e-95Q, 1.829886111019235604640158140033504624484e-92Q, 1.390785816650512241305706201256468524959e-89Q, 8.610876597126909947907951239288763095391e-87Q, 4.370440681745287512655018464467927347986e-84Q, 1.829571499724700982569308406477858583305e-81Q, 6.35467982337703555609574874386279503639e-79Q, 1.841843585185443349017139118584710840766e-76Q, 4.47965436588705164639200919931593795846e-74Q, 9.192051994113798021355923589255861583052e-72Q, 1.599661377244400320973091930394038454107e-69Q, 2.372973035131768911030516185612566198015e-67Q, 3.01536930226127366549303637826992082662e-65Q, 3.297914067466215137502368249038560260817e-63Q, 3.118845146643306964903272759796966041873e-61Q, 2.561809323663349754640588340955031999901e-59Q, 1.835614139432453324042425981398349070542e-57Q, 1.1521864053538881965046566277201188672e-55Q, 6.361211949301700767511994322063706295027e-54Q, 3.101325408187412574813091914708051546337e-52Q, 1.340315366748084943795568462034401125423e-50Q, 5.153823682493916697673436399844338582989e-49Q, 1.769604350572757034480939371983385367057e-47Q, 5.444524938929029722644073109230252087076e-46Q, 1.506078410473230887467835250237074953313e-44Q, 3.758031524066051846680267047613132037807e-43Q, 8.485476543792520256759499913448061725315e-42Q, 1.73912337985688401526741472924132534839e-40Q, 3.245018402217835203803189828064206880925e-39Q, 5.52829245911326158677969008013854969983e-38Q, 8.623186993970885363149060426291059432547e-37Q, 1.234883577447636456455512573156980104766e-35Q, 1.627825555297558296682254587731016740804e-34Q, 1.980251853197110750740177033192542117995e-33Q, 2.228623687736138529232852162477642705595e-32Q, 2.325930995307119978621491337043388856308e-31Q, 2.256361660464174192555048087618606554597e-30Q, 2.03915117811515128440130306842025272854e-29Q, 1.720544614806180272783100692189304247844e-28Q, 1.358238700291425183093124587457930780547e-27Q, 1.005239457303406154474744151833947246431e-26Q, 6.988894303606753297669433851126311708373e-26Q, 4.573289270207565220088232217355246375583e-25Q, 2.821890506943991496371146647405255494984e-24Q, 1.644856636073523601510029605009201973651e-23Q, 9.073050442568561823275320558923185848283e-23Q, 4.744096929010692481229783323592456352853e-22Q, 2.355285875813243315269790791700485018621e-21Q, 1.112029876447833293355894317984646400697e-20Q, 5.0008478161487906265030783014276491832e-20Q, 2.14524119442811961043233114548051430279e-19Q, 8.79113320178734153345564529895449040709e-19Q, 3.446365815960497059834387107630422028738e-18Q, 1.29425069073833323669197152514107143377e-17Q, 4.662195383020049630863703520736565781021e-17Q, 1.613000201366897700480549038203950457934e-16Q, 5.366485961582633012834800491739735664821e-16Q, 1.719017688382153776104960609843894364829e-15Q, 5.307775363464215365491509744435747831714e-15Q, 1.58153224028765965650956502083229696234e-14Q, 4.552534798688262530368751552485493008278e-14Q, 1.267359873762161999061953574910727734371e-13Q, 3.415589293705976822709962615841017474303e-13Q, 8.920396441522617984563473743690015005656e-13Q, 2.259831056683534791299863302560269236812e-12Q, 5.558385496914281158626259742154054243881e-12Q, 1.328609277181416985306808048226260048845e-11Q, 3.088906383077323034217900364942328595424e-11Q, 6.991047069852996644705052389828829263697e-11Q, 1.541592161799424949759540552003006648952e-10Q, 3.314631696092892696852523428007047458956e-10Q, 6.954687377912267443923690708860638478132e-10Q, 1.425030481896628988210436275967793904415e-09Q, 2.853596165859016481994370182243409560513e-09Q, 5.588439560806246713133438407216443307775e-09Q, 1.071067205395228191517684123993601779709e-08Q, 2.010297293947428624088705656550599163117e-08Q, 3.697444612237240406525896448389116570807e-08Q, 6.668262990662516945946174242814702190448e-08Q, 1.179931847916722133357063059921902676628e-07Q, 2.049697303194034837958769536530460272066e-07Q, 3.497508382194711899593633326040760388855e-07Q, 5.865487025318323293753202306221287078656e-07Q, 9.672937611928622460886601535198624050582e-07Q, 1.569449303967431028048007992388750555246e-06Q, 2.506625809822351496367236588148835401765e-06Q, 3.942730303856445318459553494614961666457e-06Q, 6.110483188339684780731192452553392150661e-06Q, 9.335213605738775483770667944380871611306e-06Q, 1.406489270953562868811484480472520033374e-05Q, 2.090736966298033607047604777694817538599e-05Q, 3.067572523977360728549911196951929768457e-05Q, 4.444254125522237612570935119262098204356e-05Q, 6.360369186365502157943693424315842416464e-05Q, 8.995198988623426391713559325836996156118e-05Q, 0.0001257606674958313871253473701449253355037Q, 0.0001738762412077100706379667970818335522797Q, 0.0002378198178307528456808477520866366646793Q, 0.0003218953586603673896746051260032347406477Q, 0.000431302857278104350328175477422461855135Q, 0.0005722538300635913579360920152701977667389Q, 0.0007520859992681880710509445633320017863057Q, 0.0009793735988494621503195966592341074592935Q, 0.001264029384952618301528623595188256832377Q, 0.001617394214613631295305190408599562642199Q, 0.002052309991459652915632773174511094733367Q, 0.00258317188244673197819727310558453131011Q, 0.003225955993218896497486226124906372664769Q, 0.003998219150540716791460047207042995806204Q, 0.004919068068090767024211469275276612172327Q, 0.00600909594733817652192578530463654010429Q, 0.007290285460855384857058707803522235069712Q, 0.008785878047288446808894606650882064620093Q, 0.01052021047666635132307480661080880814452Q, 0.01251852068056883921977029876570047333533Q, 0.01480672584232190128610556778358216498454Q, 0.01741117666809860093225669085692180516086Q, 0.02035839257460948797638140898975661102703Q, 0.02367478320248247763739778834391071393716Q, 0.02738636217273390454768575395117704136113Q, 0.03151845933082324581907457369661258727617Q, 0.03609543786059629424946593596435380994262Q, 0.04114042259887953993494104853150125354906Q, 0.0466750456480661216715303674857866168132Q, 0.05271921498296900191850699684600263052343Q, 0.05929091119945738364187060701710146534661Q, 0.06640601688035302862345335055441729364649Q, 0.07407818228628303425809436316411971898579Q, 0.08231873024496119428365313871533264809944Q, 0.09113660224143843130137094535859755638343Q, 0.1005383468331949678476633629507285246196Q, 0.1105281506546976411534200317116736403124Q, 0.121107911460692283295465500059636925578Q, 0.1322773519071888937074497167516771096546Q, 0.1440341721011981269170563712300225480081Q, 0.1563742383781529019329462935434102354245Q, 0.16929180529890363384017378918294150837Q, 0.1827797675015790272999775984418466966127Q, 0.1968299377991512902933613706115501276824Q, 0.2114333477796263038189171478034961399731Q, 0.2265805671379344452230433758251512257964Q, 0.2422620380400139215659763053475126372656Q, 0.2584684209816167422154096623392631193615Q, 0.2751909488470871954314516615118286765006Q, 0.292421786186026106706648834563937352905Q, 0.3101543910972953239589783999692036454244Q, 0.3283838775292636198506142015003861049102Q, 0.3471073762620363765649565589914160563095Q, 0.3663243933219057311460108766773067464956Q, 0.3860371650816835811494186931036726843691Q, 0.406251009815427415089167957119716552498Q, 0.4269746759961805873630290348183986624008Q, 0.4482206881460109502730547965841668757419Q, 0.4700056915656277899431961667430783936476Q, 0.4923507977844861273498956739046383206408Q, 0.5152819330813603300309886035691222305983Q, 0.5388301929311863111421213198913401934378Q, 0.5630322057392941342388625306808580909827Q, 0.5879305097331706661595300552630455764344Q, 0.6135739474002000455026043925050716049865Q, 0.6400180823944171101131289807198543701499Q, 0.6673256443945673609364872806279077990422Q, 0.6955670079895264329659912952632680789938Q, 0.7248207123067282158967442704471550423678Q, 0.755174028797632235942287932936820869365Q, 0.7867235853661413244076962098206460684032Q, 0.8195760558879440923143584503029939308205Q, 0.8538489251399243780669486054066034940311Q, 0.8896713402605466323065095493330976770865Q, 0.9271850611189796768353779214968518621624Q, 0.9665455234106549820541670985068771774387Q, 1.007923029952093538678666103220858418246Q, 1.051504087555186687117183984945832760065Q, 1.097492909063483883997601555693094342315Q, 1.146113102680112719972734092736933142041Q, 1.197609573666617166428932839178577498609Q, 1.252250666911899143547941192591371436231Q, 1.310330582839888493701788295465003738157Q, 1.37217210373676733630920077182877790563Q, 1.438129672943398791959487191769629934714Q, 1.508592875605843567792546896641817408196Q, 1.583990376960161405728445978404738182695Q, 1.664794382629429266013098961741791558223Q, 1.751525695347873485191917162770484106857Q, 1.844759454157519975124726858748082186858Q, 1.945131655755179789450074815727091684967Q, 2.053346573670745058772720412100260503836Q, 2.170185209773702783125573644862289332091Q, 2.296514934764264073224142035073302023876Q, 2.433300500447164388577695004113074013905Q, 2.58161663747988776667509546620948920106Q, 2.742662488862789158372641819356759385405Q, 2.917778172822028903433359898800151747826Q, 3.108463820292819287982021469423989376857Q, 3.316401493599933781190010602613013995669Q, 3.54348046617653089369704252750263265078Q, 3.791826430729338944919813121549353097009Q, 4.063835308168158064754708867837643609124Q, 4.362212455574033518518003957573686930251Q, 4.690018223035719205027755685192834005172Q, 5.050720991947143731968899118688088940902Q, 5.448259048256953387079920394084937571864Q, 5.887112911771720144158430210651581802686Q, 6.372390067582751971642819361195420653775Q, 6.90992444125988827953012481002020831555Q, 7.506393442161772368175053194733459234238Q, 8.169455989725808324527513652199713813185Q, 8.907915661855472823639384908936684643353Q, 9.731913995136417711816003089572337623446Q, 10.65316006472897621652551260868663551892Q, 11.68520382944801969713109764242848374433Q, 12.84376241077977807680500867803300301828Q, 14.14711056741875730648931534734397225137Q, 15.61654923657610797854796792165924553916Q, 17.27696927711813081034870582050023535149Q, 19.1575316438972062177517199312460728233Q, 21.29249037469088386815163901407216178668Q, 23.72219127477837271220994964328656674383Q, 26.49428742050364820557155179532147420304Q, 29.66522306835508141969084020865324390507Q, 33.30205089827977157270000960709570859413Q, 37.48466458890380022160714648508118317334Q, 42.30855063623495252454033790164450670327Q, 47.8881915632378843451955961800195447245Q, 54.36128918373743651121334551785550120256Q, 61.89402398727235984409338948213129946593Q, 70.68762848584778035111708853851365105352Q, 80.98663318461299861455744390021635011055Q, 93.08925000731765179043536794223242453694Q, 107.360498051909977877638468111141356496Q, 124.2488620644913487541111414904888517612Q, 144.3075208306123537479577194819288207331Q, 168.2215125059906251544039241246965052271Q, 196.8426466712140109699287106212096785157Q, 231.2345700412004162865664673411149073857Q, 272.7312019667013277459148899897857891488Q, 323.0128578028804552965843198380088014832Q, 384.2058863035695149259386485193758599267Q, 459.0137217198435660140055247689248768806Q, 550.8901200041443942937196398242337901245Q, 664.2693368837686965599246065404881270217Q, 804.8735811989890924404636182648277160974Q, 980.1259156504395891459619379603039765341Q, 1199.707861561135993394057942286167343594Q, 1476.316731695328101407692303706838300626Q, 1826.700281041640180200375170800299114979Q, 2273.078763337010832434612762840156927958Q, 2845.111583125694562939705485499061319494Q, 3582.63445229515952348100007249931464674Q, 4539.493895490226925280328582195285263756Q, 5788.955233042394450770042652752120480379Q, 7431.382535413996455795580622729193897504Q, 9605.22268816346298456472600902460366535Q, 12502.83007762372328074237673282359093081Q, 16393.43674235796806736737398613354988262Q, 21656.75254389093564900375379131087677274Q, 28832.50596892479639714830479215091321586Q, 38694.08631185854918420830577505233860916Q, 52358.93467063693914614720804658599988759Q, 71455.456360801919182448351605271054385Q, 98377.64507715702272833892935236019203581Q, 136677.0756867775216880054458611011665626Q, 191672.0751837584047014496772899197949398Q, 271403.5992651355850921027142705425693394Q, 388150.1489980647547347704942553355997537Q, 560853.4130088772447154039295543588593931Q, 819043.3312820769048716008983572259664347Q, 1209258.817558563172770397433801307820624Q, 1805669.064478872952573635882889999089934Q, 2727847.041283590928457428564030560101144Q, 4170866.124317416698666405920199452972485Q, 6456890.228079086947156608652453964442837Q, 10124726.37272406821615834787676485411144Q, 16087301.34833727189340602159225001909214Q, 25912302.39431432285806898738587495423666Q, 42329233.71376092207616725342280744956334Q, 70158627.34273633230839208484182467105049Q, 118039913.5748636616256979688722947376115Q, 201693090.8294808535841471498441901946314Q, 350171893.7910157422614179826343745861743Q, 618045198.9354320713114267484128373842008Q, 1109520762.65117402853282816165715478028Q, 2027036851.386298662396084471850133567806Q, 3770865836.139748847448857684280330919226Q, 7146997570.085695415162843692670918823862Q, 13809155423.7635644350563312672690880342Q, 27216828505.22509686672818101177168461874Q, 54753167786.17979572173272483227070679431Q, 112503345834.2116875456216420474620516059Q, 236264339141.4388903275724307413980800073Q, 507468184268.3981316720163337618534278446Q, 1115599423406.056750358630646519147758314Q, 2511986677094.979276772007287643222172789Q, 5797849169011.042298094625503200359295722Q, 13727721548993.32343665617597576637303556Q, 33370617336501.58545603365672095860275791Q, 83354238202660.91699429975122294150089333Q, 214123217249312.3976721926402658332174117Q, 566186245097249.2404127137280597778292079Q, 1542458444402443.371440183667494867781715Q, 4333492171181691.733058240784286416444505Q, 12567757410549319.01294953377020420832395Q, 37662670435513236.74825914523236427898489Q, 116748202247647142.7587746965785438338682Q, 374749992316334764.5035248090549339897237Q, 1247000912952610699.068918595764499658321Q, 4306478248247432160.48599458994176300511Q, 15453273378202816390.33518176991213146053Q, 57688614909942567753.38454019969606422075Q, 224324420244279774891.5933154795594761405Q, 909792898611770682517.3964923463766620933Q, 3853617984492513550125.129076034019123708Q, 17070801413556696833779.13934163759159904Q, 79198380783368988856761.15648214291897699Q, 385383801466035476735828.0064437179791326Q, 1969895659051426429613504.41964918030692Q, 10593618501197001697030611.61632899678015Q, 60033966329846568637130543.04333463171392Q, 359106968518167632524691177.3080001529087Q, 2271277124005940993621700920.257498362904Q, 15216157171278585594752783876.84164894054Q, 108173748902143609868441659437.8836108294Q, 817597332272823012424833955943.3418687263Q, 6582674375871431329198879326278.80655534Q, 56569460748304763531726402484221.24071294Q, 519969127337393591722068633515796.7939186Q, 5122908034001797018186468009479969.983806Q, 54219575049584711207951705824720122.49792Q, 617850853251241831307357121612505215.2627Q, 7598326740673873945470445853982730673.683Q, 101090458794504259380071592279087005881.1Q, 1458628632586491581554836293603735700553.0Q, 2.288445431879986075288969228297589916294e+40Q, 3.914281502784266353374296872381741581596e+41Q, 7.319312087167267244726757556658409266855e+42Q, 1.500458683672485184540463104819915256685e+44Q, 3.382059446944515486362813459304381825179e+45Q, 8.40717228899724214872703723897524019292e+46Q, 2.311957183444258916605122634003678725418e+48Q, 7.056075282456062930798909861538304101971e+49Q, 2.397931935961417566906622041440033927301e+51Q, 9.105063361761505316713558735495605805833e+52Q, 3.876420331062826191501135623097992286507e+54Q, 1.857198647483778496415448329375750635825e+56Q, 1.005063215679245721735518932962246661573e+58Q, 6.167590234451758437399991565606037242384e+59Q, 4.308813152379759511416924169109982265891e+61Q, 3.441182726656605944775469940970363892009e+63Q, 3.155080085289705076440136183714307040901e+65Q, 3.335560569120603606052934730277045229653e+67Q, 4.084573232398309215368829036499274751723e+69Q, 5.820628809283804990396620764580300086666e+71Q, 9.699039800361010527223356682487354608079e+73Q, 1.89923980668320512816136152429593080513e+76Q, 4.392868007405665883421052875783971749913e+78Q, 1.206505986650708892173158064003257826858e+81Q, 3.956328505753650002939043382097189172455e+83Q, 1.557688055206654931604309948079068934868e+86Q, 7.406537535531269658298708915037136600795e+88Q, 4.278562761054468958052314006843284683637e+91Q, 3.021429361815161697337775526021250674025e+94Q, 2.624991835754469757869340327198684862761e+97Q, 2.824239055865323697007157867310795887143e+100Q, 3.788616439302435442144238888291948175614e+103Q, 6.381265012445197114926701012217755404272e+106Q, 1.359307419444233008395198137493298288245e+110Q, 3.689357736818599529286450344745920764709e+113Q, 1.285719405981015169347543552934268877769e+117Q, 5.79896089805386955461804251259128564304e+120Q, 3.412858686517390979492612468054488171338e+124Q, 2.643133109091891288299365259101435230764e+128Q, 2.717298021659115627801241121693599358524e+132Q, 3.741778449844632488889983162905015325601e+136Q, 6.965790897246310296313827180334657009428e+140Q, 1.769991845748830191769012548081426586684e+145Q, 6.199682080134586417994375593693813669468e+149Q, 3.024056421749683185151625522184732565621e+154Q, 2.075860353782646995243205830982511919541e+159Q, 2.027237041997503527729877101258258485667e+164Q, 2.84819019631263809337561430719405846138e+169Q, 5.823789472478759398822868913946380670277e+174Q, 1.753831670213037732308430178708200856584e+180Q, 7.875048994214403791228526371140330003633e+185Q, 5.33959995017489809314309431564145975465e+191Q, 5.539060004117798714171786555151150971203e+197Q, 8.910405429080536887142895484227329351929e+203Q, 2.25393372621235039418834085888287214571e+210Q, 9.095096825715822376272275522195235473437e+216Q, 5.94202303286497040346001141219106057472e+223Q, 6.382118127492160537643353652683681344379e+230Q, 1.144860031429102206755598498207317533823e+238Q, 3.486326812227187949835465276465097663203e+245Q, 1.832768040117385552841365088677720918755e+253Q, 1.692379509135740137727773957097833887452e+261Q, 2.794505326132115346915299861915404249723e+269Q, 8.405076170451043189493827526418502257828e+277Q, 4.693262451309588660736308776755416725156e+286Q, 4.961738495062629283767259212421455782816e+295Q, 1.013488586645822568937692055235633940552e+305Q, 4.084221398756118821350576889490962044446e+314Q, 3.31797255076755830584401562393461184623e+324Q, 5.556156061512309994500204693690071227389e+334Q, 1.962393306169292859108099309776943823055e+345Q, 1.496911135838772621973260501875737184473e+356Q, 2.527081774155980938068575705055676841454e+367Q, 9.682952487842774440282680190380581838128e+378Q, 8.642932154430007387844488354704403530376e+390Q, 1.846024495166690994263298662566528477956e+403Q, 9.699853937915510903638593851109203549831e+415Q, 1.29019233082477503168780727447218377249e+429Q, 4.474137533288725774889486358089933849193e+442Q, 4.170041218844572969270760095147757353548e+456Q, 1.077897308040601801221120607931770758264e+471Q, 7.981471823702425518749857998096499633387e+485Q, 1.750515936677737147078175240321968864283e+501Q, 1.177053303545360119348788135380274557129e+517Q, 2.514304327715581467017451008836642461283e+533Q, 1.769970977432511196406520490255351180778e+550Q, 4.2646343986308794030088301101938804053e+567Q, 3.657021198954671244361265926107390170785e+585Q, 1.161995022380376800254911849215938667325e+604Q, 1.426161883992266887019615450265103556361e+623Q, 7.057501509770417183799008967192326349846e+642Q, 1.471878408492178033263031885767465334416e+663Q, 1.354138353815247160487911075189635081583e+684Q, 5.760831288581247091444505472239736239879e+705Q, 1.189730645764784786336307075095066200968e+728Q, 1.254105261294047490114939349887062439042e+751Q, 7.105801021107686895390768106399523520351e+774Q, 2.28281648423858553167251131768916156991e+799Q, 4.393686187647260979367904999350735520579e+824Q, 5.362504350805858665245291197548444739952e+850Q, 4.400994460175449649406744849257249937177e+877Q, 2.580184691440319635082387832634782416379e+905Q, 1.150201187760129651179050406857281109502e+934Q, 4.158019827686647740035176845444359313922e+963Q, 1.302697158180542995105180498547801432023e+994Q, 3.78804315469310114235168697055913940647e+1025Q, 1.097277067032447599839448667453494574529e+1058Q, 3.405948056419239816971511993948200677928e+1091Q, 1.221452079059747140866097947720732213944e+1126Q, 5.469728834947448905323012416213783681996e+1161Q, 3.313684879917774900254086176181829781121e+1198Q, 2.950003898158737668709569796392213974285e+1236Q, 4.202906985201980113057532813808859421914e+1275Q, 1.046450503925266293149709371732059242222e+1316Q, 4.986188211546778571602783903171292775302e+1357Q, 4.993338241348295306012588782782184198345e+1400Q, 1.157626881881270934779792801922724477911e+1445Q, 6.864630422932014748167413728259165043085e+1490Q, 1.154057064570998816035086816885432531351e+1538Q, 6.116573955685408991594979059166788310164e+1586Q, 1.14033623849635356868515171774059586735e+1637Q, 8.373064137120280572431494406435413559046e+1688Q, 2.720845114960258853420084277841813860219e+1742Q, 4.413059336919928865301216672097302323433e+1797Q, 4.044822257870394599276743613321249907269e+1854Q, 2.381229351958722417177138670512610760689e+1913Q, 1.027611652914733400897244248728364151035e+1974Q, 3.725531848970894050805213745804832393498e+2036Q, 1.306062165371036629009984640124042230203e+2101Q, 5.118934916287102017127361633252835489039e+2167Q, 2.605313756841350663666908726854909254754e+2236Q, 2.009526310597759100040671805249352251293e+2307Q, 2.754855306228952463612144173863317999165e+2380Q, 7.912081217360857939375130225445886436671e+2455Q, }, + { 7.967275909080119173260394105433878829225e-2520Q, 1.018328235596330817906641738531405586075e-2480Q, 3.221582354315018745133234535022765889901e-2442Q, 2.577837396125923566854501272739510663846e-2404Q, 5.329692879048212454158155682964916728316e-2367Q, 2.907510479746435248283830679207105484516e-2330Q, 4.272515272958308108570054029079326796036e-2294Q, 1.725920944512128844318784735433112719801e-2258Q, 1.955365288532498067112004500362223834133e-2223Q, 6.33672146224698551106793067421941599521e-2189Q, 5.989055317923577956367893208101537342355e-2155Q, 1.682695935085939711542031154300739978911e-2121Q, 1.432104065344727957976083590066231975447e-2088Q, 3.761027283440035276506274748665174438543e-2056Q, 3.103973882224385163725384328628978101726e-2024Q, 8.196024681248225777873004659982426819745e-1993Q, 7.047501943265264073804265038957515028249e-1962Q, 2.008020122030836044260092764882735792941e-1931Q, 1.928585386478996757051377061536226588734e-1901Q, 6.349936504026115699331271816067930197654e-1872Q, 7.287319738451912662822173117194663954913e-1843Q, 2.962993354437338667093054088027903427137e-1814Q, 4.337549035352199493070093298251396522747e-1786Q, 2.322667953684500393631534979205588114281e-1758Q, 4.620940493203111397883251148877460552652e-1731Q, 3.46849175006702283349982309232738215393e-1704Q, 9.97197469066253825213923346003213563319e-1678Q, 1.114585267326982901794838942479030932334e-1651Q, 4.914714563824319863256125426084037061236e-1626Q, 8.673588082334046069888398076950448507162e-1601Q, 6.214129581324762232775539905301734104147e-1576Q, 1.832790291938882421191920578959728374086e-1551Q, 2.256171136581882657900944651081598896733e-1527Q, 1.175009240711975388097085650021684742673e-1503Q, 2.62368977120029668942611642547157610416e-1480Q, 2.545000194584350068428255601470918881705e-1457Q, 1.086378274323549748723752477385721065205e-1434Q, 2.066897696539443930872351598446447515579e-1412Q, 1.774772157298710208337196463122169403564e-1390Q, 6.963196512155587707171477008714118644169e-1369Q, 1.263545167784085371065018714077427939719e-1347Q, 1.073200483671541400965432755811734945193e-1326Q, 4.317082212314184926835882760831574340329e-1306Q, 8.32053604965395861253463941646191625903e-1286Q, 7.771734618559071081107688528229970310621e-1266Q, 3.557686044605213104209030012940037706499e-1246Q, 8.070528916876981426176871131000861955335e-1227Q, 9.171668926752907939883632747855449181794e-1208Q, 5.277894673647840384307719753102608158502e-1189Q, 1.55425000722110468554188982028632391378e-1170Q, 2.366680555098895290029405613091848674444e-1152Q, 1.882599225459190082401671846340953390019e-1134Q, 7.902192246540000601320781601302423345806e-1117Q, 1.767718149213402068974713376178812787862e-1099Q, 2.128098208048214966164629867555770669406e-1082Q, 1.392051591976656401133824170145523168896e-1065Q, 4.994719960920755555531504146997873320923e-1049Q, 9.922076126548449719468150236395605850173e-1033Q, 1.101311891894924117612397672953984177965e-1016Q, 6.892130837218420956087582351392004213975e-1001Q, 2.453524489921414170305853712838952078459e-985Q, 5.012096823429272595408207301327403858682e-970Q, 5.92625397256846848563576817503982351625e-955Q, 4.090293049633920583650165040912103911016e-940Q, 1.661753006709297398826495491631296133997e-925Q, 4.006680757962520202236462553833604795318e-911Q, 5.779925457403545302890808903391113431044e-897Q, 5.02848909102539886751126002796168835514e-883Q, 2.659105037910872144852205745069380936102e-869Q, 8.613275102396233614296997155697707276489e-856Q, 1.722011941149323047500322262512900155623e-842Q, 2.140858770279205828196814199482763570967e-829Q, 1.66733371240769894937624182878072907988e-816Q, 8.193863812957329774412230281809513275895e-804Q, 2.559097724964727559938640778629276385374e-791Q, 5.11527606584153978380615675677219021198e-779Q, 6.589313932434497001234913531610383100585e-767Q, 5.507550516048129444656311084411711270861e-755Q, 3.007020142650284579022887900120691321832e-743Q, 1.079545570904019147607701162275175357017e-731Q, 2.565046260212020805453775161290492247735e-720Q, 4.059551213679369050731379503131672168122e-709Q, 4.306509253842678754390905922017562669864e-698Q, 3.081277425837841400021155036519520671543e-687Q, 1.496049756497725324561151798326667339225e-676Q, 4.958858781223578709469932084235076593428e-666Q, 1.128776827757009886737844677649633126831e-655Q, 1.774824438031273259221674871341421861954e-645Q, 1.938718628529578614339845914362132261711e-635Q, 1.479580889476868168834482402842115319684e-625Q, 7.933076560959459481932759219061929332943e-616Q, 3.004696447884786585684784182577260233339e-606Q, 8.082686940259012888778153139360914820557e-597Q, 1.552426325390131757062306746548839627663e-587Q, 2.140102119938385745802494123096422882483e-578Q, 2.128429453740900159670547695806420238397e-569Q, 1.534912683226941140367083241016749973227e-560Q, 8.066256819954909759673837062709789215779e-552Q, 3.104238792273031330484452756380286340285e-543Q, 8.790844945644080595293305902463382662207e-535Q, 1.840618291261842948588744341179843557088e-526Q, 2.862777784664184513037699746755593033611e-518Q, 3.32279837181041061553234462323492937839e-510Q, 2.891235095586630121781435408715459157878e-502Q, 1.894375038101531296060137038995059871087e-494Q, 9.387752849968810937579512549662307625661e-487Q, 3.533872224235785186218523407943928105631e-479Q, 1.014810086945078087894935086994004318066e-471Q, 2.2324717569626557013949548912766445982e-464Q, 3.777884776738657261205533855337240737918e-457Q, 4.93786751664639347798897645870074547883e-450Q, 5.004920895479663677446497643024618520578e-443Q, 3.949427686727102477250133390725874321876e-436Q, 2.435767559087040930634684216214147613966e-429Q, 1.178587076580330886964544022890917953058e-422Q, 4.491023912606049854427428106653051102875e-416Q, 1.352680705533714285427651131064219006969e-409Q, 3.232175229700192859974514601701313013174e-403Q, 6.148979779244951167078060501065764873822e-397Q, 9.346618557699555690197507374939990133164e-391Q, 1.139095638725565354570660165510495028107e-384Q, 1.116882736988512594287339256913954444686e-378Q, 8.840180431626061992850152992185607078407e-373Q, 5.667122232091659511764331764542937857446e-367Q, 2.95210171074869287556924947738750388968e-361Q, 1.253616557485983210249402924206741962015e-355Q, 4.353499566130717956144486781651064963442e-350Q, 1.240243792752263780952771158279701378416e-344Q, 2.907393260879684488880153095982345233788e-339Q, 5.625244131026162975882364543895958678556e-334Q, 9.009739108786675273276970385188647555895e-329Q, 1.198087756353396256356294131034463223006e-323Q, 1.326548775108682048756687665666583870046e-318Q, 1.226448111135483120974035454571292238148e-313Q, 9.49468504349439811133142768178704940847e-309Q, 6.17181101323002240744175397407031718684e-304Q, 3.377707669589353604487497237523332765898e-299Q, 1.560512872109863571844393575758792286036e-294Q, 6.102236208573128122093888164692727956235e-290Q, 2.024929301988449522883491544065893159998e-285Q, 5.716567372402404783728122475078537540453e-281Q, 1.376428575092612476633988432370532525456e-276Q, 2.833585596240407856348272111949931080586e-272Q, 4.999632626016703452297995188196308401074e-268Q, 7.578746796653130874873290482021210756378e-264Q, 9.893195588497945068609978048738483752363e-260Q, 1.114710731734833240955445714249086995456e-255Q, 1.086588366772543409228146502433142567442e-251Q, 9.183764349360752966385023754968415218934e-248Q, 6.745119200393479925712383108023813390928e-244Q, 4.314368731526732239250885070923775496171e-240Q, 2.408432510386531771142800736481978254764e-236Q, 1.175865689260863816680634119022166918193e-232Q, 5.031403985679824041735142472001594305874e-229Q, 1.890676059338627176469623532390876131616e-225Q, 6.251957030364086922481747023515455758277e-222Q, 1.822832110299319014901260869272013670981e-218Q, 4.695228558883599546359502992313929137066e-215Q, 1.070485041990253205844787613056619988479e-211Q, 2.164411061170786494289133504038746022617e-208Q, 3.888149057834327052303287962939662414968e-205Q, 6.217077650284409358885672093877174576393e-202Q, 8.864490176680272259518995033084329107486e-199Q, 1.129060018025413968826902845797468943636e-195Q, 1.286873424792917053839022851662100381367e-192Q, 1.314795291417549889849051617164565642141e-189Q, 1.206202769586152888447188064879769552541e-186Q, 9.952847031230403569515431731634107940163e-184Q, 7.398656727363347668880677233416039563592e-181Q, 4.962946760441355726269312188537195172159e-178Q, 3.008841426137019577290269695130774172341e-175Q, 1.651250489636657038514219704463078872032e-172Q, 8.215822870116426810896344350411473632426e-170Q, 3.711707137271423160180212748621691502977e-167Q, 1.524862581521331587673406461025625884709e-164Q, 5.70508150602545345515626627261166302806e-162Q, 1.946690864521063015447882642259593648046e-159Q, 6.066751495971832907946605731816433411601e-157Q, 1.729218890749008111955745508052309562408e-154Q, 4.514184397107540977965003426103559880641e-152Q, 1.080776439193461578737828802075769030367e-149Q, 2.37630514513441024032933923861341092174e-147Q, 4.804539863300466911851715067980750771531e-145Q, 8.944359411396089882336022433298240800498e-143Q, 1.535148433653602528126818304598839769627e-140Q, 2.432217566861172517425147458255035408531e-138Q, 3.56159164851978783755994271005743068325e-136Q, 4.826206194592030239608964808604974782439e-134Q, 6.059123883793098626317651235341860311477e-132Q, 7.056186855737804734056421101084240937306e-130Q, 7.631197540594714170535291222444902661627e-128Q, 7.673190056935230923349040383785807876549e-126Q, 7.181420901238450533979697028062603205731e-124Q, 6.262949340804115487531782118695348240253e-122Q, 5.095149668836320992407738242504181244468e-120Q, 3.870905682539942846661487470875055347721e-118Q, 2.749201932883450268151961331830477076878e-116Q, 1.827228100144142861000456602099118570404e-114Q, 1.137673382674035107250733931604905546067e-112Q, 6.642336072005941146361966661287119272804e-111Q, 3.64028512339331626869107380312786986349e-109Q, 1.87450863444735780747041756540496602537e-107Q, 9.078133222842635422121285050940964351573e-106Q, 4.138812855052761279043494154268599225563e-104Q, 1.778000270650318764431469309976610087858e-102Q, 7.203855822800213289973969862777328396312e-101Q, 2.755303928538917650732532471686512499588e-99Q, 9.957111327196065437803034062710072445763e-98Q, 3.402816997218076148572057943527130789008e-96Q, 1.100680588716144971407937016574430544574e-94Q, 3.372653914433340593300308221192502433386e-93Q, 9.79793465921741389410002031066177808616e-92Q, 2.70089978913542155792813430020605674429e-90Q, 7.070447343835118744270507416522429771431e-89Q, 1.759128817422289300267493076673104253506e-87Q, 4.162968945574391702034525851121326185222e-86Q, 9.37779241810731989238679712769217329023e-85Q, 2.01243511678120567645753438316089357156e-83Q, 4.117122160765049554856907584525124497579e-82Q, 8.03596273765328793581294339359042233865e-81Q, 1.497514661862748564043414139894766607224e-79Q, 2.66627575240526913684138994676860937559e-78Q, 4.538860378486968408830116582994751799953e-77Q, 7.392623260932249293359287648677921377725e-76Q, 1.152810282079105430900943269743976641052e-74Q, 1.722334641963998877538919046212108072676e-73Q, 2.466982294003650362347496250523874402798e-72Q, 3.389902673647822893523319180268544603664e-71Q, 4.471576114525864494621630170567724674708e-70Q, 5.665802004349935660857687324817574414575e-69Q, 6.900180136205711399260007796162289923614e-68Q, 8.082103978670433565158160112244695539644e-67Q, 9.109949614051296700342120658333526754299e-66Q, 9.887660566787155914957022540708377404886e-65Q, 1.033978824499191800266695652953562102366e-63Q, 1.042367363142603472683903942222927019223e-62Q, 1.01360253850642711420235182625207856357e-61Q, 9.512510161747350299580075950049163390633e-61Q, 8.620693578866897400350402598749549001733e-60Q, 7.548215286708061079286950592874024396203e-59Q, 6.389002522263073684828225781548498851979e-58Q, 5.2304213467999807285495233989909068078e-57Q, 4.143618029730144849471458722659316057844e-56Q, 3.178215053889138479032361583006970626875e-55Q, 2.361375497747090350319603916992762005858e-54Q, 1.700353947901992650870275190000853698062e-53Q, 1.187181461482834292235814755757571995841e-52Q, 8.040926262915060358135936625876559056833e-52Q, 5.285800219918840044239185423363506533173e-51Q, 3.373901677142706872070242716798262993283e-50Q, 2.092036760993143554287714553393156854658e-49Q, 1.26071389736459024550376938832573535614e-48Q, 7.386967875256930161617715368501896621111e-48Q, 4.210245750567381301823721041940686239094e-47Q, 2.335212680852443576888813564758399301987e-46Q, 1.260975065550456669584777965304501230694e-45Q, 6.63174909295324620401889662345375243662e-45Q, 3.398355988046612747841700088585271753564e-44Q, 1.697476472841236183609850797662451898689e-43Q, 8.268085659326493130435461342952520749743e-43Q, 3.928638007500358866351367670626935931854e-42Q, 1.821720759355284457527987958132111168364e-41Q, 8.246860808847354549111270503081351496818e-41Q, 3.646064568177825762669789860457940857642e-40Q, 1.574882443754619623541008196995070064258e-39Q, 6.648395042005376085395386282489705285924e-39Q, 2.744004024875076628507083135601534661763e-38Q, 1.107653420681031633888214018454568434403e-37Q, 4.374454244420129201505123651246128890729e-37Q, 1.690799049659970724466269924181801546001e-36Q, 6.398132877939130220610010163346102651855e-36Q, 2.371103019047426350497793704573373960345e-35Q, 8.608431951088272831647481050248077098396e-35Q, 3.062756779443238602319536870269819051555e-34Q, 1.068198659583210038973746806524748536317e-33Q, 3.653227544700454531305797630670503225392e-33Q, 1.225515001519945073404871285296100665347e-32Q, 4.033738539559432392661992185921035446855e-32Q, 1.303082875824869971414005942159261214305e-31Q, 4.132734479820748852758173795520437853314e-31Q, 1.287147098350869770886623826581464367999e-30Q, 3.937913659653477883694284311172054333025e-30Q, 1.183782052799315485733017592458599891775e-29Q, 3.497544328892517187831545842100287032186e-29Q, 1.015914466727185220837422441064387754207e-28Q, 2.901804990894522420127448030270270503252e-28Q, 8.152849127534845411362622488936266274172e-28Q, 2.25367809417179806852681105934818375896e-27Q, 6.130912603089867849064196318283416796732e-27Q, 1.64178734291463510902060102240353937311e-26Q, 4.328857792089817047005743679842334899927e-26Q, 1.124084164810469092376383461223505192932e-25Q, 2.875386797856971912981506559923184846915e-25Q, 7.247144107627277984808094958723307043434e-25Q, 1.800156961022553615025218914199947112878e-24Q, 4.407829997906358459896106459287958053e-24Q, 1.064159909656974016807111538128709340566e-23Q, 2.533679394987778730189472745065558452445e-23Q, 5.950490597088776019748683578472561818409e-23Q, 1.378803645178565675477663430920122567538e-22Q, 3.152763311863490040779656649906049613957e-22Q, 7.11555798463800555819351867739855080496e-22Q, 1.585415769087416794558428166428232224083e-21Q, 3.488033184094363861639854904349888742437e-21Q, 7.578906150306100545423157126174164576149e-21Q, 1.626690309979793927151914765130208588376e-20Q, 3.449517091693030714666710333959651136005e-20Q, 7.228499497618258130899446599161547874565e-20Q, 1.497112865860816048764094432862181982629e-19Q, 3.065182400463867687382144796026279060458e-19Q, 6.204847831174082599165287964674983928818e-19Q, 1.242096716667761537684098553412968423806e-18Q, 2.4592597959525768067059363490903017727e-18Q, 4.81672896226015964045793790028985306539e-18Q, 9.334084950562834068284127795290557105276e-18Q, 1.789925014943490672474409292990156919458e-17Q, 3.397130025636848212544218713465822505885e-17Q, 6.382243159919550687632232044625421720437e-17Q, 1.187098865362206582279245836506254018227e-16Q, 2.186352889657557664550744789902758712378e-16Q, 3.987859744831167732326236478627157162656e-16Q, 7.204620697873539912480086209051030823416e-16Q, 1.289431790155955917841351554233503242944e-15Q, 2.286467374882308613486205332118436402814e-15Q, 4.017662252161183047836187284910855861237e-15Q, 6.99656785784342408232633767751107637346e-15Q, 1.207703613093171430146873960414485693713e-14Q, 2.066611834161126240026963698131523479667e-14Q, 3.506221191208017396780249818547308545177e-14Q, 5.89874025912113410833559535930664457693e-14Q, 9.841824583826900982294185470382304100122e-14Q, 1.628711979356644195640673557575737399349e-13Q, 2.673747297244544464041144412989940524217e-13Q, 4.354698030762685456146522867684472784597e-13Q, 7.037375613470243013811036742819534450189e-13Q, 1.128576426207602409839136130428624894649e-12Q, 1.796265444979361204491866760276216506487e-12Q, 2.837790274411961929167645624257533119362e-12Q, 4.450517051624898219124643410702559319937e-12Q, 6.92963583879943637167224732796899185484e-12Q, 1.071343498653279805152831768444006526848e-11Q, 1.644800798713549170982066141603139794962e-11Q, 2.507905928632347374338630836942320447304e-11Q, 3.798122183988670139277644917971882044735e-11Q, 5.713892308950583341199546461179201773938e-11Q, 8.539758065003606420501230564062147832472e-11Q, 1.268100729620471661902817410073941033457e-10Q, 1.871113767059724245386976661776370778825e-10Q, 2.743644295142664772759283079615343882946e-10Q, 3.99833185555888171640293913723530982506e-10Q, 5.791550996315273321902088121824651906299e-10Q, 8.33905623640836900250032445405370043217e-10Q, 1.193672562105227931589388299289134785728e-09Q, 1.698789266026923550073522461535190652611e-09Q, 2.403913727893853297080383302536080724682e-09Q, 3.382686884515520208065080745279262391703e-09Q, 4.733759174712641803740945710631487071936e-09Q, 6.588541092193685952258947629496486846735e-09Q, 9.121112685152380583998835576941094529702e-09Q, 1.256082033795070258308096624958598291786e-08Q, 1.720819844523096099720474511434503885155e-08Q, 2.345498050299132447846326603361136043516e-08Q, 3.180911042916052139309955352436778506108e-08Q, 4.292583225702628201046231718407734046636e-08Q, 5.764612626060727958623931970026984259394e-08Q, 7.704397341666848653267095123338097208871e-08Q, 1.02484168952891991947754465547361714047e-07Q, 1.356926702837583879755051597078815730847e-07Q, 1.788417551503950471950015064517069882061e-07Q, 2.346525819658947020385582160747980704228e-07Q, 3.065180852876392019694236336586654765768e-07Q, 3.986495033191807496354173430939013698484e-07Q, 5.162502188850122540844684197019554711165e-07Q, 6.65720997012649014040997771515440610649e-07Q, 8.549011167117627077144919459539055163198e-07Q, 1.093350316344842739482570460075507090481e-06Q, 1.392676894662565462032126480798341973487e-06Q, 1.766917725585667241992898344161547873865e-06Q, 2.232976345560288036947373699573375726808e-06Q, 2.811125648202381706895272765136403841401e-06Q, 3.525582061468103068665653163476736687771e-06Q, 4.405158376428709913646029278948069283329e-06Q, 5.484002631927202129384801097079834656695e-06Q, 6.802430623520435693108355760476215953221e-06Q, 8.407859685487256287710959317409001943954e-06Q, 1.03558513786321915073962476007182566071e-05Q, 1.27112705917308531277560249413305391114e-05Q, 1.554956831891198412168337708959965747403e-05Q, 1.895819499809689983959597375272763044769e-05Q, 2.303815077706507768668930312189393944145e-05Q, 2.790567840555153504276820390388733949771e-05Q, 3.369410362760997145481708684122315699185e-05Q, 4.055582696403286559517626972868029344242e-05Q, 4.866446962805309592997024360400453753624e-05Q, 5.821717500966089824845365574649413158772e-05Q, 6.943706569830923930053447899093868098698e-05Q, 8.257585439721267879079897718480289417549e-05Q, 9.7916605324640385949085647909368095273e-05Q, 0.0001157766408114819489026696755064685711663Q, 0.0001365105858059673951916433332558940095964Q, 0.0001605135409048256559138258125495353142543Q, 0.0001882243723673180815859848425981422149923Q, 0.000220129105359083888832193195380277964631Q, 0.0002567644044435395558985376934615952746774Q, 0.0002987211231186489549516252551089359495587Q, 0.0003466479020167920218943287065081041086883Q, 0.0004012547932769214992784035333438157199896Q, 0.0004633168865935784338501681041310863439442Q, 0.0005336779105791366983905761533437676567429Q, 0.0006132537813759504708063524124765235945565Q, 0.0007030360689550059158765139669182449713927Q, 0.0008040953502668325012890028878715651258039Q, 0.0009175844173963607454679355479874424263829Q, 0.001044741308141107407038707367942396160755Q, 0.001186892126003470975743583081981798214652Q, 0.001345453616481502859286364987039915779821Q, 0.001521935466772907586110083455839761654915Q, 0.001717942296584680418941635241375263314963Q, 0.001935175308671765557581701564207351830222Q, 0.002175433569013882948578843986006403688485Q, 0.00244061488817701827933962177717454590009Q, 0.002732716277387093760523031790972800227035Q, 0.003053833955155494667190955668647144637077Q, 0.003406162882922376111090737904328858634942Q, 0.003791995811102684339694547552585507990223Q, 0.004213721820106255238520670138395000924438Q, 0.004673824344328191012589440091579259760752Q, 0.005174878670736688316509780570084920182513Q, 0.005719548907487502446481303679623316137136Q, 0.00631058442192985698627201889000303700039Q, 0.006950815751398609527548621000197550798988Q, 0.007643149994271354192801093440865419580856Q, 0.008390565692865655199126566293274333642062Q, 0.009196107223819374276889186313994843390353Q, 0.01006287871559507536535044833068973909294Q, 0.0109940375166376773728040945023712313313Q, 0.01199278724145422091671644293048154728942Q, 0.01306237042543906222476060243442814308369Q, 0.01420606082260259352562017237936801265042Q, 0.01542715538344503858931888643358628745717Q, 0.0167289659530203930831754338734874664053Q, 0.01811481073173395916859919022391664972282Q, 0.01958800554358856744019143892683179847952Q, 0.02115185495842169316583797633449771810677Q, 0.0228096433161443911301425779096357227542Q, 0.02456462570209342382627799804527821306298Q, 0.02642001892333428109789892692937509533337Q, 0.02837899253610309628758625557724591354616Q, 0.03044465997455174638840433200930338711507Q, 0.0326200698305684182561478766940614844802Q, 0.03490819733369493186523156261607315466053Q, 0.03731193607906478545336713244881109055547Q, 0.03983409004985797457339959837144377122436Q, 0.04247736597902870508264605012848775314015Q, 0.04524436609303125412480485866465061775906Q, 0.04813758127797071695188343575966783160027Q, 0.05115938470606436195469305247887685131832Q, 0.05431202595754248111789162569375577872956Q, 0.0575976256701728356651407164727388580805Q, 0.0610181707454887735519286127955001295239Q, 0.06457551013756707073912038813096685540493Q, 0.06827135124686695200131838960274498733873Q, 0.07210725693823589850320643270045776879156Q, 0.0760846431987396666107037402041258283206Q, 0.08020477744751167235556685358836323731335Q, 0.08446877750636786639701687175860442218662Q, 0.08887761123652361947156590658579628794683Q, 0.09343209684340379971159263353331405267565Q, 0.09813290384827947634314597377864550592762Q, 0.1029805547223161917217849662754146410394Q, 0.107975427175599384648800929258392588213Q, 0.1131177570908303240224652780558492398361Q, 0.1184076420886768784022524072852628267607Q, 0.1238450457092316689652810284506150029169Q, 0.1294298021916876848049165341926394261599Q, 0.1351616218321983257068963021357149291953Q, 0.1410400968979531369261616983876599890975Q, 0.1470647080737783262838611415820062681671Q, 0.153234831416066732619412144570512369546Q, 0.1595497457875576600290825257800962557912Q, 0.1660086407454235928297088004549011805831Q, 0.1726106248542773238830740951304465857529Q, 0.1793547343950870081915214248666534071515Q, 0.1862399424405742377120762392711272315017Q, 0.1932651682674662866336549954877868791502Q, 0.2004292870759719115746122524278836114001Q, 0.2077311399870431986348998739442376385985Q, 0.2151695442883657277414314663960325511106Q, 0.2227433039005768119334724476408616510273Q, 0.2304512200359371707379802858704110927547Q, 0.238292102022565012438636869295500477757Q, 0.2462647782683726466471199486866921649987Q, 0.254368107340013678004869448238984448963Q, 0.2626009891334426438055153641042268648289Q, 0.2709623761140977072718583929657258698507Q, 0.2794512846062298136893226330853142403707Q, 0.2880668061125078167787824382718038889734Q, 0.296808118646717980840005593177875755319Q, 0.3056744980641377677579036909396937192142Q, 0.3146653293759881203313235805942140830196Q, 0.3237801180362461983090820270519599818301Q, 0.3330185011910228622657311928027273913756Q, 0.3423802588826678418804113983776109433992Q, 0.3518653252027527789924367138981015674402Q, 0.3614737993900911492268336792036467644866Q, 0.3712059568719780542735256003769499002505Q, 0.3810622602488663480435171795984767091639Q, 0.3910433702247335339010502511824521314023Q, 0.4011501564874320933236375501478126225841Q, 0.4113837085453508612370763030338926460708Q, 0.4217453465287439745740029610957751723861Q, 0.4322366319661047574509906269685113863411Q, 0.4428593785479733817386890110895733244681Q, 0.4536156628925687094231449505202515619854Q, 0.464507835329626572328505104590646627441Q, 0.4755385307208097937482079206198446406668Q, 0.4867106793370311448540891233670977920386Q, 0.4980275178150015090250825860923349908605Q, 0.5094926002172848568191354394503605415964Q, 0.5211098092221129673730069757438879031618Q, 0.5328833674711906123911808005586354523419Q, 0.5448178491057112741679836363725011074712Q, 0.5569181915228102063547315863613788776984Q, 0.5691897073867122497869745706167773132242Q, 0.5816380969308934474793883532843665800915Q, 0.594269460589676005299802716361632023448Q, 0.6070903119998240471222356070870425052955Q, 0.6201075914149121414331976341764137620912Q, 0.6333286795775096670077450936959654630057Q, 0.6467614120965724037497804104943555382337Q, 0.6604140943798696982054270851497081511967Q, 0.6742955171738133585239271173870307816064Q, 0.6884149727657060911128222112013278833933Q, 0.7027822719062066643044698811599154029693Q, 0.7174077615127308354587586170401139201738Q, 0.7323023432175871214633425313512827364943Q, 0.7474774928279014552006592596985716213354Q, 0.7629452807678324593654003954321067804243Q, 0.7787183935772384484317206900527945313626Q, 0.794810156544848547172767589390981649492Q, 0.8112345575581350364947114757891812390685Q, 0.8280062722565051964220310805112035656865Q, 0.8451406905791530670663872308556803104808Q, 0.862653944803960940002105223911111611703Q, 0.8805629391792451103891710796280884448635Q, 0.8988853812559305452871967488187545907845Q, 0.9176398150339469056412351899494533187875Q, 0.9368456560432984078524666287687994133458Q, 0.9565232284874095042002045886475279507954Q, 0.9766938045840272767944337301321751065917Q, 0.9973796462472128045133642631801931333523Q, 1.01860404926282392956317946592394034531Q, 1.040391390119430800501306096390484332391Q, 1.062767175666867240516297891529939479756Q, 1.085758095785663642281105802222348812045Q, 1.10939207926249369916261716500126785443Q, 1.133698353079565973147506826247703249701Q, 1.158707505339675825255735779161136390472Q, 1.184451552063483495095045621317392891301Q, 1.210964008111586732614521606850934884333Q, 1.238279962501205323185680973891105950334Q, 1.266436158405892106534863447479802864076Q, 1.295471078146741458304256385907446823312Q, 1.325425033505202083685015684659959438256Q, 1.356340261710947294764081629105735343643Q, 1.388261027483455161025774293888757855687Q, 1.421233731533158113469992887140017312801Q, 1.455307025957405656451286211771500914052Q, 1.490531936998228868219023421638164269274Q, 1.526961995663202046567211183531908173458Q, 1.564653376747784111876581362830437011253Q, 1.603665046837629160778144804262475653057Q, 1.644058921912742785217971171041985143034Q, 1.685900035222313480214992667532713310022Q, 1.729256716149878219924242767000386187611Q, 1.774200780843528793008066259722862522388Q, 1.820807735445503515984476325588028533978Q, 1.869156992820145515977178445445390578286Q, 1.919332103749290742415019782061183726939Q, 1.971421003640165834597778573110233965466Q, 2.025516275873364649088115856648097485223Q, 2.081715433008021275938209590135990804757Q, 2.140121217158552655052438896015999577182Q, 2.200841920963014547929530531274604977917Q, 2.263991730677979497484300076901683513364Q, 2.32969109305976045411657347024763207472Q, 2.398067107827710058779643401999432795631Q, 2.469253947653258420191531652724380454066Q, 2.543393307779451047507153399185346597841Q, 2.620634887551268158229579783397916906989Q, 2.701136906328329337203785565785074072196Q, 2.785066656460237449889254046340672661742Q, 2.872601096232473677614318257460754228219Q, 2.963927485939276452660257201800769243529Q, 3.059244070511369011437875195340374346818Q, 3.158760812423005873912952719525474220384Q, 3.262700178927088806749953484425989249023Q, 3.371297988021823798897713011575447983367Q, 3.484804317940613202084006553747118493489Q, 3.603484485381990625764882737049172673747Q, 3.727620098162165171514708146288863084124Q, 3.857510188483308323724907886381561506691Q, 3.993472433570707806928526443290607188682Q, 4.135844471046451472454246597080688613615Q, 4.284985317082080327173205151052609770788Q, 4.441276896113985089457451399096067523765Q, 4.605125691720244026764370781104263535342Q, 4.776964529153930976873581660867167367634Q, 4.95725450101436623824090639311762907648Q, 5.146487048624035738339801115424373145069Q, 5.345186212875773055646526104283213166619Q, 5.553911069634338220218711432966624812946Q, 5.77325836623218909927059759764589584879Q, 6.003865377206048605761449274343927216903Q, 6.246412999195612054604668256261603981218Q, 6.501629106887186763618395996193518237451Q, 6.770292194054217171968109306745209606844Q, 7.053235326147045417971320097171996692265Q, 7.35135043354224614666015033130666518755Q, 7.665592977507008524711768710447822251596Q, 7.99698702419947858650763841033117635338Q, 8.346630765648955546734771430943712584567Q, 8.715702530682195108316710736134856148585Q, 9.105467333230856750332784441560793915267Q, 9.517284010423279804954247067378435207565Q, 9.952613008390899735914523387635646169422Q, 10.41302487987290341264917855291653594177Q, 10.90020956455793654418731784931574442836Q, 11.41598653074432960761644356555484658751Q, 11.96231586542698517926431253288706983627Q, 12.54131040943894482491352029147685616503Q, 13.15524904491223096736253493917986547645Q, 13.80659125421566013309472641076367137531Q, 14.49799308283537068733806522611592929918Q, 15.23232465356644138323597883223098213734Q, 16.01268939608506359051333506048449232573Q, 16.8424451747018194731026127671712692775Q, 17.72522751812091969571786639162509975806Q, 18.66497517864721511431497872041775884551Q, 19.66595827483338098446967472260739788953Q, 20.73280930143244666471574442281522903193Q, 21.87055732415900772060659367071969224017Q, 23.08466571467196402575438824917868654178Q, 24.38107382395057915687200907586246892126Q, 25.7662430405051812966499914509625384785Q, 27.24720773440068300935745005728667380869Q, 28.83163164974229758945104220936171273136Q, 30.52787037807261230893713949085699006405Q, 32.3450406241987409077896619933344018561Q, 34.29309706561872681849669817137072613286Q, 36.38291770845545162245476827741032427239Q, 38.62639875836956225627789882526940946526Q, 41.03656015631005798746236445920699096398Q, 43.62766307847848111679875785712898620598Q, 46.41534087019270662202361582551787873513Q, 49.41674507751608025548331094469808937291Q, 52.65070846212654381646552716106077643221Q, 56.13792713806019302031335914182740881889Q, 59.90116425845236114237707095933490569938Q, 63.96547801176112688533109691101640809997Q, 68.35847706663356290654056305516520187869Q, 73.1106070400535228943010840853771922367Q, 78.2554720634100436673165461770242295508Q, 83.83019609580841382274286001915828318548Q, 89.87582929516635773217532104021295646478Q, 96.43780551924200423365120382987901990037Q, 103.5664579069193585087895746723625879788Q, 111.3176005037851754525798266671368531998Q, 119.7531850674833499641095701349550588967Q, 128.9420435435961078207576974725019132169Q, 138.9607282724984871708695514001995649591Q, 149.8944638077825781408536567743182992156Q, 161.8382263398671525938367526689287312097Q, 174.8979691743083696073045128037176486302Q, 189.1920155721483495460012542161168057521Q, 204.8526435891665175913537920041964014778Q, 222.027891434725956190837338565467777867Q, 240.88361640690763753526746528298183629Q, 261.6058457649334272046319924765364648261Q, 284.403464110476071641090421744246851318Q, 309.51128913049882030120008084966685685Q, 337.1935961013210043006610512490274375597Q, 367.7481615999600937711438359582960700752Q, 401.5109086931381617979355424315925378221Q, 438.8612498100309866908178648997732329971Q, 480.2282399512316532893085494373602185103Q, 526.0976723225701163012986065722476344299Q, 577.0202714839153277613560365269689534811Q, 633.6211663623286914660652375227156227858Q, 696.6108578302568399031998061512477922416Q, 766.7979339996213953902457962279823199983Q, 845.1038321483961377544033152655484401883Q, 932.5800007502418686784878634625973295461Q, 1030.427880205268371607863481564260421702Q, 1140.022198738619409531305753764053160504Q, 1262.938173179340126267770568255475671177Q, 1400.983316165672812706630096023677023453Q, 1556.234685661799166419834076272895832667Q, 1731.082574302171248664168847453614878774Q, 1928.281830862719311465180216556548647829Q, 2151.012241278362996194541735020086674113Q, 2402.949680908323672668281479483735120957Q, 2688.35009405274898539046388166782344203Q, 3012.148774428996002817780038366771869698Q, 3380.077927947738665430980404057153553452Q, 3798.8061171273287816025804901302085407Q, 4276.103940178038843575493542846970132437Q, 4821.041218620766468858314278886473414916Q, 5444.222094388470795213327524033646097556Q, 6158.065819431147727245029087643341223611Q, 6977.142718757731621969847227843666046181Q, 7918.57689772303460428259761072791249996Q, 9002.529841616973008609731087967074460965Q, 10252.78224006547697358532192963572223849Q, 11697.43531120386115196874312407799521273Q, 13369.75779118806422297716318991439523796Q, 15309.21083364664327603498100930983535561Q, 17562.690635400711230682290340971331153Q, 20186.03805526835731073576014831323115031Q, 23245.87631298432720823386094470123690508Q, 26821.8526708964660159886933177732467881Q, 31009.37861130203017968748996249105326523Q, 35922.98645004505473991896385042800280479Q, 41700.44988478085183088793644390235506667Q, 48507.85335185738720597387629792697758441Q, 56545.84243439263590453434852169343975209Q, 66057.34773622772120970119305119425356007Q, 77337.15125150264720189777207255380428642Q, 90743.76204222132276487959174812557638943Q, 106714.1931345439161543996792387468025379Q, 125782.3919792783606644548980631212452294Q, 148602.28308268868913284386494314759249Q, 175976.6472537126831529901228629810350888Q, 208893.4054123648023151893924130651509251Q, 248571.3198896581872265252528072315261787Q, 296517.7041099588785074932688713451965026Q, 354601.4842046107884858345245389612826445Q, 425145.9388942126878002415502363163400429Q, 511046.7307492540007761231679727362111046Q, 615922.5313638820825468503152050330940154Q, 744307.7672522774013301855992769478990101Q, 901899.9500280627208570829224628231273515Q, 1095877.943017809647466283294609129783732Q, 1335312.680400192900473900972313608959584Q, 1631698.732799417297778849111829227960256Q, 1999644.301287932721508706558730228833034Q, 2457769.533243204063209231606836355450074Q, 3029879.601126654923164320051829081011141Q, 3746501.296107716197697994644755801894388Q, 4646902.065144207843314545735079873944726Q, 5781751.367051714701608613666500464883081Q, 7216639.965420261461783043861588641172554Q, 9036748.91103818439407145784950842727797Q, 11353064.30295396674362518583710002098171Q, 14310677.38848294383826734043939982225179Q, 18099907.52814647757667209831825354212464Q, 22971259.6668891917836879617589957239566Q, 29255608.85808781354322251315088609515549Q, 37391535.59237359316460832559373862826806Q, 47962479.20390166985661378587634109109441Q, 61747421.18114908020763006555364067577321Q, 79790283.20014303517364767024983720002342Q, 103495309.7818322791392225142306514842407Q, 134758668.4335062392784062691770869168908Q, 176150727.1167647396710291203195515696546Q, 231169523.1730998536214569360302706436015Q, 304594644.4399651635506297387509567217169Q, 402983315.5328752866261842165179493486228Q, 535368712.0454349728436136721216726833139Q, 714247070.3053378406139506672831438081902Q, 956978978.7740373778892004432884152696425Q, 1287787251.056266365052170195833743740423Q, 1740617888.192125045084695206325485163025Q, 2363255270.596386879033770262261785331955Q, 3223268243.013810967426011910089526282321Q, 4416641191.505012065410596295491828581351Q, 6080361037.679268493630106361893438552833Q, 8410860300.522297192863904820721664748136Q, 11691170810.23185446900657258020662184426Q, 16331097466.34382519842012415317299709164Q, 22926949953.32506221058163368461899055449Q, 32350801251.34441900313971832417983264306Q, 45884550887.87373756921169916820389200205Q, 65422328991.26591065899030653729434101914Q, 93777690083.05024525805287034041120136343Q, 135152344877.9312446339111822592163115366Q, 195855262619.5102394227400235042902030497Q, 285411966950.5744584463492472652528305332Q, 418285339123.4088687905886483684441030554Q, 616560216997.1507015559128477210327029614Q, 914155798247.046721897379660004085140681Q, 1363474103153.313475332332520737128454563Q, 2045955806530.38080332307163606468874395Q, 3088941238912.347778181637746413811180547Q, 4692768203830.229326011299203618570047404Q, 7174593389222.668179510729483054183954121Q, 11039707421424.7535285760553205782673006Q, 17098339814642.30883189402376214028857248Q, 26658220492645.27096615518476281285140601Q, 41844137833284.34059723603044347303078534Q, 66131822092212.56260433143407179128676762Q, 105246004103885.8447522437221674794658493Q, 168681559938365.0716704855055188081332796Q, 272298230587943.4228747819094080068890302Q, 442778332914208.8581203935475801325800709Q, 725340820090340.5850347950296827399214103Q, 1197189129009285.106993300968997149725738Q, 1991130686955199.032617972879924186900084Q, 3337378010666735.506952950406469988115707Q, 5638099922749490.406581662527138521678621Q, 9601427499741881.211823807926750198760527Q, 16484254092349348.98845372947631486314024Q, 28535723974924115.84032543376000631602713Q, 49813965452361994.64837345276433255672811Q, 87702782408500507.02084267463945306822658Q, 155752125029829556.4155463030004333389455Q, 279043670263039211.1950144058463979753731Q, 504415149791330774.373714179037049083309Q, 920116740121384961.3827433654664139990454Q, 1693942563317466607.969360487779734224803Q, 3147881813588503606.949687187530927219109Q, 5905629394327348620.964750033118718606609Q, 11186830170429972683.90503304219913230732Q, 21399669223814878252.89102214192683014818Q, 41345985808186444702.65217417004483350894Q, 80696386697395085475.26410049325816995634Q, 159125037274329006606.8786857330403125667Q, 317071329836898082746.6238825600530512982Q, 638529399076067500974.9466574352370019617Q, 1299818924097534326158.990461297267263975Q, 2675078654074978206518.637506117225931Q, 5566944189022631213362.099038457498976086Q, 11716552341597990248990.5171435566483995Q, 24943805360858062472816.00063661308666544Q, 53725930189976218263874.47358413133583937Q, 117096316957750403564988.56304888156271Q, 258298292038703721390495.8236396936501247Q, 576767877261231270067849.8484954071029679Q, 1303963227039250295013435.358818079135299Q, 2985377159576379451118689.073633893728235Q, 6922912113704827260367186.083906017707785Q, 16263788067632228522850044.30274061276946Q, 38715669422591640446273220.48107692525781Q, 93405902326795746218849693.41808866100623Q, 228442062263956655676707457.4277829780059Q, 566480802429004551807161785.525553048924Q, 1424611114198876208195667756.664348169039Q, 3634172949857829218775326055.022683993536Q, 9406122364586675152583301141.322786625963Q, 24706464444758897130981477914.48038397415Q, 65872820457540932835165401933.67205736797Q, 178319944111489749419279438635.2410294258Q, 490225068350940521098480834251.6808904126Q, 1368984772740533848004072374113.409441503Q, 3884333014472347772834359801746.655971535Q, 11201029764013440779432129805270.58958674Q, 32834751787829632611461325466661.61440042Q, 97871488077698794764611261629326.14611831Q, 296714970484721897998030463296972.3588181Q, 915165168173240309272518702527005.381633Q, 2872460267173498910803623624768017.743058Q, 9177464747767130953083654377275067.095958Q, 29855687257363621764846076009157648.30726Q, 98921454300453615088000828632641016.23094Q, 333916858936387164243193277343677648.8645Q, 1148677119756490680705739927834502644.262Q, 4028085735873633572809913571370067079.051Q, 14403629095536081310122394964760721828.66Q, 52535284391711770924959341342130057524.83Q, 195511238702341217234148056362961569426.5Q, 742628359135587348679681010616409214772.4Q, 2879985786290129359256278011916116854096.0Q, 1.140696796840996797711738648003995766426e+40Q, 4.615889998203199535641248805067886524741e+40Q, 1.908941368569039653622830158192604926747e+41Q, 8.071058712835471546948188653318290734289e+41Q, 3.489959706112432919449108947044335064462e+42Q, 1.543888386814652700671726911000678239128e+43Q, 6.989932474233277622942141615547447627292e+43Q, 3.240038117762964872837102805973332306521e+44Q, 1.538183968209712484725068871595387907532e+45Q, 7.481883824192840270769874827358924746817e+45Q, 3.73013225339343201187931343434453690825e+46Q, 1.906851076505672829935280449453775492013e+47Q, 9.999077656071522270351775782972854776915e+47Q, 5.380563552050893470837576599671463394205e+48Q, 2.972330032282961488357047932157273938273e+49Q, 1.686348374699422063673300554972483611095e+50Q, 9.830168535442368803758339268296974599245e+50Q, 5.890108429190751064006128529315046824849e+51Q, 3.629296561939369243399179077578354993584e+52Q, 2.300645004501572067249374084078975050572e+53Q, 1.50106294849063099901010627951209585913e+54Q, 1.008480606717589095366587976999767304221e+55Q, 6.980007119035887928080977649978198675152e+55Q, 4.979288841677991603006522250488653330001e+56Q, 3.66276106448839180486992300970231614026e+57Q, 2.779646718727500962719473248533230654228e+58Q, 2.177326686395961419408952027332377399652e+59Q, 1.761274961525829532053705828024510976734e+60Q, 1.472042344123250900757337524678434441804e+61Q, 1.271822455421028839508598095571294694327e+62Q, 1.136508544602098866393539277964124525428e+63Q, 1.050968050635916077523427282417608640335e+64Q, 1.00626207712914662753370159827651041146e+65Q, 9.981030000833852218070495344493841448017e+65Q, 1.026180847075813778541059391701842979761e+67Q, 1.09421374737140946315988080967962942332e+68Q, 1.210763841397564590646317030645949174098e+69Q, 1.391069896832891097224590572614426931551e+70Q, 1.66045803643638884585898488848404012021e+71Q, 2.060428539953847004622281786713096894814e+72Q, 2.659520130664924331541795505319434146906e+73Q, 3.573013284264659144117143659354260264313e+74Q, 4.999486492804923952719809970672723582345e+75Q, 7.290439237429593217623599777130532573045e+76Q, 1.108669253112891672863961714590332883419e+78Q, 1.759370316250180690332753515259259156688e+79Q, 2.915485723182837008934603124966328270354e+80Q, 5.048461194348245760902730455814691168198e+81Q, 9.14118029796915194428405620075256632899e+82Q, 1.731992937477462342845227375134295284526e+84Q, 3.436376953072005833211777807213125461832e+85Q, 7.144658133694111972876923978928526300053e+86Q, 1.55778737763103944888409221887807238926e+88Q, 3.564561555743844052143091887908206876342e+89Q, 8.566541566276859225670891601341438867685e+90Q, 2.163923297209145308730010116371450613445e+92Q, 5.74984144627868535047457089036754294733e+93Q, 1.60839847723572274756032280074086871365e+95Q, 4.740310317452400773817968906768308847938e+96Q, 1.473168155068744631692643356229607264882e+98Q, 4.831622757046275226639687085840067067887e+99Q, 1.673775819766076748422178976772154137065e+101Q, 6.129702080773580414198288240232221663836e+102Q, 2.375195572649536955856341846366320025447e+104Q, 9.746830708765397472546215846003382904173e+105Q, 4.239588455190572482069216933841673146039e+107Q, 1.956494245370687105054870244894992250777e+109Q, 9.588102853447409054394849979650825404339e+110Q, 4.994557760892807128927411547962380678913e+112Q, 2.768146852290885169241442660307412799022e+114Q, 1.633928319786263704798907980813701003631e+116Q, 1.028156908727469064515118226996254551401e+118Q, 6.904080374041585885024483266963686212709e+119Q, 4.952411576392766271393256067965393360727e+121Q, 3.798774197493427340709475899043548697485e+123Q, 3.119209910408000389677151746883852508364e+125Q, 2.74464281329371919028887605085237578063e+127Q, 2.590837914912684682640131392851692377728e+129Q, 2.626566210336074467392696546232535266827e+131Q, 2.862979557234280901204803416309101850378e+133Q, 3.359121393671599351439597581159266025716e+135Q, 4.247313211033286464137443445775235101828e+137Q, 5.7942272714265457019323508964771867228e+139Q, 8.538645358004657015182819424098214783173e+141Q, 1.360888004282941018668670601150276254469e+144Q, 2.348723067724485698744588128779913095071e+146Q, 4.395029120308788033535362463288942558768e+148Q, 8.928228383284871526851861594213174257963e+150Q, 1.971533670422240464246243093548157857339e+153Q, 4.738589737247294610658233560831235896082e+155Q, 1.241308244941580876284153148872321788032e+158Q, 3.548824589134106728881153020185390663367e+160Q, 1.108821925774839482718156058757565092921e+163Q, 3.791568324747532283399755029435267152261e+165Q, 1.420930300659947104773952851462106093989e+168Q, 5.84453799109152853361078444336558106409e+170Q, 2.642333927756119541622130789938393830472e+173Q, 1.315018700128967486521348415446442009019e+176Q, 7.215055214056115599570975509522351983024e+178Q, 4.370972004835405599501947122396095759213e+181Q, 2.9283613461041822425605630116860831466e+184Q, 2.173040852495516111888092260762700043093e+187Q, 1.788985622982511228211473383825580284642e+190Q, 1.636634504773987713192039651921165926626e+193Q, 1.666570888998858107369856444049108728955e+196Q, 1.892151113181535234424384795106566625139e+199Q, 2.399341256020760750689416036737132433809e+202Q, 3.403990692562377717224530571668026437231e+205Q, 5.412684450566753125713167924326746292328e+208Q, 9.663735052574312957366051717393887459725e+211Q, 1.940785411690247394647362413292066051113e+215Q, 4.392532041151062373685805234839718468544e+218Q, 1.122469784801228315610393382333655697996e+222Q, 3.244792593820658963686565461190260558268e+225Q, 1.063151412606654581889047233605046614442e+229Q, 3.955995687476636211061457789343143304844e+232Q, 1.675093730347128892220647880504964819835e+236Q, 8.087770848773335454281892374161575798369e+239Q, 4.461929541005863065785797298033896045328e+243Q, 2.818594400456011731351928477247466992727e+247Q, 2.043076786152914736967629947070114858535e+251Q, 1.703020313436824993942113027133546248076e+255Q, 1.636038893251936899296016502545612941115e+259Q, 1.815418460356235422023246399959725267478e+263Q, 2.332142886850178672234463486793710072382e+267Q, 3.476404726198879520090342868431980509165e+271Q, 6.02725450669274575708398710171785543849e+275Q, 1.218304996377836253272518577114790751006e+280Q, 2.877990538823511127754633031010804415019e+284Q, 7.964996943223120262348859076890157988359e+288Q, 2.588973716628916728047311617227986411804e+293Q, 9.908669888497828069120771232809956622636e+297Q, 4.476782590934448698631648708447218305023e+302Q, 2.393946289872904750991457301609667478573e+307Q, 1.519194065472150234303611944283693040837e+312Q, 1.147184880467145335990085347869884772013e+317Q, 1.033627774385061887195237160951315788932e+322Q, 1.114329281092576402692439832629726866969e+327Q, 1.441479839401683621084678999839363913781e+332Q, 2.243859327319511203437262571615345659758e+337Q, 4.215418497025923051098094558302194889077e+342Q, 9.585829785115038185661111425389321480842e+347Q, 2.646481452232988267470696963344934626712e+353Q, 8.89784570848809579740737460434820021581e+358Q, 3.654478434391815119731593878923994274866e+364Q, 1.839328571998191153309682048643039357777e+370Q, 1.138091115297408561689593979279964151166e+376Q, 8.685420860596502744558689502785399264335e+381Q, 8.202294873735399393185427253762485343561e+387Q, 9.617622211012637558143840626406701008311e+393Q, 1.404972969423732814470812460457324672731e+400Q, 2.565898938978703228107858106775855677516e+406Q, 5.879082125410122180654821992667679428038e+412Q, 1.696012443986232559131127974976016333649e+419Q, 6.182635207061036709662140763355431230729e+425Q, 2.858535933001077693342990841750579771279e+432Q, 1.682537298081273384688483838923408088448e+439Q, 1.265575099379113494236586140787099830899e+446Q, 1.221210377447344985626110580846200012905e+453Q, 1.517665191579856561612622774652863045029e+460Q, 2.438792156389105075630091184035735481592e+467Q, 5.087970569512535749002437068314762668605e+474Q, 1.383791668577664156393179945731681404331e+482Q, 4.926818942421142280481071642006166530446e+489Q, 2.306079479408307605132901861123305364681e+497Q, 1.425163636904652491964810204050170654619e+505Q, 1.167988230033416008655199893436256564186e+513Q, 1.275046076993048598825372293330373578487e+521Q, 1.86246353592536022566810742828968418859e+529Q, 3.656923281780862954333590022998862124388e+537Q, 9.696905002869973525940370399688193605905e+545Q, 3.488948519517137250033917388900863677716e+554Q, 1.711541280860496566193503287636236147624e+563Q, 1.150354590150357338329469526604301396277e+572Q, 1.064586955227472600644681500814476378383e+581Q, 1.363399241303394867639622834102250083249e+590Q, 2.428730562379263868477135617904841079855e+599Q, 6.049324540156405309997840862794643030452e+608Q, 2.117864171596828953446343836759090767393e+618Q, 1.047807516700166731633507555828693597684e+628Q, 7.365840114672675880252522494113514523595e+637Q, 7.398145492560429927900357801839811327058e+647Q, 1.067636747584131414468100025618283209301e+658Q, 2.22639858034098687306401094797599805894e+668Q, 6.748057923046794570772294496845240165064e+678Q, 2.990257191488723121175096872976103128614e+689Q, 1.948901043872427503145006863820911627038e+700Q, 1.879581186786894369816802738913105922879e+711Q, 2.698997931735600125081085882104105417964e+722Q, 5.806794882741622880474886909554775109619e+733Q, 1.883770843607193027100793847871062947288e+745Q, 9.274404492358642603751756778289018245069e+756Q, 6.975307042717716858281521605314873677261e+768Q, 8.067850522456048441251197638882843500221e+780Q, 1.444817834210597780118974729779559393721e+793Q, 4.033842652061704730692481744304620504234e+805Q, 1.768122616586398867633690641669676999188e+818Q, 1.225400779279196264005900309164283624649e+831Q, 1.352538486275098128663407391866246559851e+844Q, 2.395022076176373866310260662550018260889e+857Q, 6.85473457159274328678409145257099377572e+870Q, 3.195043165613256224203167145283241373075e+884Q, 2.444011394541681034079796623093288489705e+898Q, 3.092132542900569483086826127272209424616e+912Q, 6.52202827899369001274608906112336954129e+926Q, 2.311918230803327273869816369617489055755e+941Q, 1.388602808524064591680879431092854078226e+956Q, 1.424970459220504800074970047827419053133e+971Q, 2.519528084028136647765117343629838887978e+986Q, 7.741747865648544410946053665346929221769e+1001Q, 4.170084664493231900748918523968910566173e+1017Q, 3.972609017709578843063743585633222829841e+1033Q, 6.753538916409713709617458845853916542168e+1049Q, 2.067628729105681113174425295794554011159e+1066Q, 1.150595286862592019698043377859855347102e+1083Q, 1.174811465056168119582538764054374610771e+1100Q, 2.222083328904688772385369058449897242601e+1117Q, 7.861682153952467469302910158034016013007e+1134Q, 5.254318461012202675141984565028119771927e+1152Q, 6.700594094583685233271878665147881576963e+1170Q, 1.647119020685994883163368465161853068246e+1189Q, 7.885690686668208640526803176415414652937e+1207Q, 7.4304751845758892706961097079985818407e+1226Q, 1.392792237173373732943845763489796692971e+1246Q, 5.249920365660960360703118769306589305549e+1265Q, 4.023402905801975410548914995317394511897e+1285Q, 6.339599284962247390595019787493325156388e+1305Q, 2.077241686093845039324765598314087816491e+1326Q, 1.431779975481430956320443955567912020619e+1347Q, 2.100465323416655119498460724075198611756e+1368Q, 6.636983859221341948458642440032983398444e+1389Q, 4.571823013121701821960348272081362696364e+1411Q, 6.950266919826043719478213435615389027377e+1433Q, 2.361135677422321798996803825169777731761e+1456Q, 1.81529414070336188314937395066678659112e+1479Q, 3.199377508347820763307843188560103423205e+1502Q, 1.309634685394754467330604052024343046006e+1526Q, 1.261723464022528810857575246242118215115e+1550Q, 2.899755666233745652203077582611886981277e+1574Q, 1.611713776270703974807271588562419300726e+1599Q, 2.19676411063602902712587963185490636918e+1624Q, 7.447023857089897627918973727754688355819e+1649Q, 6.369675504111348389431884118799197436233e+1675Q, 1.394815207171927514566140884379200385497e+1702Q, 7.936153825171883059251330198006999518483e+1728Q, 1.1910445325646918131560389884140321995e+1756Q, 4.787444622805551600670119808904041332089e+1783Q, 5.234499335419787802823707399035765773041e+1811Q, 1.581561346401448146226935104237919854933e+1840Q, 1.341800978646655211480455388688595380576e+1869Q, 3.248945821168265660658282098925159913182e+1898Q, 2.282556137907219990369095437167406320923e+1928Q, 4.731625652419454163270049779439076104421e+1958Q, 2.943806123841568264632623519839271578756e+1989Q, 5.592866921504286485703902089288874207169e+2020Q, 3.302335002048689098318554609779249829828e+2052Q, 6.169134926587465224122713900861282080699e+2084Q, 3.712967718086223830358857404823946563008e+2117Q, 7.333531367839546065849712040185078455141e+2150Q, 4.843145606030966902891830748397061937228e+2184Q, 1.089982666110516514588223374299888929834e+2219Q, 8.522650010812465527516484755846137052377e+2253Q, 2.3610765478146005801436450249132797273e+2289Q, 2.364162440159704628905098100196710729676e+2325Q, 8.731002547249769088070048025315387840088e+2361Q, 1.213938210671504830248830740465072981967e+2399Q, 6.488456377484030822273896401425291289227e+2436Q, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -8.916559006047578828258918121202852111589Q; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + /* + std::cout << std::setprecision(35) << m_t_min << std::endl; + for (unsigned i = 0; i < m_abscissas[0].size(); ++i) + std::cout << m_abscissas[0][i] << ", "; + std::cout << std::endl; + for (unsigned i = 0; i < m_abscissas[0].size(); ++i) + std::cout << m_weights[0][i] << ", "; + std::cout << std::endl; + */ +} +#endif + +} +} +} +} + +#endif // BOOST_MATH_HAS_NVRTC + +#ifdef BOOST_MATH_ENABLE_CUDA // BOOST_MATH_ENABLE_CUDA + +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace quadrature { +namespace detail { + +// In the CUDA case we break these down into a series of fixed size arrays and then make a pointer to the arrays +// We can't use a 2D array because it takes up far too much memory that is primarily wasted space + +__constant__ float m_abscissas_float_1[9] = + { 3.47876573e-23f, 5.62503650e-09f, 9.95706124e-04f, 9.67438487e-02f, 7.43599217e-01f, 4.14293205e+00f, + 1.08086768e+02f, 4.56291316e+05f, 2.70123007e+15f, }; + +__constant__ float m_abscissas_float_2[8] = + { 2.41870864e-14f, 1.02534662e-05f, 1.65637566e-02f, 3.11290799e-01f, 1.64691269e+00f, 1.49800773e+01f, + 2.57724301e+03f, 2.24833766e+09f, }; + +__constant__ float m_abscissas_float_3[16] = + { 3.24983286e-18f, 2.51095186e-11f, 3.82035773e-07f, 1.33717837e-04f, 4.80260650e-03f, 4.41526928e-02f, + 1.83045938e-01f, 4.91960276e-01f, 1.10322609e+00f, 2.53681744e+00f, 7.39791792e+00f, 3.59560256e+01f, + 4.36061333e+02f, 2.49501460e+04f, 1.89216933e+07f, 1.03348694e+12f, }; + +__constant__ float m_abscissas_float_4[33] = + { 1.51941172e-20f, 3.70201714e-16f, 9.67598102e-13f, 4.44773051e-10f, 5.28493928e-08f, 2.19158236e-06f, + 4.00799258e-05f, 3.88011529e-04f, 2.29325538e-03f, 9.25182629e-03f, 2.78117501e-02f, 6.67553298e-02f, + 1.35173168e-01f, 2.41374946e-01f, 3.94194704e-01f, 6.07196731e-01f, 9.06432514e-01f, 1.34481045e+00f, + 2.03268444e+00f, 3.21243032e+00f, 5.46310949e+00f, 1.03365745e+01f, 2.26486752e+01f, 6.03727778e+01f, + 2.08220266e+02f, 1.00431239e+03f, 7.47843388e+03f, 9.75279951e+04f, 2.61755592e+06f, 1.77776624e+08f, + 3.98255346e+10f, 4.13443763e+13f, 3.07708133e+17f, }; + +__constant__ float m_abscissas_float_5[66] = + { 7.99409438e-22f, 2.41624595e-19f, 3.73461321e-17f, 3.19397902e-15f, 1.62042378e-13f, 5.18579386e-12f, + 1.10520072e-10f, 1.64548212e-09f, 1.78534009e-08f, 1.46529196e-07f, 9.40168786e-07f, 4.85507733e-06f, + 2.07038029e-05f, 7.45799409e-05f, 2.31536599e-04f, 6.30580368e-04f, 1.53035449e-03f, 3.35582040e-03f, + 6.73124842e-03f, 1.24856832e-02f, 2.16245309e-02f, 3.52720523e-02f, 5.45995171e-02f, 8.07587788e-02f, + 1.14840025e-01f, 1.57867103e-01f, 2.10837078e-01f, 2.74805391e-01f, 3.51015955e-01f, 4.41077540e-01f, + 5.47194016e-01f, 6.72466825e-01f, 8.21304567e-01f, 1.00000000e+00f, 1.21757511e+00f, 1.48706221e+00f, + 1.82750536e+00f, 2.26717507e+00f, 2.84887335e+00f, 3.63893880e+00f, 4.74299876e+00f, 6.33444194e+00f, + 8.70776542e+00f, 1.23825548e+01f, 1.83151803e+01f, 2.83510579e+01f, 4.62437776e+01f, 8.00917327e+01f, + 1.48560852e+02f, 2.97989725e+02f, 6.53443372e+02f, 1.58584068e+03f, 4.31897162e+03f, 1.34084311e+04f, + 4.83003053e+04f, 2.05969943e+05f, 1.06363880e+06f, 6.82457850e+06f, 5.60117371e+07f, 6.07724622e+08f, + 9.04813016e+09f, 1.92834507e+11f, 6.17122515e+12f, 3.13089095e+14f, 2.67765347e+16f, 4.13865153e+18f, }; + +__constant__ float m_abscissas_float_6[132] = + { 1.70893932e-22f, 3.56621447e-21f, 6.19138882e-20f, 9.04299298e-19f, 1.12287188e-17f, 1.19706303e-16f, + 1.10583090e-15f, 8.92931857e-15f, 6.35404710e-14f, 4.01527389e-13f, 2.26955738e-12f, 1.15522811e-11f, + 5.32913181e-11f, 2.24130967e-10f, 8.64254491e-10f, 3.07161058e-09f, 1.01117742e-08f, 3.09775637e-08f, + 8.87004371e-08f, 2.38368096e-07f, 6.03520392e-07f, 1.44488635e-06f, 3.28212299e-06f, 7.09655821e-06f, + 1.46494407e-05f, 2.89537394e-05f, 5.49357161e-05f, 1.00313252e-04f, 1.76700203e-04f, 3.00920507e-04f, + 4.96484845e-04f, 7.95150594e-04f, 1.23845781e-03f, 1.87911525e-03f, 2.78210510e-03f, 4.02538552e-03f, + 5.70009588e-03f, 7.91020800e-03f, 1.07716137e-02f, 1.44106884e-02f, 1.89624177e-02f, 2.45682104e-02f, + 3.13735515e-02f, 3.95256605e-02f, 4.91713196e-02f, 6.04550279e-02f, 7.35176150e-02f, 8.84954195e-02f, + 1.05520113e-01f, 1.24719213e-01f, 1.46217318e-01f, 1.70138063e-01f, 1.96606781e-01f, 2.25753880e-01f, + 2.57718900e-01f, 2.92655274e-01f, 3.30735809e-01f, 3.72158929e-01f, 4.17155794e-01f, 4.65998399e-01f, + 5.19008863e-01f, 5.76570161e-01f, 6.39138643e-01f, 7.07258781e-01f, 7.81580731e-01f, 8.62881450e-01f, + 9.52090320e-01f, 1.05032052e+00f, 1.15890775e+00f, 1.27945836e+00f, 1.41390963e+00f, 1.56460576e+00f, + 1.73439430e+00f, 1.92674937e+00f, 2.14593012e+00f, 2.39718593e+00f, 2.68702407e+00f, 3.02356133e+00f, + 3.41698950e+00f, 3.88019661e+00f, 4.42960272e+00f, 5.08629455e+00f, 5.87757956e+00f, 6.83913514e+00f, + 8.01801085e+00f, 9.47686632e+00f, 1.13000199e+01f, 1.36021823e+01f, 1.65412214e+01f, 2.03370584e+01f, + 2.53000199e+01f, 3.18739815e+01f, 4.07030054e+01f, 5.27358913e+01f, 6.93929374e+01f, 9.28366010e+01f, + 1.26418926e+02f, 1.75435645e+02f, 2.48423411e+02f, 3.59440052e+02f, 5.32165336e+02f, 8.07455844e+02f, + 1.25762341e+03f, 2.01416017e+03f, 3.32313676e+03f, 5.65930306e+03f, 9.96877263e+03f, 1.82030939e+04f, + 3.45378531e+04f, 6.82619916e+04f, 1.40913380e+05f, 3.04680844e+05f, 6.92095957e+05f, 1.65694484e+06f, + 4.19519229e+06f, 1.12739016e+07f, 3.22814282e+07f, 9.88946136e+07f, 3.25562103e+08f, 1.15706659e+09f, + 4.46167708e+09f, 1.87647826e+10f, 8.65629909e+10f, 4.40614549e+11f, 2.49049013e+12f, 1.57380011e+13f, + 1.11990629e+14f, 9.04297390e+14f, 8.35377903e+15f, 8.90573552e+16f, 1.10582857e+18f, 1.61514650e+19f, }; + +__constant__ float m_abscissas_float_7[263] = + { 7.75845008e-23f, 3.71846701e-22f, 1.69833677e-21f, 7.40284853e-21f, 3.08399399e-20f, 1.22962599e-19f, + 4.69855182e-19f, 1.72288020e-18f, 6.07012059e-18f, 2.05742924e-17f, 6.71669437e-17f, 2.11441966e-16f, + 6.42566550e-16f, 1.88715605e-15f, 5.36188198e-15f, 1.47533056e-14f, 3.93507835e-14f, 1.01841667e-13f, + 2.55981752e-13f, 6.25453236e-13f, 1.48683211e-12f, 3.44173601e-12f, 7.76421789e-12f, 1.70831312e-11f, + 3.66877698e-11f, 7.69632540e-11f, 1.57822184e-10f, 3.16577320e-10f, 6.21604166e-10f, 1.19551931e-09f, + 2.25364361e-09f, 4.16647469e-09f, 7.55905964e-09f, 1.34658870e-08f, 2.35675936e-08f, 4.05458117e-08f, + 6.86052525e-08f, 1.14227960e-07f, 1.87243781e-07f, 3.02323521e-07f, 4.81026747e-07f, 7.54564302e-07f, + 1.16746531e-06f, 1.78236867e-06f, 2.68618781e-06f, 3.99792342e-06f, 5.87841837e-06f, 8.54236163e-06f, + 1.22728487e-05f, 1.74387947e-05f, 2.45154696e-05f, 3.41083807e-05f, 4.69806683e-05f, 6.40841007e-05f, + 8.65936597e-05f, 1.15945600e-04f, 1.53878746e-04f, 2.02478652e-04f, 2.64224143e-04f, 3.42035594e-04f, + 4.39324211e-04f, 5.60041454e-04f, 7.08727668e-04f, 8.90558896e-04f, 1.11139085e-03f, 1.37779898e-03f, + 1.69711358e-03f, 2.07744903e-03f, 2.52772622e-03f, 3.05768742e-03f, 3.67790298e-03f, 4.39976940e-03f, + 5.23549846e-03f, 6.19809738e-03f, 7.30134015e-03f, 8.55973022e-03f, 9.98845520e-03f, 1.16033342e-02f, + 1.34207587e-02f, 1.54576276e-02f, 1.77312787e-02f, 2.02594158e-02f, 2.30600348e-02f, 2.61513493e-02f, + 2.95517158e-02f, 3.32795626e-02f, 3.73533204e-02f, 4.17913590e-02f, 4.66119283e-02f, 5.18331072e-02f, + 5.74727595e-02f, 6.35484986e-02f, 7.00776615e-02f, 7.70772927e-02f, 8.45641386e-02f, 9.25546518e-02f, + 1.01065008e-01f, 1.10111132e-01f, 1.19708739e-01f, 1.29873379e-01f, 1.40620505e-01f, 1.51965539e-01f, + 1.63923958e-01f, 1.76511391e-01f, 1.89743720e-01f, 2.03637197e-01f, 2.18208574e-01f, 2.33475238e-01f, + 2.49455360e-01f, 2.66168055e-01f, 2.83633553e-01f, 3.01873381e-01f, 3.20910560e-01f, 3.40769809e-01f, + 3.61477772e-01f, 3.83063247e-01f, 4.05557445e-01f, 4.28994258e-01f, 4.53410546e-01f, 4.78846448e-01f, + 5.05345717e-01f, 5.32956079e-01f, 5.61729623e-01f, 5.91723220e-01f, 6.22998983e-01f, 6.55624768e-01f, + 6.89674714e-01f, 7.25229845e-01f, 7.62378724e-01f, 8.01218171e-01f, 8.41854062e-01f, 8.84402205e-01f, + 9.28989312e-01f, 9.75754080e-01f, 1.02484839e+00f, 1.07643865e+00f, 1.13070727e+00f, 1.18785434e+00f, + 1.24809950e+00f, 1.31168403e+00f, 1.37887320e+00f, 1.44995892e+00f, 1.52526270e+00f, 1.60513906e+00f, + 1.68997931e+00f, 1.78021589e+00f, 1.87632722e+00f, 1.97884333e+00f, 2.08835213e+00f, 2.20550671e+00f, + 2.33103353e+00f, 2.46574193e+00f, 2.61053497e+00f, 2.76642183e+00f, 2.93453226e+00f, 3.11613304e+00f, + 3.31264716e+00f, 3.52567596e+00f, 3.75702486e+00f, 4.00873326e+00f, 4.28310945e+00f, 4.58277134e+00f, + 4.91069419e+00f, 5.27026666e+00f, 5.66535674e+00f, 6.10038953e+00f, 6.58043928e+00f, 7.11133842e+00f, + 7.69980735e+00f, 8.35360902e+00f, 9.08173387e+00f, 9.89462150e+00f, 1.08044272e+01f, 1.18253437e+01f, + 1.29739897e+01f, 1.42698826e+01f, 1.57360130e+01f, 1.73995473e+01f, 1.92926887e+01f, 2.14537359e+01f, + 2.39283915e+01f, 2.67713817e+01f, 3.00484719e+01f, 3.38389827e+01f, 3.82389447e+01f, 4.33650689e+01f, + 4.93597649e+01f, 5.63975118e+01f, 6.46929803e+01f, 7.45114359e+01f, 8.61821250e+01f, 1.00115581e+02f, + 1.16826112e+02f, 1.36961158e+02f, 1.61339834e+02f, 1.91003781e+02f, 2.27284639e+02f, 2.71894067e+02f, + 3.27044548e+02f, 3.95612465e+02f, 4.81359585e+02f, 5.89235756e+02f, 7.25795284e+02f, 8.99773468e+02f, + 1.12289036e+03f, 1.41097920e+03f, 1.78558211e+03f, 2.27622329e+03f, 2.92367233e+03f, 3.78466551e+03f, + 4.93879227e+03f, 6.49862329e+03f, 8.62473434e+03f, 1.15481896e+04f, 1.56044945e+04f, 2.12853507e+04f, + 2.93183077e+04f, 4.07905708e+04f, 5.73434125e+04f, 8.14806753e+04f, 1.17063646e+05f, 1.70113785e+05f, + 2.50129854e+05f, 3.72274789e+05f, 5.61051155e+05f, 8.56556497e+05f, 1.32526810e+06f, 2.07888648e+06f, + 3.30771485e+06f, 5.34063130e+06f, 8.75442405e+06f, 1.45761434e+07f, 2.46634599e+07f, 4.24311457e+07f, + 7.42617251e+07f, 1.32291588e+08f, 2.40011058e+08f, 4.43725882e+08f, 8.36456588e+08f, 1.60874083e+09f, + 3.15878598e+09f, 6.33624483e+09f, 1.29932136e+10f, 2.72570398e+10f, 5.85372779e+10f, 1.28795973e+11f, + 2.90551047e+11f, 6.72570892e+11f, 1.59884056e+12f, 3.90652847e+12f, 9.81916374e+12f, 2.54124546e+13f, + 6.77814197e+13f, 1.86501681e+14f, 5.29897885e+14f, 1.55625904e+15f, 4.72943011e+15f, 1.48882761e+16f, + 4.86043448e+16f, 1.64741373e+17f, 5.80423410e+17f, 2.12831536e+18f, 8.13255421e+18f, }; + +__constant__ float m_abscissas_float_8[527] = + { 5.20331508e-23f, 1.15324162e-22f, 2.52466875e-22f, 5.46028730e-22f, 1.16690465e-21f, 2.46458927e-21f, + 5.14543768e-21f, 1.06205431e-20f, 2.16767715e-20f, 4.37564009e-20f, 8.73699691e-20f, 1.72595588e-19f, + 3.37377643e-19f, 6.52669145e-19f, 1.24976973e-18f, 2.36916845e-18f, 4.44691383e-18f, 8.26580373e-18f, + 1.52174118e-17f, 2.77517606e-17f, 5.01415830e-17f, 8.97689232e-17f, 1.59270821e-16f, 2.80084735e-16f, + 4.88253693e-16f, 8.43846463e-16f, 1.44610939e-15f, 2.45762595e-15f, 4.14251017e-15f, 6.92627770e-15f, + 1.14889208e-14f, 1.89084205e-14f, 3.08802476e-14f, 5.00504297e-14f, 8.05169965e-14f, 1.28579121e-13f, + 2.03847833e-13f, 3.20880532e-13f, 5.01568631e-13f, 7.78600100e-13f, 1.20044498e-12f, 1.83848331e-12f, + 2.79712543e-12f, 4.22808302e-12f, 6.35035779e-12f, 9.47805307e-12f, 1.40588174e-11f, 2.07266430e-11f, + 3.03739182e-11f, 4.42491437e-11f, 6.40886341e-11f, 9.22929507e-11f, 1.32161843e-10f, 1.88205259e-10f, + 2.66552657e-10f, 3.75488615e-10f, 5.26149742e-10f, 7.33426418e-10f, 1.01712318e-09f, 1.40344387e-09f, + 1.92688222e-09f, 2.63261606e-09f, 3.57952343e-09f, 4.84396276e-09f, 6.52448685e-09f, 8.74769197e-09f, + 1.16754399e-08f, 1.55137320e-08f, 2.05235608e-08f, 2.70341184e-08f, 3.54587968e-08f, 4.63144836e-08f, + 6.02447248e-08f, 7.80474059e-08f, 1.00707687e-07f, 1.29437018e-07f, 1.65719157e-07f, 2.11364220e-07f, + 2.68571894e-07f, 3.40005066e-07f, 4.28875221e-07f, 5.39041105e-07f, 6.75122241e-07f, 8.42629031e-07f, + 1.04811127e-06f, 1.29932703e-06f, 1.60543396e-06f, 1.97720518e-06f, 2.42727196e-06f, 2.97039558e-06f, + 3.62377065e-06f, 4.40736236e-06f, 5.34428013e-06f, 6.46118994e-06f, 7.78876789e-06f, 9.36219733e-06f, + 1.12217116e-05f, 1.34131848e-05f, 1.59887725e-05f, 1.90076038e-05f, 2.25365270e-05f, 2.66509096e-05f, + 3.14354940e-05f, 3.69853096e-05f, 4.34066412e-05f, 5.08180543e-05f, 5.93514765e-05f, 6.91533342e-05f, + 8.03857429e-05f, 9.32277499e-05f, 1.07876627e-04f, 1.24549208e-04f, 1.43483273e-04f, 1.64938971e-04f, + 1.89200275e-04f, 2.16576471e-04f, 2.47403671e-04f, 2.82046341e-04f, 3.20898851e-04f, 3.64387021e-04f, + 4.12969671e-04f, 4.67140163e-04f, 5.27427922e-04f, 5.94399942e-04f, 6.68662248e-04f, 7.50861330e-04f, + 8.41685517e-04f, 9.41866302e-04f, 1.05217960e-03f, 1.17344692e-03f, 1.30653650e-03f, 1.45236427e-03f, + 1.61189482e-03f, 1.78614219e-03f, 1.97617055e-03f, 2.18309485e-03f, 2.40808123e-03f, 2.65234740e-03f, + 2.91716284e-03f, 3.20384886e-03f, 3.51377855e-03f, 3.84837661e-03f, 4.20911898e-03f, 4.59753235e-03f, + 5.01519359e-03f, 5.46372894e-03f, 5.94481312e-03f, 6.46016832e-03f, 7.01156301e-03f, 7.60081065e-03f, + 8.22976829e-03f, 8.90033499e-03f, 9.61445021e-03f, 1.03740920e-02f, 1.11812753e-02f, 1.20380497e-02f, + 1.29464978e-02f, 1.39087327e-02f, 1.49268962e-02f, 1.60031562e-02f, 1.71397050e-02f, 1.83387564e-02f, + 1.96025436e-02f, 2.09333170e-02f, 2.23333419e-02f, 2.38048956e-02f, 2.53502659e-02f, 2.69717481e-02f, + 2.86716433e-02f, 3.04522558e-02f, 3.23158911e-02f, 3.42648538e-02f, 3.63014456e-02f, 3.84279634e-02f, + 4.06466974e-02f, 4.29599296e-02f, 4.53699317e-02f, 4.78789641e-02f, 5.04892744e-02f, 5.32030959e-02f, + 5.60226468e-02f, 5.89501290e-02f, 6.19877276e-02f, 6.51376099e-02f, 6.84019251e-02f, 7.17828036e-02f, + 7.52823576e-02f, 7.89026802e-02f, 8.26458461e-02f, 8.65139116e-02f, 9.05089155e-02f, 9.46328794e-02f, + 9.88878087e-02f, 1.03275694e-01f, 1.07798510e-01f, 1.12458223e-01f, 1.17256783e-01f, 1.22196135e-01f, + 1.27278214e-01f, 1.32504950e-01f, 1.37878272e-01f, 1.43400107e-01f, 1.49072382e-01f, 1.54897032e-01f, + 1.60875997e-01f, 1.67011231e-01f, 1.73304700e-01f, 1.79758387e-01f, 1.86374297e-01f, 1.93154462e-01f, + 2.00100939e-01f, 2.07215821e-01f, 2.14501238e-01f, 2.21959362e-01f, 2.29592410e-01f, 2.37402653e-01f, + 2.45392415e-01f, 2.53564085e-01f, 2.61920117e-01f, 2.70463037e-01f, 2.79195450e-01f, 2.88120044e-01f, + 2.97239599e-01f, 3.06556989e-01f, 3.16075193e-01f, 3.25797297e-01f, 3.35726506e-01f, 3.45866147e-01f, + 3.56219679e-01f, 3.66790698e-01f, 3.77582948e-01f, 3.88600328e-01f, 3.99846898e-01f, 4.11326892e-01f, + 4.23044723e-01f, 4.35004995e-01f, 4.47212512e-01f, 4.59672288e-01f, 4.72389556e-01f, 4.85369781e-01f, + 4.98618671e-01f, 5.12142186e-01f, 5.25946554e-01f, 5.40038281e-01f, 5.54424165e-01f, 5.69111309e-01f, + 5.84107138e-01f, 5.99419409e-01f, 6.15056232e-01f, 6.31026081e-01f, 6.47337815e-01f, 6.64000696e-01f, + 6.81024405e-01f, 6.98419060e-01f, 7.16195243e-01f, 7.34364016e-01f, 7.52936944e-01f, 7.71926120e-01f, + 7.91344191e-01f, 8.11204381e-01f, 8.31520518e-01f, 8.52307069e-01f, 8.73579162e-01f, 8.95352625e-01f, + 9.17644013e-01f, 9.40470650e-01f, 9.63850664e-01f, 9.87803022e-01f, 1.01234758e+00f, 1.03750512e+00f, + 1.06329740e+00f, 1.08974721e+00f, 1.11687839e+00f, 1.14471595e+00f, 1.17328606e+00f, 1.20261614e+00f, + 1.23273496e+00f, 1.26367264e+00f, 1.29546076e+00f, 1.32813247e+00f, 1.36172249e+00f, 1.39626730e+00f, + 1.43180514e+00f, 1.46837616e+00f, 1.50602252e+00f, 1.54478848e+00f, 1.58472055e+00f, 1.62586760e+00f, + 1.66828098e+00f, 1.71201469e+00f, 1.75712551e+00f, 1.80367319e+00f, 1.85172058e+00f, 1.90133388e+00f, + 1.95258276e+00f, 2.00554062e+00f, 2.06028484e+00f, 2.11689693e+00f, 2.17546288e+00f, 2.23607339e+00f, + 2.29882418e+00f, 2.36381627e+00f, 2.43115639e+00f, 2.50095725e+00f, 2.57333803e+00f, 2.64842468e+00f, + 2.72635049e+00f, 2.80725648e+00f, 2.89129193e+00f, 2.97861498e+00f, 3.06939317e+00f, 3.16380413e+00f, + 3.26203621e+00f, 3.36428929e+00f, 3.47077553e+00f, 3.58172026e+00f, 3.69736291e+00f, 3.81795798e+00f, + 3.94377618e+00f, 4.07510558e+00f, 4.21225285e+00f, 4.35554468e+00f, 4.50532923e+00f, 4.66197775e+00f, + 4.82588634e+00f, 4.99747780e+00f, 5.17720373e+00f, 5.36554672e+00f, 5.56302277e+00f, 5.77018396e+00f, + 5.98762126e+00f, 6.21596768e+00f, 6.45590164e+00f, 6.70815069e+00f, 6.97349551e+00f, 7.25277437e+00f, + 7.54688785e+00f, 7.85680417e+00f, 8.18356491e+00f, 8.52829128e+00f, 8.89219104e+00f, 9.27656603e+00f, + 9.68282047e+00f, 1.01124700e+01f, 1.05671518e+01f, 1.10486353e+01f, 1.15588347e+01f, 1.20998217e+01f, + 1.26738407e+01f, 1.32833247e+01f, 1.39309131e+01f, 1.46194716e+01f, 1.53521138e+01f, 1.61322255e+01f, + 1.69634913e+01f, 1.78499242e+01f, 1.87958987e+01f, 1.98061868e+01f, 2.08859991e+01f, 2.20410294e+01f, + 2.32775056e+01f, 2.46022448e+01f, 2.60227166e+01f, 2.75471124e+01f, 2.91844234e+01f, 3.09445281e+01f, + 3.28382897e+01f, 3.48776660e+01f, 3.70758319e+01f, 3.94473180e+01f, 4.20081658e+01f, 4.47761023e+01f, + 4.77707378e+01f, 5.10137879e+01f, 5.45293247e+01f, 5.83440613e+01f, 6.24876734e+01f, 6.69931639e+01f, + 7.18972765e+01f, 7.72409663e+01f, 8.30699343e+01f, 8.94352364e+01f, 9.63939781e+01f, 1.04010108e+02f, + 1.12355322e+02f, 1.21510104e+02f, 1.31564914e+02f, 1.42621552e+02f, 1.54794728e+02f, 1.68213867e+02f, + 1.83025185e+02f, 1.99394097e+02f, 2.17507985e+02f, 2.37579409e+02f, 2.59849828e+02f, 2.84593917e+02f, + 3.12124587e+02f, 3.42798827e+02f, 3.77024517e+02f, 4.15268384e+02f, 4.58065302e+02f, 5.06029199e+02f, + 5.59865843e+02f, 6.20387872e+02f, 6.88532497e+02f, 7.65382367e+02f, 8.52190227e+02f, 9.50408087e+02f, + 1.06172182e+03f, 1.18809220e+03f, 1.33180384e+03f, 1.49552334e+03f, 1.68236894e+03f, 1.89599367e+03f, + 2.14068513e+03f, 2.42148533e+03f, 2.74433485e+03f, 3.11624675e+03f, 3.54551666e+03f, 4.04197722e+03f, + 4.61730674e+03f, 5.28540457e+03f, 6.06284853e+03f, 6.96945350e+03f, 8.02895513e+03f, 9.26984864e+03f, + 1.07264200e+04f, 1.24400169e+04f, 1.44606187e+04f, 1.68487805e+04f, 1.96780458e+04f, 2.30379493e+04f, + 2.70377620e+04f, 3.18111749e+04f, 3.75221715e+04f, 4.43724093e+04f, 5.26105241e+04f, 6.25438881e+04f, + 7.45535092e+04f, 8.91129656e+04f, 1.06812532e+05f, 1.28390012e+05f, 1.54770253e+05f, 1.87115940e+05f, + 2.26893075e+05f, 2.75955654e+05f, 3.36655497e+05f, 4.11985149e+05f, 5.05764405e+05f, 6.22884544e+05f, + 7.69629183e+05f, 9.54097173e+05f, 1.18676186e+06f, 1.48121324e+06f, 1.85514609e+06f, 2.33168052e+06f, + 2.94113264e+06f, 3.72339780e+06f, 4.73116974e+06f, 6.03430539e+06f, 7.72576515e+06f, 9.92972861e+06f, + 1.28127257e+07f, 1.65989637e+07f, 2.15915179e+07f, 2.82017465e+07f, 3.69902945e+07f, 4.87244884e+07f, + 6.44590226e+07f, 8.56498776e+07f, 1.14315868e+08f, 1.53268759e+08f, 2.06442545e+08f, 2.79366798e+08f, + 3.79850300e+08f, 5.18973079e+08f, 7.12532948e+08f, 9.83165083e+08f, 1.36346329e+09f, 1.90059962e+09f, + 2.66319659e+09f, 3.75160395e+09f, 5.31334782e+09f, 7.56648043e+09f, 1.08350637e+10f, 1.56033907e+10f, + 2.25993074e+10f, 3.29229832e+10f, 4.82470799e+10f, 7.11297379e+10f, 1.05506900e+11f, 1.57471442e+11f, + 2.36513804e+11f, 3.57509889e+11f, 5.43926613e+11f, 8.33024431e+11f, 1.28435637e+12f, 1.99374510e+12f, + 3.11642465e+12f, 4.90561997e+12f, 7.77731247e+12f, 1.24197380e+13f, 1.99798484e+13f, 3.23831600e+13f, + 5.28864904e+13f, 8.70403770e+13f, 1.44377694e+14f, 2.41399528e+14f, 4.06896744e+14f, 6.91510621e+14f, + 1.18504970e+15f, 2.04811559e+15f, 3.57034809e+15f, 6.27861398e+15f, 1.11397125e+16f, 1.99435267e+16f, + 3.60337498e+16f, 6.57141972e+16f, 1.20980371e+17f, 2.24875057e+17f, 4.22089025e+17f, 8.00147402e+17f, + 1.53216987e+18f, 2.96403754e+18f, 5.79389087e+18f, 1.14455803e+19f, 2.28537992e+19f, }; + +__constant__ float* m_abscissas_float[8] = { + m_abscissas_float_1, + m_abscissas_float_2, + m_abscissas_float_3, + m_abscissas_float_4, + m_abscissas_float_5, + m_abscissas_float_6, + m_abscissas_float_7, + m_abscissas_float_8, +}; + +__constant__ float m_weights_float_1[9] = + { 1.79979618e-21f, 1.07218106e-07f, 7.05786060e-03f, 2.72310168e-01f, 1.18863515e+00f, 8.77655464e+00f, + 5.33879432e+02f, 5.98892409e+06f, 9.60751551e+16f, }; + +__constant__ float m_weights_float_2[8] = + { 7.59287827e-13f, 1.18886775e-04f, 7.27332179e-02f, 6.09156795e-01f, 2.71431234e+00f, 4.68800805e+01f, + 2.06437304e+04f, 4.85431236e+10f, }; + +__constant__ float m_weights_float_3[16] = + { 1.30963564e-16f, 6.14135316e-10f, 5.67743391e-06f, 1.21108690e-03f, 2.67259824e-02f, 1.54234107e-01f, + 4.23412860e-01f, 8.47913037e-01f, 1.73632925e+00f, 4.63203354e+00f, 1.88206826e+01f, 1.40643917e+02f, + 2.73736946e+03f, 2.55633252e+05f, 3.18438602e+08f, 2.86363931e+13f, }; + +__constant__ float m_weights_float_4[33] = + { 6.93769555e-19f, 1.31670336e-14f, 2.68107110e-11f, 9.60294960e-09f, 8.89417585e-07f, 2.87650015e-05f, + 4.10649371e-04f, 3.10797444e-03f, 1.43958814e-02f, 4.56980985e-02f, 1.08787148e-01f, 2.08910486e-01f, + 3.43887471e-01f, 5.11338439e-01f, 7.19769211e-01f, 1.00073403e+00f, 1.42660267e+00f, 2.14966467e+00f, + 3.50341221e+00f, 6.28632057e+00f, 1.26369961e+01f, 2.90949180e+01f, 7.91163114e+01f, 2.65103292e+02f, + 1.15872311e+03f, 7.11886439e+03f, 6.77324248e+04f, 1.13081650e+06f, 3.88995005e+07f, 3.38857764e+09f, + 9.74063570e+11f, 1.29789430e+15f, 1.24001927e+19f, }; + +__constant__ float m_weights_float_5[66] = + { 3.88541434e-20f, 1.03646493e-17f, 1.41388360e-15f, 1.06725054e-13f, 4.77908002e-12f, 1.34999345e-10f, + 2.53970414e-09f, 3.33804787e-08f, 3.19755978e-07f, 2.31724882e-06f, 1.31302324e-05f, 5.98917639e-05f, + 2.25650360e-04f, 7.18397083e-04f, 1.97196929e-03f, 4.75106406e-03f, 1.02072514e-02f, 1.98317011e-02f, + 3.52844239e-02f, 5.81350403e-02f, 8.95955146e-02f, 1.30335749e-01f, 1.80445384e-01f, 2.39557131e-01f, + 3.07102681e-01f, 3.82648608e-01f, 4.66260909e-01f, 5.58867257e-01f, 6.62616429e-01f, 7.81267733e-01f, + 9.20677638e-01f, 1.08949034e+00f, 1.30019425e+00f, 1.57079633e+00f, 1.92752387e+00f, 2.40924883e+00f, + 3.07485695e+00f, 4.01578082e+00f, 5.37784753e+00f, 7.40045071e+00f, 1.04890228e+01f, 1.53538346e+01f, + 2.32861156e+01f, 3.67307348e+01f, 6.05296516e+01f, 1.04761593e+02f, 1.91598840e+02f, 3.72918009e+02f, + 7.78738763e+02f, 1.76101294e+03f, 4.35837629e+03f, 1.19484066e+04f, 3.67841605e+04f, 1.29157756e+05f, + 5.26424122e+05f, 2.54082527e+06f, 1.48545930e+07f, 1.07925566e+08f, 1.00317513e+09f, 1.23283860e+10f, + 2.07922173e+11f, 5.01997049e+12f, 1.82006578e+14f, 1.04617001e+16f, 1.01373023e+18f, 1.77530238e+20f, }; + +__constant__ float m_weights_float_6[132] = + { 8.56958007e-21f, 1.68000718e-19f, 2.74008750e-18f, 3.75978801e-17f, 4.38589881e-16f, 4.39263787e-15f, + 3.81223973e-14f, 2.89198757e-13f, 1.93338859e-12f, 1.14783389e-11f, 6.09544349e-11f, 2.91499607e-10f, + 1.26339559e-09f, 4.99234840e-09f, 1.80872790e-08f, 6.03998541e-08f, 1.86829770e-07f, 5.37807971e-07f, + 1.44704121e-06f, 3.65421571e-06f, 8.69454276e-06f, 1.95621880e-05f, 4.17628758e-05f, 8.48713297e-05f, + 1.64680159e-04f, 3.05960283e-04f, 5.45748909e-04f, 9.36950301e-04f, 1.55189915e-03f, 2.48542560e-03f, + 3.85690505e-03f, 5.81079770e-03f, 8.51529070e-03f, 1.21588421e-02f, 1.69446644e-02f, 2.30834400e-02f, + 3.07847946e-02f, 4.02482241e-02f, 5.16542634e-02f, 6.51566792e-02f, 8.08763802e-02f, 9.88975757e-02f, + 1.19266512e-01f, 1.41992893e-01f, 1.67053901e-01f, 1.94400532e-01f, 2.23965873e-01f, 2.55674859e-01f, + 2.89455038e-01f, 3.25247905e-01f, 3.63020457e-01f, 4.02776696e-01f, 4.44568958e-01f, 4.88509042e-01f, + 5.34779290e-01f, 5.83643845e-01f, 6.35460497e-01f, 6.90693630e-01f, 7.49928915e-01f, 8.13890578e-01f, + 8.83462209e-01f, 9.59712352e-01f, 1.04392634e+00f, 1.13764623e+00f, 1.24272128e+00f, 1.36137177e+00f, + 1.49627028e+00f, 1.65064527e+00f, 1.82841374e+00f, 2.03435175e+00f, 2.27431458e+00f, 2.55552245e+00f, + 2.88693336e+00f, 3.27973254e+00f, 3.74797919e+00f, 4.30946679e+00f, 4.98687594e+00f, 5.80933099e+00f, + 6.81451887e+00f, 8.05159726e+00f, 9.58522167e+00f, 1.15011733e+01f, 1.39143002e+01f, 1.69798351e+01f, + 2.09096993e+01f, 2.59962450e+01f, 3.26472377e+01f, 4.14380231e+01f, 5.31903193e+01f, 6.90928164e+01f, + 9.08883744e+01f, 1.21168895e+02f, 1.63847041e+02f, 2.24923217e+02f, 3.13754154e+02f, 4.45189215e+02f, + 6.43236850e+02f, 9.47484116e+02f, 1.42457583e+03f, 2.18920236e+03f, 3.44338342e+03f, 5.55184130e+03f, + 9.19045432e+03f, 1.56468513e+04f, 2.74471462e+04f, 4.97037777e+04f, 9.31107740e+04f, 1.80835335e+05f, + 3.64968793e+05f, 7.67360053e+05f, 1.68525439e+06f, 3.87686515e+06f, 9.37022570e+06f, 2.38705733e+07f, + 6.43128750e+07f, 1.83920179e+08f, 5.60444636e+08f, 1.82722217e+09f, 6.40182180e+09f, 2.42153053e+10f, + 9.93804949e+10f, 4.44863150e+11f, 2.18425069e+12f, 1.18337660e+13f, 7.11948688e+13f, 4.78870731e+14f, + 3.62710215e+15f, 3.11747341e+16f, 3.06542975e+17f, 3.47854955e+18f, 4.59768243e+19f, 7.14806140e+20f, }; + +__constant__ float m_weights_float_7[263] = + { 3.95175890e-21f, 1.83575349e-20f, 8.12661397e-20f, 3.43336935e-19f, 1.38634563e-18f, 5.35757029e-18f, + 1.98424944e-17f, 7.05221126e-17f, 2.40827550e-16f, 7.91175869e-16f, 2.50347754e-15f, 7.63871031e-15f, + 2.25003103e-14f, 6.40502166e-14f, 1.76389749e-13f, 4.70424252e-13f, 1.21618334e-12f, 3.05082685e-12f, + 7.43273471e-12f, 1.76028616e-11f, 4.05602375e-11f, 9.10055013e-11f, 1.98994391e-10f, 4.24390078e-10f, + 8.83436580e-10f, 1.79636925e-09f, 3.57059250e-09f, 6.94247187e-09f, 1.32133371e-08f, 2.46332536e-08f, + 4.50110843e-08f, 8.06630537e-08f, 1.41856144e-07f, 2.44958654e-07f, 4.15579069e-07f, 6.93056106e-07f, + 1.13675616e-06f, 1.83473665e-06f, 2.91544023e-06f, 4.56318858e-06f, 7.03833675e-06f, 1.07030190e-05f, + 1.60534529e-05f, 2.37597559e-05f, 3.47141604e-05f, 5.00883685e-05f, 7.14005734e-05f, 1.00592372e-04f, + 1.40115414e-04f, 1.93027181e-04f, 2.63094779e-04f, 3.54905080e-04f, 4.73978972e-04f, 6.26886955e-04f, + 8.21362793e-04f, 1.06641153e-03f, 1.37240787e-03f, 1.75118071e-03f, 2.21607971e-03f, 2.78201983e-03f, + 3.46550010e-03f, 4.28459361e-03f, 5.25890609e-03f, 6.40950150e-03f, 7.75879384e-03f, 9.33040551e-03f, + 1.11489935e-02f, 1.32400455e-02f, 1.56296499e-02f, 1.83442433e-02f, 2.14103400e-02f, 2.48542509e-02f, + 2.87017958e-02f, 3.29780164e-02f, 3.77068968e-02f, 4.29110964e-02f, 4.86117029e-02f, 5.48280093e-02f, + 6.15773214e-02f, 6.88747982e-02f, 7.67333308e-02f, 8.51634602e-02f, 9.41733378e-02f, 1.03768728e-01f, + 1.13953051e-01f, 1.24727473e-01f, 1.36091031e-01f, 1.48040798e-01f, 1.60572082e-01f, 1.73678660e-01f, + 1.87353038e-01f, 2.01586736e-01f, 2.16370598e-01f, 2.31695113e-01f, 2.47550758e-01f, 2.63928342e-01f, + 2.80819365e-01f, 2.98216379e-01f, 3.16113348e-01f, 3.34506011e-01f, 3.53392244e-01f, 3.72772414e-01f, + 3.92649735e-01f, 4.13030618e-01f, 4.33925021e-01f, 4.55346789e-01f, 4.77314001e-01f, 4.99849320e-01f, + 5.22980337e-01f, 5.46739932e-01f, 5.71166640e-01f, 5.96305036e-01f, 6.22206131e-01f, 6.48927802e-01f, + 6.76535247e-01f, 7.05101473e-01f, 7.34707835e-01f, 7.65444619e-01f, 7.97411688e-01f, 8.30719192e-01f, + 8.65488366e-01f, 9.01852407e-01f, 9.39957463e-01f, 9.79963735e-01f, 1.02204672e+00f, 1.06639858e+00f, + 1.11322974e+00f, 1.16277062e+00f, 1.21527359e+00f, 1.27101525e+00f, 1.33029891e+00f, 1.39345744e+00f, + 1.46085648e+00f, 1.53289803e+00f, 1.61002461e+00f, 1.69272386e+00f, 1.78153384e+00f, 1.87704900e+00f, + 1.97992701e+00f, 2.09089644e+00f, 2.21076567e+00f, 2.34043290e+00f, 2.48089770e+00f, 2.63327413e+00f, + 2.79880590e+00f, 2.97888368e+00f, 3.17506505e+00f, 3.38909744e+00f, 3.62294469e+00f, 3.87881764e+00f, + 4.15920968e+00f, 4.46693789e+00f, 4.80519096e+00f, 5.17758497e+00f, 5.58822853e+00f, 6.04179895e+00f, + 6.54363157e+00f, 7.09982467e+00f, 7.71736306e+00f, 8.40426388e+00f, 9.16974906e+00f, 1.00244499e+01f, + 1.09806502e+01f, 1.20525758e+01f, 1.32567410e+01f, 1.46123627e+01f, 1.61418586e+01f, 1.78714466e+01f, + 1.98318690e+01f, 2.20592694e+01f, 2.45962577e+01f, 2.74932084e+01f, 3.08098460e+01f, 3.46171893e+01f, + 3.89999428e+01f, 4.40594471e+01f, 4.99173320e+01f, 5.67200545e+01f, 6.46445583e+01f, 7.39053537e+01f, + 8.47634121e+01f, 9.75373786e+01f, 1.12617765e+02f, 1.30484989e+02f, 1.51732386e+02f, 1.77095712e+02f, + 2.07491096e+02f, 2.44064119e+02f, 2.88253545e+02f, 3.41874461e+02f, 4.07227291e+02f, 4.87241400e+02f, + 5.85665251e+02f, 7.07319497e+02f, 8.58435639e+02f, 1.04711167e+03f, 1.28392853e+03f, 1.58278901e+03f, + 1.96206607e+03f, 2.44618436e+03f, 3.06781187e+03f, 3.87091688e+03f, 4.91505977e+03f, 6.28145970e+03f, + 8.08162997e+03f, 1.04697579e+04f, 1.36605846e+04f, 1.79554230e+04f, 2.37803156e+04f, 3.17424455e+04f, + 4.27142204e+04f, 5.79596727e+04f, 7.93261335e+04f, 1.09537503e+05f, 1.52647130e+05f, 2.14743829e+05f, + 3.05063335e+05f, 4.37755687e+05f, 6.34724899e+05f, 9.30240305e+05f, 1.37850753e+06f, 2.06623977e+06f, + 3.13377596e+06f, 4.81098405e+06f, 7.47905793e+06f, 1.17782423e+07f, 1.87980927e+07f, 3.04180655e+07f, + 4.99257437e+07f, 8.31551852e+07f, 1.40614107e+08f, 2.41519712e+08f, 4.21576502e+08f, 7.48209440e+08f, + 1.35089892e+09f, 2.48263348e+09f, 4.64662007e+09f, 8.86235204e+09f, 1.72348930e+10f, 3.41967381e+10f, + 6.92714904e+10f, 1.43352142e+11f, 3.03269524e+11f, 6.56345865e+11f, 1.45422052e+12f, 3.30099910e+12f, + 7.68267630e+12f, 1.83474885e+13f, 4.49980389e+13f, 1.13430702e+14f, 2.94148450e+14f, 7.85402504e+14f, + 2.16127995e+15f, 6.13534293e+15f, 1.79847736e+16f, 5.44944507e+16f, 1.70858922e+17f, 5.54922744e+17f, + 1.86905990e+18f, 6.53599225e+18f, 2.37582887e+19f, 8.98810682e+19f, 3.54341330e+20f, }; + +__constant__ float m_weights_float_8[527] = + { 2.67108015e-21f, 5.82833463e-21f, 1.25616316e-20f, 2.67469785e-20f, 5.62745845e-20f, 1.17014394e-19f, + 2.40511019e-19f, 4.88739481e-19f, 9.82072303e-19f, 1.95168062e-18f, 3.83661097e-18f, 7.46163208e-18f, + 1.43594942e-17f, 2.73485792e-17f, 5.15573612e-17f, 9.62223075e-17f, 1.77810682e-16f, 3.25389618e-16f, + 5.89765054e-16f, 1.05888451e-15f, 1.88354538e-15f, 3.31989417e-15f, 5.79902273e-15f, 1.00398818e-14f, + 1.72308010e-14f, 2.93186753e-14f, 4.94655967e-14f, 8.27635884e-14f, 1.37343706e-13f, 2.26082511e-13f, + 3.69205736e-13f, 5.98228147e-13f, 9.61866975e-13f, 1.53484658e-12f, 2.43090464e-12f, 3.82185577e-12f, + 5.96531965e-12f, 9.24474797e-12f, 1.42267754e-11f, 2.17427910e-11f, 3.30041201e-11f, 4.97635091e-11f, + 7.45399354e-11f, 1.10929412e-10f, 1.64031748e-10f, 2.41032586e-10f, 3.51991946e-10f, 5.10905560e-10f, + 7.37124150e-10f, 1.05723929e-09f, 1.50757352e-09f, 2.13744796e-09f, 3.01344401e-09f, 4.22492806e-09f, + 5.89117093e-09f, 8.17046854e-09f, 1.12717587e-08f, 1.54693324e-08f, 2.11213594e-08f, 2.86930859e-08f, + 3.87857241e-08f, 5.21722335e-08f, 6.98414017e-08f, 9.30518593e-08f, 1.23397923e-07f, 1.62889442e-07f, + 2.14048123e-07f, 2.80023159e-07f, 3.64729321e-07f, 4.73011070e-07f, 6.10836627e-07f, 7.85526363e-07f, + 1.00602028e-06f, 1.28318979e-06f, 1.63019938e-06f, 2.06292424e-06f, 2.60043021e-06f, 3.26552286e-06f, + 4.08537275e-06f, 5.09222413e-06f, 6.32419483e-06f, 7.82617466e-06f, 9.65083023e-06f, 1.18597236e-05f, + 1.45245521e-05f, 1.77285168e-05f, 2.15678251e-05f, 2.61533347e-05f, 3.16123436e-05f, 3.80905295e-05f, + 4.57540432e-05f, 5.47917575e-05f, 6.54176707e-05f, 7.78734661e-05f, 9.24312223e-05f, 1.09396271e-04f, + 1.29110197e-04f, 1.51953965e-04f, 1.78351176e-04f, 2.08771424e-04f, 2.43733750e-04f, 2.83810168e-04f, + 3.29629253e-04f, 3.81879756e-04f, 4.41314233e-04f, 5.08752659e-04f, 5.85085996e-04f, 6.71279692e-04f, + 7.68377076e-04f, 8.77502620e-04f, 9.99865030e-04f, 1.13676015e-03f, 1.28957360e-03f, 1.45978322e-03f, + 1.64896113e-03f, 1.85877551e-03f, 2.09099200e-03f, 2.34747474e-03f, 2.63018699e-03f, 2.94119122e-03f, + 3.28264890e-03f, 3.65681963e-03f, 4.06605991e-03f, 4.51282135e-03f, 4.99964828e-03f, 5.52917497e-03f, + 6.10412222e-03f, 6.72729343e-03f, 7.40157020e-03f, 8.12990738e-03f, 8.91532760e-03f, 9.76091537e-03f, + 1.06698107e-02f, 1.16452023e-02f, 1.26903202e-02f, 1.38084285e-02f, 1.50028172e-02f, 1.62767940e-02f, + 1.76336759e-02f, 1.90767806e-02f, 2.06094173e-02f, 2.22348784e-02f, 2.39564300e-02f, 2.57773028e-02f, + 2.77006834e-02f, 2.97297055e-02f, 3.18674406e-02f, 3.41168899e-02f, 3.64809756e-02f, 3.89625331e-02f, + 4.15643030e-02f, 4.42889240e-02f, 4.71389254e-02f, 5.01167213e-02f, 5.32246039e-02f, 5.64647382e-02f, + 5.98391571e-02f, 6.33497571e-02f, 6.69982939e-02f, 7.07863800e-02f, 7.47154815e-02f, 7.87869165e-02f, + 8.30018539e-02f, 8.73613125e-02f, 9.18661613e-02f, 9.65171203e-02f, 1.01314762e-01f, 1.06259513e-01f, + 1.11351656e-01f, 1.16591337e-01f, 1.21978563e-01f, 1.27513213e-01f, 1.33195039e-01f, 1.39023671e-01f, + 1.44998628e-01f, 1.51119321e-01f, 1.57385061e-01f, 1.63795066e-01f, 1.70348473e-01f, 1.77044340e-01f, + 1.83881662e-01f, 1.90859375e-01f, 1.97976367e-01f, 2.05231492e-01f, 2.12623572e-01f, 2.20151415e-01f, + 2.27813822e-01f, 2.35609599e-01f, 2.43537565e-01f, 2.51596569e-01f, 2.59785494e-01f, 2.68103274e-01f, + 2.76548903e-01f, 2.85121445e-01f, 2.93820047e-01f, 3.02643950e-01f, 3.11592502e-01f, 3.20665165e-01f, + 3.29861530e-01f, 3.39181328e-01f, 3.48624439e-01f, 3.58190905e-01f, 3.67880941e-01f, 3.77694943e-01f, + 3.87633504e-01f, 3.97697421e-01f, 4.07887708e-01f, 4.18205605e-01f, 4.28652591e-01f, 4.39230391e-01f, + 4.49940993e-01f, 4.60786652e-01f, 4.71769905e-01f, 4.82893580e-01f, 4.94160809e-01f, 5.05575036e-01f, + 5.17140031e-01f, 5.28859900e-01f, 5.40739096e-01f, 5.52782432e-01f, 5.64995090e-01f, 5.77382639e-01f, + 5.89951040e-01f, 6.02706666e-01f, 6.15656310e-01f, 6.28807202e-01f, 6.42167019e-01f, 6.55743908e-01f, + 6.69546490e-01f, 6.83583887e-01f, 6.97865729e-01f, 7.12402181e-01f, 7.27203953e-01f, 7.42282322e-01f, + 7.57649155e-01f, 7.73316926e-01f, 7.89298740e-01f, 8.05608358e-01f, 8.22260217e-01f, 8.39269463e-01f, + 8.56651970e-01f, 8.74424378e-01f, 8.92604116e-01f, 9.11209442e-01f, 9.30259469e-01f, 9.49774208e-01f, + 9.69774604e-01f, 9.90282579e-01f, 1.01132107e+00f, 1.03291408e+00f, 1.05508673e+00f, 1.07786529e+00f, + 1.10127728e+00f, 1.12535146e+00f, 1.15011796e+00f, 1.17560829e+00f, 1.20185546e+00f, 1.22889400e+00f, + 1.25676010e+00f, 1.28549162e+00f, 1.31512826e+00f, 1.34571158e+00f, 1.37728514e+00f, 1.40989460e+00f, + 1.44358784e+00f, 1.47841507e+00f, 1.51442894e+00f, 1.55168471e+00f, 1.59024039e+00f, 1.63015687e+00f, + 1.67149810e+00f, 1.71433126e+00f, 1.75872698e+00f, 1.80475947e+00f, 1.85250679e+00f, 1.90205105e+00f, + 1.95347869e+00f, 2.00688065e+00f, 2.06235275e+00f, 2.11999592e+00f, 2.17991652e+00f, 2.24222670e+00f, + 2.30704472e+00f, 2.37449538e+00f, 2.44471039e+00f, 2.51782884e+00f, 2.59399766e+00f, 2.67337209e+00f, + 2.75611628e+00f, 2.84240383e+00f, 2.93241843e+00f, 3.02635449e+00f, 3.12441791e+00f, 3.22682682e+00f, + 3.33381238e+00f, 3.44561973e+00f, 3.56250887e+00f, 3.68475574e+00f, 3.81265333e+00f, 3.94651282e+00f, + 4.08666490e+00f, 4.23346116e+00f, 4.38727553e+00f, 4.54850596e+00f, 4.71757611e+00f, 4.89493722e+00f, + 5.08107015e+00f, 5.27648761e+00f, 5.48173646e+00f, 5.69740032e+00f, 5.92410235e+00f, 6.16250823e+00f, + 6.41332946e+00f, 6.67732689e+00f, 6.95531455e+00f, 7.24816384e+00f, 7.55680807e+00f, 7.88224735e+00f, + 8.22555401e+00f, 8.58787841e+00f, 8.97045530e+00f, 9.37461076e+00f, 9.80176975e+00f, 1.02534643e+01f, + 1.07313428e+01f, 1.12371793e+01f, 1.17728848e+01f, 1.23405187e+01f, 1.29423019e+01f, 1.35806306e+01f, + 1.42580922e+01f, 1.49774818e+01f, 1.57418213e+01f, 1.65543795e+01f, 1.74186947e+01f, 1.83385994e+01f, + 1.93182476e+01f, 2.03621450e+01f, 2.14751816e+01f, 2.26626686e+01f, 2.39303784e+01f, 2.52845893e+01f, + 2.67321348e+01f, 2.82804577e+01f, 2.99376708e+01f, 3.17126238e+01f, 3.36149769e+01f, 3.56552840e+01f, + 3.78450835e+01f, 4.01970005e+01f, 4.27248599e+01f, 4.54438126e+01f, 4.83704762e+01f, 5.15230921e+01f, + 5.49217006e+01f, 5.85883374e+01f, 6.25472527e+01f, 6.68251567e+01f, 7.14514957e+01f, 7.64587609e+01f, + 8.18828353e+01f, 8.77633847e+01f, 9.41442967e+01f, 1.01074176e+02f, 1.08606902e+02f, 1.16802259e+02f, + 1.25726650e+02f, 1.35453899e+02f, 1.46066166e+02f, 1.57654979e+02f, 1.70322410e+02f, 1.84182406e+02f, + 1.99362306e+02f, 2.16004568e+02f, 2.34268740e+02f, 2.54333703e+02f, 2.76400239e+02f, 3.00693971e+02f, + 3.27468728e+02f, 3.57010397e+02f, 3.89641362e+02f, 4.25725590e+02f, 4.65674502e+02f, 5.09953726e+02f, + 5.59090900e+02f, 6.13684688e+02f, 6.74415211e+02f, 7.42056139e+02f, 8.17488717e+02f, 9.01718069e+02f, + 9.95892168e+02f, 1.10132394e+03f, 1.21951707e+03f, 1.35219615e+03f, 1.50134197e+03f, 1.66923291e+03f, + 1.85849349e+03f, 2.07215152e+03f, 2.31370536e+03f, 2.58720328e+03f, 2.89733724e+03f, 3.24955383e+03f, + 3.65018587e+03f, 4.10660860e+03f, 4.62742547e+03f, 5.22268956e+03f, 5.90416786e+03f, 6.68565726e+03f, + 7.58336313e+03f, 8.61635357e+03f, 9.80710572e+03f, 1.11821637e+04f, 1.27729327e+04f, 1.46166396e+04f, + 1.67574960e+04f, 1.92481112e+04f, 2.21512104e+04f, 2.55417295e+04f, 2.95093735e+04f, 3.41617487e+04f, + 3.96282043e+04f, 4.60645561e+04f, 5.36589049e+04f, 6.26388223e+04f, 7.32802431e+04f, 8.59184957e+04f, + 1.00962017e+05f, 1.18909442e+05f, 1.40370957e+05f, 1.66095034e+05f, 1.97001996e+05f, 2.34226253e+05f, + 2.79169596e+05f, 3.33568603e+05f, 3.99580125e+05f, 4.79889989e+05f, 5.77851588e+05f, 6.97663062e+05f, + 8.44594440e+05f, 1.02527965e+06f, 1.24809298e+06f, 1.52363581e+06f, 1.86536786e+06f, 2.29042802e+06f, + 2.82070529e+06f, 3.48424008e+06f, 4.31706343e+06f, 5.36561882e+06f, 6.68996113e+06f, 8.36799594e+06f, + 1.05011160e+07f, 1.32217203e+07f, 1.67032788e+07f, 2.11738506e+07f, 2.69343047e+07f, 3.43829654e+07f, + 4.40490690e+07f, 5.66383460e+07f, 7.30953564e+07f, 9.46890531e+07f, 1.23130681e+08f, 1.60736861e+08f, + 2.10656057e+08f, 2.77184338e+08f, 3.66207397e+08f, 4.85821891e+08f, 6.47212479e+08f, 8.65895044e+08f, + 1.16348659e+09f, 1.57023596e+09f, 2.12865840e+09f, 2.89877917e+09f, 3.96573294e+09f, 5.45082863e+09f, + 7.52773593e+09f, 1.04462776e+10f, 1.45675716e+10f, 2.04161928e+10f, 2.87579864e+10f, 4.07167363e+10f, + 5.79499965e+10f, 8.29154750e+10f, 1.19276754e+11f, 1.72524570e+11f, 2.50933409e+11f, 3.67042596e+11f, + 5.39962441e+11f, 7.98985690e+11f, 1.18927611e+12f, 1.78088199e+12f, 2.68310388e+12f, 4.06753710e+12f, + 6.20525592e+12f, 9.52719664e+12f, 1.47228407e+13f, 2.29025392e+13f, 3.58662837e+13f, 5.65517100e+13f, + 8.97859411e+13f, 1.43556057e+14f, 2.31171020e+14f, 3.74966777e+14f, 6.12702071e+14f, 1.00868013e+15f, + 1.67323268e+15f, 2.79711270e+15f, 4.71267150e+15f, 8.00353033e+15f, 1.37027503e+16f, 2.36538022e+16f, + 4.11734705e+16f, 7.22793757e+16f, 1.27982244e+17f, 2.28603237e+17f, 4.11976277e+17f, 7.49169358e+17f, + 1.37488861e+18f, 2.54681529e+18f, 4.76248383e+18f, 8.99167123e+18f, 1.71428840e+19f, 3.30088717e+19f, + 6.42020070e+19f, 1.26155602e+20f, 2.50480806e+20f, 5.02601059e+20f, 1.01935525e+21f, }; + +__constant__ float* m_weights_float[8] = { + m_weights_float_1, + m_weights_float_2, + m_weights_float_3, + m_weights_float_4, + m_weights_float_5, + m_weights_float_6, + m_weights_float_7, + m_weights_float_8 +}; + +__constant__ double m_abscissas_double_1[13] = + { 7.241670621354483269e-163, 2.257639733856759198e-60, 1.153241619257215165e-22, 8.747691973876861825e-09, + 1.173446923800022477e-03, 1.032756936219208144e-01, 7.719261204224504866e-01, 4.355544675823585545e+00, + 1.215101039066652656e+02, 6.228845436711506169e+05, 6.278613977336989392e+15, 9.127414935180233465e+42, + 6.091127771174027909e+116, }; + +__constant__ double m_abscissas_double_2[12] = + { 4.547459836328942014e-99, 6.678756542928857080e-37, 5.005042973041566360e-14, 1.341318484151208960e-05, + 1.833875636365939263e-02, 3.257972971286326131e-01, 1.712014688483495078e+00, 1.613222549264089627e+01, + 3.116246745274236447e+03, 3.751603952020919663e+09, 1.132259067258797346e+26, 6.799257464097374238e+70, }; + +__constant__ double m_abscissas_double_3[25] = + { 5.314690663257815465e-127, 2.579830034615362946e-77, 3.534801062399966878e-47, 6.733941646704537777e-29, + 8.265803726974829043e-18, 4.424914371157762285e-11, 5.390411046738629465e-07, 1.649389713333761449e-04, + 5.463728936866216652e-03, 4.787896410534771955e-02, 1.931544616590306846e-01, 5.121421856617965197e-01, + 1.144715949265016019e+00, 2.648424684387670480e+00, 7.856804169938798917e+00, 3.944731803343517708e+01, + 5.060291993016831194e+02, 3.181117494063683297e+04, 2.820174654949211729e+07, 1.993745099515255184e+12, + 1.943469269499068563e+20, 2.858803732300638372e+33, 1.457292199029008637e+55, 8.943565831706355607e+90, + 9.016198369791554655e+149, }; + +__constant__ double m_abscissas_double_4[49] = + { 8.165631636299519857e-144, 3.658949309353149331e-112, 1.635242513882908826e-87, 2.578381184977746454e-68, + 2.305546416275824199e-53, 1.016725540031465162e-41, 1.191823622917539774e-32, 1.379018088205016509e-25, + 4.375640088826073184e-20, 8.438464631330991606e-16, 1.838483310261119782e-12, 7.334264181393092650e-10, + 7.804740587931068021e-08, 2.970395577741681504e-06, 5.081805431666579484e-05, 4.671401627620431498e-04, + 2.652347404231090523e-03, 1.037409202661683856e-02, 3.045225582205323946e-02, 7.178280364982721201e-02, + 1.434001065841990688e-01, 2.535640852949085796e-01, 4.113268917643175920e-01, 6.310260805648534613e-01, + 9.404706503455087817e-01, 1.396267301972783068e+00, 2.116896928689963277e+00, 3.364289290471596568e+00, + 5.770183960005836987e+00, 1.104863531218761752e+01, 2.460224479439805859e+01, 6.699316387888639988e+01, + 2.375794092475844708e+02, 1.188092202760116066e+03, 9.269848635975416108e+03, 1.283900116155671304e+05, + 3.723397798030112514e+06, 2.793667983952389721e+08, 7.112973790863854188e+10, 8.704037695808749572e+13, + 8.001474015782459984e+17, 9.804091819390540578e+22, 3.342777673392873288e+29, 8.160092668471508447e+37, + 4.798775331663586528e+48, 3.228614320248853938e+62, 1.836986041572136151e+80, 1.153145986877483804e+103, + 2.160972586723647751e+132, }; + +__constant__ double m_abscissas_double_5[98] = + { 4.825077401709435655e-153, 3.813781211050297560e-135, 2.377824349780240844e-119, 2.065817295388293122e-105, + 4.132105770181358886e-93, 2.963965169989404311e-82, 1.127296662046635391e-72, 3.210346399945695041e-64, + 9.282992368222161062e-57, 3.565977853916619677e-50, 2.306962519220473637e-44, 3.098751038516535098e-39, + 1.039558064722960891e-34, 1.025256027381235200e-30, 3.432612000569885403e-27, 4.429681881379089961e-24, + 2.464589267395236846e-21, 6.526691446363344923e-19, 8.976892324445928684e-17, 6.926277695183452225e-15, + 3.208805316815751272e-13, 9.478053068835988899e-12, 1.882052586691155400e-10, 2.632616062773909009e-09, + 2.703411837703917665e-08, 2.113642195965330965e-07, 1.299327029813074013e-06, 6.461189935136030673e-06, + 2.665090959570723827e-05, 9.322774986189288194e-05, 2.820463407940068813e-04, 7.508613300035051413e-04, + 1.786142185986551786e-03, 3.848376610765768211e-03, 7.600810651854199771e-03, 1.390873269178271700e-02, + 2.380489559528694982e-02, 3.842796337748997654e-02, 5.895012901671883992e-02, 8.651391160689367948e-02, + 1.221961347398101671e-01, 1.670112314557845555e-01, 2.219593619059930701e-01, 2.881200442770917241e-01, + 3.667906976948184315e-01, 4.596722879563388211e-01, 5.691113093602836208e-01, 6.984190600916228379e-01, + 8.523070690462583711e-01, 1.037505121571600249e+00, 1.263672635742961915e+00, 1.544788480334120896e+00, + 1.901333876886441433e+00, 2.363816272813317635e+00, 2.978614980117902904e+00, 3.817957977526709364e+00, + 4.997477803461245639e+00, 6.708150685706236545e+00, 9.276566033183386532e+00, 1.328332469239125539e+01, + 1.980618680552458639e+01, 3.094452809319702849e+01, 5.101378787119006225e+01, 8.943523638413590523e+01, + 1.682138665185088325e+02, 3.427988270281270587e+02, 7.653823671943767281e+02, 1.895993667030670343e+03, + 5.285404568827643942e+03, 1.684878049282191210e+04, 6.254388805482299369e+04, 2.759556544455721132e+05, + 1.481213238071008345e+06, 9.929728611179601424e+06, 8.564987764771851841e+07, 9.831650826344826952e+08, + 1.560339073978569502e+10, 3.575098885016726922e+11, 1.241973798101884982e+13, 6.915106205748805839e+14, + 6.571419716645131084e+16, 1.144558033138694099e+19, 3.960915669532823553e+21, 2.984410558028297842e+24, + 5.430494850258846715e+27, 2.683747612498502676e+31, 4.114885708325522701e+35, 2.276004816861421600e+40, + 5.387544917595833246e+45, 6.623575732955432303e+51, 5.266881304835239338e+58, 3.473234812654772210e+66, + 2.517492645985977377e+75, 2.759797646289240629e+85, 6.569603829502412077e+96, 5.116181648220647995e+109, + 2.073901892339407423e+124, 7.406462446666255838e+140, }; + +__constant__ double m_abscissas_double_6[196] = + { 7.053618140948655098e-158, 2.343354218558056628e-148, 2.062509087689351439e-139, 5.212388628332260488e-131, + 4.079380320868843387e-123, 1.061481285006738214e-115, 9.816727607793017691e-109, 3.435400719609722581e-102, + 4.825198574681495574e-96, 2.874760995089533358e-90, 7.652499977338879996e-85, 9.556944498127119032e-80, + 5.862241023038227937e-75, 1.843934000129616663e-70, 3.096983980846232911e-66, 2.885057452402340330e-62, + 1.544904681826443837e-58, 4.917572705671511534e-55, 9.602608566391652866e-52, 1.184882375237471009e-48, + 9.499223316355714793e-46, 5.078965858882528461e-43, 1.856080838373584123e-40, 4.744245560917271585e-38, + 8.667497891102658240e-36, 1.155086178652063612e-33, 1.144541329818836153e-31, 8.585083084065812874e-30, + 4.957702933032408922e-28, 2.239353794616277882e-26, 8.030405447708765492e-25, 2.318459271131684362e-23, + 5.460287296679086677e-22, 1.062054307071706375e-20, 1.725955878033239909e-19, 2.369168446274347137e-18, + 2.775176063916613602e-17, 2.800847352316621903e-16, 2.457625954357892245e-15, 1.890842052364646528e-14, + 1.285791209258834942e-13, 7.786001004707878219e-13, 4.228083024410741194e-12, 2.072664297543567489e-11, + 9.229295073519997559e-11, 3.754886152592311575e-10, 1.403443871774813834e-09, 4.843962757371872495e-09, + 1.551373196623161433e-08, 4.631448362339623514e-08, 1.294370176865168120e-07, 3.400050664017164356e-07, + 8.426290307581447654e-07, 1.977205177561996033e-06, 4.407362363338667830e-06, 9.362197325373404563e-06, + 1.900760383449277992e-05, 3.698530963711860636e-05, 6.915333419235766653e-05, 1.245492076251852927e-04, + 2.165764713808099093e-04, 3.643870211078977292e-04, 5.943999416122372516e-04, 9.418663022314558591e-04, + 1.452364274261880083e-03, 2.183094846035196562e-03, 3.203848855069215278e-03, 4.597532353031862490e-03, + 6.460168315117479792e-03, 8.900334989802041559e-03, 1.203804973137064275e-02, 1.600315622064554965e-02, + 2.093331703849583304e-02, 2.697174812170771748e-02, 3.426485378063329473e-02, 4.295992956149806344e-02, + 5.320309587203163231e-02, 6.513760993479510261e-02, 7.890268021756337834e-02, 9.463287940877026649e-02, + 1.124582226719385153e-01, 1.325049504086213973e-01, 1.548970316076579260e-01, 1.797583869192584860e-01, + 2.072158210677632145e-01, 2.374026527414815016e-01, 2.704630368855767324e-01, 3.065569893452247137e-01, + 3.458661469783558388e-01, 3.886003277325320632e-01, 4.350049951304795319e-01, 4.853697810067132707e-01, + 5.400382807495678589e-01, 5.994194092045578293e-01, 6.640006964388650918e-01, 7.343640159321037167e-01, + 8.112043806284638130e-01, 8.953526245122194172e-01, 9.878030224123093447e-01, 1.089747207002141516e+00, + 1.202616144679226559e+00, 1.328132465995424226e+00, 1.468376159872979355e+00, 1.625867601500928277e+00, + 1.803673186618691186e+00, 2.005540624723209206e+00, 2.236073393446881709e+00, 2.500957254018255004e+00, + 2.807256477663534857e+00, 3.163804128101147487e+00, 3.581720263742550029e+00, 4.075105576391566303e+00, + 4.661977749936137761e+00, 5.365546718714963091e+00, 6.215967676434536043e+00, 7.252774367330402583e+00, + 8.528291278204291331e+00, 1.011247001122720391e+01, 1.209982167952718578e+01, 1.461947158782994207e+01, + 1.784992423404041042e+01, 2.204102944968352178e+01, 2.754711235628932374e+01, 3.487766600641650640e+01, + 4.477610230214251576e+01, 5.834406132739843834e+01, 7.724096630394042216e+01, 1.040101075374387191e+02, + 1.426215523101601730e+02, 1.993940974645466479e+02, 2.845939167898235356e+02, 4.152683836292551147e+02, + 6.203878718481709769e+02, 9.504080873581791535e+02, 1.495523342124078853e+03, 2.421485328006836634e+03, + 4.041977218227396500e+03, 6.969453497454785202e+03, 1.244001690461442846e+04, 2.303794930506892099e+04, + 4.437240927040385250e+04, 8.911296561746717657e+04, 1.871159398849787994e+05, 4.119851492265743330e+05, + 9.540971729944126398e+05, 2.331680521880789706e+06, 6.034305391011695472e+06, 1.659896369452266448e+07, + 4.872448839341613053e+07, 1.532687586549090392e+08, 5.189730792935011722e+08, 1.900599621040508288e+09, + 7.566480431232731818e+09, 3.292298322781643849e+10, 1.574714421665075635e+11, 8.330244306239795892e+11, + 4.905619969814187571e+12, 3.238316002757222702e+13, 2.413995281454699076e+14, 2.048115587426077343e+15, + 1.994352670766892066e+16, 2.248750566422739144e+17, 2.964037541992353401e+18, 4.613233119968213445e+19, + 8.569680508342001161e+20, 1.921851711942844799e+22, 5.266829246099861758e+23, 1.786779952992288976e+25, + 7.607919705736976491e+26, 4.125721424346450007e+28, 2.894340142292214313e+30, 2.670720269656428272e+32, + 3.299248229135205151e+34, 5.560105583582310103e+36, 1.304167266599523020e+39, 4.349382146382717353e+41, + 2.109720387774341509e+44, 1.524825352702403324e+47, 1.684941265105084589e+50, 2.925572737558413426e+53, + 8.217834961057481281e+56, 3.852117991896536784e+60, 3.114452310394384063e+64, 4.498555465873245751e+68, + 1.205113215232800796e+73, 6.230864727145221322e+77, 6.487131248948465269e+82, 1.422810109167834249e+88, + 6.897656089181724717e+93, 7.779163462756485195e+99, 2.155213251859555072e+106, 1.554347160152705281e+113, + 3.103875072425192272e+120, 1.832673821557018634e+128, 3.431285951865278376e+136, 2.194542081542393530e+145, }; + +__constant__ double m_abscissas_double_7[393] = + { 2.363803632659058081e-160, 1.926835442612677686e-155, 1.109114905180506786e-150, 4.556759282087534164e-146, + 1.350172241067816232e-141, 2.914359263635229435e-137, 4.627545976953585825e-133, 5.456508344460398758e-129, + 4.821828861306345485e-125, 3.221779152402086241e-121, 1.641732102111619421e-117, 6.433569189921227126e-114, + 1.954582672700428961e-110, 4.639912078942456372e-107, 8.671928891742699827e-104, 1.285485264305858782e-100, + 1.522161801460927566e-97, 1.449767844425295085e-94, 1.118122255504445235e-91, 7.028344777398825069e-89, + 3.623454064991238081e-86, 1.541513438874996543e-83, 5.443699502170284982e-81, 1.604913673768949456e-78, + 3.972206240977317536e-76, 8.297975554162539562e-74, 1.470748835855054032e-71, 2.222935801472624670e-69, + 2.879160361851977720e-67, 3.210837413250902178e-65, 3.097303984958235490e-63, 2.595974479763180595e-61, + 1.898656799199089593e-59, 1.216865518398435626e-57, 6.862041810601184397e-56, 3.418134121780773218e-54, + 1.509758535747580387e-52, 5.934924977563731784e-51, 2.083865009061241099e-49, 6.558128104492290092e-48, + 1.856133016606468181e-46, 4.739964621828176249e-45, 1.095600459825324697e-43, 2.299177139060262518e-42, + 4.393663812095906869e-41, 7.667728102142858487e-40, 1.225476279042445010e-38, 1.798526997315960782e-37, + 2.430201154741018716e-36, 3.030993518975438712e-35, 3.497966609954172613e-34, 3.744308272796551045e-33, + 3.726132797819332658e-32, 3.455018936399215381e-31, 2.991524108706319604e-30, 2.423818520801870809e-29, + 1.841452809687011486e-28, 1.314419760826235421e-27, 8.831901010260867670e-27, 5.596660060604091621e-26, + 3.350745417080507841e-25, 1.898675566025820409e-24, 1.019982287418197376e-23, 5.203315082978366918e-23, + 2.524668746906057148e-22, 1.166904646009344233e-21, 5.145437675264868732e-21, 2.167677145279166596e-20, + 8.736996911006110678e-20, 3.373776431076593266e-19, 1.249769727462160008e-18, 4.446913832647864892e-18, + 1.521741180930875343e-17, 5.014158301377399707e-17, 1.592708205361177316e-16, 4.882536933653862982e-16, + 1.446109387544416586e-15, 4.142510168443201880e-15, 1.148892083132325407e-14, 3.088024760858924214e-14, + 8.051699653634442236e-14, 2.038478329249539199e-13, 5.015686309363884049e-13, 1.200444984849900298e-12, + 2.797125428309156462e-12, 6.350357793399881333e-12, 1.405881744263466936e-11, 3.037391821635123795e-11, + 6.408863411016101449e-11, 1.321618431565916164e-10, 2.665526566207284474e-10, 5.261497418654313068e-10, + 1.017123184766088896e-09, 1.926882221639203388e-09, 3.579523428497157488e-09, 6.524486847652635035e-09, + 1.167543991262942921e-08, 2.052356080018121741e-08, 3.545879678923676129e-08, 6.024472481556065885e-08, + 1.007076869023518125e-07, 1.657191565891799652e-07, 2.685718943404479677e-07, 4.288752213761154116e-07, + 6.751222405372943925e-07, 1.048111270324302884e-06, 1.605433960692314060e-06, 2.427271958412371013e-06, + 3.623770645356477660e-06, 5.344280132492750309e-06, 7.788767891027678939e-06, 1.122171160022519082e-05, + 1.598877254198599908e-05, 2.253652700952153115e-05, 3.143549403208496646e-05, 4.340664122305257288e-05, + 5.935147653125578529e-05, 8.038574285450253209e-05, 1.078766266062957565e-04, 1.434832731669987826e-04, + 1.892002753957224677e-04, 2.474036705329449166e-04, 3.208988510028906069e-04, 4.129696713145546995e-04, + 5.274279220384250390e-04, 6.686622480794640482e-04, 8.416855170641220285e-04, 1.052179598744440400e-03, + 1.306536501050643762e-03, 1.611894824798787196e-03, 1.976170547826080496e-03, 2.408081229927640721e-03, + 2.917162840577481875e-03, 3.513778549028205519e-03, 4.209118976964403112e-03, 5.015193592567630665e-03, + 5.944813116164644191e-03, 7.011563005746090924e-03, 8.229768289624073049e-03, 9.614450207543986041e-03, + 1.118127530523730813e-02, 1.294649779580742160e-02, 1.492689615029751590e-02, 1.713970500593860526e-02, + 1.960254358145296755e-02, 2.233334186285684056e-02, 2.535026586984720664e-02, 2.867164333232700310e-02, + 3.231589109997912964e-02, 3.630144557680610965e-02, 4.064669741956638109e-02, 4.536993166688766414e-02, + 5.048927437769432941e-02, 5.602264675683979161e-02, 6.198772763597769678e-02, 6.840192506222012774e-02, + 7.528235762939712171e-02, 8.264584606994605986e-02, 9.050891551257121825e-02, 9.888780870447738360e-02, + 1.077985103995250356e-01, 1.172567830270636607e-01, 1.272782136821146663e-01, 1.378782724173011162e-01, + 1.490723817714478840e-01, 1.608759974398061173e-01, 1.733046999768424060e-01, 1.863742974247175786e-01, + 2.001009387790379976e-01, 2.145012382381487190e-01, 2.295924102330349785e-01, 2.453924153016625057e-01, + 2.619201169541956490e-01, 2.791954497739298773e-01, 2.972395991130188526e-01, 3.160751928723792943e-01, + 3.357265060019327741e-01, 3.562196785212496373e-01, 3.775829480426418792e-01, 3.998468979800887046e-01, + 4.230447228497335035e-01, 4.472125123131631074e-01, 4.723895558858634018e-01, 4.986186705332947608e-01, + 5.259465537097384485e-01, 5.544241647649479754e-01, 5.841071380560416511e-01, 6.150562315632864018e-01, + 6.473378153258308278e-01, 6.810244045956889952e-01, 7.161952432654565143e-01, 7.529369438691556459e-01, + 7.913441913000366617e-01, 8.315205183502086596e-01, 8.735791622734589226e-01, 9.176440128265773576e-01, + 9.638506636817484398e-01, 1.012347580753402101e+00, 1.063297402882930381e+00, 1.116878392515788506e+00, + 1.173286056537125469e+00, 1.232734960362603918e+00, 1.295460761779549539e+00, 1.361722494981910846e+00, + 1.431805139837984876e+00, 1.506022516788234345e+00, 1.584720554029819354e+00, 1.668280980969603645e+00, + 1.757125510515793421e+00, 1.851720582866847453e+00, 1.952582755329533200e+00, 2.060284836698905963e+00, + 2.175462881275503983e+00, 2.298824177179966629e+00, 2.431156386859774759e+00, 2.573338025304717222e+00, + 2.726350494395667363e+00, 2.891291931102408784e+00, 3.069393174263124520e+00, 3.262036211067640944e+00, + 3.470775532153801919e+00, 3.697362905908153155e+00, 3.943776181224350319e+00, 4.212252847439515687e+00, + 4.505329225191826639e+00, 4.825886338442190807e+00, 5.177203733275742875e+00, 5.563022772612923373e+00, + 5.987621259260909859e+00, 6.455901637501497370e+00, 6.973495514195020291e+00, 7.546887847708181032e+00, + 8.183564906772872855e+00, 8.892191039842283431e+00, 9.682820467523296204e+00, 1.056715177903931837e+01, + 1.155883465937652851e+01, 1.267384070151528947e+01, 1.393091310389918289e+01, 1.535211379418177923e+01, + 1.696349128797309510e+01, 1.879589868990482198e+01, 2.088599907466058846e+01, 2.327750557804054323e+01, + 2.602271658731131093e+01, 2.918442338619305962e+01, 3.283828974258811174e+01, 3.707583192189045823e+01, + 4.200816575721451990e+01, 4.777073782243997224e+01, 5.452932468101429049e+01, 6.248767344468634478e+01, + 7.189727649240108469e+01, 8.306993427631743111e+01, 9.639397813652482031e+01, 1.123553215857374919e+02, + 1.315649140340119335e+02, 1.547947284376312334e+02, 1.830251850988715552e+02, 2.175079854175568113e+02, + 2.598498278995140400e+02, 3.121245867818556035e+02, 3.770245173783702458e+02, 4.580653020257635092e+02, + 5.598658426219653689e+02, 6.885324967857802403e+02, 8.521902266884453403e+02, 1.061721815114114004e+03, + 1.331803836529085656e+03, 1.682368940494210217e+03, 2.140685129891926443e+03, 2.744334847491432747e+03, + 3.545516659371773357e+03, 4.617306735234797694e+03, 6.062848530677391758e+03, 8.028955134017154634e+03, + 1.072641999277462936e+04, 1.446061873485939411e+04, 1.967804579389513789e+04, 2.703776201447279367e+04, + 3.752217148194723312e+04, 5.261052412010591097e+04, 7.455350923854624329e+04, 1.068125318497402759e+05, + 1.547702528541975911e+05, 2.268930751685412563e+05, 3.366554971645478061e+05, 5.057644049026088560e+05, + 7.696291826884134742e+05, 1.186761864945790800e+06, 1.855146094294667715e+06, 2.941132644236832276e+06, + 4.731169740596920355e+06, 7.725765147199987935e+06, 1.281272565991955126e+07, 2.159151785284808339e+07, + 3.699029448836502904e+07, 6.445902263727884020e+07, 1.143158678867853615e+08, 2.064425450996979446e+08, + 3.798502995329785506e+08, 7.125329484929003007e+08, 1.363463294023391629e+09, 2.663196590686555077e+09, + 5.313347815419462975e+09, 1.083506369700027396e+10, 2.259930737910197667e+10, 4.824707991473375387e+10, + 1.055069002818752104e+11, 2.365138040635727209e+11, 5.439266129959972285e+11, 1.284356371641026839e+12, + 3.116424654245920797e+12, 7.777312465656280419e+12, 1.997984843259596733e+13, 5.288649037339853118e+13, + 1.443776937640548342e+14, 4.068967444890414804e+14, 1.185049702391501141e+15, 3.570348091883284324e+15, + 1.113971254034978026e+16, 3.603374982229766184e+16, 1.209803708182151942e+17, 4.220890251904870611e+17, + 1.532169872312865862e+18, 5.793890867821715890e+18, 2.285379920879842924e+19, 9.415714369232187727e+19, + 4.057471211245170887e+20, 1.831405465804324767e+21, 8.671209773404504008e+21, 4.313209261217173994e+22, + 2.257498454242656934e+23, 1.245267136898199709e+24, 7.251536499435180219e+24, 4.465573963364524765e+25, + 2.913233420596266283e+26, 2.017063171206072979e+27, 1.485014353353330393e+28, 1.164811091759882662e+29, + 9.753661264047912784e+29, 8.737124417851167566e+30, 8.390503265508677363e+31, 8.657362701430272680e+32, + 9.619472292454361392e+33, 1.153735498483960294e+35, 1.497284701983562213e+36, 2.107816695320163748e+37, + 3.227106623185610745e+38, 5.387696372515021985e+39, 9.835496017627849225e+40, 1.968904749086105300e+42, + 4.334704147416758275e+43, 1.052717645113369473e+45, 2.829013521120326147e+46, 8.439656297525588822e+47, + 2.804279894508234869e+49, 1.041383695988523864e+51, 4.337366591019718310e+52, 2.033523569151676725e+54, + 1.077238847489773081e+56, 6.472891251891105455e+57, 4.429404678715878536e+59, 3.466135480828349864e+61, + 3.114928656972704276e+63, 3.228947925415990689e+65, 3.878402486902381042e+67, 5.423187597439531197e+69, + 8.870779393460412583e+71, 1.705832285076755970e+74, 3.876224350373120420e+76, 1.046359534886878004e+79, + 3.373858809560757544e+81, 1.306762499786044015e+84, 6.115300889685679832e+86, 3.478550048884517349e+89, + 2.420073578988056289e+92, 2.072453567501123129e+95, 2.199029867204449277e+98, 2.910868575802139983e+101, + 4.840699137490951163e+104, 1.018669397739170369e+108, 2.733025017438095928e+111, 9.420797277586029837e+114, + 4.205525105722885986e+118, 2.451352708852151939e+122, 1.881577053794165543e+126, 1.918506219134233785e+130, + 2.622069659115564900e+134, 4.848463485415763756e+138, 1.224645005481997780e+143, 4.267387286482591954e+147, + 2.072505613372582377e+152, }; + +__constant__ double m_abscissas_double_8[786] = + { 1.323228129684237783e-161, 4.129002973520822791e-159, 1.178655462569548882e-156, 3.082189008893206231e-154, + 7.393542832199414487e-152, 1.629100644355328639e-149, 3.301545529059822941e-147, 6.162031390854241227e-145, + 1.060528194470986309e-142, 1.685225757497235089e-140, 2.475534097582263629e-138, 3.365764749507587192e-136, + 4.240562683924022383e-134, 4.956794227885611715e-132, 5.381716367914161520e-130, 5.433507172294988849e-128, + 5.107031242794315420e-126, 4.473704932098646394e-124, 3.656376947377888629e-122, 2.791170022694259001e-120, + 1.992200238692415032e-118, 1.330894359393789718e-116, 8.330356767359890503e-115, 4.890256639970245146e-113, + 2.695128935451165447e-111, 1.395829605415630844e-109, 6.799997527188085942e-108, 3.119037767379032293e-106, + 1.348260131419216291e-104, 5.497526018943990804e-103, 2.116384670251198533e-101, 7.699148714858061209e-100, + 2.649065347250598345e-98, 8.628189263549727753e-97, 2.662520943248368922e-95, 7.790698623582886341e-94, + 2.163354866683077281e-92, 5.705576739797220361e-91, 1.430338193028564913e-89, 3.411040781372328747e-88, + 7.744268073516449037e-87, 1.675136564303435813e-85, 3.454795810595704816e-84, 6.798573137099477363e-83, + 1.277474708033782661e-81, 2.293702139426309483e-80, 3.938021700015175030e-79, 6.469593934876300124e-78, + 1.017725266990912471e-76, 1.534019529793324951e-75, 2.216999886838860916e-74, 3.074100747562803362e-73, + 4.092295330837549092e-72, 5.233434175636538471e-71, 6.433506079763357418e-70, 7.607042677901362161e-69, + 8.656714387163425357e-68, 9.486746058685489974e-67, 1.001756724248288397e-65, 1.019853943834854330e-64, + 1.001591106610665630e-63, 9.494277822444263952e-63, 8.691422918891890649e-62, 7.687977047887448276e-61, + 6.574408104196605248e-60, 5.438162502918425191e-59, 4.353340831363003212e-58, 3.374338762181243411e-57, + 2.533770921173042330e-56, 1.844048925248616738e-55, 1.301410812308480184e-54, 8.910466744374470063e-54, + 5.921538384124132331e-53, 3.821356134297705127e-52, 2.395780657353036891e-51, 1.459882187581820236e-50, + 8.650105472076777327e-50, 4.985933550797199316e-49, 2.796911903237435916e-48, 1.527570118993503332e-47, + 8.126314048196993302e-47, 4.212436363948578182e-46, 2.128604050242564662e-45, 1.048938356323431072e-44, + 5.042753142653687842e-44, 2.365999225494165364e-43, 1.083813462091040325e-42, 4.848963367960316169e-42, + 2.119612873737657277e-41, 9.055947139022002648e-41, 3.782987192192666650e-40, 1.545649846917574765e-39, + 6.178909752126026357e-39, 2.417597558625940386e-38, 9.261305999966332746e-38, 3.474712971194656115e-37, + 1.277215890629181345e-36, 4.600938133935473864e-36, 1.624804314773052044e-35, 5.626808103137929972e-35, + 1.911442429947086471e-34, 6.371300415498187125e-34, 2.084444531309441237e-33, 6.695356060065574234e-33, + 2.112038435637792931e-32, 6.544802906551512393e-32, 1.992864937623987114e-31, 5.964358817764151755e-31, + 1.754973231464949500e-30, 5.078231558861773863e-30, 1.445447866528259475e-29, 4.048099759391660786e-29, + 1.115752878927994221e-28, 3.027334168442338592e-28, 8.087868498106224788e-28, 2.128106544151858936e-27, + 5.516210113930227985e-27, 1.408890921124863906e-26, 3.546520734326774807e-26, 8.800636481096360494e-26, + 2.153319509043984465e-25, 5.196136544731926346e-25, 1.236869058422202190e-24, 2.904891674490918873e-24, + 6.732707317563258763e-24, 1.540253603361391055e-23, 3.478765727687221019e-23, 7.758450079933031976e-23, + 1.708939324269830276e-22, 3.718467010568811152e-22, 7.994094376769029920e-22, 1.698336774318343123e-21, + 3.566214469724002275e-21, 7.402848534866351662e-21, 1.519411719755297549e-20, 3.083993994528608740e-20, + 6.191388817974459809e-20, 1.229625987010589227e-19, 2.416245949308411084e-19, 4.698551818749419706e-19, + 9.042992978848520439e-19, 1.722880198390020817e-18, 3.249832858354112322e-18, 6.070120594586457562e-18, + 1.122871881646098441e-17, 2.057429235664205922e-17, 3.734613207742816399e-17, 6.716694369267842075e-17, + 1.197063025055043952e-16, 2.114419661115663617e-16, 3.702017138231021853e-16, 6.425665498746337860e-16, + 1.105830903726985419e-15, 1.887156051660563224e-15, 3.193979018679125833e-15, 5.361881977473204459e-15, + 8.929318568606692809e-15, 1.475330560958586660e-14, 2.418708636765824964e-14, 3.935078350904051302e-14, + 6.354047096308654479e-14, 1.018416666466509442e-13, 1.620423782999307693e-13, 2.559817517056126166e-13, + 4.015273886294212810e-13, 6.254532358261761291e-13, 9.675981021394182858e-13, 1.486832112534566186e-12, + 2.269557377760486879e-12, 3.441736008766365832e-12, 5.185793859860652413e-12, 7.764217889314004663e-12, + 1.155228105746548036e-11, 1.708313121464262097e-11, 2.510951856086201897e-11, 3.668776978510952341e-11, + 5.329131813941740314e-11, 7.696325397299480856e-11, 1.105200723643722855e-10, 1.578221843796034825e-10, + 2.241309672940976766e-10, 3.165773201144956642e-10, 4.447730510871610704e-10, 6.216041661455164049e-10, + 8.642544905395987868e-10, 1.195519306516659349e-09, 1.645482121417189823e-09, 2.253643612941620883e-09, + 3.071610576496751310e-09, 4.166474690460445927e-09, 5.625036504185181035e-09, 7.559059638953998396e-09, + 1.011177417876491092e-08, 1.346588701906267454e-08, 1.785340092957703350e-08, 2.356759364235337519e-08, + 3.097756373337616088e-08, 4.054581171302714730e-08, 5.284939280085554173e-08, 6.860525247854168448e-08, + 8.870043714076795346e-08, 1.142279599340281637e-07, 1.465291959965373757e-07, 1.872437814520259903e-07, + 2.383680961705324062e-07, 3.023235208219232784e-07, 3.820357732606947876e-07, 4.810267467496160044e-07, + 6.035203917139166314e-07, 7.545643021775656875e-07, 9.401687861337141280e-07, 1.167465314019272078e-06, + 1.444886349199346242e-06, 1.782368666762205796e-06, 2.191582359683820240e-06, 2.686187812137005286e-06, + 3.282122985909738110e-06, 3.997923415034129149e-06, 4.855077333283880469e-06, 5.878418366687560187e-06, + 7.096558206229387964e-06, 8.542361632206236097e-06, 1.025346618920209381e-05, 1.227284870748632855e-05, + 1.464944073127878202e-05, 1.743879474552002742e-05, 2.070380288967650755e-05, 2.451546960924430874e-05, + 2.895373942298085844e-05, 3.410838067694928604e-05, 4.007992581615393488e-05, 4.698066833232878622e-05, + 5.493571614427227251e-05, 6.408410073746518169e-05, 7.457994093551813828e-05, 8.659365970069775654e-05, + 1.003132518682442285e-04, 1.159456002136906496e-04, 1.337178367385581674e-04, 1.538787455425709779e-04, + 1.767002031351005554e-04, 2.024786515302844608e-04, 2.315365989746650402e-04, 2.642241426787982083e-04, + 3.009205074706080013e-04, 3.420355938637258307e-04, 3.880115286439000550e-04, 4.393242107257947798e-04, + 4.964848447258090522e-04, 5.600414544382562271e-04, 6.305803681962314437e-04, 7.087276679481586600e-04, + 7.951505937892094439e-04, 8.905588956558126794e-04, 9.957061239230124343e-04, 1.111390850739538593e-03, + 1.238457814094548688e-03, 1.377798976832850428e-03, 1.530354493121150144e-03, 1.697113575214988470e-03, + 1.879115253782404405e-03, 2.077449025503311209e-03, 2.293255382179820056e-03, 2.527726216158548279e-03, + 2.782105097477072741e-03, 3.057687418798497807e-03, 3.355820404885606963e-03, 3.677902984083964409e-03, + 4.025385520026097270e-03, 4.399769402530814407e-03, 4.802606497446985045e-03, 5.235498455973840111e-03, + 5.700095884774212336e-03, 6.198097378977308725e-03, 6.731248420937948614e-03, 7.301340148374219834e-03, + 7.910207996239952125e-03, 8.559730217397303903e-03, 9.251826287833445298e-03, 9.988455202809488913e-03, + 1.077161367093554544e-02, 1.160333421372954856e-02, 1.248568317873621646e-02, 1.342075867475355427e-02, + 1.441068843813546585e-02, 1.545762763950860648e-02, 1.656375664055830135e-02, 1.773127871080136402e-02, + 1.896241771447260382e-02, 2.025941577780677588e-02, 2.162453094709917839e-02, 2.306003484797691421e-02, + 2.456821035631025318e-02, 2.615134929114115217e-02, 2.781175013990572523e-02, 2.955171582608151263e-02, + 3.137355152920124081e-02, 3.327956256694509270e-02, 3.527205234875621605e-02, 3.735332041012234938e-02, + 3.952566053633324126e-02, 4.179135898416228534e-02, 4.415269280953487221e-02, 4.661192830883879903e-02, + 4.917131958110712872e-02, 5.183310721786459418e-02, 5.459951712697841302e-02, 5.747275949639657337e-02, + 6.045502790319455825e-02, 6.354849857288828754e-02, 6.675532979350985865e-02, 7.007766148848641979e-02, + 7.351761495191403887e-02, 7.707729274938041525e-02, 8.075877878706524317e-02, 8.456413855143733669e-02, + 8.849541952147546057e-02, 9.255465175496720496e-02, 9.674384865008904765e-02, 1.010650078831426502e-01, + 1.055201125230189472e-01, 1.101111323226840632e-01, 1.148400251877307103e-01, 1.197087388218165293e-01, + 1.247192125486176994e-01, 1.298733793097628269e-01, 1.351731678380792159e-01, 1.406205050053816316e-01, + 1.462173183439629526e-01, 1.519655387409069424e-01, 1.578671033043359383e-01, 1.639239584007306411e-01, + 1.701380628625154331e-01, 1.765113913651907042e-01, 1.830459379734134606e-01, 1.897437198555789051e-01, + 1.966067811666385690e-01, 2.036371970991047974e-01, 2.108370781024367852e-01, 2.182085742712797843e-01, + 2.257538799033364379e-01, 2.334752382279873511e-01, 2.413749463071469410e-01, 2.494553601102403241e-01, + 2.577188997656175820e-01, 2.661680549911833443e-01, 2.748053907075124803e-01, 2.836335528372471376e-01, + 2.926552742951268547e-01, 3.018733811735925662e-01, 3.112907991295277084e-01, 3.209105599783561596e-01, + 3.307358085024083972e-01, 3.407698094811951648e-01, 3.510159549519934555e-01, 3.614777717099542274e-01, + 3.721589290577866932e-01, 3.830632468159621812e-01, 3.941947036053136035e-01, 4.055574454148868711e-01, + 4.171557944689308074e-01, 4.289942584079951543e-01, 4.410775398002453309e-01, 4.534105460003012245e-01, + 4.659983993741692944e-01, 4.788464479101668631e-01, 4.919602762371392109e-01, 5.053457170727489659e-01, + 5.190088631261786795e-01, 5.329560794812372669e-01, 5.471940164876055195e-01, 5.617296231898020413e-01, + 5.765701613254061793e-01, 5.917232199261468491e-01, 6.071967305576643327e-01, 6.229989832360855492e-01, + 6.391386430620321596e-01, 6.556247676153161584e-01, 6.724668251563812272e-01, 6.896747136835329047e-01, + 7.072587808981804764e-01, 7.252298451337033758e-01, 7.435992173071710726e-01, 7.623787239570054101e-01, + 7.815807314337971290e-01, 8.012181713158943859e-01, 8.213045671260926392e-01, 8.418540624307963733e-01, + 8.628814504084197628e-01, 8.844022049795737430e-01, 9.064325135977815717e-01, 9.289893118061069464e-01, + 9.520903196722039764e-01, 9.757540802219457353e-01, 1.000000000000000000e+00, 1.024848391894543008e+00, + 1.050320520372784475e+00, 1.076438649284173871e+00, 1.103226092399127978e+00, 1.130707266862927052e+00, + 1.158907749757141229e+00, 1.187854337974646084e+00, 1.217575111629048984e+00, 1.248099501235266386e+00, + 1.279458358915164500e+00, 1.311684033900709062e+00, 1.344810452627081143e+00, 1.378873203729832710e+00, + 1.413909628283517352e+00, 1.449958915644490754e+00, 1.487062205287898607e+00, 1.525262695058439148e+00, + 1.564605756286502811e+00, 1.605139056255971231e+00, 1.646912688547541313e+00, 1.689979311822189937e+00, + 1.734394297653598793e+00, 1.780215888066332921e+00, 1.827505363488657555e+00, 1.876327221885466881e+00, + 1.926749369898304239e+00, 1.978843326886336694e+00, 2.032684442834914613e+00, 2.088352131177556992e+00, + 2.145930117663470432e+00, 2.205506706496711366e+00, 2.267175065075584681e+00, 2.331033528772661605e+00, + 2.397185927317806037e+00, 2.465741934479827004e+00, 2.536817442887937264e+00, 2.610534965993323711e+00, + 2.687024069345184956e+00, 2.766421833546071979e+00, 2.848873351459948781e+00, 2.934532262474922666e+00, + 3.023561326873131923e+00, 3.116133043635102211e+00, 3.212430315307524598e+00, 3.312647163894682976e+00, + 3.416989502097797957e+00, 3.525675964626843197e+00, 3.638938804749809967e+00, 3.757024861729272487e+00, + 3.880196605330264341e+00, 4.008733264172298986e+00, 4.142932045347867609e+00, 4.283109453446644399e+00, + 4.429602717916437040e+00, 4.582771338567048147e+00, 4.742998759991079249e+00, 4.910694186746867507e+00, + 5.086294552335034437e+00, 5.270266656314831820e+00, 5.463109485364516396e+00, 5.665356735708146927e+00, + 5.877579556128345480e+00, 6.100389532781943879e+00, 6.334441939256981670e+00, 6.580439277782222274e+00, + 6.839135140254664526e+00, 7.111338420820842566e+00, 7.397917915172903763e+00, 7.699807345544508469e+00, + 8.018010854664294474e+00, 8.353609016702406728e+00, 8.707765418592385473e+00, 9.081733871099147484e+00, + 9.476866315716376006e+00, 9.894621501007146275e+00, 1.033657451045679019e+01, 1.080442723340841910e+01, + 1.130001988133777781e+01, 1.182534366375335115e+01, 1.238255475156052427e+01, 1.297398967101161563e+01, + 1.360218228861306245e+01, 1.426988256684760289e+01, 1.498007729260327644e+01, 1.573601300513857081e+01, + 1.654122137866316500e+01, 1.739954734664685784e+01, 1.831518029132688981e+01, 1.929268866318984532e+01, + 2.033705844217826172e+01, 2.145373590584482942e+01, 2.264867523060898736e+01, 2.392839152177298272e+01, + 2.530001994731418268e+01, 2.677138174118011529e+01, 2.835105794560498805e+01, 3.004847188085487195e+01, + 3.187398146713610639e+01, 3.383898267989664904e+01, 3.595602559959535672e+01, 3.823894472392493310e+01, + 4.070300544879345396e+01, 4.336506889917953679e+01, 4.624377760823269784e+01, 4.935976490967979071e+01, + 5.273589133292714765e+01, 5.639751178186770847e+01, 6.037277784867852275e+01, 6.469298027622754351e+01, + 6.939293735292118365e+01, 7.451143592061966836e+01, 8.009173272176674066e+01, 8.618212503236856949e+01, + 9.283660095406551480e+01, 1.001155814082968890e+02, 1.080867678325352448e+02, 1.168261118752949279e+02, + 1.264189260858047240e+02, 1.369611577708331715e+02, 1.485608519349011866e+02, 1.613398336385932743e+02, + 1.754356453320629017e+02, 1.910037809024609590e+02, 2.082202655019913565e+02, 2.272846389233001078e+02, + 2.484234106336023257e+02, 2.718940668983047258e+02, 2.979897251188232016e+02, 3.270445480633676878e+02, + 3.594400516741229885e+02, 3.956124653087335485e+02, 4.360613334959077953e+02, 4.813595846269808355e+02, + 5.321653357808338203e+02, 5.892357556996862196e+02, 6.534433717775449045e+02, 7.257952842284018994e+02, + 8.074558443729566627e+02, 8.997734679339701200e+02, 1.004312392957944252e+03, 1.122890361185594877e+03, + 1.257623408459775530e+03, 1.410979202907522234e+03, 1.585840680166573460e+03, 1.785582106601447262e+03, + 2.014160171499825914e+03, 2.276223289283167479e+03, 2.577243010007973485e+03, 2.923672325162804598e+03, + 3.323136759290736047e+03, 3.784665511113575050e+03, 4.318971620160236406e+03, 4.938792274850918489e+03, + 5.659303058273368331e+03, 6.498623292476395004e+03, 7.478433875318933386e+03, 8.624734342286166238e+03, + 9.968772633484590145e+03, 1.154818959559393902e+04, 1.340843110702649390e+04, 1.560449453908580443e+04, + 1.820309391023133793e+04, 2.128535066649680777e+04, 2.495014598048375046e+04, 2.931830770482188047e+04, + 3.453785313845473397e+04, 4.079057084931056631e+04, 4.830030527863206410e+04, 5.734341246586992004e+04, + 6.826199159022146453e+04, 8.148067525594191464e+04, 9.752799507478730867e+04, 1.170636462204808295e+05, + 1.409133795481584143e+05, 1.701137853111825512e+05, 2.059699426710509940e+05, 2.501298539735692463e+05, + 3.046808435555379486e+05, 3.722747886360361411e+05, 4.562913164460176067e+05, 5.610511554921845541e+05, + 6.920959565810343691e+05, 8.565564972181198149e+05, 1.063638800552326000e+06, 1.325268101226286025e+06, + 1.656944841847240121e+06, 2.078886479301160156e+06, 2.617555920130068069e+06, 3.307714852226224955e+06, + 4.195192293202626259e+06, 5.340631300250745566e+06, 6.824578495767020734e+06, 8.754424053248831818e+06, + 1.127390159772263517e+07, 1.457614342739689625e+07, 1.892169326841938100e+07, 2.466345986800667442e+07, + 3.228142821711217588e+07, 4.243114571539869754e+07, 5.601173714434088431e+07, 7.426172509723072112e+07, + 9.889461357830121731e+07, 1.322915875470427182e+08, 1.777766240727455981e+08, 2.400110583389834263e+08, + 3.255621033641982742e+08, 4.437258820593761403e+08, 6.077246218504877165e+08, 8.364565879857375417e+08, + 1.157066594326456169e+09, 1.608740826498742961e+09, 2.248337657948688269e+09, 3.158785978851336228e+09, + 4.461677081363911380e+09, 6.336244831048209270e+09, 9.048130159588677560e+09, 1.299321362309972265e+10, + 1.876478261212947929e+10, 2.725703976712888971e+10, 3.982553459064288940e+10, 5.853727794017415415e+10, + 8.656299089553103385e+10, 1.287959733041898747e+11, 1.928345065430099883e+11, 2.905510467545806044e+11, + 4.406145488098485809e+11, 6.725708918778493152e+11, 1.033486938212196930e+12, 1.598840557086695854e+12, + 2.490490134218272825e+12, 3.906528466724583921e+12, 6.171225147961354244e+12, 9.819163736485109137e+12, + 1.573800106991564475e+13, 2.541245461530031221e+13, 4.134437628407981776e+13, 6.778141973485971528e+13, + 1.119906286595884492e+14, 1.865016806041768967e+14, 3.130890948724989738e+14, 5.298978847669068280e+14, + 9.042973899804181753e+14, 1.556259036818991439e+15, 2.701230066368200812e+15, 4.729430105054711279e+15, + 8.353779033096586530e+15, 1.488827606293191651e+16, 2.677653466031614956e+16, 4.860434481369499270e+16, + 8.905735519300993312e+16, 1.647413728306871552e+17, 3.077081325673016377e+17, 5.804234101329097680e+17, + 1.105828570628099614e+18, 2.128315358808074026e+18, 4.138651532085235581e+18, 8.132554212123920035e+18, + 1.615146503312570855e+19, 3.242548467260718193e+19, 6.581494581080701321e+19, 1.350831366183090003e+20, + 2.804093832520937396e+20, 5.888113683467563837e+20, 1.250923435312468276e+21, 2.689280279098215635e+21, + 5.851582825664479700e+21, 1.288917231788944660e+22, 2.874582763768997631e+22, 6.492437335109217869e+22, + 1.485286605867082177e+23, 3.442469159113307066e+23, 8.084930196860438207e+23, 1.924506778048094878e+24, + 4.643992662491470729e+24, 1.136281452083591334e+25, 2.819664891060694571e+25, 7.097781559991856367e+25, + 1.812838850127688486e+26, 4.699012851344539124e+26, 1.236419707162832951e+27, 3.303236261210411286e+27, + 8.962558097638891218e+27, 2.470294852986226117e+28, 6.918270960555942883e+28, 1.969189447958411510e+29, + 5.698092609453981289e+29, 1.676626156396922084e+30, 5.017901520171556970e+30, 1.527929892279834489e+31, + 4.734762318366711949e+31, 1.493572546446777040e+32, 4.797441164681908184e+32, 1.569538296400998732e+33, + 5.231651156910242454e+33, 1.777206511525290941e+34, 6.154587299576916134e+34, 2.173469781356604872e+35, + 7.829529896526581616e+35, 2.877935554073076917e+36, 1.079761320923458592e+37, 4.136337730951207042e+37, + 1.618408489711185844e+38, 6.469770640447824771e+38, 2.643413654859316358e+39, 1.104246728308525703e+40, + 4.717842641881260665e+40, 2.062296462389327711e+41, 9.226680005161257219e+41, 4.226544071632731963e+42, + 1.983043729707066518e+43, 9.533448690970155039e+43, 4.697914578740208606e+44, 2.373923101980436574e+45, + 1.230570211868531753e+46, 6.546344338411695147e+46, 3.575371819335804914e+47, 2.005642453538335506e+48, + 1.156055268028903078e+49, 6.849867807870312958e+49, 4.174004815218951121e+50, 2.616872034052857472e+51, + 1.688750346837297725e+52, 1.122275666009684101e+53, 7.683968740248677071e+53, 5.422849612654278583e+54, + 3.946686701799533415e+55, 2.963543587288132884e+56, 2.297086395798939516e+57, 1.838856414208555761e+58, + 1.521049475711243996e+59, 1.300732291175071112e+60, 1.150559591141716740e+61, 1.053265997373725461e+62, + 9.984114209879020836e+62, 9.805325615938694719e+63, 9.982463564199115995e+64, 1.054102211457911410e+66, + 1.155172684780782463e+67, 1.314571302334116663e+68, 1.554362407685457310e+69, 1.910791206002645077e+70, + 2.443616403890711206e+71, 3.252983822318823232e+72, 4.510600140020139737e+73, 6.518821831001902447e+74, + 9.825834460774267633e+75, 1.545692063622722856e+77, 2.539346088408163253e+78, 4.359763993811836117e+79, + 7.827943627464404744e+80, 1.470896877674301183e+82, 2.894527071420674290e+83, 5.969662541607915492e+84, + 1.291277613981057357e+86, 2.931656535626877923e+87, 6.991353547531463135e+88, 1.752671194525972852e+90, + 4.622450137056020715e+91, 1.283581933169566226e+93, 3.755839001138390788e+94, 1.158991729845978702e+96, + 3.774916315438862678e+97, 1.298844894462381673e+99, 4.725038949943384889e+100, 1.819000031203286740e+102, + 7.416966330876906188e+103, 3.206116996910598204e+105, 1.470588770071975193e+107, 7.164198238238641057e+108, + 3.710397624567077270e+110, 2.044882454279709373e+112, 1.200428778654730225e+114, 7.513744370030172114e+115, + 5.019575746343410636e+117, 3.582726927665698318e+119, 2.734947775877248560e+121, 2.235283764078944248e+123, + 1.958084751118243323e+125, 1.840431913109305657e+127, 1.858143260692831108e+129, 2.017432949655777136e+131, + 2.358177615888101494e+133, 2.971092974178603610e+135, 4.039532321435816302e+137, 5.933923069661132195e+139, + 9.429263693444953240e+141, 1.622841456932873872e+144, 3.028884476067694180e+146, 6.138356175015339477e+148, + 1.352531557191942648e+151, 3.244447362295582945e+153, }; + +__constant__ double* m_abscissas_double[8] = { + m_abscissas_double_1, + m_abscissas_double_2, + m_abscissas_double_3, + m_abscissas_double_4, + m_abscissas_double_5, + m_abscissas_double_6, + m_abscissas_double_7, + m_abscissas_double_8, +}; + +__constant__ double m_weights_double_1[13] = + { 2.703640234162693583e-160, 3.100862940179668765e-58, 5.828334625665462970e-21, 1.628894422402653830e-07, + 8.129907377394029252e-03, 2.851214447180802931e-01, 1.228894002317118650e+00, 9.374610761705565881e+00, + 6.136846875218162167e+02, 8.367995944653844271e+06, 2.286032371256753845e+17, 9.029964022492184559e+44, + 1.637973037681055808e+119, }; + +__constant__ double m_weights_double_2[12] = + { 1.029757744225565290e-96, 5.564174008086804112e-35, 1.534846576427062716e-12, 1.519539651119905182e-04, + 7.878691652861874032e-02, 6.288072016384128612e-01, 2.842403831496369386e+00, 5.152309209026500589e+01, + 2.554172947873109927e+04, 8.291547503290989754e+10, 6.794911791960761587e+27, 1.108995159102362663e+73, }; + +__constant__ double m_weights_double_3[25] = + { 1.545310485347377408e-124, 4.549745016271158113e-75, 3.781189989988588481e-45, 4.369440793304363176e-27, + 3.253896178006708087e-16, 1.057239289288944987e-09, 7.826174663495492476e-06, 1.459783224353939263e-03, + 2.972970552567852420e-02, 1.637950661613330541e-01, 4.392303913269138921e-01, 8.744243777287317807e-01, + 1.804759465860974506e+00, 4.894937215283148383e+00, 2.036214502429748943e+01, 1.576549789679037479e+02, + 3.249553828744194733e+03, 3.335686029489862584e+05, 4.858218914917275532e+08, 5.655171002571584464e+13, + 9.084276291356790926e+21, 2.202757570781655071e+35, 1.851176020895552142e+57, 1.873046373612647920e+93, + 3.113183070605141140e+152, }; + +__constant__ double m_weights_double_4[49] = + { 2.690380169654157101e-141, 9.388760099830475385e-110, 3.267856956418766261e-85, 4.012903562780032075e-66, + 2.794595941054873674e-51, 9.598140333687791635e-40, 8.762766371925782803e-31, 7.896919977115783593e-24, + 1.951680620313826776e-18, 2.931867534349928041e-14, 4.976350908135118762e-11, 1.546933241860617074e-08, + 1.283189791774752963e-06, 3.809052946018782340e-05, 5.087526585392884730e-04, 3.656819625189471368e-03, + 1.627679402690602992e-02, 5.011672130624018967e-02, 1.165913368715250324e-01, 2.201514148384271336e-01, + 3.581909054968942386e-01, 5.288599003801643436e-01, 7.422823219366348741e-01, 1.032914080772662205e+00, + 1.478415067523268199e+00, 2.242226697017918644e+00, 3.684755742578570582e+00, 6.677326887819023056e+00, + 1.358063058433697357e+01, 3.171262375809110066e+01, 8.776338468947827779e+01, 3.006939713363920293e+02, + 1.352196150715330628e+03, 8.616353573310419356e+03, 8.591849573350877359e+04, 1.523635814554291966e+06, + 5.663834603448267056e+07, 5.450828629396188577e+09, 1.780881993484818221e+12, 2.797112703281894578e+15, + 3.300887168363313931e+19, 5.192538272313512016e+24, 2.273085973059979872e+31, 7.124498195222272142e+39, + 5.379592741425673874e+50, 4.647296508337283075e+64, 3.395147156494395571e+82, 2.736576372417856435e+105, + 6.584825756536212781e+134, }; + +__constant__ double m_weights_double_5[98] = + { 1.692276285171240629e-150, 1.180420021590838281e-132, 6.494931071412232065e-117, 4.979673804239645358e-103, + 8.790122245397054202e-91, 5.564311726870413043e-80, 1.867634664877268411e-70, 4.693767384843440310e-62, + 1.197772698674604837e-54, 4.060530886983702887e-48, 2.318268710612758367e-42, 2.748088060676949794e-37, + 8.136086869664039226e-33, 7.081491999860360593e-29, 2.092407629019781417e-25, 2.383020547076997517e-22, + 1.170143938604536054e-19, 2.734857915002515580e-17, 3.319894174569245506e-15, 2.260825106530477104e-13, + 9.244747974241858562e-12, 2.410325858091057071e-10, 4.224928060220423782e-09, 5.217223349652829804e-08, + 4.730110697329046717e-07, 3.265522864288710545e-06, 1.772851678458610971e-05, 7.787346612077215804e-05, + 2.838101678971546354e-04, 8.775026198694109646e-04, 2.347474744139291716e-03, 5.529174974874315725e-03, + 1.164520226280038968e-02, 2.223487842904240574e-02, 3.896253311038730452e-02, 6.334975706136386464e-02, + 9.651712033300261848e-02, 1.390236708907266445e-01, 1.908593745910709887e-01, 2.515965688234414960e-01, + 3.206651646562737595e-01, 3.976974208167367099e-01, 4.828935799767836828e-01, 5.773826389735376677e-01, + 6.835838865575605461e-01, 8.056083579298257627e-01, 9.497742078309479997e-01, 1.125351459431134254e+00, + 1.345711576612114788e+00, 1.630156867495860456e+00, 2.006880650908830857e+00, 2.517828844916874130e+00, + 3.226826819856410846e+00, 4.233461155863004269e+00, 5.697400323487776530e+00, 7.882247346334201378e+00, + 1.123717929435969530e+01, 1.655437952523069781e+01, 2.528458931361129124e+01, 4.019700050163276117e+01, + 6.682515670231120695e+01, 1.168022589948424530e+02, 2.160045684819153702e+02, 4.257255901158116698e+02, + 9.017180693982791021e+02, 2.072151523320542727e+03, 5.222689557952776194e+03, 1.461663959276604441e+04, + 4.606455611513396576e+04, 1.660950339384278845e+05, 6.976630616605097333e+05, 3.484240083705972727e+06, + 2.117385064786894718e+07, 1.607368605379557548e+08, 1.570235957877638143e+09, 2.041619284762317483e+10, + 3.670425964529826371e+11, 9.527196643411724126e+12, 3.749667772735766186e+14, 2.365380223523087981e+16, + 2.546815287226970627e+18, 5.026010591299970789e+20, 1.970775914722195502e+23, 1.682531038342715298e+26, + 3.469062187981719410e+29, 1.942614547946028081e+33, 3.375034694941022784e+37, 2.115298406181711256e+42, + 5.673738540911562268e+47, 7.904099301170483654e+53, 7.121903115084356741e+60, 5.321820777644930491e+68, + 4.370977753639010591e+77, 5.429657931755513797e+87, 1.464602226824232950e+99, 1.292445035662836561e+112, + 5.936633203060705474e+126, 2.402419924621336913e+143, }; + +__constant__ double m_weights_double_6[196] = + { 2.552410363565288863e-155, 7.965872719315690060e-146, 6.586401422963018216e-137, 1.563673437419490296e-128, + 1.149636272392214573e-120, 2.810189759625314580e-113, 2.441446149780773329e-106, 8.026292508555041710e-100, + 1.059034284623927886e-93, 5.927259046205893861e-88, 1.482220909125121967e-82, 1.738946448501809732e-77, + 1.002047910184021813e-72, 2.960929073720769637e-68, 4.671749731809402860e-64, 4.088398674807775827e-60, + 2.056642628601930023e-56, 6.149878578966749305e-53, 1.128142221531950274e-49, 1.307702777646013040e-46, + 9.848757125541659318e-44, 4.946847667192787369e-41, 1.698284656321589089e-38, 4.077947349805764486e-36, + 6.998897321243266048e-34, 8.762183229651405846e-32, 8.156281709801700633e-30, 5.747366069381804213e-28, + 3.117951907317865517e-26, 1.323052992594482858e-24, 4.457166057119926322e-23, 1.208896132634708032e-21, + 2.674697849739340358e-20, 4.887394807742436672e-19, 7.461632083041868391e-18, 9.622230748739818989e-17, + 1.058884510032627118e-15, 1.003988180288807180e-14, 8.276358838778374127e-14, 5.982281469656734375e-13, + 3.821855766886203088e-12, 2.174279097299082001e-11, 1.109294120074848583e-10, 5.109055596902086022e-10, + 2.137447956882816268e-09, 8.170468538364022161e-09, 2.869308592926374871e-08, 9.305185930419436742e-08, + 2.800231592227134982e-07, 7.855263634214717091e-07, 2.062924236714395731e-06, 5.092224131071637441e-06, + 1.185972357373608535e-05, 2.615333473470835518e-05, 5.479175746096322166e-05, 1.093962713107868416e-04, + 2.087714243290528595e-04, 3.818797556417767457e-04, 6.712796918790164790e-04, 1.136760145626956604e-03, + 1.858775505765622915e-03, 2.941191222579735746e-03, 4.512821350378020080e-03, 6.727293426938802892e-03, + 9.760915371480980900e-03, 1.380842853102550981e-02, 1.907678055354397196e-02, 2.577730275571060412e-02, + 3.411688991056810143e-02, 4.428892397843486143e-02, 5.646473816310556552e-02, 7.078637998740884103e-02, + 8.736131246718460273e-02, 1.062595125372295046e-01, 1.275132133780278017e-01, 1.511193209351630349e-01, + 1.770443400812491404e-01, 2.052314915777496186e-01, 2.356095985715091716e-01, 2.681032744853198083e-01, + 3.026439500331752405e-01, 3.391813282438962329e-01, 3.776949427111484449e-01, 4.182056049753837852e-01, + 4.607866519948383101e-01, 5.055750360563806155e-01, 5.527824318481410262e-01, 6.027066663808878454e-01, + 6.557439076684384801e-01, 7.124021812071310501e-01, 7.733169258916167748e-01, 8.392694625821144443e-01, + 9.112094418201526544e-01, 9.902825786957198607e-01, 1.077865293953107863e+00, 1.175608288920191064e+00, + 1.285491624542001346e+00, 1.409894601042286311e+00, 1.551684711657329886e+00, 1.714331263928885829e+00, + 1.902051053858215699e+00, 2.119995922515087770e+00, 2.374495377438728901e+00, 2.673372087884984440e+00, + 3.026354489757871517e+00, 3.445619726158519068e+00, 3.946512819227006419e+00, 4.548505964859933724e+00, + 5.276487613615791435e+00, 6.162508226184798743e+00, 7.248163842886806184e+00, 8.587878410768473380e+00, + 1.025346434903602082e+01, 1.234051869120733230e+01, 1.497748183201988157e+01, 1.833859935862139637e+01, + 2.266266859437541631e+01, 2.828045768298752298e+01, 3.565528397044830339e+01, 4.544381261232990127e+01, + 5.858833744254070379e+01, 7.645876087681923606e+01, 1.010741758687003802e+02, 1.354538987141142977e+02, + 1.841824059064608872e+02, 2.543337025162468240e+02, 3.570103970895535977e+02, 5.099537256432247190e+02, + 7.420561390174965949e+02, 1.101323941193719451e+03, 1.669232910686306616e+03, 2.587203282090385703e+03, + 4.106608602134535014e+03, 6.685657263550896700e+03, 1.118216368762133982e+04, 1.924811115485038079e+04, + 3.416174865734933127e+04, 6.263882227839496242e+04, 1.189094418952240294e+05, 2.342262528110389793e+05, + 4.798899889628646876e+05, 1.025279649144740527e+06, 2.290428015483177407e+06, 5.365618820221241118e+06, + 1.322172034826883742e+07, 3.438296542047893623e+07, 9.468905314460992170e+07, 2.771843378168242512e+08, + 8.658950437199969679e+08, 2.898779165825890846e+09, 1.044627762990198184e+10, 4.071673625087267154e+10, + 1.725245696783106160e+11, 7.989856904303845909e+11, 4.067537100664303783e+12, 2.290253922913114847e+13, + 1.435560574531699914e+14, 1.008680130601194048e+15, 8.003530334765274913e+15, 7.227937568629809266e+16, + 7.491693576707361828e+17, 8.991671234614216799e+18, 1.261556024888540618e+20, 2.090038400033346091e+21, + 4.132773073376509056e+22, 9.865671928781943336e+23, 2.877978132616007671e+25, 1.039303004928044064e+27, + 4.710544722984128252e+28, 2.719194692980296464e+30, 2.030608169419634520e+32, 1.994536427964099457e+34, + 2.622806931876485852e+36, 4.705142628855489738e+38, 1.174794916996875010e+41, 4.170574236544843559e+43, + 2.153441953645800917e+46, 1.656794933445123415e+49, 1.948830907651317326e+52, 3.601980393005358786e+55, + 1.077033440153993124e+59, 5.374188883861674378e+62, 4.625267105826449467e+66, 7.111646979020385006e+70, + 2.027996051444846521e+75, 1.116168784120367146e+80, 1.237019821283735086e+85, 2.888108172342166477e+90, + 1.490426937972460544e+96, 1.789306677271856318e+102, 5.276973875344766848e+108, 4.051217867886536330e+115, + 8.611617868168979525e+122, 5.412634353380155695e+130, 1.078756609821147465e+139, 7.344353246966125053e+147, }; + +__constant__ double m_weights_double_7[393] = + { 8.688318611421924613e-158, 6.864317997043424201e-153, 3.829638174036322920e-148, 1.524985558970066863e-143, + 4.379527631402474835e-139, 9.162408388991747001e-135, 1.410086556664696347e-130, 1.611529786006329005e-126, + 1.380269212504431613e-122, 8.938739565456142404e-119, 4.414803004265274778e-115, 1.676831992534574674e-111, + 4.937648515671545377e-108, 1.136068312653058895e-104, 2.057969760853201132e-101, 2.956779836249922681e-98, + 3.393449014375824853e-95, 3.132619285740674842e-92, 2.341677665639346254e-89, 1.426656997926173190e-86, + 7.128825597334931865e-84, 2.939485275517928205e-81, 1.006113300119903410e-78, 2.874969402023240560e-76, + 6.896713338909433222e-74, 1.396405038640012785e-71, 2.398869799873387326e-69, 3.514180228970525006e-67, + 4.411557600438730779e-65, 4.768408435763044172e-63, 4.458287229998440383e-61, 3.621710763086768959e-59, + 2.567373174003034094e-57, 1.594829856885795944e-55, 8.716746897177859412e-54, 4.208424534880021226e-52, + 1.801637343401221381e-50, 6.864432292330768862e-49, 2.336084584516383243e-47, 7.125716658075193173e-46, + 1.954733295862350631e-44, 4.838195020814970471e-43, 1.083903033389729471e-41, 2.204655424309513426e-40, + 4.083431629921110537e-39, 6.907095608064865023e-38, 1.069951518082577963e-36, 1.521972185061747284e-35, + 1.993254198127980161e-34, 2.409552194902670884e-33, 2.695243589253751811e-32, 2.796309045342585624e-31, + 2.697138787161831243e-30, 2.423968619042656074e-29, 2.034233848004972409e-28, 1.597498662808006882e-27, + 1.176341105034547043e-26, 8.138404856556384931e-26, 5.300199402716282910e-25, 3.255367628680633536e-24, + 1.889060856810273071e-23, 1.037502167741821871e-22, 5.402129194695882094e-22, 2.671080147950250592e-21, + 1.256163163817414397e-20, 5.627458451375099018e-20, 2.405110192151924414e-19, 9.820723025892385774e-19, + 3.836610965933493002e-18, 1.435949417965440387e-17, 5.155736116435221852e-17, 1.778106820243535736e-16, + 5.897650538103448384e-16, 1.883545377386949394e-15, 5.799022727889041128e-15, 1.723080101027408120e-14, + 4.946559668895564981e-14, 1.373437058883951037e-13, 3.692057356296675476e-13, 9.618669754374864080e-13, + 2.430904641718059201e-12, 5.965319652795549281e-12, 1.422677541958913512e-11, 3.300412010407028696e-11, + 7.453993539444124847e-11, 1.640317480539372495e-10, 3.519919455549922227e-10, 7.371241496931924727e-10, + 1.507573517782825692e-09, 3.013444008176544118e-09, 5.891170930525923854e-09, 1.127175867596519203e-08, + 2.112135943063526334e-08, 3.878572405868819131e-08, 6.984140168311147329e-08, 1.233979234102365865e-07, + 2.140481233406505212e-07, 3.647293211756793211e-07, 6.108366265875129839e-07, 1.006020283089617901e-06, + 1.630199379920459998e-06, 2.600430208375972125e-06, 4.085372746054298735e-06, 6.324194831966406940e-06, + 9.650830226718535837e-06, 1.452455211307694488e-05, 2.156782506321975658e-05, 3.161234361554654466e-05, + 4.575404320696170555e-05, 6.541767069965264068e-05, 9.243122234114186712e-05, 1.291101968446571125e-04, + 1.783511762821284409e-04, 2.437337497712608884e-04, 3.296292528289701234e-04, 4.413142327104518440e-04, + 5.850859955683163216e-04, 7.683770763700705263e-04, 9.998650298180469208e-04, 1.289573601590465490e-03, + 1.648961132392222413e-03, 2.090991995585424661e-03, 2.630186988492201910e-03, 3.282648895332118799e-03, + 4.066059914467245175e-03, 4.999648283080481820e-03, 6.104122218554241819e-03, 7.401570199659662364e-03, + 8.915327597805008451e-03, 1.066981070009509413e-02, 1.269032020049755525e-02, 1.500281723149735994e-02, + 1.763367592672867332e-02, 2.060941730962251417e-02, 2.395642996410886880e-02, 2.770068343772389725e-02, + 3.186744063963193757e-02, 3.648097561865623097e-02, 4.156430303997019336e-02, 4.713892543167989540e-02, + 5.322460385886412684e-02, 5.983915712308283792e-02, 6.699829390463281224e-02, 7.471548149065050122e-02, + 8.300185389391494996e-02, 9.186616129460712899e-02, 1.013147618591979452e-01, 1.113516561340355690e-01, + 1.219785634003157786e-01, 1.331950386328042665e-01, 1.449986280439946752e-01, 1.573850606313672716e-01, + 1.703484726870446791e-01, 1.838816618814874884e-01, 1.979763672973498048e-01, 2.126235716643688402e-01, + 2.278138220265254991e-01, 2.435375651517067386e-01, 2.597854941629632707e-01, 2.765489031191654411e-01, + 2.938200465906351752e-01, 3.115925016510994851e-01, 3.298615301301230823e-01, 3.486244394295739435e-01, + 3.678809406939879716e-01, 3.876335036292959599e-01, 4.078877077798518471e-01, 4.286525905940105684e-01, + 4.499409931290513174e-01, 4.717699047639316286e-01, 4.941608088016098926e-01, 5.171400313514193966e-01, + 5.407390963876342256e-01, 5.649950903858123945e-01, 5.899510404480374918e-01, 6.156563103475134535e-01, + 6.421670194591982411e-01, 6.695464901047961714e-01, 6.978657294374126896e-01, 7.272039526349696447e-01, + 7.576491548751669105e-01, 7.892987403432202489e-01, 8.222602173936578230e-01, 8.566519699682320391e-01, + 8.926041164852169437e-01, 9.302594686857616145e-01, 9.697746043788558519e-01, 1.011321069700320644e+00, + 1.055086728430498711e+00, 1.101277278143300224e+00, 1.150117955536247302e+00, 1.201855456275760449e+00, + 1.256760098152647779e+00, 1.315128260359919236e+00, 1.377285136373095709e+00, 1.443587843343442141e+00, + 1.514428937238563465e+00, 1.590240390338335337e+00, 1.671498096302065311e+00, 1.758726978084942299e+00, + 1.852506785760205887e+00, 1.953478685110838140e+00, 2.062352754065132708e+00, 2.179916523112736371e+00, + 2.307044718290330681e+00, 2.444710391817196957e+00, 2.593997656772008968e+00, 2.756116279277535182e+00, + 2.932418425642610903e+00, 3.124417914187536020e+00, 3.333812383735923205e+00, 3.562508865047068391e+00, + 3.812653330296280988e+00, 4.086664902155689132e+00, 4.387275531849634155e+00, 4.717576109385405085e+00, + 5.081070154695596855e+00, 5.481736462718817995e+00, 5.924102347216244340e+00, 6.413329458204850426e+00, + 6.955314549766230740e+00, 7.556808065486941215e+00, 8.225554008952760095e+00, 8.970455302965185036e+00, + 9.801769746699598466e+00, 1.073134279679936208e+01, 1.177288477943655549e+01, 1.294230185297226511e+01, + 1.425809217068106541e+01, 1.574182134943112610e+01, 1.741869467329444792e+01, 1.931824763074534781e+01, + 2.147518163232618457e+01, 2.393037838236259586e+01, 2.673213477270754163e+01, 2.993767083537830673e+01, + 3.361497689655818107e+01, 3.784508348524495401e+01, 4.272485990900652026e+01, 4.837047622725585887e+01, + 5.492170063250241752e+01, 6.254725265973777743e+01, 7.145149574983117631e+01, 8.188283528217430591e+01, + 9.414429671899321190e+01, 1.086069017070108772e+02, 1.257266497442910506e+02, 1.460661655727672308e+02, + 1.703224100743601641e+02, 1.993623058409479084e+02, 2.342687403011957198e+02, 2.764002385528330658e+02, + 3.274687277481591846e+02, 3.896413615832930151e+02, 4.656745019682919178e+02, 5.590908996105107215e+02, + 6.744152109571297875e+02, 8.174887172033244140e+02, 9.958921680864290197e+02, 1.219517071629880108e+03, + 1.501341972869855447e+03, 1.858493492282554856e+03, 2.313705362529768409e+03, 2.897337235279879262e+03, + 3.650185874628374320e+03, 4.627425468074182920e+03, 5.904167858279871204e+03, 7.583363128219763259e+03, + 9.807105719965428472e+03, 1.277293273832114230e+04, 1.675749596877978193e+04, 2.215121038263169759e+04, + 2.950937349291504490e+04, 3.962820433513419525e+04, 5.365890489878942635e+04, 7.328024305737981431e+04, + 1.009620167752942516e+05, 1.403709568321740997e+05, 1.970019955923188504e+05, 2.791695960502382133e+05, + 3.995801250202947693e+05, 5.778515877588312220e+05, 8.445944401474017243e+05, 1.248092975135001687e+06, + 1.865367859966950385e+06, 2.820705292493674480e+06, 4.317063433830483499e+06, 6.689961127164684387e+06, + 1.050111601631327499e+07, 1.670327884792325766e+07, 2.693430470211696200e+07, 4.404906898054894166e+07, + 7.309535640536363311e+07, 1.231306812701882145e+08, 2.106560568719367745e+08, 3.662073971851359192e+08, + 6.472124787519330196e+08, 1.163486593592585616e+09, 2.128658395254150452e+09, 3.965732938755983605e+09, + 7.527735928223242836e+09, 1.456757162128879538e+10, 2.875798636941021041e+10, 5.794999654160054887e+10, + 1.192767536774485257e+11, 2.509334090779650360e+11, 5.399624414800303207e+11, 1.189276111740286910e+12, + 2.683103883355551677e+12, 6.205255919751506427e+12, 1.472284072112162717e+13, 3.586628373992547853e+13, + 8.978594107356889337e+13, 2.311710197091641250e+14, 6.127020712804348908e+14, 1.673232679378485978e+15, + 4.712671499032329365e+15, 1.370275025680988289e+16, 4.117347054027612886e+16, 1.279822436878842710e+17, + 4.119762767831332886e+17, 1.374888606936629814e+18, 4.762483833659790733e+18, 1.714288404980390540e+19, + 6.420200704842635702e+19, 2.504808062315322558e+20, 1.019355251138167687e+21, 4.332952958521756932e+21, + 1.926416464889827426e+22, 8.971059571108856501e+22, 4.382317748928748816e+23, 2.249003059943548727e+24, + 1.214458587662725100e+25, 6.911683912813140938e+25, 4.152578123301633020e+26, 2.638346388179288086e+27, + 1.775811490887700718e+28, 1.268552401544524965e+29, 9.635786341213661742e+29, 7.797939379813000783e+30, + 6.736900087983560033e+31, 6.226288752443836475e+32, 6.169035287163451891e+33, 6.567250104576983172e+34, + 7.528666735185428595e+35, 9.316271421365627344e+36, 1.247410737003664698e+38, 1.811787648043939987e+39, + 2.861918583157116420e+40, 4.929657099622567574e+41, 9.284951278562156071e+42, 1.917687997037326435e+44, + 4.355948096683946408e+45, 1.091453486585817118e+47, 3.026206402784023251e+48, 9.314478983991942688e+49, + 3.193195693823940775e+51, 1.223447678968662613e+53, 5.257403184148516426e+54, 2.543108925126136766e+56, + 1.389947584026783879e+58, 8.616987336205957549e+59, 6.083777056769299984e+61, 4.911841077800001710e+63, + 4.554259483169784661e+65, 4.870815185962582259e+67, 6.036211886847067841e+69, 8.708377755587698026e+71, + 1.469655296381977267e+74, 2.915822924489215887e+76, 6.836044306573246016e+78, 1.903917300559946782e+81, + 6.333813341980360028e+83, 2.531082268773868753e+86, 1.222077360592898816e+89, 7.172167453276776330e+91, + 5.148160232410244898e+94, 4.548619807672339638e+97, 4.979632843475864923e+100, 6.800802744782331957e+103, + 1.166855497965918386e+107, 2.533457765534279043e+110, 7.012864641215147208e+113, 2.494083354169569414e+117, + 1.148722178881219993e+121, 6.908313932158993510e+124, 5.470912484744367184e+128, 5.755359832684120769e+132, + 8.115681923907451939e+136, 1.548304780334447081e+141, 4.034912159113614601e+145, 1.450632759611715526e+150, + 7.268799665580789770e+154, }; + +__constant__ double m_weights_double_8[786] = + { 4.901759085947701448e-159, 1.505832423620814399e-156, 4.231872109262999523e-154, 1.089479701785106001e-151, + 2.572922387150651649e-149, 5.581311054334156941e-147, 1.113575900126970040e-144, 2.046165051332286084e-142, + 3.466994885004770636e-140, 5.423795404073501922e-138, 7.843833272402847010e-136, 1.049922957933194415e-133, + 1.302301071957418603e-131, 1.498659737828393008e-129, 1.601906622414286282e-127, 1.592248618401983561e-125, + 1.473375345916436274e-123, 1.270651551394009593e-121, 1.022408263525766209e-119, 7.683762602329562781e-118, + 5.399268127233373186e-116, 3.551074274853494676e-114, 2.188235409519121010e-112, 1.264667515430816934e-110, + 6.861807566737243712e-109, 3.498691686825209963e-107, 1.678016807398375157e-105, 7.577439431441931490e-104, + 3.224703770159386809e-102, 1.294487090677705963e-100, 4.906133250963454139e-99, 1.757121317988153326e-97, + 5.952042491454320383e-96, 1.908566653286417264e-94, 5.798224459236429212e-93, 1.670293239978334727e-91, + 4.566236673398083038e-90, 1.185617342791547945e-88, 2.926160027801296929e-87, 6.870061134126707137e-86, + 1.535565783500379945e-84, 3.270036736778401257e-83, 6.639558007206580362e-82, 1.286319750967398593e-80, + 2.379566581139022958e-79, 4.206268231398883425e-78, 7.109719237833379433e-77, 1.149915104115372777e-75, + 1.780876201255594220e-74, 2.642703796179329883e-73, 3.760085375941719327e-72, 5.132920951124251993e-71, + 6.727100274601427696e-70, 8.469585621347697498e-69, 1.025032382672232848e-67, 1.193219127557863348e-66, + 1.336816930381306582e-65, 1.442283479679798385e-64, 1.499374555004793991e-63, 1.502797203133501438e-62, + 1.453005969318485303e-61, 1.355980448377862540e-60, 1.222072412212552127e-59, 1.064223180270520159e-58, + 8.959667396075636845e-58, 7.296288808079294105e-57, 5.750255296190181158e-56, 4.388011664829013518e-55, + 3.243852451291832398e-54, 2.324239357665538806e-53, 1.614869776203026446e-52, 1.088524605545274842e-51, + 7.121755574192829045e-51, 4.524647662549067074e-50, 2.792730715818793035e-49, 1.675384879603864227e-48, + 9.773114328777676091e-48, 5.545910766847627082e-47, 3.062809705627873645e-46, 1.646862118038266234e-45, + 8.625108513887155847e-45, 4.401687663868890701e-44, 2.189755778847646746e-43, 1.062345336449265889e-42, + 5.028036663485684049e-42, 2.322524635717249223e-41, 1.047406593898341306e-40, 4.613438388449698168e-40, + 1.985397445118162005e-39, 8.351027367454628343e-39, 3.434440903484543389e-38, 1.381489131877196646e-37, + 5.437051201310225224e-37, 2.094357548080647717e-36, 7.898676618592006902e-36, 2.917536870947471272e-35, + 1.055788886022716597e-34, 3.744333812160330812e-34, 1.301801185251957290e-33, 4.438346216893387768e-33, + 1.484348268951816542e-32, 4.871001129849836971e-32, 1.568903000742513942e-31, 4.961295315917935235e-31, + 1.540773910027990821e-30, 4.700558022172014910e-30, 1.409115230718949596e-29, 4.151913103955692034e-29, + 1.202737613715427748e-28, 3.426327374934496736e-28, 9.601405359397026012e-28, 2.647278642033773301e-27, + 7.183442220565147103e-27, 1.918850545981494042e-26, 5.046974779455992494e-26, 1.307394799925911700e-25, + 3.336342198236957082e-25, 8.389259581136262194e-25, 2.079051813513548608e-24, 5.079178967243765280e-24, + 1.223501794357837278e-23, 2.906654911057549530e-23, 6.811668606095015470e-23, 1.574985938238025303e-22, + 3.593796788969348326e-22, 8.094185411205212564e-22, 1.799796183237481721e-21, 3.951758901641017285e-21, + 8.569580068050865775e-21, 1.835753486517298696e-20, 3.885414339966022317e-20, 8.126613972895021790e-20, + 1.680007182889503141e-19, 3.433369351563962828e-19, 6.937695550399427499e-19, 1.386345631008981755e-18, + 2.740087497759230881e-18, 5.357570288683386626e-18, 1.036464933022803784e-17, 1.984249442010084992e-17, + 3.759788006060003409e-17, 7.052211261821684795e-17, 1.309635641529546221e-16, 2.408275496109180528e-16, + 4.385898809611711552e-16, 7.911758686849121285e-16, 1.413883597877183873e-15, 2.503477536644680210e-15, + 4.392637866550705827e-15, 7.638710306960574612e-15, 1.316703360377476041e-14, 2.250031027275448919e-14, + 3.812239733412214953e-14, 6.405021660191363479e-14, 1.067250538270319484e-13, 1.763897493784721010e-13, + 2.891987565334547756e-13, 4.704242520369958085e-13, 7.592878273512691990e-13, 1.216183338372525172e-12, + 1.933388593436624879e-12, 3.050826852442290751e-12, 4.779080020017636657e-12, 7.432734713385425098e-12, + 1.147833888125873666e-11, 1.760286160372422754e-11, 2.681071101623953168e-11, 4.056023754295965437e-11, + 6.095443492241537222e-11, 9.100550129616064211e-11, 1.349993452136967652e-10, 1.989943912395156051e-10, + 2.914996073619059788e-10, 4.243900781412219621e-10, 6.141353162671391082e-10, 8.834365795894798511e-10, + 1.263395594025933170e-09, 1.796369250051716047e-09, 2.539704143326480862e-09, 3.570592498287890499e-09, + 4.992348403150539107e-09, 6.942471870489931483e-09, 9.602949600164561371e-09, 1.321333712761666777e-08, + 1.808727901635346390e-08, 2.463325364767791516e-08, 3.338047870136870496e-08, 4.501108426108505069e-08, + 6.039985413333259594e-08, 8.066305374526097834e-08, 1.072181059018892614e-07, 1.418561443795353991e-07, + 1.868297699836383305e-07, 2.449586539172972009e-07, 3.197559780442760832e-07, 4.155790690867544334e-07, + 5.378079713325544678e-07, 6.930561064776686194e-07, 8.894175852502122454e-07, 1.136756157868726006e-06, + 1.447041212534730898e-06, 1.834736645332833504e-06, 2.317248822354253644e-06, 2.915440225825303911e-06, + 3.654215709863551870e-06, 4.563188576773760151e-06, 5.677433909482232878e-06, 7.038336747307571784e-06, + 8.694542758083067228e-06, 1.070301902702759858e-05, 1.313023243937403750e-05, 1.605345286789073897e-05, + 1.956218797728780449e-05, 2.375975591555218862e-05, 2.876500146954361208e-05, 3.471416041263076209e-05, + 4.176287576185915239e-05, 5.008836848967403773e-05, 5.989176390181730373e-05, 7.140057340280213227e-05, + 8.487132973049760036e-05, 1.005923719620999934e-04, 1.188867746885496973e-04, 1.401154137398069279e-04, + 1.646801587388731249e-04, 1.930271805904271778e-04, 2.256503597954330556e-04, 2.630947792533707128e-04, + 3.059602829980946180e-04, 3.549050801425155303e-04, 4.106493712131842727e-04, 4.739789720708565436e-04, + 5.457489087697051069e-04, 6.268869550379884668e-04, 7.183970825975973673e-04, 8.213627933082928901e-04, + 9.369503011517966364e-04, 1.066411531385725184e-03, 1.211086903819095417e-03, 1.372407867107646339e-03, + 1.551899151252505624e-03, 1.751180706119547318e-03, 1.971969294784470944e-03, 2.216079711850908971e-03, + 2.485425598581779636e-03, 2.782019828718993257e-03, 3.107974441230220176e-03, 3.465500098895993776e-03, + 3.856905054613959619e-03, 4.284593610523639393e-03, 4.751064058515097225e-03, 5.258906094345618421e-03, + 5.810797701414435799e-03, 6.409501504198915943e-03, 7.057860595396970186e-03, 7.758793844909123446e-03, + 8.515290702888369372e-03, 9.330405513145299523e-03, 1.020725135717912572e-02, 1.114899345297222760e-02, + 1.215884213639836574e-02, 1.324004545661629463e-02, 1.439588142011718850e-02, 1.562964992113485073e-02, + 1.694466439888404584e-02, 1.834424326453982033e-02, 1.983170114298836870e-02, 2.141033997615067889e-02, + 2.308344003609062690e-02, 2.485425089716015368e-02, 2.672598241710042669e-02, 2.870179577730820310e-02, + 3.078479463239356953e-02, 3.297801641870515720e-02, 3.528442387069167064e-02, 3.770689679281728890e-02, + 4.024822413326941635e-02, 4.291109640390936770e-02, 4.569809848884132640e-02, 4.861170288163592155e-02, + 5.165426338866744454e-02, 5.482800933323496446e-02, 5.813504029216542680e-02, 6.157732139347005467e-02, + 6.515667920037330165e-02, 6.887479820368566403e-02, 7.273321794107712090e-02, 7.673333075835566151e-02, + 8.087638022439339824e-02, 8.516346020789830747e-02, 8.959551462082867423e-02, 9.417333782991444898e-02, + 9.889757573450802477e-02, 1.037687275058577967e-01, 1.087871479799008567e-01, 1.139530506928239996e-01, + 1.192665115459606141e-01, 1.247274730840887416e-01, 1.303357493688843496e-01, 1.360910314271734020e-01, + 1.419928932517243620e-01, 1.480407983306351483e-01, 1.542341066798992024e-01, 1.605720823524863565e-01, + 1.670539013962460335e-01, 1.736786602321317742e-01, 1.804453844236544912e-01, 1.873530378080931153e-01, + 1.944005319598201097e-01, 2.015867359561292115e-01, 2.089104864161762672e-01, 2.163705977840528187e-01, + 2.239658728275971045e-01, 2.316951133252986765e-01, 2.395571309145607347e-01, 2.475507580756380088e-01, + 2.556748592267567912e-01, 2.639283419072366399e-01, 2.723101680268593668e-01, 2.808193651612593497e-01, + 2.894550378747292326e-01, 2.982163790535362503e-01, 3.071026812346166036e-01, 3.161133479163487600e-01, + 3.252479048399920142e-01, 3.345060112323053140e-01, 3.438874710018250777e-01, 3.533922438832718793e-01, + 3.630204565265675291e-01, 3.727724135289699431e-01, 3.826486084108677024e-01, 3.926497345378144818e-01, + 4.027766959934214472e-01, 4.130306184097598756e-01, 4.234128597639539906e-01, 4.339250211516634154e-01, + 4.445689575501645526e-01, 4.553467885857401860e-01, 4.662609093220769612e-01, 4.773140010883521767e-01, + 4.885090423676662636e-01, 4.998493197684479070e-01, 5.113384391034281429e-01, 5.229803366027518117e-01, + 5.347792902897740156e-01, 5.467399315500809553e-01, 5.588672569262846167e-01, 5.711666401731758417e-01, + 5.836438446098876156e-01, 5.963050358078278898e-01, 6.091567946552975691e-01, 6.222061308419237716e-01, + 6.354604968083211637e-01, 6.489278022087558681e-01, 6.626164289370386795e-01, 6.765352467684294227e-01, + 6.906936296730053994e-01, 7.051014728587479919e-01, 7.197692106055475377e-01, 7.347078349544334315e-01, + 7.499289153196209421e-01, 7.654446190944464391e-01, 7.812677333259577661e-01, 7.974116875368567865e-01, + 8.138905777776784362e-01, 8.307191919965581771e-01, 8.479130368187123741e-01, 8.654883658328603475e-01, + 8.834622094872810766e-01, 9.018524067040521621e-01, 9.206776383262963142e-01, 9.399574625199963151e-01, + 9.597123522591707284e-01, 9.799637350309700387e-01, 1.000734034905599933e+00, 1.022046717124952010e+00, + 1.043926335373472893e+00, 1.066398581905185161e+00, 1.089490340711946628e+00, 1.113229743930062164e+00, + 1.137646231695313314e+00, 1.162770615670420260e+00, 1.188635146483979071e+00, 1.215273585336112390e+00, + 1.242721280043529050e+00, 1.271015245815510799e+00, 1.300194251072644711e+00, 1.330298908642019971e+00, + 1.361371772686240192e+00, 1.393457441749111730e+00, 1.426602668328411758e+00, 1.460856475415888358e+00, + 1.496270280476785338e+00, 1.532898027375920169e+00, 1.570796326794896619e+00, 1.610024605725646420e+00, + 1.650645266669431435e+00, 1.692723857217988332e+00, 1.736329250744977731e+00, 1.781533838991654903e+00, + 1.828413737391087381e+00, 1.877049004040720448e+00, 1.927523873304087635e+00, 1.979927005099477087e+00, + 2.034351751016940433e+00, 2.090896438495766214e+00, 2.149664674393090421e+00, 2.210765669381402212e+00, + 2.274314584729113927e+00, 2.340432903144970240e+00, 2.409248825504827076e+00, 2.480897695429288043e+00, + 2.555522453844001656e+00, 2.633274125832370887e+00, 2.714312342284411608e+00, 2.798805899057066353e+00, + 2.886933356592141886e+00, 2.978883683190077867e+00, 3.074856945413050211e+00, 3.175065049391765683e+00, + 3.279732537139255280e+00, 3.389097442334834102e+00, 3.503412210435275865e+00, 3.622944688401595705e+00, + 3.747979189802462585e+00, 3.878817641573403805e+00, 4.015780819279312670e+00, 4.159209678351536168e+00, + 4.309466789455788368e+00, 4.466937886899736897e+00, 4.632033539816493591e+00, 4.805190956770360727e+00, + 4.986875935432896972e+00, 5.177584970080537688e+00, 5.377847530880629761e+00, 5.588228530273088035e+00, + 5.809330993233640059e+00, 6.041798949837089488e+00, 6.286320570342285919e+00, 6.543631565013652661e+00, + 6.814518873098582608e+00, 7.099824667819718682e+00, 7.400450706942931008e+00, 7.717363061475788814e+00, + 8.051597258371279584e+00, 8.404263876795383951e+00, 8.776554641607500109e+00, 9.169749062247565207e+00, + 9.585221670276993889e+00, 1.002444991444300704e+01, 1.048902277839603856e+01, 1.098065019316492606e+01, + 1.150117332427169985e+01, 1.205257582204547280e+01, 1.263699613338454324e+01, 1.325674098404332380e+01, + 1.391430015262873368e+01, 1.461236267104086712e+01, 1.535383460126837531e+01, 1.614185855545811846e+01, + 1.697983514525758524e+01, 1.787144656784601339e+01, 1.882068256013178484e+01, 1.983186897964764985e+01, + 2.090969930111845450e+01, 2.205926935196095527e+01, 2.328611564861881683e+01, 2.459625773922860138e+01, + 2.599624500732998276e+01, 2.749320844694889238e+01, 2.909491798228195984e+01, 3.080984597641076715e+01, + 3.264723765414180400e+01, 3.461718925554321861e+01, 3.673073484057443067e+01, 3.899994278315456980e+01, + 4.143802312713618427e+01, 4.405944712930142330e+01, 4.688008048840357439e+01, 4.991733195758662298e+01, + 5.319031926387298369e+01, 5.672005451703465811e+01, 6.052965158594831140e+01, 6.464455825915836491e+01, + 6.909281639443131774e+01, 7.390535370725211687e+01, 7.911631135942343489e+01, 8.476341209659472308e+01, + 9.088837435982152722e+01, 9.753737857533253823e+01, 1.047615927251647361e+02, 1.126177653386554197e+02, + 1.211688952437418817e+02, 1.304849888043593828e+02, 1.406439169773708701e+02, 1.517323863863765989e+02, + 1.638470407739824279e+02, 1.770957117100033620e+02, 1.915988403612775885e+02, 2.074910955409497265e+02, + 2.249232172361061194e+02, 2.440641194630869936e+02, 2.651032917390266964e+02, 2.882535448280364212e+02, + 3.137541538897424513e+02, 3.418744609277612322e+02, 3.729180087461214321e+02, 4.072272907593818790e+02, + 4.451892153103389878e+02, 4.872414000388630927e+02, 5.338794318098249932e+02, 5.856652513400113117e+02, + 6.432368496766822816e+02, 7.073194969336578611e+02, 7.787387632221277236e+02, 8.584356387770406827e+02, + 9.474841163944599543e+02, 1.047111666301969297e+03, 1.158723113719277435e+03, 1.283928525349707755e+03, + 1.424575826189363437e+03, 1.582789006393775706e+03, 1.761012944445459235e+03, 1.962066073573121788e+03, + 2.189202360708354222e+03, 2.446184360349559652e+03, 2.737369460761187093e+03, 3.067811870808767638e+03, + 3.443383419509962754e+03, 3.870916878218207705e+03, 4.358376293464465508e+03, 4.915059769420260559e+03, + 5.551841303216967404e+03, 6.281459704453426129e+03, 7.118864385205665710e+03, 8.081629967627799596e+03, + 9.190454321738597280e+03, 1.046975794051835702e+04, 1.194840663946247320e+04, 1.366058463062104793e+04, + 1.564685131637809273e+04, 1.795542299179967539e+04, 2.064373043744082514e+04, 2.378031563732670807e+04, + 2.744714621995650953e+04, 3.174244552480722739e+04, 3.678416050731336226e+04, 4.271422037773508051e+04, + 4.970377768100323981e+04, 5.795967273138576164e+04, 6.773242484608792593e+04, 7.932613346949942761e+04, + 9.311077397156915450e+04, 1.095375030536372224e+05, 1.291577556735669526e+05, 1.526471301608741586e+05, + 1.808353350969648289e+05, 2.147438294770164181e+05, 2.556332515573999948e+05, 3.050633345562097502e+05, + 3.649687926665853954e+05, 4.377556866857485380e+05, 5.264241222943208736e+05, 6.347248990108319410e+05, + 7.673600526542426466e+05, 9.302403050337502786e+05, 1.130816502666451845e+06, 1.378507531155523742e+06, + 1.685254393964162275e+06, 2.066239770168639390e+06, 2.540825270229354918e+06, 3.133775962036416630e+06, + 3.876865148275802393e+06, 4.810984054018349430e+06, 5.988924089534678664e+06, 7.479057929608060924e+06, + 9.370225698693408867e+06, 1.177824230977510661e+07, 1.485459301432580619e+07, 1.879809270383398104e+07, + 2.387057334436346400e+07, 3.041806552258603202e+07, 3.889950046843262151e+07, 4.992574374586696017e+07, + 6.431287504495613210e+07, 8.315518519925858136e+07, 1.079255664704117961e+08, 1.406141073390035115e+08, + 1.839201785677305607e+08, 2.415197116904975365e+08, 3.184386015381112281e+08, 4.215765018929686736e+08, + 5.604446356915114550e+08, 7.482094398046911572e+08, 1.003175129668246151e+09, 1.350898918997482870e+09, + 1.827222165053491590e+09, 2.482633480831760933e+09, 3.388577637234919719e+09, 4.646620065299105644e+09, + 6.401821801566297122e+09, 8.862352038053251473e+09, 1.232838602859196811e+10, 1.723489297480180023e+10, + 2.421530528469447376e+10, 3.419673813208063025e+10, 4.854312364622606540e+10, 6.927149043760342676e+10, + 9.938049490186203616e+10, 1.433521424759854145e+11, 2.079221734483088227e+11, 3.032695241820108158e+11, + 4.448631503727710431e+11, 6.563458646477901051e+11, 9.740635696398910980e+11, 1.454220520059656158e+12, + 2.184250688898627320e+12, 3.300999104757560757e+12, 5.019970485022749012e+12, 7.682676299017607834e+12, + 1.183376596003983872e+13, 1.834748853557035315e+13, 2.863639312458363586e+13, 4.499803892715039958e+13, + 7.119486876989154498e+13, 1.134307017980122346e+14, 1.820065782363618395e+14, 2.941484500615394037e+14, + 4.788707305890930382e+14, 7.854025036928623551e+14, 1.297894304619860251e+15, 2.161279954782425640e+15, + 3.627102147035003834e+15, 6.135342933440950378e+15, 1.046170006362244506e+16, 1.798477357839665686e+16, + 3.117473412332331475e+16, 5.449445073049184222e+16, 9.607515505017978212e+16, 1.708589224452677852e+17, + 3.065429751110228665e+17, 5.549227437451149511e+17, 1.013730232778046314e+18, 1.869059895876405824e+18, + 3.478549552381578424e+18, 6.535992245975463763e+18, 1.240019272261066308e+19, 2.375828866910936629e+19, + 4.597682433604432625e+19, 8.988106816837128428e+19, 1.775302379393632263e+20, 3.543413304390973486e+20, + 7.148061397675525327e+20, 1.457620510577186305e+21, 3.005137124879829797e+21, 6.265024861633250697e+21, + 1.320979941090283816e+22, 2.817487535902146221e+22, 6.079933041429805231e+22, 1.327658853647212083e+23, + 2.934311759183641318e+23, 6.565087216807130026e+23, 1.487212273437937650e+24, 3.411840196076788128e+24, + 7.928189928797018762e+24, 1.866451877029704857e+25, 4.452521859886739549e+25, 1.076545435174977662e+26, + 2.638685681190697586e+26, 6.557908470244186498e+26, 1.652952243735585721e+27, 4.226383395914916199e+27, + 1.096450394268080148e+28, 2.886822082999286080e+28, 7.715480389344015925e+28, 2.093728789309964846e+29, + 5.770275789447655037e+29, 1.615463845391781140e+30, 4.595470055795608691e+30, 1.328629392686523255e+31, + 3.905079681530784219e+31, 1.167134024271997252e+32, 3.548058538654277403e+32, 1.097378059358046160e+33, + 3.454102978064445595e+33, 1.106745393701652323e+34, 3.610899559139069994e+34, 1.199946999283670567e+35, + 4.062687014190878792e+35, 1.401835223893224514e+36, 4.931085527333162173e+36, 1.768812393284919500e+37, + 6.472148293945199961e+37, 2.416453721739211922e+38, 9.208944720398123862e+38, 3.583297028622126676e+39, + 1.424097482596699440e+40, 5.782627833426411524e+40, 2.399862204084363183e+41, 1.018291572042305460e+42, + 4.419105414822034531e+42, 1.962126117680499311e+43, 8.916742424061253707e+43, 4.148882478294757720e+44, + 1.977256529558276930e+45, 9.655300233875401080e+45, 4.832878898335598922e+46, 2.480575878223098058e+47, + 1.306102809757654706e+48, 7.057565717289569232e+48, 3.915276522229618618e+49, 2.230898980943393318e+50, + 1.306141334496309306e+51, 7.861021286656392627e+51, 4.865583758538451107e+52, 3.098487425915704674e+53, + 2.031037614862563901e+54, 1.370999647608260200e+55, 9.534736274325001528e+55, 6.834959923166415407e+56, + 5.052733546324789020e+57, 3.853810997282159979e+58, 3.034183107853208298e+59, 2.467161926009838899e+60, + 2.072901039813580593e+61, 1.800563980579615383e+62, 1.617764027895344257e+63, 1.504283028250688329e+64, + 1.448393206525427172e+65, 1.444855510980115799e+66, 1.494120428855029243e+67, 1.602566566107015722e+68, + 1.783880504153942988e+69, 2.061999240572760738e+70, 2.476521794698572715e+71, 3.092349914153497358e+72, + 4.016927238305985810e+73, 5.431607545226497387e+74, 7.650086824042822759e+75, 1.123017984114349288e+77, + 1.719382952966052004e+78, 2.747335718690686674e+79, 4.584545010557684123e+80, 7.995082041539250252e+81, + 1.458119909365899044e+83, 2.783001178679600175e+84, 5.562812231966194628e+85, 1.165338768982404578e+87, + 2.560399126432838224e+88, 5.904549641859098192e+89, 1.430278474749838710e+91, 3.642046122956932563e+92, + 9.756698571206402300e+93, 2.751946044275883051e+95, 8.179164793643197279e+96, 2.563704735086825890e+98, + 8.481656496128255880e+99, 2.964260254403981007e+101, 1.095342970031208886e+103, 4.283148547584870628e+104, + 1.773954352944319744e+106, 7.788991081894224760e+107, 3.628931721056821352e+109, 1.795729272516020592e+111, + 9.446685151482835339e+112, 5.288263179614488101e+114, 3.153311236741401362e+116, 2.004807079683827669e+118, + 1.360407192665237716e+120, 9.862825609807810517e+121, 7.647551788591128099e+123, 6.348802224871730088e+125, + 5.649062361980019098e+127, 5.393248003523784781e+129, 5.530897191915703916e+131, 6.099598644640894333e+133, + 7.242098433491964504e+135, 9.268083053637375570e+137, 1.279942702416040582e+140, 1.909796626960621302e+142, + 3.082540300669885040e+144, 5.388809732384179657e+146, 1.021610251056626535e+149, 2.103005440072790650e+151, + 4.706753990348725570e+153, 1.146834128125248991e+156, }; + +__constant__ double* m_weights_double[8] = { + m_weights_double_1, + m_weights_double_2, + m_weights_double_3, + m_weights_double_4, + m_weights_double_5, + m_weights_double_6, + m_weights_double_7, + m_weights_double_8 +}; + +__constant__ boost::math::size_t float_coefficients_size[8] = {9, 8, 16, 33, 66, 132, 263, 527}; + +__constant__ boost::math::size_t double_coefficients_size[8] = {13, 12, 25, 49, 98, 196, 393, 786}; + +template +struct coefficients_selector; + +template<> +struct coefficients_selector +{ + __device__ static const auto abscissas() { return m_abscissas_float; } + __device__ static const auto weights() { return m_weights_float; } + __device__ static const auto size() { return float_coefficients_size; } +}; + +template<> +struct coefficients_selector +{ + __device__ static const auto abscissas() { return m_abscissas_double; } + __device__ static const auto weights() { return m_weights_double; } + __device__ static const auto size() { return double_coefficients_size; } +}; + + +template > +__device__ auto exp_sinh_integrate_impl(const F& f, Real tolerance, Real* error, Real* L1, boost::math::size_t* levels) +{ + using K = decltype(f(static_cast(0))); + using boost::math::constants::half; + using boost::math::constants::half_pi; + + // This provided a nice error message for real valued integrals, but it's super awkward for complex-valued integrals: + /*K y_max = f(tools::max_value()); + if(abs(y_max) > tools::epsilon() || !(boost::math::isfinite)(y_max)) + { + K val = abs(y_max); + return static_cast(policies::raise_domain_error(function, "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", val, Policy())); + }*/ + + //std::cout << std::setprecision(5*std::numeric_limits::digits10); + + // Get the party started with two estimates of the integral: + const auto m_abscissas = coefficients_selector::abscissas(); + const auto m_weights = coefficients_selector::weights(); + const auto m_size = coefficients_selector::size(); + + Real min_abscissa{ 0 }, max_abscissa{ boost::math::tools::max_value() }; + K I0 = 0; + Real L1_I0 = 0; + for(boost::math::size_t i = 0; i < m_size[0]; ++i) + { + K y = f(m_abscissas[0][i]); + K I0_last = I0; + I0 += y*m_weights[0][i]; + L1_I0 += abs(y)*m_weights[0][i]; + if ((I0_last == I0) && (abs(I0) != 0)) + { + max_abscissa = m_abscissas[0][i]; + break; + } + } + + //std::cout << "First estimate : " << I0 << std::endl; + K I1 = I0; + Real L1_I1 = L1_I0; + bool have_first_j = false; + boost::math::size_t first_j = 0; + for (boost::math::size_t i = 0; (i < m_size[1]) && (m_abscissas[1][i] < max_abscissa); ++i) + { + K y = f(m_abscissas[1][i]); + K I1_last = I1; + I1 += y*m_weights[1][i]; + L1_I1 += abs(y)*m_weights[1][i]; + if (!have_first_j && (I1_last == I1)) + { + // No change to the sum, disregard these values on the LHS: + if ((i < m_size[1] - 1) && (m_abscissas[1][i + 1] > max_abscissa)) + { + // The summit is so high, that we found nothing in this row which added to the integral!! + have_first_j = true; + } + else + { + min_abscissa = m_abscissas[1][i]; + first_j = i; + } + } + else + { + have_first_j = true; + } + } + + if (I0 == static_cast(0)) + { + // We failed to find anything, is the integral zero, or have we just not found it yet? + // We'll try one more level, if that still finds nothing then it'll terminate. + min_abscissa = 0; + max_abscissa = boost::math::tools::max_value(); + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + //std::cout << "Second estimate: " << I1 << " Error estimate at level " << 1 << " = " << err << std::endl; + + boost::math::size_t i = 2; + for(; i < 8U; ++i) // Magic number 8 is the number of precomputed levels + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1)/static_cast(1 << i); + K sum = 0; + Real absum = 0; + + auto& abscissas_row = m_abscissas[i]; + auto& weight_row = m_weights[i]; + + // appoximate location to start looking for lowest meaningful abscissa value + first_j = first_j == 0 ? 0 : 2 * first_j - 1; + + boost::math::size_t j = first_j; + while (abscissas_row[j] < min_abscissa) + { + ++j; + } + + for(; (j < m_size[i]) && (abscissas_row[j] < max_abscissa); ++j) + { + Real x = abscissas_row[j]; + K y = f(x); + sum += y*weight_row[j]; + Real abterm0 = abs(y)*weight_row[j]; + absum += abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + if (!(boost::math::isfinite)(L1_I1)) + { + return static_cast(policies::raise_evaluation_error("exp_sinh_integrate", "The exp_sinh quadrature evaluated your function at a singular point and returned %1%. Please ensure your function evaluates to a finite number over its entire domain.", I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if(L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + +} // namespace detail +} // namespace quadrature +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif // BOOST_MATH_QUADRATURE_DETAIL_EXP_SINH_DETAIL_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp b/third-party/boost-math/include/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp new file mode 100644 index 0000000000000..49677a8d2912d --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp @@ -0,0 +1,676 @@ +// Copyright Nick Thompson, 2019 +// 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) +#ifndef BOOST_MATH_QUADRATURE_DETAIL_OOURA_FOURIER_INTEGRALS_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_OOURA_FOURIER_INTEGRALS_DETAIL_HPP +#include // for std::pair. +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#include +#endif + +namespace boost { namespace math { namespace quadrature { namespace detail { + +// Ooura and Mori, A robust double exponential formula for Fourier-type integrals, +// eta is the argument to the exponential in equation 3.3: +template +std::pair ooura_eta(Real x, Real alpha) { + using std::expm1; + using std::exp; + using std::abs; + Real expx = exp(x); + Real eta_prime = 2 + alpha/expx + expx/4; + Real eta; + // This is the fast branch: + if (abs(x) > 0.125) { + eta = 2*x - alpha*(1/expx - 1) + (expx - 1)/4; + } + else {// this is the slow branch using expm1 for small x: + eta = 2*x - alpha*expm1(-x) + expm1(x)/4; + } + return {eta, eta_prime}; +} + +// Ooura and Mori, A robust double exponential formula for Fourier-type integrals, +// equation 3.6: +template +Real calculate_ooura_alpha(Real h) +{ + using boost::math::constants::pi; + using std::log1p; + using std::sqrt; + Real x = sqrt(16 + 4*log1p(pi()/h)/h); + return 1/x; +} + +template +std::pair ooura_sin_node_and_weight(long n, Real h, Real alpha) +{ + using std::expm1; + using std::exp; + using std::abs; + using boost::math::constants::pi; + using std::isnan; + + if (n == 0) { + // Equation 44 of https://arxiv.org/pdf/0911.4796.pdf + // Fourier Transform of the Stretched Exponential Function: Analytic Error Bounds, + // Double Exponential Transform, and Open-Source Implementation, + // Joachim Wuttke, + // The C library libkww provides functions to compute the Kohlrausch-Williams-Watts function, + // the Laplace-Fourier transform of the stretched (or compressed) exponential function exp(-t^beta) + // for exponent beta between 0.1 and 1.9 with sixteen decimal digits accuracy. + + Real eta_prime_0 = Real(2) + alpha + Real(1)/Real(4); + Real node = pi()/(eta_prime_0*h); + Real weight = pi()*boost::math::sin_pi(1/(eta_prime_0*h)); + Real eta_dbl_prime = -alpha + Real(1)/Real(4); + Real phi_prime_0 = (1 - eta_dbl_prime/(eta_prime_0*eta_prime_0))/2; + weight *= phi_prime_0; + return {node, weight}; + } + Real x = n*h; + auto p = ooura_eta(x, alpha); + auto eta = p.first; + auto eta_prime = p.second; + + Real expm1_meta = expm1(-eta); + Real exp_meta = exp(-eta); + Real node = -n*pi()/expm1_meta; + + + // I have verified that this is not a significant source of inaccuracy in the weight computation: + Real phi_prime = -(expm1_meta + x*exp_meta*eta_prime)/(expm1_meta*expm1_meta); + + // The main source of inaccuracy is in computation of sin_pi. + // But I've agonized over this, and I think it's as good as it can get: + Real s = pi(); + Real arg; + if(eta > 1) { + arg = n/( 1/exp_meta - 1 ); + s *= boost::math::sin_pi(arg); + if (n&1) { + s *= -1; + } + } + else if (eta < -1) { + arg = n/(1-exp_meta); + s *= boost::math::sin_pi(arg); + } + else { + arg = -n*exp_meta/expm1_meta; + s *= boost::math::sin_pi(arg); + if (n&1) { + s *= -1; + } + } + + Real weight = s*phi_prime; + return {node, weight}; +} + +#ifdef BOOST_MATH_INSTRUMENT_OOURA +template +void print_ooura_estimate(size_t i, Real I0, Real I1, Real omega) { + using std::abs; + std::cout << std::defaultfloat + << std::setprecision(std::numeric_limits::digits10) + << std::fixed; + std::cout << "h = " << Real(1)/Real(1<::epsilon() * 2) { + throw std::domain_error("The relative error goal cannot be smaller than the unit roundoff."); + } + using std::abs; + requested_levels_ = levels; + starting_level_ = 0; + rel_err_goal_ = relative_error_goal; + big_nodes_.reserve(levels); + bweights_.reserve(levels); + little_nodes_.reserve(levels); + lweights_.reserve(levels); + + for (size_t i = 0; i < levels; ++i) { + if (std::is_same::value) { + add_level(i); + } + else if (std::is_same::value) { + add_level(i); + } + else { + add_level(i); + } + } + } + + std::vector> const & big_nodes() const { + return big_nodes_; + } + + std::vector> const & weights_for_big_nodes() const { + return bweights_; + } + + std::vector> const & little_nodes() const { + return little_nodes_; + } + + std::vector> const & weights_for_little_nodes() const { + return lweights_; + } + + template + std::pair integrate(F const & f, Real omega) { + using std::abs; + using std::max; + using boost::math::constants::pi; + + if (omega == 0) { + return {Real(0), Real(0)}; + } + if (omega < 0) { + auto p = this->integrate(f, -omega); + return {-p.first, p.second}; + } + + Real I1 = std::numeric_limits::quiet_NaN(); + Real relative_error_estimate = std::numeric_limits::quiet_NaN(); + // As we compute integrals, we learn about their structure. + // Assuming we compute f(t)sin(wt) for many different omega, this gives some + // a posteriori ability to choose a refinement level that is roughly appropriate. + size_t i = starting_level_; + do { + Real I0 = estimate_integral(f, omega, i); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(i, I0, I1, omega); +#endif + Real absolute_error_estimate = abs(I0-I1); + Real scale = (max)(abs(I0), abs(I1)); + if (!isnan(I1) && absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(i) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + } while(++i < big_nodes_.size()); + + // We've used up all our precomputed levels. + // Now we need to add more. + // It might seems reasonable to just keep adding levels indefinitely, if that's what the user wants. + // But in fact the nodes and weights just merge into each other and the error gets worse after a certain number. + // This value for max_additional_levels was chosen by observation of a slowly converging oscillatory integral: + // f(x) := cos(7cos(x))sin(x)/x + size_t max_additional_levels = 4; + while (big_nodes_.size() < requested_levels_ + max_additional_levels) { + size_t ii = big_nodes_.size(); + if (std::is_same::value) { + add_level(ii); + } + else if (std::is_same::value) { + add_level(ii); + } + else { + add_level(ii); + } + Real I0 = estimate_integral(f, omega, ii); + Real absolute_error_estimate = abs(I0-I1); + Real scale = (max)(abs(I0), abs(I1)); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(ii, I0, I1, omega); +#endif + if (absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(ii) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + ++ii; + } + + starting_level_ = static_cast(big_nodes_.size() - 2); + return {I1/omega, relative_error_estimate}; + } + +private: + + template + void add_level(size_t i) { + using std::abs; + size_t current_num_levels = big_nodes_.size(); + Real unit_roundoff = std::numeric_limits::epsilon()/2; + // h0 = 1. Then all further levels have h_i = 1/2^i. + // Since the nodes don't nest, we could conceivably divide h by (say) 1.5, or 3. + // It's not clear how much benefit (or loss) would be obtained from this. + PreciseReal h = PreciseReal(1)/PreciseReal(1< bnode_row; + std::vector bweight_row; + + // This is a pretty good estimate for how many elements will be placed in the vector: + bnode_row.reserve((static_cast(1)<(1)< lnode_row; + std::vector lweight_row; + + lnode_row.reserve((static_cast(1)<(1)<(precise_nw.first); + Real weight = static_cast(precise_nw.second); + w = weight; + if (bnode_row.size() == bnode_row.capacity()) { + bnode_row.reserve(2*bnode_row.size()); + bweight_row.reserve(2*bnode_row.size()); + } + + bnode_row.push_back(node); + bweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + ++n; + // f(t)->0 as t->infty, which is why the weights are computed up to the unit roundoff. + } while(abs(w) > unit_roundoff*max_weight); + + // This class tends to consume a lot of memory; shrink the vectors back down to size: + bnode_row.shrink_to_fit(); + bweight_row.shrink_to_fit(); + // Why we are splitting the nodes into regimes where t_n >> 1 and t_n << 1? + // It will create the opportunity to sensibly truncate the quadrature sum to significant terms. + n = -1; + do { + auto precise_nw = ooura_sin_node_and_weight(n, h, alpha); + Real node = static_cast(precise_nw.first); + if (node <= 0) { + break; + } + Real weight = static_cast(precise_nw.second); + w = weight; + using std::isnan; + if (isnan(node)) { + // This occurs at n = -11 in quad precision: + break; + } + if (lnode_row.size() > 0) { + if (lnode_row[lnode_row.size()-1] == node) { + // The nodes have fused into each other: + break; + } + } + if (lnode_row.size() == lnode_row.capacity()) { + lnode_row.reserve(2*lnode_row.size()); + lweight_row.reserve(2*lnode_row.size()); + } + lnode_row.push_back(node); + lweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + --n; + // f(t)->infty is possible as t->0, hence compute up to the min. + } while(abs(w) > (std::numeric_limits::min)()*max_weight); + + lnode_row.shrink_to_fit(); + lweight_row.shrink_to_fit(); + + #ifdef BOOST_MATH_HAS_THREADS + // std::scoped_lock once C++17 is more common? + std::lock_guard lock(node_weight_mutex_); + #endif + // Another thread might have already finished this calculation and appended it to the nodes/weights: + if (current_num_levels == big_nodes_.size()) { + big_nodes_.push_back(bnode_row); + bweights_.push_back(bweight_row); + + little_nodes_.push_back(lnode_row); + lweights_.push_back(lweight_row); + } + } + + template + Real estimate_integral(F const & f, Real omega, size_t i) { + // Because so few function evaluations are required to get high accuracy on the integrals in the tests, + // Kahan summation doesn't really help. + //auto cond = boost::math::tools::summation_condition_number(0); + Real I0 = 0; + auto const & b_nodes = big_nodes_[i]; + auto const & b_weights = bweights_[i]; + // Will benchmark if this is helpful: + Real inv_omega = 1/omega; + for(size_t j = 0 ; j < b_nodes.size(); ++j) { + I0 += f(b_nodes[j]*inv_omega)*b_weights[j]; + } + + auto const & l_nodes = little_nodes_[i]; + auto const & l_weights = lweights_[i]; + // If f decays rapidly as |t|->infty, not all of these calls are necessary. + for (size_t j = 0; j < l_nodes.size(); ++j) { + I0 += f(l_nodes[j]*inv_omega)*l_weights[j]; + } + return I0; + } + + #ifdef BOOST_MATH_HAS_THREADS + std::mutex node_weight_mutex_; + #endif + // Nodes for n >= 0, giving t_n = pi*phi(nh)/h. Generally t_n >> 1. + std::vector> big_nodes_; + // The term bweights_ will indicate that these are weights corresponding + // to the big nodes: + std::vector> bweights_; + + // Nodes for n < 0: Generally t_n << 1, and an invariant is that t_n > 0. + std::vector> little_nodes_; + std::vector> lweights_; + Real rel_err_goal_; + + #ifdef BOOST_MATH_HAS_THREADS + std::atomic starting_level_{}; + #else + long starting_level_; + #endif + size_t requested_levels_; +}; + +template +class ooura_fourier_cos_detail { +public: + ooura_fourier_cos_detail(const Real relative_error_goal, size_t levels) { +#ifdef BOOST_MATH_INSTRUMENT_OOURA + std::cout << "ooura_fourier_cos with relative error goal " << relative_error_goal + << " & " << levels << " levels." << std::endl; + std::cout << "epsilon for type = " << std::numeric_limits::epsilon() << std::endl; +#endif // BOOST_MATH_INSTRUMENT_OOURA + if (relative_error_goal < std::numeric_limits::epsilon() * 2) { + throw std::domain_error("The relative error goal cannot be smaller than the unit roundoff!"); + } + + using std::abs; + requested_levels_ = levels; + starting_level_ = 0; + rel_err_goal_ = relative_error_goal; + big_nodes_.reserve(levels); + bweights_.reserve(levels); + little_nodes_.reserve(levels); + lweights_.reserve(levels); + + for (size_t i = 0; i < levels; ++i) { + if (std::is_same::value) { + add_level(i); + } + else if (std::is_same::value) { + add_level(i); + } + else { + add_level(i); + } + } + + } + + template + std::pair integrate(F const & f, Real omega) { + using std::abs; + using std::max; + using boost::math::constants::pi; + + if (omega == 0) { + throw std::domain_error("At omega = 0, the integral is not oscillatory. The user must choose an appropriate method for this case.\n"); + } + + if (omega < 0) { + return this->integrate(f, -omega); + } + + Real I1 = std::numeric_limits::quiet_NaN(); + Real absolute_error_estimate = std::numeric_limits::quiet_NaN(); + Real scale = std::numeric_limits::quiet_NaN(); + size_t i = starting_level_; + do { + Real I0 = estimate_integral(f, omega, i); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(i, I0, I1, omega); +#endif + absolute_error_estimate = abs(I0-I1); + scale = (max)(abs(I0), abs(I1)); + if (!isnan(I1) && absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(i) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + } while(++i < big_nodes_.size()); + + size_t max_additional_levels = 4; + while (big_nodes_.size() < requested_levels_ + max_additional_levels) { + size_t ii = big_nodes_.size(); + if (std::is_same::value) { + add_level(ii); + } + else if (std::is_same::value) { + add_level(ii); + } + else { + add_level(ii); + } + Real I0 = estimate_integral(f, omega, ii); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(ii, I0, I1, omega); +#endif + absolute_error_estimate = abs(I0-I1); + scale = (max)(abs(I0), abs(I1)); + if (absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(ii) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + ++ii; + } + + starting_level_ = static_cast(big_nodes_.size() - 2); + return {I1/omega, absolute_error_estimate/scale}; + } + +private: + + template + void add_level(size_t i) { + using std::abs; + size_t current_num_levels = big_nodes_.size(); + Real unit_roundoff = std::numeric_limits::epsilon()/2; + PreciseReal h = PreciseReal(1)/PreciseReal(1< bnode_row; + std::vector bweight_row; + bnode_row.reserve((static_cast(1)<(1)< lnode_row; + std::vector lweight_row; + + lnode_row.reserve((static_cast(1)<(1)<(precise_nw.first); + Real weight = static_cast(precise_nw.second); + w = weight; + if (bnode_row.size() == bnode_row.capacity()) { + bnode_row.reserve(2*bnode_row.size()); + bweight_row.reserve(2*bnode_row.size()); + } + + bnode_row.push_back(node); + bweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + ++n; + // f(t)->0 as t->infty, which is why the weights are computed up to the unit roundoff. + } while(abs(w) > unit_roundoff*max_weight); + + bnode_row.shrink_to_fit(); + bweight_row.shrink_to_fit(); + n = -1; + do { + auto precise_nw = ooura_cos_node_and_weight(n, h, alpha); + Real node = static_cast(precise_nw.first); + // The function cannot be singular at zero, + // so zero is not a unreasonable node, + // unlike in the case of the Fourier Sine. + // Hence only break if the node is negative. + if (node < 0) { + break; + } + Real weight = static_cast(precise_nw.second); + w = weight; + if (lnode_row.size() > 0) { + if (lnode_row.back() == node) { + // The nodes have fused into each other: + break; + } + } + if (lnode_row.size() == lnode_row.capacity()) { + lnode_row.reserve(2*lnode_row.size()); + lweight_row.reserve(2*lnode_row.size()); + } + + lnode_row.push_back(node); + lweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + --n; + } while(abs(w) > (std::numeric_limits::min)()*max_weight); + + lnode_row.shrink_to_fit(); + lweight_row.shrink_to_fit(); + + #ifdef BOOST_MATH_HAS_THREADS + std::lock_guard lock(node_weight_mutex_); + #endif + + // Another thread might have already finished this calculation and appended it to the nodes/weights: + if (current_num_levels == big_nodes_.size()) { + big_nodes_.push_back(bnode_row); + bweights_.push_back(bweight_row); + + little_nodes_.push_back(lnode_row); + lweights_.push_back(lweight_row); + } + } + + template + Real estimate_integral(F const & f, Real omega, size_t i) { + Real I0 = 0; + auto const & b_nodes = big_nodes_[i]; + auto const & b_weights = bweights_[i]; + Real inv_omega = 1/omega; + for(size_t j = 0 ; j < b_nodes.size(); ++j) { + I0 += f(b_nodes[j]*inv_omega)*b_weights[j]; + } + + auto const & l_nodes = little_nodes_[i]; + auto const & l_weights = lweights_[i]; + for (size_t j = 0; j < l_nodes.size(); ++j) { + I0 += f(l_nodes[j]*inv_omega)*l_weights[j]; + } + return I0; + } + + #ifdef BOOST_MATH_HAS_THREADS + std::mutex node_weight_mutex_; + #endif + + std::vector> big_nodes_; + std::vector> bweights_; + + std::vector> little_nodes_; + std::vector> lweights_; + Real rel_err_goal_; + + #ifdef BOOST_MATH_HAS_THREADS + std::atomic starting_level_{}; + #else + long starting_level_; + #endif + + size_t requested_levels_; +}; + + +}}}} +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/detail/sinh_sinh_detail.hpp b/third-party/boost-math/include/boost/math/quadrature/detail/sinh_sinh_detail.hpp new file mode 100644 index 0000000000000..7f7477a6e63af --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/detail/sinh_sinh_detail.hpp @@ -0,0 +1,1353 @@ +// Copyright Nick Thompson, 2017 +// Copyright Matt Borland, 2024 +// 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) + +#ifndef BOOST_MATH_QUADRATURE_DETAIL_SINH_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_SINH_SINH_DETAIL_HPP + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + + +// Returns the sinh-sinh quadrature of a function f over the entire real line + +template +class sinh_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + sinh_sinh_detail(size_t max_refinements); + + template + auto integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())); + +private: + + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const std::integral_constant&); +#endif + + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + using std::sinh; + using std::cosh; + using std::exp; + using constants::half_pi; + + std::size_t row = ++m_committed_refinements; + + Real h = ldexp(Real(1), -static_cast(row)); + size_t k = static_cast(boost::math::lltrunc(ceil(m_t_max / (2 * h)))); + m_abscissas[row].reserve(k); + m_weights[row].reserve(k); + Real arg = h; + while (arg < m_t_max) + { + Real tmp = half_pi()*sinh(arg); + Real x = sinh(tmp); + m_abscissas[row].emplace_back(x); + Real w = cosh(arg)*half_pi()*cosh(tmp); + m_weights[row].emplace_back(w); + arg += 2 * h; + } + } + + Real m_t_max; + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + std::size_t m_max_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif +}; + +template +sinh_sinh_detail::sinh_sinh_detail(size_t max_refinements) + : m_abscissas(max_refinements), m_weights(max_refinements), m_max_refinements(max_refinements) +{ + init(std::integral_constant()); +} + +template +template +auto sinh_sinh_detail::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + using std::abs; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + static const char* function = "boost::math::quadrature::sinh_sinh<%1%>::integrate"; + + typedef decltype(f(static_cast(0))) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + K y_max = f(boost::math::tools::max_value()); + if(abs(y_max) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", y_max, Policy())); + } + + K y_min = f(-boost::math::tools::max_value()); + if(abs(y_min) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at -infinity, and instead evaluates to %1%", y_max, Policy())); + } + + // Get the party started with two estimates of the integral: + K I0 = f(0)*half_pi(); + Real L1_I0 = abs(I0); + for(size_t i = 0; i < m_abscissas[0].size(); ++i) + { + Real x = m_abscissas[0][i]; + K yp = f(x); + K ym = f(-x); + I0 += (yp + ym)*m_weights[0][i]; + L1_I0 += (abs(yp)+abs(ym))*m_weights[0][i]; + } + + // Uncomment the estimates to work the convergence on the command line. + // std::cout << std::setprecision(std::numeric_limits::digits10); + // std::cout << "First estimate : " << I0 << std::endl; + K I1 = I0; + Real L1_I1 = L1_I0; + for (size_t i = 0; i < m_abscissas[1].size(); ++i) + { + Real x= m_abscissas[1][i]; + K yp = f(x); + K ym = f(-x); + I1 += (yp + ym)*m_weights[1][i]; + L1_I1 += (abs(yp) + abs(ym))*m_weights[1][i]; + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + // std::cout << "Second estimate: " << I1 << " Error estimate at level " << 1 << " = " << err << std::endl; + + size_t i = 2; + for(; i <= m_max_refinements; ++i) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1) / static_cast(1 << i); + K sum = 0; + Real absum = 0; + + Real abterm1 = 1; + Real eps = boost::math::tools::epsilon()*L1_I1; + + auto abscissa_row = get_abscissa_row(i); + auto weight_row = get_weight_row(i); + + for(size_t j = 0; j < abscissa_row.size(); ++j) + { + Real x = abscissa_row[j]; + K yp = f(x); + K ym = f(-x); + sum += (yp + ym)*weight_row[j]; + Real abterm0 = (abs(yp) + abs(ym))*weight_row[j]; + absum += abterm0; + + // We require two consecutive terms to be < eps in case we hit a zero of f. + if (x > static_cast(100) && abterm0 < eps && abterm1 < eps) + { + break; + } + abterm1 = abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + // std::cout << "Estimate: " << I1 << " Error estimate at level " << i << " = " << err << std::endl; + if (!(boost::math::isfinite)(L1_I1)) + { + const char* err_msg = "The sinh_sinh quadrature evaluated your function at a singular point, leading to the value %1%.\n" + "sinh_sinh quadrature cannot handle singularities in the domain.\n" + "If you are sure your function has no singularities, please submit a bug against boost.math\n"; + return static_cast(policies::raise_evaluation_error(function, err_msg, I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if (L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + using std::log; + using std::sqrt; + using std::cosh; + using std::sinh; + using std::ceil; + using boost::math::constants::two_div_pi; + using boost::math::constants::half_pi; + + m_committed_refinements = 4; + + // t_max is chosen to make g'(t_max) ~ sqrt(max) (g' grows faster than g). + // This will allow some flexibility on the users part; they can at least square a number function without overflow. + // But there is no unique choice; the further out we can evaluate the function, the better we can do on slowly decaying integrands. + m_t_max = log(2 * two_div_pi()*log(2 * two_div_pi()*sqrt(tools::max_value()))); + + for (size_t i = 0; i <= 4; ++i) + { + Real h = static_cast(1) / static_cast(1 << i); + size_t k = static_cast(boost::math::lltrunc(ceil(m_t_max / (2 * h)))); + m_abscissas[i].reserve(k); + m_weights[i].reserve(k); + // We don't add 0 to the abscissas; that's treated as a special case. + Real arg = h; + while (arg < m_t_max) + { + Real tmp = half_pi()*sinh(arg); + Real x = sinh(tmp); + m_abscissas[i].emplace_back(x); + Real w = cosh(arg)*half_pi()*cosh(tmp); + m_weights[i].emplace_back(w); + + if (i != 0) + { + arg += 2 * h; + } + else + { + arg += h; + } + } + } +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828742e+00f, 1.48993185e+02f, 3.41228925e+06f, 2.06932577e+18f, }, + { 9.13048763e-01f, 1.41578929e+01f, 6.70421552e+03f, 9.64172533e+10f, }, + { 4.07297690e-01f, 1.68206671e+00f, 6.15089799e+00f, 4.00396235e+01f, 7.92920025e+02f, 1.02984971e+05f, 3.03862311e+08f, 1.56544547e+14f, }, + { 1.98135272e-01f, 6.40155674e-01f, 1.24892870e+00f, 2.26608084e+00f, 4.29646270e+00f, 9.13029039e+00f, 2.31110765e+01f, 7.42770603e+01f, 3.26720921e+02f, 2.15948569e+03f, 2.41501526e+04f, 5.31819400e+05f, 2.80058686e+07f, 4.52406508e+09f, 3.08561257e+12f, 1.33882673e+16f, }, + { 9.83967894e-02f, 3.00605618e-01f, 5.19857979e-01f, 7.70362083e-01f, 1.07131137e+00f, 1.45056976e+00f, 1.95077855e+00f, 2.64003177e+00f, 3.63137237e+00f, 5.11991533e+00f, 7.45666098e+00f, 1.13022613e+01f, 1.79641069e+01f, 3.01781070e+01f, 5.40387580e+01f, 1.04107731e+02f, 2.18029520e+02f, 5.02155699e+02f, 1.28862131e+03f, 3.73921687e+03f, 1.24750730e+04f, 4.87639975e+04f, 2.28145658e+05f, 1.30877796e+06f, 9.46084663e+06f, 8.88883120e+07f, 1.12416883e+09f, 1.99127673e+10f, 5.16743469e+11f, 2.06721881e+13f, 1.35061503e+15f, 1.53854066e+17f, }, + { 4.91151004e-02f, 1.48013150e-01f, 2.48938814e-01f, 3.53325424e-01f, 4.62733557e-01f, 5.78912068e-01f, 7.03870253e-01f, 8.39965859e-01f, 9.90015066e-01f, 1.15743257e+00f, 1.34641276e+00f, 1.56216711e+00f, 1.81123885e+00f, 2.10192442e+00f, 2.44484389e+00f, 2.85372075e+00f, 3.34645891e+00f, 3.94664582e+00f, 4.68567310e+00f, 5.60576223e+00f, 6.76433234e+00f, 8.24038318e+00f, 1.01439436e+01f, 1.26302471e+01f, 1.59213040e+01f, 2.03392186e+01f, 2.63584645e+01f, 3.46892633e+01f, 4.64129147e+01f, 6.32055079e+01f, 8.77149726e+01f, 1.24209693e+02f, 1.79718635e+02f, 2.66081728e+02f, 4.03727303e+02f, 6.28811307e+02f, 1.00707984e+03f, 1.66156823e+03f, 2.82965144e+03f, 4.98438627e+03f, 9.10154693e+03f, 1.72689266e+04f, 3.41309958e+04f, 7.04566898e+04f, 1.52340422e+05f, 3.46047978e+05f, 8.28472421e+05f, 2.09759615e+06f, 5.63695080e+06f, 1.61407141e+07f, 4.94473068e+07f, 1.62781052e+08f, 5.78533297e+08f, 2.23083854e+09f, 9.38239131e+09f, 4.32814954e+10f, 2.20307274e+11f, 1.24524507e+12f, 7.86900053e+12f, 5.59953143e+13f, 4.52148695e+14f, 4.17688952e+15f, 4.45286776e+16f, 5.52914285e+17f, 8.07573252e+18f, }, + { 2.45471558e-02f, 7.37246687e-02f, 1.23152531e-01f, 1.73000138e-01f, 2.23440665e-01f, 2.74652655e-01f, 3.26821679e-01f, 3.80142101e-01f, 4.34818964e-01f, 4.91070037e-01f, 5.49128046e-01f, 6.09243132e-01f, 6.71685571e-01f, 7.36748805e-01f, 8.04752842e-01f, 8.76048080e-01f, 9.51019635e-01f, 1.03009224e+00f, 1.11373586e+00f, 1.20247203e+00f, 1.29688123e+00f, 1.39761124e+00f, 1.50538689e+00f, 1.62102121e+00f, 1.74542840e+00f, 1.87963895e+00f, 2.02481711e+00f, 2.18228138e+00f, 2.35352849e+00f, 2.54026147e+00f, 2.74442267e+00f, 2.96823279e+00f, 3.21423687e+00f, 3.48535896e+00f, 3.78496698e+00f, 4.11695014e+00f, 4.48581137e+00f, 4.89677825e+00f, 5.35593629e+00f, 5.87038976e+00f, 6.44845619e+00f, 7.09990245e+00f, 7.83623225e+00f, 8.67103729e+00f, 9.62042778e+00f, 1.07035620e+01f, 1.19433001e+01f, 1.33670142e+01f, 1.50075962e+01f, 1.69047155e+01f, 1.91063967e+01f, 2.16710044e+01f, 2.46697527e+01f, 2.81898903e+01f, 3.23387613e+01f, 3.72490076e+01f, 4.30852608e+01f, 5.00527965e+01f, 5.84087761e+01f, 6.84769282e+01f, 8.06668178e+01f, 9.54992727e+01f, 1.13640120e+02f, 1.35945194e+02f, 1.63520745e+02f, 1.97804969e+02f, 2.40678754e+02f, 2.94617029e+02f, 3.62896953e+02f, 4.49886178e+02f, 5.61444735e+02f, 7.05489247e+02f, 8.92790773e+02f, 1.13811142e+03f, 1.46183599e+03f, 1.89233262e+03f, 2.46939604e+03f, 3.24931157e+03f, 4.31236711e+03f, 5.77409475e+03f, 7.80224724e+03f, 1.06426753e+04f, 1.46591538e+04f, 2.03952854e+04f, 2.86717062e+04f, 4.07403376e+04f, 5.85318231e+04f, 8.50568927e+04f, 1.25064927e+05f, 1.86137394e+05f, 2.80525578e+05f, 4.28278249e+05f, 6.62634051e+05f, 1.03944324e+06f, 1.65385743e+06f, 2.67031565e+06f, 4.37721203e+06f, 7.28807171e+06f, 1.23317299e+07f, 2.12155729e+07f, 3.71308625e+07f, 6.61457938e+07f, 1.20005529e+08f, 2.21862941e+08f, 4.18228294e+08f, 8.04370413e+08f, 1.57939299e+09f, 3.16812242e+09f, 6.49660681e+09f, 1.36285199e+10f, 2.92686390e+10f, 6.43979867e+10f, 1.45275523e+11f, 3.36285446e+11f, 7.99420279e+11f, 1.95326423e+12f, 4.90958187e+12f, 1.27062273e+13f, 3.38907099e+13f, 9.32508403e+13f, 2.64948942e+14f, 7.78129518e+14f, 2.36471505e+15f, 7.44413803e+15f, 2.43021724e+16f, 8.23706864e+16f, 2.90211705e+17f, 1.06415768e+18f, 4.06627711e+18f, }, + { 1.22722792e-02f, 3.68272289e-02f, 6.14133763e-02f, 8.60515971e-02f, 1.10762884e-01f, 1.35568393e-01f, 1.60489494e-01f, 1.85547813e-01f, 2.10765290e-01f, 2.36164222e-01f, 2.61767321e-01f, 2.87597761e-01f, 3.13679240e-01f, 3.40036029e-01f, 3.66693040e-01f, 3.93675878e-01f, 4.21010910e-01f, 4.48725333e-01f, 4.76847237e-01f, 5.05405685e-01f, 5.34430786e-01f, 5.63953775e-01f, 5.94007101e-01f, 6.24624511e-01f, 6.55841151e-01f, 6.87693662e-01f, 7.20220285e-01f, 7.53460977e-01f, 7.87457528e-01f, 8.22253686e-01f, 8.57895297e-01f, 8.94430441e-01f, 9.31909591e-01f, 9.70385775e-01f, 1.00991475e+00f, 1.05055518e+00f, 1.09236885e+00f, 1.13542087e+00f, 1.17977990e+00f, 1.22551840e+00f, 1.27271289e+00f, 1.32144424e+00f, 1.37179794e+00f, 1.42386447e+00f, 1.47773961e+00f, 1.53352485e+00f, 1.59132774e+00f, 1.65126241e+00f, 1.71344993e+00f, 1.77801893e+00f, 1.84510605e+00f, 1.91485658e+00f, 1.98742510e+00f, 2.06297613e+00f, 2.14168493e+00f, 2.22373826e+00f, 2.30933526e+00f, 2.39868843e+00f, 2.49202464e+00f, 2.58958621e+00f, 2.69163219e+00f, 2.79843963e+00f, 2.91030501e+00f, 3.02754584e+00f, 3.15050230e+00f, 3.27953915e+00f, 3.41504770e+00f, 3.55744805e+00f, 3.70719145e+00f, 3.86476298e+00f, 4.03068439e+00f, 4.20551725e+00f, 4.38986641e+00f, 4.58438376e+00f, 4.78977239e+00f, 5.00679110e+00f, 5.23625945e+00f, 5.47906320e+00f, 5.73616037e+00f, 6.00858792e+00f, 6.29746901e+00f, 6.60402117e+00f, 6.92956515e+00f, 7.27553483e+00f, 7.64348809e+00f, 8.03511888e+00f, 8.45227058e+00f, 8.89695079e+00f, 9.37134780e+00f, 9.87784877e+00f, 1.04190601e+01f, 1.09978298e+01f, 1.16172728e+01f, 1.22807990e+01f, 1.29921443e+01f, 1.37554055e+01f, 1.45750793e+01f, 1.54561061e+01f, 1.64039187e+01f, 1.74244972e+01f, 1.85244301e+01f, 1.97109839e+01f, 2.09921804e+01f, 2.23768845e+01f, 2.38749023e+01f, 2.54970927e+01f, 2.72554930e+01f, 2.91634608e+01f, 3.12358351e+01f, 3.34891185e+01f, 3.59416839e+01f, 3.86140099e+01f, 4.15289481e+01f, 4.47120276e+01f, 4.81918020e+01f, 5.20002465e+01f, 5.61732106e+01f, 6.07509371e+01f, 6.57786566e+01f, 7.13072704e+01f, 7.73941341e+01f, 8.41039609e+01f, 9.15098607e+01f, 9.96945411e+01f, 1.08751694e+02f, 1.18787600e+02f, 1.29922990e+02f, 1.42295202e+02f, 1.56060691e+02f, 1.71397955e+02f, 1.88510933e+02f, 2.07632988e+02f, 2.29031559e+02f, 2.53013612e+02f, 2.79932028e+02f, 3.10193130e+02f, 3.44265522e+02f, 3.82690530e+02f, 4.26094527e+02f, 4.75203518e+02f, 5.30860437e+02f, 5.94045681e+02f, 6.65901543e+02f, 7.47761337e+02f, 8.41184173e+02f, 9.47996570e+02f, 1.07034233e+03f, 1.21074246e+03f, 1.37216724e+03f, 1.55812321e+03f, 1.77275819e+03f, 2.02098849e+03f, 2.30865326e+03f, 2.64270219e+03f, 3.03142418e+03f, 3.48472668e+03f, 4.01447750e+03f, 4.63492426e+03f, 5.36320995e+03f, 6.22000841e+03f, 7.23030933e+03f, 8.42439022e+03f, 9.83902287e+03f, 1.15189746e+04f, 1.35188810e+04f, 1.59055875e+04f, 1.87610857e+04f, 2.21862046e+04f, 2.63052621e+04f, 3.12719440e+04f, 3.72767546e+04f, 4.45564828e+04f, 5.34062659e+04f, 6.41950058e+04f, 7.73851264e+04f, 9.35579699e+04f, 1.13446538e+05f, 1.37977827e+05f, 1.68327749e+05f, 2.05992575e+05f, 2.52882202e+05f, 3.11442272e+05f, 3.84814591e+05f, 4.77048586e+05f, 5.93380932e+05f, 7.40606619e+05f, 9.27573047e+05f, 1.16584026e+06f, 1.47056632e+06f, 1.86169890e+06f, 2.36558487e+06f, 3.01715270e+06f, 3.86288257e+06f, 4.96486431e+06f, 6.40636283e+06f, 8.29948185e+06f, 1.07957589e+07f, 1.41008733e+07f, 1.84951472e+07f, 2.43622442e+07f, 3.22295113e+07f, 4.28249388e+07f, 5.71579339e+07f, 7.66343793e+07f, 1.03221273e+08f, 1.39683399e+08f, 1.89925150e+08f, 2.59486540e+08f, 3.56266474e+08f, 4.91582541e+08f, 6.81731647e+08f, 9.50299811e+08f, 1.33159830e+09f, 1.87580198e+09f, 2.65667391e+09f, 3.78324022e+09f, 5.41753185e+09f, 7.80169537e+09f, 1.12996537e+10f, 1.64614916e+10f, 2.41235400e+10f, 3.55648690e+10f, 5.27534501e+10f, 7.87357211e+10f, 1.18256902e+11f, 1.78754944e+11f, 2.71963306e+11f, 4.16512215e+11f, 6.42178186e+11f, 9.96872550e+11f, 1.55821233e+12f, 2.45280998e+12f, 3.88865623e+12f, 6.20986899e+12f, 9.98992422e+12f, 1.61915800e+13f, 2.64432452e+13f, 4.35201885e+13f, 7.21888469e+13f, 1.20699764e+14f, 2.03448372e+14f, 3.45755310e+14f, 5.92524851e+14f, 1.02405779e+15f, 1.78517405e+15f, 3.13930699e+15f, 5.56985627e+15f, 9.97176335e+15f, 1.80168749e+16f, 3.28570986e+16f, 6.04901854e+16f, 1.12437528e+17f, 2.11044513e+17f, 4.00073701e+17f, 7.66084936e+17f, 1.48201877e+18f, 2.89694543e+18f, 5.72279017e+18f, 1.14268996e+19f, }, + }; + m_weights = { + { 7.86824160e+00f, 8.80516388e+02f, 5.39627832e+07f, 8.87651190e+19f, }, + { 2.39852428e+00f, 5.24459642e+01f, 6.45788782e+04f, 2.50998524e+12f, }, + { 1.74936958e+00f, 3.97965898e+00f, 1.84851460e+01f, 1.86488072e+02f, 5.97420570e+03f, 1.27041264e+06f, 6.16419301e+09f, 5.23085003e+15f, }, + { 1.61385906e+00f, 1.99776729e+00f, 3.02023198e+00f, 5.47764184e+00f, 1.17966092e+01f, 3.03550485e+01f, 9.58442179e+01f, 3.89387024e+02f, 2.17919325e+03f, 1.83920812e+04f, 2.63212061e+05f, 7.42729651e+06f, 5.01587565e+08f, 1.03961087e+11f, 9.10032891e+13f, 5.06865116e+17f, }, + { 1.58146596e+00f, 1.66914991e+00f, 1.85752319e+00f, 2.17566262e+00f, 2.67590138e+00f, 3.44773868e+00f, 4.64394654e+00f, 6.53020450e+00f, 9.58228502e+00f, 1.46836141e+01f, 2.35444955e+01f, 3.96352727e+01f, 7.03763521e+01f, 1.32588012e+02f, 2.66962565e+02f, 5.79374920e+02f, 1.36869193e+03f, 3.55943572e+03f, 1.03218668e+04f, 3.38662130e+04f, 1.27816626e+05f, 5.65408251e+05f, 2.99446204e+06f, 1.94497502e+07f, 1.59219301e+08f, 1.69428882e+09f, 2.42715618e+10f, 4.87031785e+11f, 1.43181966e+13f, 6.48947152e+14f, 4.80375775e+16f, 6.20009636e+18f, }, + { 1.57345777e+00f, 1.59489276e+00f, 1.63853652e+00f, 1.70598041e+00f, 1.79972439e+00f, 1.92332285e+00f, 2.08159737e+00f, 2.28093488e+00f, 2.52969785e+00f, 2.83878478e+00f, 3.22239575e+00f, 3.69908136e+00f, 4.29318827e+00f, 5.03686536e+00f, 5.97287114e+00f, 7.15853842e+00f, 8.67142780e+00f, 1.06174736e+01f, 1.31428500e+01f, 1.64514563e+01f, 2.08309945e+01f, 2.66923599e+01f, 3.46299351e+01f, 4.55151836e+01f, 6.06440809e+01f, 8.19729692e+01f, 1.12502047e+02f, 1.56909655e+02f, 2.22620435e+02f, 3.21638549e+02f, 4.73757451e+02f, 7.12299455e+02f, 1.09460965e+03f, 1.72169779e+03f, 2.77592491e+03f, 4.59523007e+03f, 7.82342759e+03f, 1.37235744e+04f, 2.48518896e+04f, 4.65553875e+04f, 9.04176678e+04f, 1.82484396e+05f, 3.83680026e+05f, 8.42627197e+05f, 1.93843257e+06f, 4.68511285e+06f, 1.19352867e+07f, 3.21564375e+07f, 9.19600893e+07f, 2.80222318e+08f, 9.13611083e+08f, 3.20091090e+09f, 1.21076526e+10f, 4.96902475e+10f, 2.22431575e+11f, 1.09212534e+12f, 5.91688298e+12f, 3.55974344e+13f, 2.39435365e+14f, 1.81355107e+15f, 1.55873671e+16f, 1.53271488e+17f, 1.73927478e+18f, 2.29884122e+19f, 3.57403070e+20f, }, + { 1.57146132e+00f, 1.57679017e+00f, 1.58749564e+00f, 1.60367396e+00f, 1.62547113e+00f, 1.65308501e+00f, 1.68676814e+00f, 1.72683132e+00f, 1.77364814e+00f, 1.82766042e+00f, 1.88938482e+00f, 1.95942057e+00f, 2.03845873e+00f, 2.12729290e+00f, 2.22683194e+00f, 2.33811466e+00f, 2.46232715e+00f, 2.60082286e+00f, 2.75514621e+00f, 2.92706011e+00f, 3.11857817e+00f, 3.33200254e+00f, 3.56996830e+00f, 3.83549565e+00f, 4.13205150e+00f, 4.46362211e+00f, 4.83479919e+00f, 5.25088196e+00f, 5.71799849e+00f, 6.24325042e+00f, 6.83488580e+00f, 7.50250620e+00f, 8.25731548e+00f, 9.11241941e+00f, 1.00831875e+01f, 1.11876913e+01f, 1.24472371e+01f, 1.38870139e+01f, 1.55368872e+01f, 1.74323700e+01f, 1.96158189e+01f, 2.21379089e+01f, 2.50594593e+01f, 2.84537038e+01f, 3.24091185e+01f, 3.70329629e+01f, 4.24557264e+01f, 4.88367348e+01f, 5.63712464e+01f, 6.52994709e+01f, 7.59180776e+01f, 8.85949425e+01f, 1.03788130e+02f, 1.22070426e+02f, 1.44161210e+02f, 1.70968019e+02f, 2.03641059e+02f, 2.43645006e+02f, 2.92854081e+02f, 3.53678602e+02f, 4.29234308e+02f, 5.23570184e+02f, 6.41976690e+02f, 7.91405208e+02f, 9.81042209e+02f, 1.22309999e+03f, 1.53391256e+03f, 1.93546401e+03f, 2.45753455e+03f, 3.14073373e+03f, 4.04081819e+03f, 5.23488160e+03f, 6.83029446e+03f, 8.97771323e+03f, 1.18901592e+04f, 1.58712239e+04f, 2.13571111e+04f, 2.89798371e+04f, 3.96630673e+04f, 5.47687519e+04f, 7.63235654e+04f, 1.07371915e+05f, 1.52531667e+05f, 2.18877843e+05f, 3.17362450e+05f, 4.65120153e+05f, 6.89253766e+05f, 1.03311989e+06f, 1.56688798e+06f, 2.40549203e+06f, 3.73952896e+06f, 5.88912115e+06f, 9.39904635e+06f, 1.52090328e+07f, 2.49628719e+07f, 4.15775926e+07f, 7.03070537e+07f, 1.20759856e+08f, 2.10788251e+08f, 3.74104720e+08f, 6.75449459e+08f, 1.24131674e+09f, 2.32331003e+09f, 4.43117602e+09f, 8.61744649e+09f, 1.70983691e+10f, 3.46357452e+10f, 7.16760712e+10f, 1.51634762e+11f, 3.28172932e+11f, 7.27110260e+11f, 1.65049955e+12f, 3.84133815e+12f, 9.17374427e+12f, 2.24990195e+13f, 5.67153509e+13f, 1.47074225e+14f, 3.92701252e+14f, 1.08063998e+15f, 3.06767147e+15f, 8.99238679e+15f, 2.72472254e+16f, 8.54294612e+16f, 2.77461372e+17f, 9.34529948e+17f, 3.26799612e+18f, 1.18791443e+19f, 4.49405341e+19f, 1.77170665e+20f, }, + { 1.57096255e+00f, 1.57229290e+00f, 1.57495658e+00f, 1.57895955e+00f, 1.58431079e+00f, 1.59102230e+00f, 1.59910918e+00f, 1.60858966e+00f, 1.61948515e+00f, 1.63182037e+00f, 1.64562338e+00f, 1.66092569e+00f, 1.67776241e+00f, 1.69617233e+00f, 1.71619809e+00f, 1.73788633e+00f, 1.76128784e+00f, 1.78645779e+00f, 1.81345587e+00f, 1.84234658e+00f, 1.87319943e+00f, 1.90608922e+00f, 1.94109632e+00f, 1.97830698e+00f, 2.01781368e+00f, 2.05971547e+00f, 2.10411838e+00f, 2.15113585e+00f, 2.20088916e+00f, 2.25350798e+00f, 2.30913084e+00f, 2.36790578e+00f, 2.42999091e+00f, 2.49555516e+00f, 2.56477893e+00f, 2.63785496e+00f, 2.71498915e+00f, 2.79640147e+00f, 2.88232702e+00f, 2.97301705e+00f, 3.06874019e+00f, 3.16978367e+00f, 3.27645477e+00f, 3.38908227e+00f, 3.50801806e+00f, 3.63363896e+00f, 3.76634859e+00f, 3.90657947e+00f, 4.05479525e+00f, 4.21149322e+00f, 4.37720695e+00f, 4.55250922e+00f, 4.73801517e+00f, 4.93438579e+00f, 5.14233166e+00f, 5.36261713e+00f, 5.59606472e+00f, 5.84356014e+00f, 6.10605759e+00f, 6.38458564e+00f, 6.68025373e+00f, 6.99425915e+00f, 7.32789480e+00f, 7.68255767e+00f, 8.05975815e+00f, 8.46113023e+00f, 8.88844279e+00f, 9.34361190e+00f, 9.82871448e+00f, 1.03460033e+01f, 1.08979234e+01f, 1.14871305e+01f, 1.21165112e+01f, 1.27892047e+01f, 1.35086281e+01f, 1.42785033e+01f, 1.51028871e+01f, 1.59862046e+01f, 1.69332867e+01f, 1.79494108e+01f, 1.90403465e+01f, 2.02124072e+01f, 2.14725057e+01f, 2.28282181e+01f, 2.42878539e+01f, 2.58605342e+01f, 2.75562800e+01f, 2.93861096e+01f, 3.13621485e+01f, 3.34977526e+01f, 3.58076454e+01f, 3.83080730e+01f, 4.10169773e+01f, 4.39541917e+01f, 4.71416602e+01f, 5.06036855e+01f, 5.43672075e+01f, 5.84621188e+01f, 6.29216205e+01f, 6.77826252e+01f, 7.30862125e+01f, 7.88781469e+01f, 8.52094636e+01f, 9.21371360e+01f, 9.97248336e+01f, 1.08043785e+02f, 1.17173764e+02f, 1.27204209e+02f, 1.38235512e+02f, 1.50380485e+02f, 1.63766039e+02f, 1.78535118e+02f, 1.94848913e+02f, 2.12889407e+02f, 2.32862309e+02f, 2.55000432e+02f, 2.79567594e+02f, 3.06863126e+02f, 3.37227087e+02f, 3.71046310e+02f, 4.08761417e+02f, 4.50874968e+02f, 4.97960949e+02f, 5.50675821e+02f, 6.09771424e+02f, 6.76110054e+02f, 7.50682104e+02f, 8.34626760e+02f, 9.29256285e+02f, 1.03608458e+03f, 1.15686082e+03f, 1.29360914e+03f, 1.44867552e+03f, 1.62478326e+03f, 1.82509876e+03f, 2.05330964e+03f, 2.31371761e+03f, 2.61134924e+03f, 2.95208799e+03f, 3.34283233e+03f, 3.79168493e+03f, 4.30817984e+03f, 4.90355562e+03f, 5.59108434e+03f, 6.38646863e+03f, 7.30832183e+03f, 8.37874981e+03f, 9.62405722e+03f, 1.10756067e+04f, 1.27708661e+04f, 1.47546879e+04f, 1.70808754e+04f, 1.98141031e+04f, 2.30322789e+04f, 2.68294532e+04f, 3.13194118e+04f, 3.66401221e+04f, 4.29592484e+04f, 5.04810088e+04f, 5.94547213e+04f, 7.01854788e+04f, 8.30475173e+04f, 9.85009981e+04f, 1.17113127e+05f, 1.39584798e+05f, 1.66784302e+05f, 1.99790063e+05f, 2.39944995e+05f, 2.88925794e+05f, 3.48831531e+05f, 4.22297220e+05f, 5.12639825e+05f, 6.24046488e+05f, 7.61817907e+05f, 9.32683930e+05f, 1.14521401e+06f, 1.41035265e+06f, 1.74212004e+06f, 2.15853172e+06f, 2.68280941e+06f, 3.34498056e+06f, 4.18399797e+06f, 5.25055801e+06f, 6.61086017e+06f, 8.35163942e+06f, 1.05869253e+07f, 1.34671524e+07f, 1.71914827e+07f, 2.20245345e+07f, 2.83191730e+07f, 3.65476782e+07f, 4.73445266e+07f, 6.15653406e+07f, 8.03684303e+07f, 1.05328028e+08f, 1.38592169e+08f, 1.83103699e+08f, 2.42910946e+08f, 3.23606239e+08f, 4.32947522e+08f, 5.81743297e+08f, 7.85117979e+08f, 1.06432920e+09f, 1.44938958e+09f, 1.98286647e+09f, 2.72541431e+09f, 3.76386796e+09f, 5.22313881e+09f, 7.28378581e+09f, 1.02080964e+10f, 1.43789932e+10f, 2.03583681e+10f, 2.89749983e+10f, 4.14577375e+10f, 5.96383768e+10f, 8.62622848e+10f, 1.25466705e+11f, 1.83521298e+11f, 2.69981221e+11f, 3.99492845e+11f, 5.94638056e+11f, 8.90440997e+11f, 1.34155194e+12f, 2.03376855e+12f, 3.10262796e+12f, 4.76359832e+12f, 7.36142036e+12f, 1.14512696e+13f, 1.79331419e+13f, 2.82758550e+13f, 4.48929705e+13f, 7.17780287e+13f, 1.15585510e+14f, 1.87483389e+14f, 3.06351036e+14f, 5.04340065e+14f, 8.36616340e+14f, 1.39855635e+15f, 2.35633575e+15f, 4.00176517e+15f, 6.85137513e+15f, 1.18269011e+16f, 2.05867353e+16f, 3.61396878e+16f, 6.39911218e+16f, 1.14301619e+17f, 2.05988138e+17f, 3.74584679e+17f, 6.87444303e+17f, 1.27340764e+18f, 2.38124192e+18f, 4.49583562e+18f, 8.57144202e+18f, 1.65044358e+19f, 3.21010035e+19f, 6.30778012e+19f, 1.25240403e+20f, 2.51300530e+20f, 5.09677626e+20f, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 4.03936524f; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.088287417976322866e+00, 1.489931846492091580e+02, 3.412289247883437102e+06, 2.069325766042617791e+18, 2.087002407609475560e+50, 2.019766160717908151e+137, }, + { 9.130487626376696748e-01, 1.415789294662811592e+01, 6.704215516223276482e+03, 9.641725327150499415e+10, 2.508950760085778485e+30, 1.447263535710337145e+83, }, + { 4.072976900657586902e-01, 1.682066707021148743e+00, 6.150897986386729515e+00, 4.003962351929400222e+01, 7.929200247931026321e+02, 1.029849713330979583e+05, 3.038623109252438574e+08, 1.565445474362494869e+14, 4.042465098430219104e+23, 1.321706827429658179e+39, 4.991231782099557998e+64, 7.352943850359875966e+106, }, + { 1.981352722514781726e-01, 6.401556735005260177e-01, 1.248928698253977663e+00, 2.266080840944321232e+00, 4.296462696702327381e+00, 9.130290387099955696e+00, 2.311107653864279933e+01, 7.427706034324012430e+01, 3.267209207115258917e+02, 2.159485694311818716e+03, 2.415015262896413060e+04, 5.318194002756929158e+05, 2.800586857217043323e+07, 4.524065079794338780e+09, 3.085612573980677122e+12, 1.338826733015807478e+16, 6.254617176562341381e+20, 6.182098535814164754e+26, 3.077293649788458067e+34, 2.348957289370104303e+44, 1.148543197899469758e+57, 2.255300070010069868e+73, 1.877919500569195394e+94, 1.367473887938624280e+121, }, + { 9.839678940067320339e-02, 3.006056176599550351e-01, 5.198579789949384900e-01, 7.703620832988877009e-01, 1.071311369641311830e+00, 1.450569758088998445e+00, 1.950778549520360334e+00, 2.640031773695551468e+00, 3.631372373667412273e+00, 5.119915330903350570e+00, 7.456660981404883289e+00, 1.130226126889972624e+01, 1.796410692472772550e+01, 3.017810704601898222e+01, 5.403875800312370567e+01, 1.041077314477469548e+02, 2.180295201202628077e+02, 5.021556986259101646e+02, 1.288621310998222420e+03, 3.739216870800548324e+03, 1.247507297020191232e+04, 4.876399753226692124e+04, 2.281456582219130122e+05, 1.308777960064843017e+06, 9.460846634209664077e+06, 8.888831203637279622e+07, 1.124168828974344134e+09, 1.991276729532144470e+10, 5.167434691060984650e+11, 2.067218814203990888e+13, 1.350615033184100406e+15, 1.538540662836508188e+17, 3.290747290540350661e+19, 1.437291381884498816e+22, 1.409832445530347286e+25, 3.459135480277971441e+28, 2.398720582340954092e+32, 5.398806604617292960e+36, 4.613340002580628610e+41, 1.787685909667902457e+47, 3.841984370124338536e+53, 5.752797955708583700e+60, 7.771812038427286551e+68, 1.269673044204081626e+78, 3.495676773765731568e+88, 2.362519474971692445e+100, 6.002143893273651123e+113, 9.290716303464155539e+128, 1.514442238033847090e+146, }, + { 4.911510035029024930e-02, 1.480131496743607333e-01, 2.489388137406836857e-01, 3.533254236926684378e-01, 4.627335566122353259e-01, 5.789120681640963067e-01, 7.038702533860627799e-01, 8.399658591446505688e-01, 9.900150664244376147e-01, 1.157432570143699131e+00, 1.346412759185361763e+00, 1.562167113901335551e+00, 1.811238852782323380e+00, 2.101924419006550301e+00, 2.444843885584197934e+00, 2.853720746632915024e+00, 3.346458910955350787e+00, 3.946645821057838387e+00, 4.685673101596678529e+00, 5.605762230908151175e+00, 6.764332336830574204e+00, 8.240383175379985221e+00, 1.014394356129857730e+01, 1.263024714338892472e+01, 1.592130395780345258e+01, 2.033921861921857185e+01, 2.635846445760633752e+01, 3.468926333224152409e+01, 4.641291467019728963e+01, 6.320550793890424203e+01, 8.771497261808906374e+01, 1.242096926240411498e+02, 1.797186347845127557e+02, 2.660817283327900190e+02, 4.037273029575712841e+02, 6.288113066545908703e+02, 1.007079837507490594e+03, 1.661568229185114288e+03, 2.829651440786582598e+03, 4.984386266585669139e+03, 9.101546927647810893e+03, 1.726892655475049727e+04, 3.413099578778601190e+04, 7.045668977053092802e+04, 1.523404217761279128e+05, 3.460479782897947414e+05, 8.284724209233183002e+05, 2.097596146601193946e+06, 5.636950798861273236e+06, 1.614071410855607245e+07, 4.944730678915060360e+07, 1.627810516820991356e+08, 5.785332971632280838e+08, 2.230838540681955690e+09, 9.382391306064739643e+09, 4.328149544776551692e+10, 2.203072744049242904e+11, 1.245245067109136413e+12, 7.869000534957822375e+12, 5.599531432979422461e+13, 4.521486949902090877e+14, 4.176889516548293265e+15, 4.452867759650496656e+16, 5.529142853140498068e+17, 8.075732516562854275e+18, 1.402046916260468698e+20, 2.925791412832239850e+21, 7.426433029335410886e+22, 2.321996331245735364e+24, 9.064194250638442432e+25, 4.481279048819445609e+27, 2.849046304726990645e+29, 2.367381159183355975e+31, 2.615825578455121227e+33, 3.914764948263290808e+35, 8.092042448555929219e+37, 2.358921320940630332e+40, 9.915218648535332591e+42, 6.152851059342658764e+45, 5.780276340144515388e+48, 8.443751734186488626e+51, 1.973343350899766708e+55, 7.605247378556219980e+58, 4.992057104939510418e+62, 5.775863423903912316e+66, 1.221808201945355603e+71, 4.912917230387133816e+75, 3.913971813732202372e+80, 6.456388069905286787e+85, 2.311225068528010358e+91, 1.887458157719431339e+97, 3.708483165438453094e+103, 1.855198812283538635e+110, 2.509787873171705318e+117, 9.790423755591216617e+124, 1.179088807944050747e+133, 4.714631846722476620e+141, 6.762657785959713240e+150, }, + { 2.454715583629863651e-02, 7.372466873903346224e-02, 1.231525309416766543e-01, 1.730001377719248556e-01, 2.234406649596860001e-01, 2.746526549718518258e-01, 3.268216792980646669e-01, 3.801421009804789245e-01, 4.348189637215614948e-01, 4.910700365099428407e-01, 5.491280459480215441e-01, 6.092431324382654397e-01, 6.716855712021148069e-01, 7.367488049067938643e-01, 8.047528416336950644e-01, 8.760480802482050705e-01, 9.510196351823332253e-01, 1.030092244532470067e+00, 1.113735859588680765e+00, 1.202472030918058876e+00, 1.296881226496863751e+00, 1.397611241828373026e+00, 1.505386891360545205e+00, 1.621021205894798030e+00, 1.745428403369044572e+00, 1.879638952031029331e+00, 2.024817107609328524e+00, 2.182281382147884181e+00, 2.353528494823881355e+00, 2.540261468229626457e+00, 2.744422672171478111e+00, 2.968232787190606619e+00, 3.214236869520657666e+00, 3.485358957907730467e+00, 3.784966983117372821e+00, 4.116950138940295100e+00, 4.485811369388231710e+00, 4.896778246562001812e+00, 5.355936290826725948e+00, 5.870389762600956907e+00, 6.448456189131117605e+00, 7.099902452679558236e+00, 7.836232253282841261e+00, 8.671037293575230635e+00, 9.620427777985990363e+00, 1.070356198876799531e+01, 1.194330008139441022e+01, 1.336701421038499647e+01, 1.500759615914396343e+01, 1.690471548203528376e+01, 1.910639668731689597e+01, 2.167100443216577994e+01, 2.466975274695099197e+01, 2.818989025157845355e+01, 3.233876132429401745e+01, 3.724900758097245740e+01, 4.308526084907741997e+01, 5.005279647654703975e+01, 5.840877607253876528e+01, 6.847692821534239862e+01, 8.066681777060714848e+01, 9.549927270200249260e+01, 1.136401195769487885e+02, 1.359451944976603209e+02, 1.635207451879744447e+02, 1.978049687912586950e+02, 2.406787535889776661e+02, 2.946170292930555023e+02, 3.628969532147125333e+02, 4.498861782715596902e+02, 5.614447353133496106e+02, 7.054892470899271429e+02, 8.927907732799964116e+02, 1.138111424979478376e+03, 1.461835991563605367e+03, 1.892332623444716186e+03, 2.469396036186133479e+03, 3.249311569298824731e+03, 4.312367113170283012e+03, 5.774094754500139661e+03, 7.802247237500851845e+03, 1.064267530975806972e+04, 1.465915383535674990e+04, 2.039528541239754835e+04, 2.867170622421556265e+04, 4.074033762183453297e+04, 5.853182310596923393e+04, 8.505689265265206640e+04, 1.250649269847856615e+05, 1.861373943166749766e+05, 2.805255777452010927e+05, 4.282782486084761748e+05, 6.626340506127657304e+05, 1.039443239650339565e+06, 1.653857426112961316e+06, 2.670315650125279161e+06, 4.377212026624358795e+06, 7.288071713698413821e+06, 1.233172993400331694e+07, 2.121557285769933699e+07, 3.713086254861535383e+07, 6.614579377352135534e+07, 1.200055291694917110e+08, 2.218629410296880690e+08, 4.182282939928687703e+08, 8.043704132493714804e+08, 1.579392989425668114e+09, 3.168122415524104635e+09, 6.496606811549861323e+09, 1.362851988356444486e+10, 2.926863897008707708e+10, 6.439798665209493735e+10, 1.452755233772903022e+11, 3.362854459389246576e+11, 7.994202785433479271e+11, 1.953264233362291960e+12, 4.909581868242554569e+12, 1.270622730765015610e+13, 3.389070986742985764e+13, 9.325084030208844833e+13, 2.649489423834534140e+14, 7.781295184094957195e+14, 2.364715052527355639e+15, 7.444138031465958255e+15, 2.430217240684749635e+16, 8.237068641534357762e+16, 2.902117050664548840e+17, 1.064157679404037013e+18, 4.066277106061960017e+18, 1.621274233630359097e+19, 6.754156830915450013e+19, 2.944056841733781919e+20, 1.344640139549107817e+21, 6.444586158944723300e+21, 3.246218667554608934e+22, 1.721234579556653533e+23, 9.622533890240474391e+23, 5.681407260417956671e+24, 3.548890779995928184e+25, 2.349506425672269562e+26, 1.651618130605205643e+27, 1.235147426493113059e+28, 9.845947239792057550e+28, 8.383130781984610418e+29, 7.639649461399172445e+30, 7.467862732233885201e+31, 7.847691482004993660e+32, 8.886032557626454704e+33, 1.086734890678302436e+35, 1.438967777036538458e+36, 2.068168865475603521e+37, 3.234885320223912385e+38, 5.521233641542628514e+39, 1.031148231194663855e+41, 2.113272035816365982e+42, 4.766724345485077520e+43, 1.186961550990218287e+45, 3.273172169205847573e+46, 1.002821226769167753e+48, 3.424933903935156479e+49, 1.308436017026428736e+51, 5.611378330048420503e+52, 2.711424806327139291e+54, 1.481771793644066442e+56, 9.194282071042778804e+57, 6.503661455875355562e+59, 5.266329986868627303e+61, 4.902662807969347359e+63, 5.270511057289557050e+65, 6.572856511670583316e+67, 9.553956030013225387e+69, 1.626491911159411616e+72, 3.259410915500951223e+74, 7.728460318113614280e+76, 2.179881996905918059e+79, 7.354484388371505915e+81, 2.984831270803957746e+84, 1.465828267813438962e+87, 8.763355972629864261e+89, 6.417909665847831130e+92, 5.794958649229893510e+95, 6.494224472311908365e+98, 9.095000156016433698e+101, 1.603058498455299102e+105, 3.582099119119320529e+108, 1.022441227139854687e+112, 3.756872185015086057e+115, 1.791363463832849159e+119, 1.117641882039472124e+123, 9.202159565546528285e+126, 1.008716474827888568e+131, 1.485546487089301805e+135, 2.966961534830566097e+139, 8.114207284664369360e+143, 3.069178087507669739e+148, 1.622223681147791473e+153, }, + { 1.227227917054637830e-02, 3.682722894492590471e-02, 6.141337626871079991e-02, 8.605159708778207907e-02, 1.107628840017845446e-01, 1.355683934957785482e-01, 1.604894937454335489e-01, 1.855478131645089496e-01, 2.107652898670700524e-01, 2.361642222214626268e-01, 2.617673206785495261e-01, 2.875977610631342900e-01, 3.136792395249035647e-01, 3.400360293536632770e-01, 3.666930398731810193e-01, 3.936758776386451797e-01, 4.210109101746846268e-01, 4.487253325041450341e-01, 4.768472367324829462e-01, 5.054056849688209375e-01, 5.344307858825229079e-01, 5.639537752137267134e-01, 5.940071005777549000e-01, 6.246245109268716053e-01, 6.558411510586397969e-01, 6.876936615883514922e-01, 7.202202848338683401e-01, 7.534609770949572224e-01, 7.874575278460963461e-01, 8.222536864020499377e-01, 8.578952966595825808e-01, 8.944304405668593009e-01, 9.319095910247435485e-01, 9.703857749817920659e-01, 1.009914747547728584e+00, 1.050555178019083150e+00, 1.092368848786092579e+00, 1.135420868172514300e+00, 1.179779898350424466e+00, 1.225518399571142610e+00, 1.272712892062026473e+00, 1.321444237057985065e+00, 1.371797938567245953e+00, 1.423864467614384096e+00, 1.477739610861208115e+00, 1.533524845679288858e+00, 1.591327743938355098e+00, 1.651262406984310076e+00, 1.713449934511288211e+00, 1.778018930286256858e+00, 1.845106047964720870e+00, 1.914856580544951899e+00, 1.987425097349017093e+00, 2.062976132795275283e+00, 2.141684931642916785e+00, 2.223738255848994521e+00, 2.309335258687213796e+00, 2.398688432341103821e+00, 2.492024635808356095e+00, 2.589586210645122756e+00, 2.691632192846832444e+00, 2.798439630014497291e+00, 2.910305013902562652e+00, 3.027545839497364963e+00, 3.150502302946919722e+00, 3.279539151967394330e+00, 3.415047703805410611e+00, 3.557448047456550733e+00, 3.707191448649779817e+00, 3.864762978128342125e+00, 4.030684386016531344e+00, 4.205517247588613835e+00, 4.389866408585172458e+00, 4.584383761391930748e+00, 4.789772386950687695e+00, 5.006791101261363264e+00, 5.236259449815274050e+00, 5.479063198337523150e+00, 5.736160373884817415e+00, 6.008587916728619858e+00, 6.297469010648863048e+00, 6.604021167380929133e+00, 6.929565150124677837e+00, 7.275534831383860972e+00, 7.643488092123492064e+00, 8.035118882502459288e+00, 8.452270579478188130e+00, 8.896950793641785313e+00, 9.371347797016395173e+00, 9.877848765573446033e+00, 1.041906005527762037e+01, 1.099782975900831706e+01, 1.161727282423952258e+01, 1.228079904848924611e+01, 1.299214431196691048e+01, 1.375540545535625881e+01, 1.457507926620621316e+01, 1.545610610104852468e+01, 1.640391874338302925e+01, 1.742449718154208970e+01, 1.852443008688437526e+01, 1.971098388378266494e+01, 2.099218043080961648e+01, 2.237688448013982946e+01, 2.387490225270073820e+01, 2.549709266380430464e+01, 2.725549296232531555e+01, 2.916346081119624987e+01, 3.123583514423284962e+01, 3.348911849136805118e+01, 3.594168387985465099e+01, 3.861400990307230737e+01, 4.152894811329303023e+01, 4.471202755441533396e+01, 4.819180202224910174e+01, 5.200024654361558757e+01, 5.617321062537384494e+01, 6.075093706918782079e+01, 6.577865661168003966e+01, 7.130727037357721343e+01, 7.739413413465805794e+01, 8.410396085269633392e+01, 9.150986068496734448e+01, 9.969454113547704016e+01, 1.087516939426018897e+02, 1.187876000643037532e+02, 1.299229897614516371e+02, 1.422952015056372537e+02, 1.560606914665002671e+02, 1.713979549326432406e+02, 1.885109325154830073e+02, 2.076329877740125935e+02, 2.290315594654587370e+02, 2.530136115655676467e+02, 2.799320282398896912e+02, 3.101931299766730890e+02, 3.442655222107529892e+02, 3.826905303289378387e+02, 4.260945266207607701e+02, 4.752035175892902045e+02, 5.308604366239058864e+02, 5.940456805372995009e+02, 6.659015428338778262e+02, 7.477613367309153870e+02, 8.411841730471343023e+02, 9.479965698013741524e+02, 1.070342331375881840e+03, 1.210742457518582660e+03, 1.372167241552205820e+03, 1.558123212187692722e+03, 1.772758188662716282e+03, 2.020988485411862984e+03, 2.308653259329163157e+03, 2.642702189813684273e+03, 3.031424182869210212e+03, 3.484726676985756018e+03, 4.014477504733973505e+03, 4.634924264049394751e+03, 5.363209949773439749e+03, 6.220008412114342803e+03, 7.230309332853029956e+03, 8.424390216735217783e+03, 9.839022871538541787e+03, 1.151897463083113988e+04, 1.351888098874374202e+04, 1.590558745460066947e+04, 1.876108572764816176e+04, 2.218620462393366275e+04, 2.630526205054915357e+04, 3.127194401941711057e+04, 3.727675461256652923e+04, 4.455648280312273249e+04, 5.340626592018903930e+04, 6.419500580388918123e+04, 7.738512642386820060e+04, 9.355796993981725963e+04, 1.134465375820669470e+05, 1.379778272209741713e+05, 1.683277485807887053e+05, 2.059925746120735305e+05, 2.528822024503158254e+05, 3.114422718347725915e+05, 3.848145913435570736e+05, 4.770485864966822643e+05, 5.933809324724740854e+05, 7.406066190351666115e+05, 9.275730471470643372e+05, 1.165840260940180415e+06, 1.470566322118246135e+06, 1.861698899014921971e+06, 2.365584870298354495e+06, 3.017152695505764877e+06, 3.862882573599929249e+06, 4.964864305589750358e+06, 6.406362829959736606e+06, 8.299481847261302115e+06, 1.079575892642401854e+07, 1.410087327474604091e+07, 1.849514724418250100e+07, 2.436224419670805500e+07, 3.222951131863941234e+07, 4.282493882385925337e+07, 5.715793394339267637e+07, 7.663437932745451635e+07, 1.032212725498489699e+08, 1.396833991976194842e+08, 1.899251497664892740e+08, 2.594865396467505851e+08, 3.562664742464501497e+08, 4.915825413172413471e+08, 6.817316470116958142e+08, 9.502998105202541438e+08, 1.331598295343277538e+09, 1.875801976010459831e+09, 2.656673907709731487e+09, 3.783240215616365909e+09, 5.417531848500136979e+09, 7.801695369892847510e+09, 1.129965368955098833e+10, 1.646149161390821924e+10, 2.412353995736687694e+10, 3.556486895431927094e+10, 5.275345014093760519e+10, 7.873572108325378177e+10, 1.182569020317863604e+11, 1.787549442508363461e+11, 2.719633064979986142e+11, 4.165122153119897946e+11, 6.421781858205134197e+11, 9.968725497576275918e+11, 1.558212327122960399e+12, 2.452809984907093786e+12, 3.888656232828140210e+12, 6.209868990509424909e+12, 9.989924216297983665e+12, 1.619158001378611351e+13, 2.644324518669926559e+13, 4.352018847904374786e+13, 7.218884688202741709e+13, 1.206997640727349538e+14, 2.034483722445207402e+14, 3.457553102874402920e+14, 5.925248511957505706e+14, 1.024057793713038672e+15, 1.785174045941642162e+15, 3.139306988668494696e+15, 5.569856270174890128e+15, 9.971763353834460328e+15, 1.801687491114883092e+16, 3.285709858322565542e+16, 6.049018540910759710e+16, 1.124375283211369572e+17, 2.110445125952435305e+17, 4.000737007891229992e+17, 7.660849361564329309e+17, 1.482018770996176700e+18, 2.896945433910857945e+18, 5.722790165693470493e+18, 1.142689960439921462e+19, 2.306616559984106723e+19, 4.707857184616093863e+19, 9.717346347495342813e+19, 2.028735605622585444e+20, 4.284840254171000581e+20, 9.157027329021623836e+20, 1.980457834766411777e+21, 4.335604886702252004e+21, 9.609258559714223995e+21, 2.156604630608586997e+22, 4.902045909695270289e+22, 1.128749227121328467e+23, 2.633414623049930879e+23, 6.226335684490998543e+23, 1.492205279014148921e+24, 3.625768249717590109e+24, 8.933899764961444882e+24, 2.232786981682262383e+25, 5.661295336293986732e+25, 1.456616710298133142e+26, 3.803959852868488245e+26, 1.008531585603036490e+27, 2.715247425129423358e+27, 7.425071766766651967e+27, 2.062860712173225003e+28, 5.824055458799413312e+28, 1.671388836696436644e+29, 4.876830632023956392e+29, 1.447170071146107156e+30, 4.368562208925583783e+30, 1.341873806249251338e+31, 4.195251632754338682e+31, 1.335360134828214136e+32, 4.328681350715136340e+32, 1.429401866150319186e+33, 4.809736146227180696e+33, 1.649624114567602575e+34, 5.768677492419801469e+34, 2.057442854162761350e+35, 7.486423509917811063e+35, 2.780052791791155051e+36, 1.053908347660081874e+37, 4.080046334235754223e+37, 1.613553311592805373e+38, 6.520836332997615098e+38, 2.693848186257510992e+39, 1.138002408430710800e+40, 4.917748008813924613e+40, 2.174691073191358676e+41, 9.844523745430526502e+41, 4.563707467590116732e+42, 2.167352073708379137e+43, 1.054860193887170754e+44, 5.263588225566847365e+44, 2.693772458797916623e+45, 1.414506760560163074e+46, 7.624126763512016620e+46, 4.219828148762794411e+47, 2.399387665831793264e+48, 1.402139947254117434e+49, 8.424706325525422943e+49, 5.206918479942619318e+50, 3.311787866477716151e+51, 2.168683295509859155e+52, 1.462786368779206713e+53, 1.016761784575838363e+54, 7.286460995145043184e+54, 5.386194237448865407e+55, 4.108917480528740640e+56, 3.236445625945552728e+57, 2.633440652417619669e+58, 2.214702339357939268e+59, 1.926058995948268392e+60, 1.733067740414174932e+61, 1.614307160124426969e+62, 1.557464328486352138e+63, 1.557226155197192031e+64, 1.614473962707995344e+65, 1.736617406327386105e+66, 1.939201243451190521e+67, 2.249277732936622876e+68, 2.711593798719765599e+69, 3.399628732048687119e+70, 4.435389696730206291e+71, 6.025566076164003981e+72, 8.529161425383779849e+73, 1.258746322992988688e+75, 1.938112175186560210e+76, 3.115432363572610661e+77, 5.231797674434390018e+78, 9.184930207860680757e+79, 1.686929404780378772e+81, 3.243565624474232635e+82, 6.533812498930220075e+83, 1.379898823144620314e+85, 3.057650444842839916e+86, 7.114050545839171245e+87, 1.739275024442258674e+89, 4.471782915853177804e+90, 1.210036789494028144e+92, 3.448828044590862359e+93, 1.036226783750561565e+95, 3.284801914751206038e+96, 1.099514933602224638e+98, 3.889581731378242597e+99, 1.455434287901069991e+101, 5.765729934387419019e+102, 2.420349568745475582e+104, 1.077606625929777536e+106, 5.093346988695851845e+107, 2.558090824110323997e+109, 1.366512508719047964e+111, 7.771735800763526406e+112, 4.710398638793014918e+114, 3.045563885587013954e+116, 2.102762552861442993e+118, 1.551937536212596136e+120, 1.225676354426075970e+122, 1.036950946169703711e+124, 9.407885268970827717e+125, 9.163369107785093171e+127, 9.592531095671168926e+129, 1.080486293361823875e+132, 1.311034829557782450e+134, 1.715642975932639188e+136, 2.424231742707881878e+138, 3.703231223333127919e+140, 6.123225027409988902e+142, 1.097271040771196765e+145, 2.133693643241295977e+147, 4.508099184895777328e+149, 1.036252806686291189e+152, }, + }; + m_weights = { + { 7.868241604839621507e+00, 8.805163880733011116e+02, 5.396278323520705668e+07, 8.876511896968161317e+19, 2.432791879269225553e+52, 6.399713512080202911e+139, }, + { 2.398524276302635218e+00, 5.244596423726681022e+01, 6.457887819598201760e+04, 2.509985242511374506e+12, 1.774029269327138701e+32, 2.781406115983097314e+85, }, + { 1.749369583108386852e+00, 3.979658981934607813e+00, 1.848514598574449570e+01, 1.864880718932067988e+02, 5.974205695263265855e+03, 1.270412635144623341e+06, 6.164193014295984071e+09, 5.230850031811222530e+15, 2.226260929943369774e+25, 1.199931102042181592e+41, 7.470602144275146214e+66, 1.814465860528410676e+109, }, + { 1.613859062188366173e+00, 1.997767291869673262e+00, 3.020231979908834220e+00, 5.477641843859057761e+00, 1.179660916492671672e+01, 3.035504848518598294e+01, 9.584421793794920860e+01, 3.893870238229992076e+02, 2.179193250357911344e+03, 1.839208123964132852e+04, 2.632120612599856167e+05, 7.427296507169468210e+06, 5.015875648341232356e+08, 1.039610867241544113e+11, 9.100328911818091977e+13, 5.068651163890231571e+17, 3.039966520714902616e+22, 3.857740194672007962e+28, 2.465542763666581087e+36, 2.416439449167799461e+46, 1.517091553926604149e+59, 3.825043412021411380e+75, 4.089582396821598640e+96, 3.823775894295564050e+123, }, + { 1.581465959536694744e+00, 1.669149910438534746e+00, 1.857523188595005770e+00, 2.175662623626994120e+00, 2.675901375211020564e+00, 3.447738682498791744e+00, 4.643946540355464126e+00, 6.530204496574248616e+00, 9.582285015566804961e+00, 1.468361407515440960e+01, 2.354449548740987533e+01, 3.963527273305166705e+01, 7.037635206267538547e+01, 1.325880124784838868e+02, 2.669625649541569172e+02, 5.793749198508472676e+02, 1.368691928321303605e+03, 3.559435721533130554e+03, 1.032186677270763318e+04, 3.386621302858741487e+04, 1.278166259840246830e+05, 5.654082513926693098e+05, 2.994462044781721833e+06, 1.944975023421914947e+07, 1.592193007690560588e+08, 1.694288818617459913e+09, 2.427156182311303271e+10, 4.870317848199455490e+11, 1.431819656229181793e+13, 6.489471523099301256e+14, 4.803757752508989106e+16, 6.200096361305331541e+18, 1.502568562439914899e+21, 7.436061367189688251e+23, 8.264761218677928603e+26, 2.297735027897804345e+30, 1.805449779569534997e+34, 4.604472360199061931e+38, 4.458371212030626854e+43, 1.957638261114809309e+49, 4.767368137162500764e+55, 8.088820139476721285e+62, 1.238260897349286357e+71, 2.292272505278842062e+80, 7.151392373749193549e+90, 5.476714850156044431e+102, 1.576655618370700681e+116, 2.765448595957851958e+131, 5.108051255283132673e+148, }, + { 1.573457773573108386e+00, 1.594892755038663787e+00, 1.638536515530234742e+00, 1.705980408212213620e+00, 1.799724394608737275e+00, 1.923322854425656307e+00, 2.081597373313268178e+00, 2.280934883790070511e+00, 2.529697852387704655e+00, 2.838784782552951185e+00, 3.222395745020980612e+00, 3.699081358854235112e+00, 4.293188274330526800e+00, 5.036865356322330076e+00, 5.972871140910932199e+00, 7.158538424311077564e+00, 8.671427800892076385e+00, 1.061747360297922326e+01, 1.314285002260235600e+01, 1.645145625668428040e+01, 2.083099449998189069e+01, 2.669235989791640190e+01, 3.462993514791378189e+01, 4.551518362653662579e+01, 6.064408087764392116e+01, 8.197296917485846798e+01, 1.125020468081652564e+02, 1.569096552844714123e+02, 2.226204347868638276e+02, 3.216385489504077755e+02, 4.737574505945461739e+02, 7.122994548146997637e+02, 1.094609652686376553e+03, 1.721697789176049576e+03, 2.775924909253835146e+03, 4.595230066268149347e+03, 7.823427586641573672e+03, 1.372357435269105405e+04, 2.485188961645119553e+04, 4.655538745425972783e+04, 9.041766782135686884e+04, 1.824843964862728392e+05, 3.836800264094614027e+05, 8.426271970245168026e+05, 1.938432574158782634e+06, 4.685112849356485528e+06, 1.193528667218607927e+07, 3.215643752247989316e+07, 9.196008928386600386e+07, 2.802223178457559964e+08, 9.136110825267458886e+08, 3.200910900783148591e+09, 1.210765264234723689e+10, 4.969024745093101808e+10, 2.224315751863855216e+11, 1.092125344449313660e+12, 5.916882980019919359e+12, 3.559743438494577249e+13, 2.394353652945465191e+14, 1.813551073517501917e+15, 1.558736706166165738e+16, 1.532714875555114333e+17, 1.739274776190789212e+18, 2.298841216802216313e+19, 3.574030698837762664e+20, 6.604899705451419080e+21, 1.467155879591820659e+23, 3.964094964398509381e+24, 1.319342840595348793e+26, 5.482251971340400742e+27, 2.885137894723827518e+29, 1.952539840765392110e+31, 1.727051489032222797e+33, 2.031343507095439396e+35, 3.236074146972599980e+37, 7.120487412983497200e+39, 2.209552707411017265e+42, 9.886282647791384648e+44, 6.530514048788273529e+47, 6.530706672481546528e+50, 1.015518807431281951e+54, 2.526366773162394510e+57, 1.036450519906790297e+61, 7.241966032627135861e+64, 8.919402520769714938e+68, 2.008463619152992905e+73, 8.596914764830260020e+77, 7.290599546829495220e+82, 1.280199563216419112e+88, 4.878349285603201150e+93, 4.240828248064127940e+99, 8.869771764721598720e+105, 4.723342575741417669e+112, 6.802035963326188581e+119, 2.824531180990009549e+127, 3.621049216745982252e+135, 1.541270150334942520e+144, 2.353376995174362785e+153, }, + { 1.571461316550783294e+00, 1.576790166316938345e+00, 1.587495640370383316e+00, 1.603673956341370210e+00, 1.625471125457493943e+00, 1.653085011915939302e+00, 1.686768142525911236e+00, 1.726831323537516202e+00, 1.773648138667236602e+00, 1.827660421478661448e+00, 1.889384817044018196e+00, 1.959420572855037091e+00, 2.038458728047908923e+00, 2.127292904083847225e+00, 2.226831940199076941e+00, 2.338114664555130296e+00, 2.462327148722991304e+00, 2.600822860927085164e+00, 2.755146214814554359e+00, 2.927060108424483555e+00, 3.118578166240921951e+00, 3.332002540339506630e+00, 3.569968300410740276e+00, 3.835495653996447262e+00, 4.132051496512934885e+00, 4.463622106699067881e+00, 4.834799191008006557e+00, 5.250881957765679608e+00, 5.717998490875333124e+00, 6.243250421598568105e+00, 6.834885801226541839e+00, 7.502506202789340802e+00, 8.257315484493544201e+00, 9.112419405864642634e+00, 1.008318749543997758e+01, 1.118769134993865202e+01, 1.244723705914106881e+01, 1.388701390605507587e+01, 1.553688715915900190e+01, 1.743237000680942831e+01, 1.961581894823993424e+01, 2.213790886354273806e+01, 2.505945934677137610e+01, 2.845370377742137561e+01, 3.240911845969524834e+01, 3.703296289480230161e+01, 4.245572644746267911e+01, 4.883673480337985582e+01, 5.637124640586975420e+01, 6.529947092752610340e+01, 7.591807755694122837e+01, 8.859494252391663822e+01, 1.037881295005788124e+02, 1.220704263969226746e+02, 1.441612098131200535e+02, 1.709680191245773511e+02, 2.036410593843575570e+02, 2.436450058708723643e+02, 2.928540812182076105e+02, 3.536786019152253392e+02, 4.292343083967296939e+02, 5.235701840488733027e+02, 6.419766898003024575e+02, 7.914052083668759283e+02, 9.810422089081931637e+02, 1.223099994999740393e+03, 1.533912555427112127e+03, 1.935464013605830339e+03, 2.457534549912886852e+03, 3.140733731623635519e+03, 4.040818188564651898e+03, 5.234881599712225681e+03, 6.830294457607329226e+03, 8.977713228649887143e+03, 1.189015920967326839e+04, 1.587122387044346962e+04, 2.135711106445789331e+04, 2.897983705189681437e+04, 3.966306726795547950e+04, 5.476875193750000787e+04, 7.632356539388055680e+04, 1.073719149754976951e+05, 1.525316674555574152e+05, 2.188778434744216586e+05, 3.173624496019295608e+05, 4.651201525869328462e+05, 6.892537656280580572e+05, 1.033119885120019982e+06, 1.566887981043252499e+06, 2.405492027026531795e+06, 3.739528964815910340e+06, 5.889121154895580032e+06, 9.399046351922342030e+06, 1.520903276129653518e+07, 2.496287187293576168e+07, 4.157759259963074840e+07, 7.030705366950267312e+07, 1.207598558452493366e+08, 2.107882509464846833e+08, 3.741047199023457864e+08, 6.754494594987415572e+08, 1.241316740415880537e+09, 2.323310032649552862e+09, 4.431176019026625759e+09, 8.617446487400900130e+09, 1.709836906604031513e+10, 3.463574521880171339e+10, 7.167607123799270726e+10, 1.516347620910054079e+11, 3.281729323238950526e+11, 7.271102600298280790e+11, 1.650499552378780378e+12, 3.841338149508803917e+12, 9.173744267785176575e+12, 2.249901946357519979e+13, 5.671535089900611731e+13, 1.470742250307697019e+14, 3.927012518464311775e+14, 1.080639977391212820e+15, 3.067671466720475189e+15, 8.992386789198328428e+15, 2.724722536524592111e+16, 8.542946122263389258e+16, 2.774613718725574755e+17, 9.345299479382029121e+17, 3.267996122987731882e+18, 1.187914433455468315e+19, 4.494053408418564214e+19, 1.771706652195486743e+20, 7.288102552885931527e+20, 3.132512430816625349e+21, 1.408743767951073110e+22, 6.638294268236060414e+22, 3.282543608403565013e+23, 1.705920098038394064e+24, 9.332259385148524285e+24, 5.382727175874888312e+25, 3.278954235122093249e+26, 2.113191697957458099e+27, 1.443411041499643040e+28, 1.046864394654982423e+29, 8.077319226958905700e+29, 6.643146963432616277e+30, 5.835670121359986260e+31, 5.486890296790230798e+32, 5.533726968508261614e+33, 5.999734996418352834e+34, 7.009176119466122569e+35, 8.844061966424597499e+36, 1.208226860869605961e+38, 1.791648514311063338e+39, 2.891313916713205762e+40, 5.091457860211527298e+41, 9.810630588402496553e+42, 2.074441239147378860e+44, 4.827650116937700540e+45, 1.240287939111549029e+47, 3.528782858644784616e+48, 1.115449490471696659e+50, 3.930510643328196314e+51, 1.549243712957852337e+53, 6.854998238041301002e+54, 3.417479961583207704e+56, 1.926905498641079990e+58, 1.233580963004919450e+60, 9.002819902898076915e+61, 7.521415141253441645e+63, 7.224277554900578993e+65, 8.012832830535078610e+67, 1.030999620286380369e+70, 1.546174957076748679e+72, 2.715803772613248694e+74, 5.615089920571746438e+76, 1.373667859345343337e+79, 3.997541020769625126e+81, 1.391500589339800087e+84, 5.826693844912022892e+86, 2.952274820929549096e+89, 1.821023061478466282e+92, 1.375973022137941526e+95, 1.281852367543412945e+98, 1.482130127201990503e+101, 2.141574273792435314e+104, 3.894495540947112380e+107, 8.978646362580102961e+110, 2.644131589807244050e+114, 1.002403539841913834e+118, 4.931412804903905259e+121, 3.174401112435865044e+125, 2.696624001761892390e+129, 3.049799322320447166e+133, 4.634041526818687785e+137, 9.548983134803106512e+141, 2.694404866192089829e+146, 1.051502720036395325e+151, 5.734170640626244955e+155, }, + { 1.570962550997832611e+00, 1.572292902367211961e+00, 1.574956581912666755e+00, 1.578959553636163985e+00, 1.584310789563614305e+00, 1.591022301117035107e+00, 1.599109181186160337e+00, 1.608589657109067468e+00, 1.619485154826419743e+00, 1.631820374530739318e+00, 1.645623378191125679e+00, 1.660925689395424109e+00, 1.677762406016463717e+00, 1.696172326277082973e+00, 1.716198088860732467e+00, 1.737886327791014562e+00, 1.761287842885152410e+00, 1.786457786673686420e+00, 1.813455868772335587e+00, 1.842346578792652542e+00, 1.873199428986627521e+00, 1.906089217937612619e+00, 1.941096316736779451e+00, 1.978306979221816566e+00, 2.017813678003844337e+00, 2.059715468170813895e+00, 2.104118380732327493e+00, 2.151135848063375554e+00, 2.200889163814591418e+00, 2.253507979986114202e+00, 2.309130844113053375e+00, 2.367905779785113334e+00, 2.429990914023652954e+00, 2.495555155369085590e+00, 2.564778926893134514e+00, 2.637854958747451684e+00, 2.714989145296268067e+00, 2.796401472360280536e+00, 2.882327020626578700e+00, 2.973017051860293803e+00, 3.068740185193628238e+00, 3.169783671473487386e+00, 3.276454774427328601e+00, 3.389082268266156098e+00, 3.508018062292869136e+00, 3.633638964133530274e+00, 3.766348594369884204e+00, 3.906579466636309289e+00, 4.054795248667541120e+00, 4.211493221360917802e+00, 4.377206954666462219e+00, 4.552509221059946388e+00, 4.738015169510782826e+00, 4.934385785253587887e+00, 5.142331663338191074e+00, 5.362617126899976224e+00, 5.596064724397100194e+00, 5.843560143744373307e+00, 6.106057585381734693e+00, 6.384585640900671436e+00, 6.680253728973824449e+00, 6.994259146058412709e+00, 7.327894795748901060e+00, 7.682557667824588764e+00, 8.059758146071137270e+00, 8.461130232962342889e+00, 8.888442789395671080e+00, 9.343611899025485155e+00, 9.828714479494622022e+00, 1.034600327721380625e+01, 1.089792339849122916e+01, 1.148713054801325790e+01, 1.211651116619788555e+01, 1.278920468010096321e+01, 1.350862810871281096e+01, 1.427850329305334421e+01, 1.510288705493181327e+01, 1.598620462612703196e+01, 1.693328673269081128e+01, 1.794941076780000506e+01, 1.904034654190823159e+01, 2.021240716182964334e+01, 2.147250566192247370e+01, 2.282821809199713505e+01, 2.428785385941680425e+01, 2.586053422878117785e+01, 2.755628000354674426e+01, 2.938610955221109564e+01, 3.136214849990951329e+01, 3.349775258749912582e+01, 3.580764540799625468e+01, 3.830807296872530167e+01, 4.101697730155473447e+01, 4.395419165876113623e+01, 4.714166019494196927e+01, 5.060368545366659226e+01, 5.436720746019445252e+01, 5.846211877912138439e+01, 6.292162054058128784e+01, 6.778262518512416663e+01, 7.308621254265223015e+01, 7.887814686488147292e+01, 8.520946359734658334e+01, 9.213713603387774717e+01, 9.972483357670754649e+01, 1.080437851679046426e+02, 1.171737636088621692e+02, 1.272042089988687372e+02, 1.382355124664102373e+02, 1.503804848151483311e+02, 1.637660387526102742e+02, 1.785351181233383403e+02, 1.948489131607280604e+02, 2.128894073598352670e+02, 2.328623093447990790e+02, 2.550004322843281994e+02, 2.795675942672445782e+02, 3.068631259124280934e+02, 3.372270867451200874e+02, 3.710463099965576255e+02, 4.087614170466174911e+02, 4.508749684194593670e+02, 4.979609488959773491e+02, 5.506758209385785877e+02, 6.097714244663179092e+02, 6.761100535726473685e+02, 7.506821038741422446e+02, 8.346267600518081192e+02, 9.292562845315541998e+02, 1.036084578498234728e+03, 1.156860819661897657e+03, 1.293609142453808600e+03, 1.448675521854205144e+03, 1.624783259532197615e+03, 1.825098759915318560e+03, 2.053309635972617554e+03, 2.313717614494777200e+03, 2.611349236640186999e+03, 2.952087994093624299e+03, 3.342832332560548180e+03, 3.791684927756595099e+03, 4.308179838716318955e+03, 4.903555624570201673e+03, 5.591084343634811452e+03, 6.386468625571246341e+03, 7.308321829412979440e+03, 8.378749812799703561e+03, 9.624057218749638059e+03, 1.107560666191146008e+04, 1.277086605445904388e+04, 1.475468792019489452e+04, 1.708087537417066343e+04, 1.981410309695485051e+04, 2.303227888204754908e+04, 2.682945317928632535e+04, 3.131941178398428200e+04, 3.664012209706997997e+04, 4.295924836668690170e+04, 5.048100882639843572e+04, 5.945472133180055290e+04, 7.018547875172689579e+04, 8.304751726175694003e+04, 9.850099805053575446e+04, 1.171131266261766060e+05, 1.395847982160589845e+05, 1.667843016393077556e+05, 1.997900626520524686e+05, 2.399449946032992187e+05, 2.889257939838013232e+05, 3.488315309194304548e+05, 4.222972201496778447e+05, 5.126398246369253619e+05, 6.240464876221989792e+05, 7.618179073233615941e+05, 9.326839300224119257e+05, 1.145214007774297539e+06, 1.410352646274233119e+06, 1.742120041875863385e+06, 2.158531716934287014e+06, 2.682809410126426731e+06, 3.344980563595418861e+06, 4.183997972337706048e+06, 5.250558008165501752e+06, 6.610860174141680988e+06, 8.351639423967558693e+06, 1.058692532393929900e+07, 1.346715235106239409e+07, 1.719148271024263021e+07, 2.202453449027701694e+07, 2.831917301724337797e+07, 3.654767820268344932e+07, 4.734452657230626106e+07, 6.156534063509513873e+07, 8.036843026897869248e+07, 1.053280284359690289e+08, 1.385921689084126286e+08, 1.831036985925683524e+08, 2.429109457458640820e+08, 3.236062393759667463e+08, 4.329475218599986663e+08, 5.817432967962929479e+08, 7.851179789388191786e+08, 1.064329197627075307e+09, 1.449389582912945485e+09, 1.982866469377991849e+09, 2.725414314698094324e+09, 3.763867964111621444e+09, 5.223138814950990937e+09, 7.283785810644397704e+09, 1.020809642381158743e+10, 1.437899318470510521e+10, 2.035836812543633578e+10, 2.897499827080027444e+10, 4.145773751645494878e+10, 5.963837683872426287e+10, 8.626228483915530800e+10, 1.254667045389825180e+11, 1.835212982264913186e+11, 2.699812207400151604e+11, 3.994928452151922954e+11, 5.946380558701434550e+11, 8.904409967424091107e+11, 1.341551941677775838e+12, 2.033768550332151892e+12, 3.102627959875753214e+12, 4.763598321705862063e+12, 7.361420360560813584e+12, 1.145126961456557423e+13, 1.793314186996273926e+13, 2.827585501285792232e+13, 4.489297053678444669e+13, 7.177802872658499571e+13, 1.155855098545820625e+14, 1.874833886367883093e+14, 3.063510356402174454e+14, 5.043400653005970242e+14, 8.366163396892429890e+14, 1.398556351640947289e+15, 2.356335749516164682e+15, 4.001765167382637456e+15, 6.851375128404941445e+15, 1.182690111761543990e+16, 2.058673527013806443e+16, 3.613968784314904633e+16, 6.399112184394213551e+16, 1.143016185628376923e+17, 2.059881383915666443e+17, 3.745846788353680914e+17, 6.874443034683149068e+17, 1.273407643613485314e+18, 2.381241916829895366e+18, 4.495835617307108399e+18, 8.571442024901952701e+18, 1.650443584181656965e+19, 3.210100352421317851e+19, 6.307780124442703091e+19, 1.252404031157661279e+20, 2.513005295649985394e+20, 5.096776255690838436e+20, 1.045019200016673046e+21, 2.166476479260878466e+21, 4.542138145678395463e+21, 9.632082324449137128e+21, 2.066386536688254528e+22, 4.485529785554428251e+22, 9.853879573610977508e+22, 2.191158874464374408e+23, 4.932835964390971668e+23, 1.124501529971774363e+24, 2.596269136156756008e+24, 6.072292938313625501e+24, 1.438989066308003836e+25, 3.455841956406570469e+25, 8.412655191713576490e+25, 2.076289061650816510e+26, 5.196515024640220322e+26, 1.319173194089644043e+27, 3.397455895980380794e+27, 8.879057454438503591e+27, 2.355272361492064126e+28, 6.342762007722624824e+28, 1.734531093990859705e+29, 4.817893170606830871e+29, 1.359597346490148232e+30, 3.898969689906500392e+30, 1.136542986529989936e+31, 3.368450043991780017e+31, 1.015304084709817260e+32, 3.113144376221918237e+32, 9.713072739730140403e+32, 3.084517643581725946e+33, 9.972682139820497284e+33, 3.283625052288491586e+34, 1.101378785390827536e+35, 3.764333367592714297e+35, 1.311403465938242926e+36, 4.658135710682813672e+36, 1.687517347470511392e+37, 6.237053685018323490e+37, 2.352571314427744869e+38, 9.058938240219699936e+38, 3.562249097611136071e+39, 1.430959291578558210e+40, 5.873974584984375049e+40, 2.464828549811283787e+41, 1.057649203090855628e+42, 4.642475639281078035e+42, 2.085287118272421779e+43, 9.588439985186632177e+43, 4.514982011246092280e+44, 2.177974048341973204e+45, 1.076720976822900458e+46, 5.457267432929085589e+46, 2.836869270455781134e+47, 1.513103201392011626e+48, 8.283974667225617075e+48, 4.657239491995971344e+49, 2.689796370712836937e+50, 1.596597846911970388e+51, 9.744154538256586629e+51, 6.117238394843313065e+52, 3.952049650585241827e+53, 2.628701592074258213e+54, 1.800990196502679393e+55, 1.271554462563068383e+56, 9.255880104477760711e+56, 6.949737920133919393e+57, 5.385167200769965621e+58, 4.308493668102978774e+59, 3.560951557542178371e+60, 3.041888528384649992e+61, 2.687094441930837189e+62, 2.455920538900000855e+63, 2.323648254168641537e+64, 2.277129741584892331e+65, 2.312633552913224734e+66, 2.435407592981291129e+67, 2.660910388822465246e+68, 3.018105943423533920e+69, 3.555823489510192503e+70, 4.354188877793849013e+71, 5.544975795511813315e+72, 7.348276481909886336e+73, 1.013998025722423261e+75, 1.457911462244607943e+76, 2.185488876819505295e+77, 3.418022153286623008e+78, 5.580843920601835728e+79, 9.519586502799733908e+80, 1.697573578247197786e+82, 3.166906670990180014e+83, 6.185099106418675430e+84, 1.265541134386934377e+86, 2.714828965877756899e+87, 6.110386802964494082e+88, 1.444054086171083239e+90, 3.586083726638388165e+91, 9.365231868063239600e+92, 2.574080116205122449e+94, 7.452134689862302719e+95, 2.274309903836169819e+97, 7.323011134121164749e+98, 2.489816421737932462e+100, 8.946533386359281588e+101, 3.400401372391165979e+103, 1.368288186208928217e+105, 5.834277489829591931e+106, 2.638486937672383424e+108, 1.266728882767139521e+110, 6.462225178314182803e+111, 3.506432320607573604e+113, 2.025608933943268165e+115, 1.247041677084784707e+117, 8.189865188405279038e+118, 5.743610894406099965e+120, 4.305808934084489763e+122, 3.454156966079496755e+124, 2.968316601530352737e+126, 2.735456242372183592e+128, 2.706317176690077847e+130, 2.877679916342060385e+132, 3.292412878268106390e+134, 4.057840961953725969e+136, 5.393783049105737324e+138, 7.741523901672235406e+140, 1.201209962310668456e+143, 2.017456079556807301e+145, 3.672176623483062526e+147, 7.253163798058577630e+149, 1.556591535302570570e+152, 3.634399832790394885e+154, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 6.114056619798597593; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +#if LDBL_MAX_EXP == 16384 +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828741797632286606397498241221385e+00L, 1.48993184649209158013612709175719825e+02L, 3.41228924788343710247727162226946917e+06L, 2.06932576604261779073902718911207249e+18L, 2.08700240760947556038306635808129743e+50L, 2.01976616071790815078008252209994199e+137L, 5.67213444764437168603513205349222232e+373L, 3.06198394306784061113736467298565948e+1016L, }, + { 9.13048762637669674838078869945948356e-01L, 1.41578929466281159169215570833490092e+01L, 6.70421551622327648231120321610008518e+03L, 9.64172532715049941526010563818587232e+10L, 2.50895076008577848514087028569888161e+30L, 1.44726353571033714499079379626715686e+83L, 3.75263401205045334128277886549019357e+226L, 2.57846123932685341261715758547064293e+616L, 1.25169402230987931584130068460134989e+1676L, }, + { 4.07297690065758690150573950473604675e-01L, 1.68206670702114874332932330092838356e+00L, 6.15089798638672951539668935798437533e+00L, 4.00396235192940022205839866641270319e+01L, 7.92920024793102632052902471550336177e+02L, 1.02984971333097958319686053784919407e+05L, 3.03862310925243857437932941891415841e+08L, 1.56544547436249486913719231527597560e+14L, 4.04246509843021910355659662715183671e+23L, 1.32170682742965817915034577861235933e+39L, 4.99123178209955799774620736137366103e+64L, 7.35294385035987596594501676609562008e+106L, 2.45145417229813114714431821340237112e+176L, 1.03030479197459267961759023741376327e+291L, 9.88478945193556730604342445576518136e+479L, 3.74498116076433060427765453233124618e+791L, 1.90292390713026708045766158039087796e+1305L, 1.72712488231809244721915842027236657e+2152L, }, + { 1.98135272251478172615235718398538323e-01L, 6.40155673500526017670785720911319502e-01L, 1.24892869825397766254802900819319987e+00L, 2.26608084094432123181038001270985037e+00L, 4.29646269670232738148137717958679987e+00L, 9.13029038709995569641811827045549232e+00L, 2.31110765386427993316995139635470937e+01L, 7.42770603432401243012214481410240677e+01L, 3.26720920711525891697790966796945063e+02L, 2.15948569431181871552028449867301828e+03L, 2.41501526289641306037808670196966696e+04L, 5.31819400275692915826269282626844010e+05L, 2.80058685721704332307817790755562305e+07L, 4.52406507979433877971977526863358905e+09L, 3.08561257398067712180174566763237112e+12L, 1.33882673301580747789133427708622972e+16L, 6.25461717656234138147247754416652254e+20L, 6.18209853581416475394863999233554548e+26L, 3.07729364978845806686511011060697837e+34L, 2.34895728937010430290698332595743680e+44L, 1.14854319789946975790127332653552673e+57L, 2.25530007001006986846545694404767295e+73L, 1.87791950056919539419801461538703336e+94L, 1.36747388793862427976781689638282239e+121L, 4.24212177246407592514720294750151286e+155L, 8.23473099012134325391170623028607158e+199L, 6.06134211888406631001019923425936351e+256L, 6.32519197436029413652766295658658263e+329L, 3.61942292928205643948383705201563065e+423L, 8.82464433126646489632943769283758364e+543L, 3.35512488018651738642854323317447493e+698L, 1.02411434678684822400261582079656500e+897L, 7.40716670979374017620610271197945784e+1151L, 1.30455147283895162835186634827124464e+1479L, 2.02948723345659016173510134582487641e+1899L, 6.99019443250345564805134094483457477e+2438L, }, + { 9.83967894006732033862249554537934739e-02L, 3.00605617659955035122465185012715805e-01L, 5.19857978994938490000644785900799951e-01L, 7.70362083298887700858583505753306721e-01L, 1.07131136964131183026831222500748063e+00L, 1.45056975808899844502126797109703210e+00L, 1.95077854952036033400296546339240312e+00L, 2.64003177369555146770080103921424631e+00L, 3.63137237366741227331951933364601985e+00L, 5.11991533090335057003526222543242753e+00L, 7.45666098140488328926087222725984231e+00L, 1.13022612688997262443461342203136009e+01L, 1.79641069247277254966592982669611020e+01L, 3.01781070460189822236726995418068214e+01L, 5.40387580031237056709826662540066860e+01L, 1.04107731447746954767459980678311109e+02L, 2.18029520120262807725988909352359830e+02L, 5.02155698625910164594509258651311707e+02L, 1.28862131099822242045586488612672886e+03L, 3.73921687080054832376623401153054636e+03L, 1.24750729702019123239464970064060864e+04L, 4.87639975322669212414357357061002683e+04L, 2.28145658221913012154676335814417144e+05L, 1.30877796006484301664040981436471740e+06L, 9.46084663420966407698078336053299177e+06L, 8.88883120363727962245667776649286152e+07L, 1.12416882897434413447175648471746990e+09L, 1.99127672953214446985509145592687205e+10L, 5.16743469106098464964433058111638245e+11L, 2.06721881420399088776240044545119948e+13L, 1.35061503318410040604770421574064883e+15L, 1.53854066283650818848773859278941683e+17L, 3.29074729054035066052820102585085173e+19L, 1.43729138188449881561963100200796631e+22L, 1.40983244553034728562740932242727657e+25L, 3.45913548027797144127990544649862792e+28L, 2.39872058234095409213724024023509754e+32L, 5.39880660461729295997086364918754801e+36L, 4.61334000258062860955942270137550165e+41L, 1.78768590966790245678294238939560892e+47L, 3.84198437012433853552557148945213178e+53L, 5.75279795570858370009870455748773410e+60L, 7.77181203842728655149182334288749850e+68L, 1.26967304420408162635234502672130357e+78L, 3.49567677376573156773252547632961336e+88L, 2.36251947497169244454694635287097330e+100L, 6.00214389327365112307366927985587840e+113L, 9.29071630346415553922675334522602561e+128L, 1.51444223803384709004933819608345315e+146L, 4.83290204410990250226310317342789471e+165L, 6.09623012864338569215560315517200736e+187L, 6.73889214277659359787962707085479315e+212L, 1.60917893672694484647176104023542732e+241L, 2.30724123468764987944582372785293125e+273L, 6.32636439816284705814531208407868829e+309L, 1.23274815890184688792156489065830724e+351L, 7.55519778823055185901318833981345378e+397L, 7.85730655106759111844772008129590573e+450L, 9.36328400229780321059086898529742817e+510L, 1.11332545426270395766246494603539938e+579L, 1.53432069979625061288117473415446630e+656L, 3.94622553764411915381186808199466267e+743L, 4.41554290953392996069257034424439949e+842L, 7.62037777854651720247173134262034607e+954L, 1.15650294539918196985498353779647134e+1082L, 1.50761161209705395018419027031866347e+1226L, 3.03485088181756935935831645680716816e+1389L, 3.38561189018537177501905611143498298e+1574L, 1.64407968993192526511230001818530622e+1784L, 6.63148743223242467667800355907041029e+2021L, 1.15911606715877477373516464924821476e+2291L, }, + { 4.91151003502902493004859475143401791e-02L, 1.48013149674360733270682895306542340e-01L, 2.48938813740683685679302156785267041e-01L, 3.53325423692668437764413545980527251e-01L, 4.62733556612235325924240102411897269e-01L, 5.78912068164096306746325958452873475e-01L, 7.03870253386062779930091622585657886e-01L, 8.39965859144650568772715366992985538e-01L, 9.90015066424437614655918533324528544e-01L, 1.15743257014369913143250540144278056e+00L, 1.34641275918536176274682426896283388e+00L, 1.56216711390133555099139972670978661e+00L, 1.81123885278232337973709010374295886e+00L, 2.10192441900655030086142289233010995e+00L, 2.44484388558419793403331221069953203e+00L, 2.85372074663291502355627105440782037e+00L, 3.34645891095535078662878051589922609e+00L, 3.94664582105783838715586741669722603e+00L, 4.68567310159667852940801410152900804e+00L, 5.60576223090815117543658276010994803e+00L, 6.76433233683057420359243855855175747e+00L, 8.24038317537998522052755780107530197e+00L, 1.01439435612985772971719760903679427e+01L, 1.26302471433889247197016543768391586e+01L, 1.59213039578034525767683420917805218e+01L, 2.03392186192185718515730871595417962e+01L, 2.63584644576063375239063530328964372e+01L, 3.46892633322415240903243772580777748e+01L, 4.64129146701972896279022543245987086e+01L, 6.32055079389042420324823016892494512e+01L, 8.77149726180890637368701810147417239e+01L, 1.24209692624041149789460094889690346e+02L, 1.79718634784512755704082576283626343e+02L, 2.66081728332790018970422286819998479e+02L, 4.03727302957571284052623415274320934e+02L, 6.28811306654590870314912279241546792e+02L, 1.00707983750749059403228978538051896e+03L, 1.66156822918511428805794334715835287e+03L, 2.82965144078658259775800007408843245e+03L, 4.98438626658566913853681230634186899e+03L, 9.10154692764781089316711776560031531e+03L, 1.72689265547504972749956316341831556e+04L, 3.41309957877860119013952370617496464e+04L, 7.04566897705309280220071327032864763e+04L, 1.52340421776127912819322591860346971e+05L, 3.46047978289794741370038030428999755e+05L, 8.28472420923318300234685980449600520e+05L, 2.09759614660119394556971994518988102e+06L, 5.63695079886127323617800640982012165e+06L, 1.61407141085560724511058572293479599e+07L, 4.94473067891506035994359725043521250e+07L, 1.62781051682099135552732962095205423e+08L, 5.78533297163228083837980097936281368e+08L, 2.23083854068195568971189557384768608e+09L, 9.38239130606473964277252886929412279e+09L, 4.32814954477655169232818147143370442e+10L, 2.20307274404924290439096300978395664e+11L, 1.24524506710913641251205336694034299e+12L, 7.86900053495782237478847410099854059e+12L, 5.59953143297942246131549106648666176e+13L, 4.52148694990209087674492643778610401e+14L, 4.17688951654829326508268412199901397e+15L, 4.45286775965049665585698503105745526e+16L, 5.52914285314049806809138826588984682e+17L, 8.07573251656285427526228838811700627e+18L, 1.40204691626046869792238856080062664e+20L, 2.92579141283223985009947325351094360e+21L, 7.42643302933541088612408356755400686e+22L, 2.32199633124573536432554419147246735e+24L, 9.06419425063844243203436385576505269e+25L, 4.48127904881944560890552322697008678e+27L, 2.84904630472699064463968599282594753e+29L, 2.36738115918335597454764956918757980e+31L, 2.61582557845512122680388807973635504e+33L, 3.91476494826329080795479762913295296e+35L, 8.09204244855592921872201325412806040e+37L, 2.35892132094063033238721339006551614e+40L, 9.91521864853533259120934844876236731e+42L, 6.15285105934265876352030730244956160e+45L, 5.78027634014451538840307809528507880e+48L, 8.44375173418648862568787172019022001e+51L, 1.97334335089976670761175825761931164e+55L, 7.60524737855621997973474323106432459e+58L, 4.99205710493951041807363394610235299e+62L, 5.77586342390391231642398949899839793e+66L, 1.22180820194535560304052518248291191e+71L, 4.91291723038713381630505551954597084e+75L, 3.91397181373220237220120723831917341e+80L, 6.45638806990528678730571952330861768e+85L, 2.31122506852801035759561549878351498e+91L, 1.88745815771943133919251977215527414e+97L, 3.70848316543845309405007424631179900e+103L, 1.85519881228353863491690263658048910e+110L, 2.50978787317170531780713813087390423e+117L, 9.79042375559121661656574862110333881e+124L, 1.17908880794405074709159757136517906e+133L, 4.71463184672247661988055185868884361e+141L, 6.76265778595971324046101731037889126e+150L, 3.77863792934416463055998231270977695e+160L, 8.97819133628477274891556066769979914e+170L, 9.95914407403494739885505580434362313e+181L, 5.69630798679205432723450802096176313e+193L, 1.86743452325707784871951519925288377e+206L, 3.92719945859412568046939678789391943e+219L, 5.97262802266570558434581771213406728e+233L, 7.46293577265068378653739984957785219e+248L, 8.77620026161886682323882402399676732e+264L, 1.12240955327637524990782988952974327e+282L, 1.82091452946462555573948654780251641e+300L, 4.41446070956615785669448222555093749e+319L, 1.90397541953366074155779318767572880e+340L, 1.75902281129585020130874703618203168e+362L, 4.24169226543235148528312412985493520e+385L, 3.29481560149200680874049429678412127e+410L, 1.03135148368973063748422508803572335e+437L, 1.65119340908368036904973428016231291e+465L, 1.74266589416784110509614783944413581e+495L, 1.58844581452329281145953920728196433e+527L, 1.66707913260906132496128590135534752e+561L, 2.73591938942385354685476950777714705e+597L, 9.72579530056263762611950442873242859e+635L, 1.05939976357545005153997575210948938e+677L, 5.11518133258374954640812727174811520e+720L, 1.62189977683387633564608415164137138e+767L, 5.13160378352024380054652132361473058e+816L, 2.52913238575275285564889845966314333e+869L, 3.11944472707029467274111976509771118e+925L, 1.59495166899855372832309254674677663e+985L, 5.78489108811836645985010918537259212e+1048L, 2.63682062563962607583302320466728244e+1116L, 2.77639914729635446526568065100606294e+1188L, 1.29100591117079370649785145859270604e+1265L, 5.28444381883484729377275155781628201e+1346L, 3.96822241951490935324304074734991606e+1433L, 1.19450143809568524145027520220707370e+1526L, 3.31232848440880307300003548888720354e+1624L, 2.05165402811808892980123939590704909e+1729L, 7.28745294435475474950235921073537827e+1840L, 4.04980582052614743975213722266303496e+1959L, 1.02489069982330185861864247663932840e+2086L, 3.68323339665104313610706754895420191e+2220L, 6.30765607309438726154024457882187086e+2363L, }, + { 2.45471558362986365068916495863375252e-02L, 7.37246687390334622422734853496288652e-02L, 1.23152530941676654318795303724845312e-01L, 1.73000137771924855589325108501317324e-01L, 2.23440664959686000105440799041805360e-01L, 2.74652654971851825832501290298110601e-01L, 3.26821679298064666878532098621581949e-01L, 3.80142100980478924532143540106066542e-01L, 4.34818963721561494844111167726460593e-01L, 4.91070036509942840677161193401564426e-01L, 5.49128045948021544092182270959032951e-01L, 6.09243132438265439671151238479162657e-01L, 6.71685571202114806905814141850507988e-01L, 7.36748804906793864301473114817726587e-01L, 8.04752841633695064447122683633828025e-01L, 8.76048080248205070538153903222362252e-01L, 9.51019635182333225305914695670696308e-01L, 1.03009224453247006650365629888427541e+00L, 1.11373585958868076495962122155474153e+00L, 1.20247203091805887562283157205483916e+00L, 1.29688122649686375081031224280895230e+00L, 1.39761124182837302592381732283067440e+00L, 1.50538689136054520464181654424860094e+00L, 1.62102120589479802996006107398491112e+00L, 1.74542840336904457155639617870301735e+00L, 1.87963895203102933109827214352261973e+00L, 2.02481710760932852386806039721112499e+00L, 2.18228138214788418140109912591097815e+00L, 2.35352849482388135462737441996874099e+00L, 2.54026146822962645747200253699005204e+00L, 2.74442267217147811137997080576917741e+00L, 2.96823278719060661900608946565759698e+00L, 3.21423686952065766588900110700898117e+00L, 3.48535895790773046725176601804623352e+00L, 3.78496698311737282096444166343378976e+00L, 4.11695013894029509955211911245969952e+00L, 4.48581136938823171042685637747918431e+00L, 4.89677824656200181220988391922608405e+00L, 5.35593629082672594809503436864536474e+00L, 5.87038976260095690701450882557564694e+00L, 6.44845618913111760490837120481487939e+00L, 7.09990245267955823638498704195342171e+00L, 7.83623225328284126133289428371735767e+00L, 8.67103729357523063452024155765264339e+00L, 9.62042777798599036292354986394365067e+00L, 1.07035619887679953097266587864897721e+01L, 1.19433000813944102150187593166292839e+01L, 1.33670142103849964717469335941905385e+01L, 1.50075961591439634296262105146352627e+01L, 1.69047154820352837629069726738079470e+01L, 1.91063966873168959742774555727687289e+01L, 2.16710044321657799400571191555580338e+01L, 2.46697527469509919694460528848277171e+01L, 2.81898902515784535507915179415086299e+01L, 3.23387613242940174515264777910328241e+01L, 3.72490075809724574016769417176033924e+01L, 4.30852608490774199699508301986096898e+01L, 5.00527964765470397507453905247128474e+01L, 5.84087760725387652778097774354827947e+01L, 6.84769282153423986221602875181609661e+01L, 8.06668177706071484780398912645020900e+01L, 9.54992727020024926023862465179431320e+01L, 1.13640119576948788485338465195796676e+02L, 1.35945194497660320895127779474436433e+02L, 1.63520745187974444650772294136165162e+02L, 1.97804968791258694996900535479466855e+02L, 2.40678753588977666070114453459006852e+02L, 2.94617029293055502283701272741864024e+02L, 3.62896953214712533295812475420140158e+02L, 4.49886178271559690246754005443952599e+02L, 5.61444735313349610605402755114132063e+02L, 7.05489247089927142932822047183046835e+02L, 8.92790773279996411641203534672635638e+02L, 1.13811142497947837649816383892464930e+03L, 1.46183599156360536709532001371341489e+03L, 1.89233262344471618571971876282268943e+03L, 2.46939603618613347923158360306283371e+03L, 3.24931156929882473061795067124714454e+03L, 4.31236711317028301201344127304044700e+03L, 5.77409475450013966113987691727433327e+03L, 7.80224723750085184509285318864950930e+03L, 1.06426753097580697178856711472253120e+04L, 1.46591538353567498972551254799117195e+04L, 2.03952854123975483493635354197048606e+04L, 2.86717062242155626463726121489695136e+04L, 4.07403376218345329677215262695648133e+04L, 5.85318231059692339303875522971681880e+04L, 8.50568926526520663990658694675860445e+04L, 1.25064926984785661460287048343378461e+05L, 1.86137394316674976633487938076388915e+05L, 2.80525577745201092730917964861422661e+05L, 4.28278248608476174804382253986989659e+05L, 6.62634050612765730354133581004327179e+05L, 1.03944323965033956450234998906270616e+06L, 1.65385742611296131560210844780522467e+06L, 2.67031565012527916099202454680251592e+06L, 4.37721202662435879490158484533403820e+06L, 7.28807171369841382127860775464397414e+06L, 1.23317299340033169377433189565436518e+07L, 2.12155728576993369873860452866846505e+07L, 3.71308625486153538260132253550700609e+07L, 6.61457937735213553402161639469475625e+07L, 1.20005529169491711045823979192639236e+08L, 2.21862941029688069011551388945586459e+08L, 4.18228293992868770261761230703186170e+08L, 8.04370413249371480388874614907492609e+08L, 1.57939298942566811374336496311019268e+09L, 3.16812241552410463468859624242708347e+09L, 6.49660681154986132317647460889788282e+09L, 1.36285198835644448552647856869429224e+10L, 2.92686389700870770766115985553270450e+10L, 6.43979866520949373493178830943697748e+10L, 1.45275523377290302218030864454825923e+11L, 3.36285445938924657613055409970261746e+11L, 7.99420278543347927144872935893265787e+11L, 1.95326423336229196043471517599153542e+12L, 4.90958186824255456862636657247754379e+12L, 1.27062273076501561032764305894113023e+13L, 3.38907098674298576400746683674724217e+13L, 9.32508403020884483292253012776198040e+13L, 2.64948942383453414004877623922649545e+14L, 7.78129518409495719454885394657867226e+14L, 2.36471505252735563941195059995826485e+15L, 7.44413803146595825477962585154187758e+15L, 2.43021724068474963516185214140527324e+16L, 8.23706864153435776160816132466078110e+16L, 2.90211705066454883998576313308511774e+17L, 1.06415767940403701307268606275625099e+18L, 4.06627710606196001743762877107146413e+18L, 1.62127423363035909653152786372227505e+19L, 6.75415683091545001302004267324917730e+19L, 2.94405684173378191865875139697985419e+20L, 1.34464013954910781728162580030274237e+21L, 6.44458615894472329986968048792306357e+21L, 3.24621866755460893428420802873638947e+22L, 1.72123457955665353317614924039447693e+23L, 9.62253389024047439092145016046085843e+23L, 5.68140726041795667144549981860838281e+24L, 3.54889077999592818369666361009585253e+25L, 2.34950642567226956175428754094351900e+26L, 1.65161813060520564300895544060422208e+27L, 1.23514742649311305869239755896991097e+28L, 9.84594723979205755046350596451684287e+28L, 8.38313078198461041780434493882428621e+29L, 7.63964946139917244491542497186650823e+30L, 7.46786273223388520123213229503835823e+31L, 7.84769148200499366026301301860529069e+32L, 8.88603255762645470434690507794367917e+33L, 1.08673489067830243582954987160820285e+35L, 1.43896777703653845844251806933839180e+36L, 2.06816886547560352123602144529722761e+37L, 3.23488532022391238528760911223890778e+38L, 5.52123364154262851432456431974095092e+39L, 1.03114823119466385539623421556538031e+41L, 2.11327203581636598172202380321061095e+42L, 4.76672434548507751952154119062281282e+43L, 1.18696155099021828703717401094811909e+45L, 3.27317216920584757332668902845797411e+46L, 1.00282122676916775281745610945056481e+48L, 3.42493390393515647893744567642140320e+49L, 1.30843601702642873582064430681159468e+51L, 5.61137833004842050312648039721074217e+52L, 2.71142480632713929135631433480050921e+54L, 1.48177179364406644198189668782951739e+56L, 9.19428207104277880378138495715383545e+57L, 6.50366145587535556181715778862405651e+59L, 5.26632998686862730262822409628217101e+61L, 4.90266280796934735938520451826335739e+63L, 5.27051105728955705039001489033126495e+65L, 6.57285651167058331634360929791632134e+67L, 9.55395603001322538662375429270666445e+69L, 1.62649191115941161585027771743899152e+72L, 3.25941091550095122341298778408441950e+74L, 7.72846031811361427986096662411063427e+76L, 2.17988199690591805869859473392710071e+79L, 7.35448438837150591476717971591286847e+81L, 2.98483127080395774595532033544389202e+84L, 1.46582826781343896171132281512590065e+87L, 8.76335597262986426104836504228132778e+89L, 6.41790966584783113047113716478179340e+92L, 5.79495864922989350993450871503126827e+95L, 6.49422447231190836548908540847688948e+98L, 9.09500015601643369774077853623649258e+101L, 1.60305849845529910220272077472033035e+105L, 3.58209911911932052869313856359636456e+108L, 1.02244122713985468653173668554645414e+112L, 3.75687218501508605716480350749498176e+115L, 1.79136346383284915921138840751400855e+119L, 1.11764188203947212384081419514165395e+123L, 9.20215956554652828530686799399533824e+126L, 1.00871647482788856814534779759128531e+131L, 1.48554648708930180487801088228218062e+135L, 2.96696153483056609742176098165601109e+139L, 8.11420728466436936033056414100674073e+143L, 3.06917808750766973862958599324080278e+148L, 1.62222368114779147260405024572949430e+153L, 1.21094608845400598319807865894230970e+158L, 1.29069460371207764384235331328282226e+163L, 1.98663030134211110165437011771903132e+168L, 4.46757261704134429970068624260491498e+173L, 1.48564187771108280640829188970287255e+179L, 7.39669065831627851911038512117013389e+184L, 5.58477447271859974925476129175614574e+190L, 6.47976647473179732779115257999520915e+196L, 1.17117420317317171387535528766936277e+203L, 3.34428267755162742939489398076764840e+209L, 1.53076558056194845489001829008909627e+216L, 1.14010185551912954998170816176845430e+223L, 1.40319939603195121408389523582430293e+230L, 2.89974936197123389451668716314083017e+237L, 1.02284833216532051937856086912560392e+245L, 6.26387216223145817942640023700922965e+252L, 6.77735971213475345230129326178116125e+260L, 1.31920032114466459135766725110063188e+269L, 4.70640341492973980389482209817290571e+277L, 3.13724441498341266441161693520329378e+286L, 3.98571382107801782113811082484615717e+295L, 9.85039693194582447444400924997258508e+304L, 4.83687381317675554709367324551273400e+314L, 4.82285202614019890234802453942628315e+324L, 9.98703239968301934722476402798215616e+334L, 4.39579560388542750852159646726102667e+345L, 4.21213245293498773753031381258995955e+356L, 9.00647826017501992250418906434620537e+367L, 4.40820570973056960340923739077146754e+379L, 5.07036496321109968512657627671150030e+391L, 1.40820593625978850981984707085120209e+404L, 9.71170922560303314648712317222502389e+416L, 1.71185299004740150846260848238269630e+430L, 7.94539187117702846067322763172557224e+443L, 1.00135866851780201306228838620557915e+458L, 3.53720801942577272956188201390769482e+472L, 3.61856514873836509067172206947444182e+487L, 1.10885899005952624619970603738429749e+503L, 1.05391354932473165812334641476989979e+519L, 3.22052822779158301893419142803165095e+535L, 3.28354332174247719776999412908271692e+552L, 1.16054782509911106933820737153108500e+570L, 1.47919833966504706156198174688381009e+588L, 7.08133783868969672071172398101964598e+606L, 1.32792489232842472677863721400834701e+626L, 1.01864740027867286775312222487805144e+646L, 3.34261841519397423195159276540555265e+666L, 4.91359232957804830460198547632977969e+687L, 3.39338961080932963058551495328009206e+709L, 1.15643101006244038688616288204262882e+732L, 2.04580060100421448267115092746141073e+755L, 1.97956226677236405650286559215774642e+779L, 1.10576482674657666978217926798043956e+804L, 3.76975534316002585938373910751464161e+829L, 8.30723712530280347580443574905340732e+855L, 1.25551214072288994426628885709173410e+883L, 1.38340901524945057559377504414014724e+911L, 1.18367583857036159478030255830898223e+940L, 8.39312984240762796712708279978405886e+969L, 5.27445408794117779852142535860614541e+1000L, 3.14827291975085189890248083313318702e+1032L, 1.91708860929520191993037622102307238e+1065L, 1.28205230070904948620917170049585485e+1099L, 1.01601053886738575799673411634857928e+1134L, 1.03205637073787228175634527391820202e+1170L, 1.45709248520841293241982349536788740e+1207L, 3.10836026767661586110721101783586616e+1245L, 1.09211875259058272695772315187071594e+1285L, 6.90756042513315914107755467851436390e+1325L, 8.62072629674515227183116754798059355e+1367L, 2.33367455582609053817676883927592981e+1411L, 1.51088703661957707064674032871094166e+1456L, 2.58751847359969149251723060639056652e+1502L, 1.30061395127966085145757755976532379e+1550L, 2.13606222552299322654005297188550444e+1599L, 1.28040046650693999927593879574416998e+1650L, 3.14004479696111085451082602060045251e+1702L, 3.54445798947819813290733040762684700e+1756L, 2.07959058928044687396800353571401401e+1812L, 7.18928436789152221379187719747515467e+1869L, 1.66674057039586083195182422956301841e+1929L, 2.96144319154423967308042996118314268e+1990L, 4.62818622228372755683383431403798070e+2053L, 7.33344579812102490343077358675798902e+2118L, 1.36418147108226874642787854899398972e+2186L, 3.46578234556914165783357030404723460e+2255L, 1.40565670831906218450256157719581702e+2327L, 1.06915717420033634558717882909227336e+2401L, }, + { 1.22722791705463782987186673092730169e-02L, 3.68272289449259047084662870963424169e-02L, 6.14133762687107999107794380606156658e-02L, 8.60515970877820790729887694832007789e-02L, 1.10762884001784544594356091768970671e-01L, 1.35568393495778548180370153140547366e-01L, 1.60489493745433548938038568465534727e-01L, 1.85547813164508949628358434474487020e-01L, 2.10765289867070052445854835116288718e-01L, 2.36164222221462626796458521613760417e-01L, 2.61767320678549526133854585166690062e-01L, 2.87597761063134290040469640683594256e-01L, 3.13679239524903564719983726260388052e-01L, 3.40036029353663277020320913399073202e-01L, 3.66693039873181019259593465683200480e-01L, 3.93675877638645179710808224562806486e-01L, 4.21010910174684626844126582677407364e-01L, 4.48725332504145034061613569614932171e-01L, 4.76847236732482946224267058692370227e-01L, 5.05405684968820937507178521019349537e-01L, 5.34430785882522907921272727308422687e-01L, 5.63953775213726713429575640521392073e-01L, 5.94007100577754899987320597582638522e-01L, 6.24624510926871605306723866692531653e-01L, 6.55841151058639796949436231740377164e-01L, 6.87693661588351492208131027097817883e-01L, 7.20220284833868340062109216385730821e-01L, 7.53460977094957222390047011401038344e-01L, 7.87457527846096346070444259791519611e-01L, 8.22253686402049937748559808122413409e-01L, 8.57895296659582580760899947902549978e-01L, 8.94430440566859300921740259698532581e-01L, 9.31909591024743548462187459499302759e-01L, 9.70385774981792065875818381502464879e-01L, 1.00991474754772858364115613090157760e+00L, 1.05055517801908314962647763431650363e+00L, 1.09236884878609257919070489976671100e+00L, 1.13542086817251430035405051069824787e+00L, 1.17977989835042446581611499466432280e+00L, 1.22551839957114260989771330348614290e+00L, 1.27271289206202647251525071825625510e+00L, 1.32144423705798506493224886295961288e+00L, 1.37179793856724595345645859982391269e+00L, 1.42386446761438409645831411537400020e+00L, 1.47773961086120811494347321807905579e+00L, 1.53352484567928885758582112389540236e+00L, 1.59132774393835509765516748425726982e+00L, 1.65126240698431007605515051243084836e+00L, 1.71344993451128821134705183982006487e+00L, 1.77801893028625685775809622156398356e+00L, 1.84510604796472086962932266394457464e+00L, 1.91485658054495189874749078346703174e+00L, 1.98742509734901709257017841100790150e+00L, 2.06297613279527528332657028179424398e+00L, 2.14168493164291678457053660944377397e+00L, 2.22373825584899452105160804133355977e+00L, 2.30933525868721379620595550412858017e+00L, 2.39868843234110382076332419963510302e+00L, 2.49202463580835609502681428341212971e+00L, 2.58958621064512275641789028727789739e+00L, 2.69163219284683244353140722232296853e+00L, 2.79843963001449729057960489638268331e+00L, 2.91030501390256265160483634586060233e+00L, 3.02754583949736496303590546881335550e+00L, 3.15050230294691972178684607549631061e+00L, 3.27953915196739433034632435779672485e+00L, 3.41504770380541061125886820639123018e+00L, 3.55744804745655073349177433143963235e+00L, 3.70719144864977981720917442750632409e+00L, 3.86476297812834212534134362353667523e+00L, 4.03068438601653134401780732606469366e+00L, 4.20551724758861383531605318041260028e+00L, 4.38986640858517245778656669889477004e+00L, 4.58438376139193074830218319449001571e+00L, 4.78977238695068769484017601922716285e+00L, 5.00679110126136326392507134554822932e+00L, 5.23625944981527405022093792997629943e+00L, 5.47906319833752315041593490985864953e+00L, 5.73616037388481741547685088499196591e+00L, 6.00858791672861985829483499535828449e+00L, 6.29746901064886304750229195240462364e+00L, 6.60402116738092913326417425575120773e+00L, 6.92956515012467783689325375523493772e+00L, 7.27553483138386097168028487959046984e+00L, 7.64348809212349206445236344518102598e+00L, 8.03511888250245928810782085772095077e+00L, 8.45227057947818812962999536922397314e+00L, 8.89695079364178531317631891553840631e+00L, 9.37134779701639517335117345438905815e+00L, 9.87784876557344603277558247754926945e+00L, 1.04190600552776203680920477623835667e+01L, 1.09978297590083170587228134865897514e+01L, 1.16172728242395225830192073579898657e+01L, 1.22807990484892461058359016635119689e+01L, 1.29921443119669104778276499842319618e+01L, 1.37554054553562588138800381241813305e+01L, 1.45750792662062131604851118656361439e+01L, 1.54561061010485246793800779406223808e+01L, 1.64039187433830292507497745621200597e+01L, 1.74244971815420897003963134996594183e+01L, 1.85244300868843752575149709549249943e+01L, 1.97109838837826649364051644134983470e+01L, 2.09921804308096164753912694285306280e+01L, 2.23768844801398294581745473457799699e+01L, 2.38749022527007382030837433327528532e+01L, 2.54970926638043046429091560004131137e+01L, 2.72554929623253155508089897070407353e+01L, 2.91634608111962498675086489719161981e+01L, 3.12358351442328496157597338087371982e+01L, 3.34891184913680511842485226603345913e+01L, 3.59416838798546509869193271004218290e+01L, 3.86140099030723073708193155942738501e+01L, 4.15289481132930302349687386068430483e+01L, 4.47120275544153339602356644078995085e+01L, 4.81918020222491017368298630788454953e+01L, 5.20002465436155875740198471916042599e+01L, 5.61732106253738449367657038097317749e+01L, 6.07509370691878207865695555214723350e+01L, 6.57786566116800396636894823760941404e+01L, 7.13072703735772134302608508415302565e+01L, 7.73941341346580579448409414339011685e+01L, 8.41039608526963339165414121007032304e+01L, 9.15098606849673444816151204282990934e+01L, 9.96945411354770401552161275609161166e+01L, 1.08751693942601889700382157585301539e+02L, 1.18787600064303753208251167345242212e+02L, 1.29922989761451637135259469378151165e+02L, 1.42295201505637253678660735501099867e+02L, 1.56060691466500267146385748883961050e+02L, 1.71397954932643240617797882975933747e+02L, 1.88510932515483007342988031066863162e+02L, 2.07632987774012593538662727768467525e+02L, 2.29031559465458736990493497603665470e+02L, 2.53013611565567646662052901877967628e+02L, 2.79932028239889691165098106403660221e+02L, 3.10193129976673089035599193653267696e+02L, 3.44265522210752989223327890530839313e+02L, 3.82690530328937838722167127466549147e+02L, 4.26094526620760770127774483839356753e+02L, 4.75203517589290204505256185266901137e+02L, 5.30860436623905886389110002239619071e+02L, 5.94045680537299500918768911865886523e+02L, 6.65901542833877826224842736585170818e+02L, 7.47761336730915387004112664458834008e+02L, 8.41184173047134302254019501114516601e+02L, 9.47996569801374152415232558717779048e+02L, 1.07034233137588184029692740932268166e+03L, 1.21074245751858265959674123771999362e+03L, 1.37216724155220581953081355884482812e+03L, 1.55812321218769272183468357733000347e+03L, 1.77275818866271628150109400030205931e+03L, 2.02098848541186298361330491694554409e+03L, 2.30865325932916315664195536323762336e+03L, 2.64270218981368427312930076396387941e+03L, 3.03142418286921021219727597009903791e+03L, 3.48472667698575601755930501247710368e+03L, 4.01447750473397350451805793460750946e+03L, 4.63492426404939475098008035447052569e+03L, 5.36320994977343974892087068772061383e+03L, 6.22000841211434280322218569985211936e+03L, 7.23030933285302995642999721294241650e+03L, 8.42439021673521778311062568091410678e+03L, 9.83902287153854178745596238243054980e+03L, 1.15189746308311398832174294139085014e+04L, 1.35188809887437420186309997879371889e+04L, 1.59055874546006694678895534154510667e+04L, 1.87610857276481617624948313285750831e+04L, 2.21862046239336627450920062330548753e+04L, 2.63052620505491535696779646542992118e+04L, 3.12719440194171105738301413156011152e+04L, 3.72767546125665292256151356126569138e+04L, 4.45564828031227324859783992706804335e+04L, 5.34062659201890392985687357687040023e+04L, 6.41950058038891812326608231510870856e+04L, 7.73851264238682005972799669756325711e+04L, 9.35579699398172596314688114151429601e+04L, 1.13446537582066946954261668152086820e+05L, 1.37977827220974171292929858459577092e+05L, 1.68327748580788705255881136304020641e+05L, 2.05992574612073530499207561599578962e+05L, 2.52882202450315825396186949822484192e+05L, 3.11442271834772591489327431348343937e+05L, 3.84814591343557073602914002196809171e+05L, 4.77048586496682264260701809258611041e+05L, 5.93380932472474085420815642783399996e+05L, 7.40606619035166611456854888146209865e+05L, 9.27573047147064337154043416441694054e+05L, 1.16584026094018041532121013906762681e+06L, 1.47056632211824613527279037871707355e+06L, 1.86169889901492197099442712763381073e+06L, 2.36558487029835449538535481946926618e+06L, 3.01715269550576487659856266530294113e+06L, 3.86288257359992924875408921517049995e+06L, 4.96486430558975035817682789982702410e+06L, 6.40636282995973660643182932326803288e+06L, 8.29948184726130211549565432685136745e+06L, 1.07957589264240185368036619492890404e+07L, 1.41008732747460409136778616182972970e+07L, 1.84951472441825010015226156029368615e+07L, 2.43622441967080550013889014979179789e+07L, 3.22295113186394123446611158573926085e+07L, 4.28249388238592533660285754208101809e+07L, 5.71579339433926763705565010979377786e+07L, 7.66343793274545163464956180626615373e+07L, 1.03221272549848969879325123115356857e+08L, 1.39683399197619484239843178827556776e+08L, 1.89925149766489273996177039954695089e+08L, 2.59486539646750585135581953531723138e+08L, 3.56266474246450149668190479113931322e+08L, 4.91582541317241347106730357233806750e+08L, 6.81731647011695814167689014048918740e+08L, 9.50299810520254143758401252895411400e+08L, 1.33159829534327753848250753466160796e+09L, 1.87580197601045983131635998256926235e+09L, 2.65667390770973148718390348704244405e+09L, 3.78324021561636590874538087942452353e+09L, 5.41753184850013697899991815866441223e+09L, 7.80169536989284750988699417135654043e+09L, 1.12996536895509883334977946121306167e+10L, 1.64614916139082192438237472977949088e+10L, 2.41235399573668769368537292636420902e+10L, 3.55648689543192709406699873104224405e+10L, 5.27534501409376051919461374149743655e+10L, 7.87357210832537817724326568648616226e+10L, 1.18256902031786360426341053633539951e+11L, 1.78754944250836346103770384839274996e+11L, 2.71963306497998614239753953623599024e+11L, 4.16512215311989794586279802552971310e+11L, 6.42178185820513419673438138950789714e+11L, 9.96872549757627591785162935837099498e+11L, 1.55821232712296039863279650270498705e+12L, 2.45280998490709378571967041325143017e+12L, 3.88865623282814020969225986222930869e+12L, 6.20986899050942490907341584961146266e+12L, 9.98992421629798366453910164990598035e+12L, 1.61915800137861135092472802019186093e+13L, 2.64432451866992655897802160266314720e+13L, 4.35201884790437478598011793154963363e+13L, 7.21888468820274170949384690425513293e+13L, 1.20699764072734953803867091697058471e+14L, 2.03448372244520740184714594138600722e+14L, 3.45755310287440291972421764598644671e+14L, 5.92524851195750570615520553006806424e+14L, 1.02405779371303867152496937066868237e+15L, 1.78517404594164216208571127025070841e+15L, 3.13930698866849469593365078009075683e+15L, 5.56985627017489012771720073467849986e+15L, 9.97176335383446032822138577325280050e+15L, 1.80168749111488309180201148764368470e+16L, 3.28570985832256554206799328627718020e+16L, 6.04901854091075971038418094513619254e+16L, 1.12437528321136957183940077137648079e+17L, 2.11044512595243530534854315009251863e+17L, 4.00073700789122999206498186212756047e+17L, 7.66084936156432930897007145016954725e+17L, 1.48201877099617670026480296368024580e+18L, 2.89694543391085794507262308584519511e+18L, 5.72279016569347049314117808244814073e+18L, 1.14268996043992146219736887475145416e+19L, 2.30661655998410672274449611000740199e+19L, 4.70785718461609386331913071438798214e+19L, 9.71734634749534281292184698073106843e+19L, 2.02873560562258544354738566036230939e+20L, 4.28484025417100058060231110755876699e+20L, 9.15702732902162383627232801008773485e+20L, 1.98045783476641177674243338550380776e+21L, 4.33560488670225200389961701585516223e+21L, 9.60925855971422399500251930072135526e+21L, 2.15660463060858699692371033788512835e+22L, 4.90204590969527028901267517972005859e+22L, 1.12874922712132846722486415215181510e+23L, 2.63341462304993087921430516281962614e+23L, 6.22633568449099854312810660038498408e+23L, 1.49220527901414892100221726222044247e+24L, 3.62576824971759010933939677750446994e+24L, 8.93389976496144488245242728630867648e+24L, 2.23278698168226238263925345166626442e+25L, 5.66129533629398673236467837398265907e+25L, 1.45661671029813314161310452512420504e+26L, 3.80395985286848824540247897299973294e+26L, 1.00853158560303648965770564091212618e+27L, 2.71524742512942335771421173573350598e+27L, 7.42507176676665196668682930989072343e+27L, 2.06286071217322500340710263294206778e+28L, 5.82405545879941331172090843001915861e+28L, 1.67138883669643664401793246595736207e+29L, 4.87683063202395639212825400688637822e+29L, 1.44717007114610715647680482586441902e+30L, 4.36856220892558378299543245366740004e+30L, 1.34187380624925133807232471810065508e+31L, 4.19525163275433868171703825329949387e+31L, 1.33536013482821413616157861182819558e+32L, 4.32868135071513633988478443702722304e+32L, 1.42940186615031918577626278068758606e+33L, 4.80973614622718069618478648576546160e+33L, 1.64962411456760257539667516081290921e+34L, 5.76867749241980146921395997917892869e+34L, 2.05744285416276135030539237103441019e+35L, 7.48642350991781106283346301415985262e+35L, 2.78005279179115505131111680664033100e+36L, 1.05390834766008187386632631340309755e+37L, 4.08004633423575422346694643614725290e+37L, 1.61355331159280537271141620030872711e+38L, 6.52083633299761509812680604349515166e+38L, 2.69384818625751099248700493623895698e+39L, 1.13800240843071080011666704740931517e+40L, 4.91774800881392461265365745148130197e+40L, 2.17469107319135867637675221560360895e+41L, 9.84452374543052650164816403972682005e+41L, 4.56370746759011673249611086081412694e+42L, 2.16735207370837913732627450052443800e+43L, 1.05486019388717075432105322007580054e+44L, 5.26358822556684736475437714203858810e+44L, 2.69377245879791662278222405278060831e+45L, 1.41450676056016307353065763949943988e+46L, 7.62412676351201661991424110428992680e+46L, 4.21982814876279441119734812029287822e+47L, 2.39938766583179326419454951543637572e+48L, 1.40213994725411743432292186837126106e+49L, 8.42470632552542294312824936421510125e+49L, 5.20691847994261931825305937850643235e+50L, 3.31178786647771615130587348221001406e+51L, 2.16868329550985915487173624396649870e+52L, 1.46278636877920671278346292184781720e+53L, 1.01676178457583836251098427369753410e+54L, 7.28646099514504318390031595979099009e+54L, 5.38619423744886540736133132036039525e+55L, 4.10891748052874064027571987877723004e+56L, 3.23644562594555272761751761693655719e+57L, 2.63344065241761966896134121065725150e+58L, 2.21470233935793926784783273212022849e+59L, 1.92605899594826839190384056135440397e+60L, 1.73306774041417493183516299971659594e+61L, 1.61430716012442696900215232150692807e+62L, 1.55746432848635213822960416335985349e+63L, 1.55722615519719203130606727886637242e+64L, 1.61447396270799534426677571780472075e+65L, 1.73661740632738610492724345532304845e+66L, 1.93920124345119052093186699988150897e+67L, 2.24927773293662287552890832545827854e+68L, 2.71159379871976559871119761600619238e+69L, 3.39962873204868711911086284140566930e+70L, 4.43538969673020629145547409643969707e+71L, 6.02556607616400398134689309091612155e+72L, 8.52916142538377984909758513093573554e+73L, 1.25874632299298868846704179091958707e+75L, 1.93811217518656021005493439215804850e+76L, 3.11543236357261066088271223403230465e+77L, 5.23179767443439001771782033104475730e+78L, 9.18493020786068075728039142759876527e+79L, 1.68692940478037877214426031162304858e+81L, 3.24356562447423263461643222429327622e+82L, 6.53381249893022007452896440352725950e+83L, 1.37989882314462031449133502146398295e+85L, 3.05765044484283991620932285441735220e+86L, 7.11405054583917124472478320152556329e+87L, 1.73927502444225867447030753694640018e+89L, 4.47178291585317780365328749453520010e+90L, 1.21003678949402814425759810458701117e+92L, 3.44882804459086235858169840236819767e+93L, 1.03622678375056156465794049465547871e+95L, 3.28480191475120603834848118907352203e+96L, 1.09951493360222463836336540053884847e+98L, 3.88958173137824259730333790282903582e+99L, 1.45543428790106999149108053530575702e+101L, 5.76572993438741901863543434592570728e+102L, 2.42034956874547558153049344213268717e+104L, 1.07760662592977753585432532225577347e+106L, 5.09334698869585184485524316150431382e+107L, 2.55809082411032399725764692067377039e+109L, 1.36651250871904796376617702296414102e+111L, 7.77173580076352640634836399351925362e+112L, 4.71039863879301491830684051990330316e+114L, 3.04556388558701395434830609997782218e+116L, 2.10276255286144299282309486039761104e+118L, 1.55193753621259613591555622965540441e+120L, 1.22567635442607596952721498552003566e+122L, 1.03695094616970371146721395255392215e+124L, 9.40788526897082771733750170914488215e+125L, 9.16336910778509317089313688240113814e+127L, 9.59253109567116892554520172575780003e+129L, 1.08048629336182387529116109869898182e+132L, 1.31103482955778245018110865569797769e+134L, 1.71564297593263918799907327094023177e+136L, 2.42423174270788187824126863980761699e+138L, 3.70323122333312791897064549131589865e+140L, 6.12322502740998890169801438496313135e+142L, 1.09727104077119676484946099784861221e+145L, 2.13369364324129597715060714813970067e+147L, 4.50809918489577732767734472523944713e+149L, 1.03625280668629118864461701581877696e+152L, 2.59492839368798847123238762058931299e+154L, 7.08856065084285960511459463166728250e+156L, 2.11523492515131956204689196091626210e+159L, 6.90448414659433816403326070235535578e+161L, 2.46882138492543386747726128195908117e+164L, 9.68405620339094731040251680095733169e+166L, 4.17318211031646842247767173261932179e+169L, 1.97862256312448325694613011941349554e+172L, 1.03370703084875834422987498885049116e+175L, 5.95983823379168614646426490979367954e+177L, 3.79793920709700480341002000892325755e+180L, 2.67930862060725892983600714882836079e+183L, 2.09582063696050703960100191266610779e+186L, 1.82074244214148973928235757920582367e+189L, 1.75963855825241574501304502726864570e+192L, 1.89499379332809905379546394212298551e+195L, 2.27793735309853697376707463982899100e+198L, 3.06180392186430523426845441481052145e+201L, 4.60976071298011598021963844074936266e+204L, 7.78790454205446308413194702704532804e+207L, 1.47908157180353184742483342055946619e+211L, 3.16368583872054810499056635486446885e+214L, 7.63549763158546449019055671859541326e+217L, 2.08329116709848069811436257881072129e+221L, 6.43828341650089537912773112646579654e+224L, 2.25813433461443519689405569138116459e+228L, 9.00646808360283887236786414348123292e+231L, 4.09320439419929471708152017376102969e+235L, 2.12407325647515198386324613590453899e+239L, 1.26118767744139661919617876453932054e+243L, 8.58648519817790365555570528355195441e+246L, 6.71757354945431655557160007037610215e+250L, 6.05231172230061504649457274179966269e+254L, 6.29372154343611302741074349158106138e+258L, 7.57097597581835804454005529249965405e+262L, 1.05596735728342565613175490019879868e+267L, 1.71165116794080014782255848570375371e+271L, 3.23201945416757368365209341689336569e+275L, 7.12640648337469193163827718081711822e+279L, 1.83935498907936650155252747841577857e+284L, 5.57103618187823353431701691950875589e+288L, 1.98507054903582594730288556561442957e+293L, 8.34251060679185969108286852637314516e+297L, 4.14598050279815660053056892060055710e+302L, 2.44294673707515955659314553816687272e+307L, 1.71128222954502480992240259231707340e+312L, 1.42900308749681080618580596429329500e+317L, 1.42642910690539638749189376290614404e+322L, 1.70684173154227881505687976959428819e+327L, 2.45528610324097413976825941240621397e+332L, 4.25829782132342793910509184917611473e+337L, 8.93046646026781112771479518830708119e+342L, 2.27151544737307916343177075009962798e+348L, 7.02878727199449743249339960113532074e+353L, 2.65404789370370153123009487802961972e+359L, 1.22676780524208968705932842819459632e+365L, 6.96344727462083702750636558199408867e+370L, 4.86966795424296645258294731476827244e+376L, 4.20934473165669380666938166564826622e+382L, 4.51252011030278817555903939588122000e+388L, 6.01984854233799583525556662766352847e+394L, 1.00278809583154248088779511185941092e+401L, 2.09319142855536626778348201007914114e+407L, 5.49449523120000769396463190666315855e+413L, 1.82025791721843330667826837307018788e+420L, 7.63864295498675379110157901286555290e+426L, 4.07562853905456437955133694031162566e+433L, 2.77530355159307878582751292111532382e+440L, 2.42120842363222072539668100784464301e+447L, 2.71677827391519917988250533365057684e+454L, 3.93638693069501511102210790122717956e+461L, 7.39454183839498133330514511562965145e+468L, 1.80830021083203927258676228302841634e+476L, 5.78068632124848075130373030745294118e+483L, 2.42588452835387252450192322587436972e+491L, 1.34215845252903171028854514732509154e+499L, 9.83265508980143417319549250479290229e+506L, 9.58056982887069577741485477351756765e+514L, 1.24714172045678509784766926344381810e+523L, 2.17883996343750012869434076146952309e+531L, 5.13253875779605180900218275684122450e+539L, 1.63787417999262086647656267832207076e+548L, 7.11453353628067905769574986613707006e+556L, 4.22706394134172663816196292889312018e+565L, 3.45223064191878555675199989739485645e+574L, 3.89497996822823191874712723630878414e+583L, 6.10190158010921783812771061850774756e+592L, 1.33421132288849391233542855134113771e+602L, 4.09320749021551498574887738660496448e+611L, 1.77132716471266560117452274418925035e+621L, 1.08713213788405301831391213988591367e+631L, 9.51489736810900467024086259204897883e+640L, 1.19423949258625915586962226198410651e+651L, 2.16177179741543970148744161752725437e+661L, 5.67627906160460395827390123125168239e+671L, 2.17468780419782497779087319492719363e+682L, 1.22290652527655281598138666471594618e+693L, 1.01549393259398829829790551999023256e+704L, 1.25289600863132317250645757199143453e+715L, 2.31107594661956354485796436668094840e+726L, 6.41394790132987132728494077504399223e+737L, 2.69551958118799603835043225368071745e+749L, 1.72664572305999101481397361296053504e+761L, 1.69703260411568714431268560545429241e+773L, 2.57650655058878846949421879421719884e+785L, 6.08415755628422694511089641903676709e+797L, 2.25018717111577650332251351426363709e+810L, 1.31266605271635406458566527913919394e+823L, 1.21653337436496205608516398221959572e+836L, 1.80423787152105848481394522091997928e+849L, 4.31399102346512532331941966328171850e+862L, 1.67550866484958200095075315692314084e+876L, 1.06515761703845778105889680563699868e+890L, 1.11699400379133199608851392356049526e+904L, 1.94751426714424559351617923238456424e+918L, 5.69089114062808012687080164398087070e+932L, 2.80983921519267570591812248264495618e+947L, 2.36358690419951504134253704409272547e+962L, 3.41581578617948637677662230945252306e+977L, 8.55364646944583859412326553382242541e+992L, 3.74370530455423912034790817625191291e+1008L, 2.88911104228589616462565573594290893e+1024L, 3.96659525977064102663870040642245025e+1040L, 9.77693110684684436928410437465483271e+1056L, 4.36636679166615668883990202463770904e+1073L, 3.56644781478399708285654633626787310e+1090L, 5.37871519143314493436384142989505797e+1107L, 1.51231507376826438439352643482625072e+1125L, 8.00547597409214659416862336552752652e+1142L, 8.05824292014776003962551051182620642e+1160L, 1.55810667707874651581920999067306413e+1179L, 5.84685322894210562805362663900103590e+1197L, 4.30279053871861463775007328286068764e+1216L, 6.27606568696844727186804750244767860e+1235L, 1.83405691639178257209003812558712559e+1255L, 1.08562206577049472147312923532596973e+1275L, 1.31617110088183556471407953592008454e+1295L, 3.30534811890625751178778666339188597e+1315L, 1.73929710751143724152073404455311704e+1336L, 1.94017558758640506527365311633351598e+1357L, 4.64256117877888468390840687039281473e+1378L, 2.41181028167559547953976181592626603e+1400L, 2.75359028326650146526233980288420348e+1422L, 6.99538184026698121966983693939988891e+1444L, 4.00451124186760586509360315430592520e+1467L, 5.23202484555080004711423052985251790e+1490L, 1.58057811961053246035386581678791248e+1514L, 1.11871792077110492782575037665515064e+1538L, 1.88021076704060084216083677757823795e+1562L, 7.60656064089491206752552083826812435e+1586L, 7.51058336307020750806534892000369186e+1611L, 1.83554419567039732901090730190332067e+1637L, 1.12631598317224168716420027493130577e+1663L, 1.76058045324267978077071148859252887e+1689L, 7.11454090252573253550862708170430267e+1715L, 7.54447665013986581882495689819567483e+1742L, 2.13157561258614754140817896581925999e+1770L, 1.62953544267683384450064825605699335e+1798L, 3.42393824570039208761545128642814549e+1826L, 2.00910152737038919233657554807306054e+1855L, 3.34591874171713502502193846562110253e+1884L, 1.60768420173566681503057284560969387e+1914L, 2.26623321264716591681578650589551852e+1944L, 9.53208108881430895613749023747672822e+1974L, 1.21710154769951529957336846304572308e+2006L, 4.80082954212402831503263841738379326e+2037L, 5.95484092414598408997112765002169497e+2069L, 2.36496081234284780469612914593602194e+2102L, 3.06292618387296708176633714456063693e+2135L, 1.31792936450130144017383754294435167e+2169L, 1.92000470996606623202622993195686002e+2203L, 9.65401246356529853165036795448719991e+2237L, 1.70836636787270782624240314280943940e+2273L, 1.08524396756651055665425968680627268e+2309L, 2.52515527758383642102305453689375992e+2345L, 2.19655419566926380800477364631433717e+2382L, 7.29302139222844158929601074949211737e+2419L, 9.43942215540978305304206842223557338e+2457L, }, + }; + m_weights = { + { 7.86824160483962150718731247753528972e+00L, 8.80516388073301111614873617217928009e+02L, 5.39627832352070566780640331455747505e+07L, 8.87651189696816131653619534136597185e+19L, 2.43279187926922555339407396412240848e+52L, 6.39971351208020291074628474066382445e+139L, 4.88537754925138382971529406336289926e+376L, 7.16883681174178397147232888689884595e+1019L, }, + { 2.39852427630263521821751964327863340e+00L, 5.24459642372668102196104972893810164e+01L, 6.45788781959820175983419155536535220e+04L, 2.50998524251137450575088710958358197e+12L, 1.77402926932713870128394504873348147e+32L, 2.78140611598309731397930137939524577e+85L, 1.96038425539892219077400134901764646e+229L, 3.66150166331050442649946863740591804e+619L, 4.83160223742266359875093017291942249e+1679L, }, + { 1.74936958310838685164948357553735581e+00L, 3.97965898193460781260142246747934196e+00L, 1.84851459857444957000370375296526856e+01L, 1.86488071893206798762140574520079510e+02L, 5.97420569526326585534733485801413054e+03L, 1.27041263514462334076609190768051333e+06L, 6.16419301429598407050713079962266577e+09L, 5.23085003181122252980303620742723664e+15L, 2.22626092994336977442577822584431966e+25L, 1.19993110204218159156995352671876189e+41L, 7.47060214427514621386633671542416223e+66L, 1.81446586052841067579857900138568293e+109L, 9.97368828205170536427067380214302839e+178L, 6.91104863699861841609881512683369620e+293L, 1.09318211394169115127064538702854062e+483L, 6.82844528756738528157668552351754659e+794L, 5.72058982179767644458682394627277737e+1308L, 8.56032690374774097638382410967859196e+2155L, }, + { 1.61385906218836617287347897159238284e+00L, 1.99776729186967326240633804225996920e+00L, 3.02023197990883422014272607858586524e+00L, 5.47764184385905776136260784219973923e+00L, 1.17966091649267167180700675171097629e+01L, 3.03550484851859829445106624470076282e+01L, 9.58442179379492086007230677188042206e+01L, 3.89387023822999207648300659707623000e+02L, 2.17919325035791134362027855479039721e+03L, 1.83920812396413285238691815996130729e+04L, 2.63212061259985616674528417452471371e+05L, 7.42729650716946820985576548297567563e+06L, 5.01587564834123235599460194208596041e+08L, 1.03961086724154411336246801784030341e+11L, 9.10032891181809197707572646881781254e+13L, 5.06865116389023157141527800972456655e+17L, 3.03996652071490261550678134010186516e+22L, 3.85774019467200796234141077624516370e+28L, 2.46554276366658108662483315347592086e+36L, 2.41643944916779946083480638296809418e+46L, 1.51709155392660414912154078562432491e+59L, 3.82504341202141137966304147261186085e+75L, 4.08958239682159863968142401533332977e+96L, 3.82377589429556404969214069508991010e+123L, 1.52310131188389950567280579870007714e+158L, 3.79636429591225792206340580596443044e+202L, 3.58806569407775804668752012761380285e+259L, 4.80771394235873283225580334249205764e+332L, 3.53246347094395956018650264083397114e+426L, 1.10588270611697913736223556513462127e+547L, 5.39876096236024571737551333865366627e+701L, 2.11595993056851385189640470523173475e+900L, 1.96510021934867185245970661270267904e+1155L, 4.44393205109502635384704176698510343e+1482L, 8.87699807096655545789464168899561262e+1902L, 3.92593109193326452307669545677335709e+2442L, }, + { 1.58146595953669474418006927755018553e+00L, 1.66914991043853474595928766810899114e+00L, 1.85752318859500577038805456054280667e+00L, 2.17566262362699411973750280579195666e+00L, 2.67590137521102056412774254907718688e+00L, 3.44773868249879174414308452011308777e+00L, 4.64394654035546412593428923628065357e+00L, 6.53020449657424861626175040050215115e+00L, 9.58228501556680496101434956408351228e+00L, 1.46836140751544096048943311347045852e+01L, 2.35444954874098753301967806270994218e+01L, 3.96352727330516670475446596081886449e+01L, 7.03763520626753854729866526912608057e+01L, 1.32588012478483886772029444321222706e+02L, 2.66962564954156917240259777486475719e+02L, 5.79374919850847267642551329761882844e+02L, 1.36869192832130360517783396696756604e+03L, 3.55943572153313055370459329132660088e+03L, 1.03218667727076331844496375241465304e+04L, 3.38662130285874148722242481662728477e+04L, 1.27816625984024682983932609690817446e+05L, 5.65408251392669309819682774275375355e+05L, 2.99446204478172183285915112991350446e+06L, 1.94497502342191494704216422938073734e+07L, 1.59219300769056058775193216743984073e+08L, 1.69428881861745991307405037132734657e+09L, 2.42715618231130327064401251217732118e+10L, 4.87031784819945548978505622564878836e+11L, 1.43181965622918179279761684530563788e+13L, 6.48947152309930125567236832263111486e+14L, 4.80375775250898910621624420686976943e+16L, 6.20009636130533154063228597685772759e+18L, 1.50256856243991489872472363253210358e+21L, 7.43606136718968825065770257988550430e+23L, 8.26476121867792860277670169213789988e+26L, 2.29773502789780434527854280137181506e+30L, 1.80544977956953499695878114747293447e+34L, 4.60447236019906193095622500171344417e+38L, 4.45837121203062685356208723886733392e+43L, 1.95763826111480930920135175891530462e+49L, 4.76736813716250076391436967954985413e+55L, 8.08882013947672128478290968549029064e+62L, 1.23826089734928635728800137667726115e+71L, 2.29227250527884206154485624438166937e+80L, 7.15139237374919354944182099110281069e+90L, 5.47671485015604443103262357109062276e+102L, 1.57665561837070068115746726288773175e+116L, 2.76544859595785195782707224216472471e+131L, 5.10805125528313267335507302418826239e+148L, 1.84712724771593770593326127127227089e+168L, 2.64019849791365137425805671512502957e+190L, 3.30712207665004277982044248938187504e+215L, 8.94854908018147130170828014681013313e+243L, 1.45387781135416845215757148230318159e+276L, 4.51726707740089625471551690811905600e+312L, 9.97430447590682462482304866834403173e+353L, 6.92693028486990716815899177110112886e+400L, 8.16310561774970561761094556639568748e+453L, 1.10229203674018117764688357752075301e+514L, 1.48517414340573263317638725427854581e+582L, 2.31930659130340479680373862468017961e+659L, 6.75943980795305614491339585238335763e+746L, 8.57037256903489416057847741388693004e+845L, 1.67601881139415883633596646631875881e+958L, 2.88227840597067494281761984210848274e+1085L, 4.25760590360997372209644858208981618e+1229L, 9.71180927884114514977776411099980676e+1392L, 1.22768447544318231419683656745290694e+1578L, 6.75552744777466879522724469574589977e+1787L, 3.08769330528996647489562213811332711e+2025L, 6.11556995885701147380172201043083647e+2294L, }, + { 1.57345777357310838646187303563867071e+00L, 1.59489275503866378652125176234375753e+00L, 1.63853651553023474161201404240726646e+00L, 1.70598040821221362042267472116012952e+00L, 1.79972439460873727464624167982278042e+00L, 1.92332285442565630724716834865923523e+00L, 2.08159737331326817824115844787944556e+00L, 2.28093488379007051069614759371332643e+00L, 2.52969785238770465522974588384012833e+00L, 2.83878478255295118549225363326336900e+00L, 3.22239574502098061154099310373833179e+00L, 3.69908135885423511174795221061725889e+00L, 4.29318827433052679979662014839909054e+00L, 5.03686535632233007617225633242190622e+00L, 5.97287114091093219903794699750262296e+00L, 7.15853842431107756435392592099817447e+00L, 8.67142780089207638456187671594514668e+00L, 1.06174736029792232565670017416978690e+01L, 1.31428500226023559963724543395522033e+01L, 1.64514562566842803959315507240301356e+01L, 2.08309944999818906870911848992408145e+01L, 2.66923598979164019005652953856219015e+01L, 3.46299351479137818875120770497256101e+01L, 4.55151836265366257897259922581190951e+01L, 6.06440808776439211617961123881399848e+01L, 8.19729691748584679772374579308014156e+01L, 1.12502046808165256396405270593673624e+02L, 1.56909655284471412314380735570422525e+02L, 2.22620434786863827630193937721495593e+02L, 3.21638548950407775497940425181412035e+02L, 4.73757450594546173931972158718216152e+02L, 7.12299454814699763671577043536625350e+02L, 1.09460965268637655307120839628626644e+03L, 1.72169778917604957594996919520027157e+03L, 2.77592490925383514631415480161515100e+03L, 4.59523006626814934713366494475518926e+03L, 7.82342758664157367197225266771664916e+03L, 1.37235743526910540538254088034330370e+04L, 2.48518896164511955326091118611007805e+04L, 4.65553874542597278270867281925971401e+04L, 9.04176678213568688399001015321300800e+04L, 1.82484396486272839208899824313480775e+05L, 3.83680026409461402659414641247062580e+05L, 8.42627197024516802563287310497296237e+05L, 1.93843257415878263434890786889254173e+06L, 4.68511284935648552770705724295731096e+06L, 1.19352866721860792702129481323969824e+07L, 3.21564375224798931587480096707273872e+07L, 9.19600892838660038574630990314077029e+07L, 2.80222317845755996380600711673673348e+08L, 9.13611082526745888639724836491288094e+08L, 3.20091090078314859097182280497599932e+09L, 1.21076526423472368892320719657876832e+10L, 4.96902474509310180847282308967509245e+10L, 2.22431575186385521573661995325533148e+11L, 1.09212534444931366008730317965795763e+12L, 5.91688298001991935913437013926087352e+12L, 3.55974343849457724875846980164154730e+13L, 2.39435365294546519110955303872941851e+14L, 1.81355107351750191688958030705258863e+15L, 1.55873670616616573768075986251057862e+16L, 1.53271487555511433265791312985848665e+17L, 1.73927477619078921206684554401295421e+18L, 2.29884121680221631264260395223605839e+19L, 3.57403069883776266374408947394989771e+20L, 6.60489970545141907950722926660909000e+21L, 1.46715587959182065910258109064501314e+23L, 3.96409496439850938104106380506197921e+24L, 1.31934284059534879276193138323357204e+26L, 5.48225197134040074244755342952808857e+27L, 2.88513789472382751842871762855110475e+29L, 1.95253984076539210960955400019857653e+31L, 1.72705148903222279729658337426192599e+33L, 2.03134350709543939580166226396358099e+35L, 3.23607414697259998035422932108168633e+37L, 7.12048741298349720027592249584649287e+39L, 2.20955270741101726546978031488466999e+42L, 9.88628264779138464833350749737352873e+44L, 6.53051404878827352855218417636385136e+47L, 6.53070667248154652797117704066842547e+50L, 1.01551880743128195070423638840822631e+54L, 2.52636677316239450980056816553072407e+57L, 1.03645051990679029664966085872637264e+61L, 7.24196603262713586073897504016245799e+64L, 8.91940252076971493816577515322150818e+68L, 2.00846361915299290502283821529295631e+73L, 8.59691476483026002005094018998424562e+77L, 7.29059954682949521964023913634428261e+82L, 1.28019956321641911210408802307006043e+88L, 4.87834928560320114983891893560226105e+93L, 4.24082824806412793978885646592598549e+99L, 8.86977176472159872046976711615695992e+105L, 4.72334257574141766931261505651248075e+112L, 6.80203596332618858057580041658814811e+119L, 2.82453118099000954895979587744113614e+127L, 3.62104921674598225195529453488856248e+135L, 1.54127015033494251978994281882356439e+144L, 2.35337699517436278507886852532825112e+153L, 1.39975657916895026384257958622345253e+163L, 3.54037503829826541837221286091526442e+173L, 4.18047500721395810079642214620070836e+184L, 2.54530778191403081572971577964641848e+196L, 8.88250526322285889574436025179770286e+208L, 1.98845751036127430533908054978079217e+222L, 3.21915661509946819003841034873947498e+236L, 4.28183215516658291456439674095688919e+251L, 5.36006145974509206228714676601426569e+267L, 7.29722806821457796264952588871034685e+284L, 1.26019994797636341237075623262002305e+303L, 3.25215241711283834871808603425369243e+322L, 1.49313102632599158215031971670664716e+343L, 1.46842377691796129245813472736592684e+365L, 3.76931518236156669675469780787997744e+388L, 3.11671991143285521404945273561352902e+413L, 1.03852445906488241953781523768340610e+440L, 1.76991068936691550622045923706396857e+468L, 1.98843278522413458075823481121326426e+498L, 1.92935688449069146367365017414279935e+530L, 2.15545898606278242992831028009446695e+564L, 3.76556572065746315676705102085514331e+600L, 1.42493629186903074753303377268119903e+639L, 1.65224172380259971159552714105694350e+680L, 8.49215944410421946026158352935784666e+723L, 2.86631893981320588349507785370693896e+770L, 9.65377141044877270160840903468092119e+819L, 5.06475979937176267805686278644876593e+872L, 6.64979079902917739733555562625190968e+928L, 3.61927525412094487856735509111512169e+988L, 1.39737404381894022658529893979427383e+1052L, 6.78018387620311055320186127570560827e+1119L, 7.59952044103401209205510909410129754e+1191L, 3.76162862667265940011010617225061429e+1268L, 1.63904309514033654209643026524489542e+1350L, 1.31017858257252889370615733020834140e+1437L, 4.19821396072116298475329351264459339e+1529L, 1.23923791809549425227491870065845752e+1628L, 8.17087984671936465200033730232853592e+1732L, 3.08946915513007963115203650683840400e+1844L, 1.82761916569338643673217752139790470e+1963L, 4.92348318803338950087945240543349430e+2089L, 1.88350835331965060456271693216651123e+2224L, 3.43360015586068277793841059306542129e+2367L, }, + { 1.57146131655078329437644376888801138e+00L, 1.57679016631693834484126246342345329e+00L, 1.58749564037038331646069625234555521e+00L, 1.60367395634137020950291269057600307e+00L, 1.62547112545749394267938666988196139e+00L, 1.65308501191593930171844822364141731e+00L, 1.68676814252591123625053019619255158e+00L, 1.72683132353751620184313195813656600e+00L, 1.77364813866723660171326886678529701e+00L, 1.82766042147866144821632902536146347e+00L, 1.88938481704401819562549601165115021e+00L, 1.95942057285503709111658357403615203e+00L, 2.03845872804790892275259742585569433e+00L, 2.12729290408384722476899855222432786e+00L, 2.22683194019907694104850876757126753e+00L, 2.33811466455513029581902771513343722e+00L, 2.46232714872299130380967769641847017e+00L, 2.60082286092708516436098022317536381e+00L, 2.75514621481455435937229822050004007e+00L, 2.92706010842448355516791030533685920e+00L, 3.11857816624092195149666191379786472e+00L, 3.33200254033950662971711811118318338e+00L, 3.56996830041074027550628111498923678e+00L, 3.83549565399644726181552365400966870e+00L, 4.13205149651293488468153425460318353e+00L, 4.46362210669906788115667211361364802e+00L, 4.83479919100800655701530131187647507e+00L, 5.25088195776567960767293727240320892e+00L, 5.71799849087533312421158643544587353e+00L, 6.24325042159856810533215887376856930e+00L, 6.83488580122654183866366620676303900e+00L, 7.50250620278934080195915244309172491e+00L, 8.25731548449354420110207897041998984e+00L, 9.11241940586464263380079984086513597e+00L, 1.00831874954399775830998395457182684e+01L, 1.11876913499386520162594085796167645e+01L, 1.24472370591410688131760615976965093e+01L, 1.38870139060550758665255786705519681e+01L, 1.55368871591590018952847646637454593e+01L, 1.74323700068094283108112572669239084e+01L, 1.96158189482399342378436216339159090e+01L, 2.21379088635427380602824337731297019e+01L, 2.50594593467713760968808829296439171e+01L, 2.84537037774213756120135736520435304e+01L, 3.24091184596952483433430577491101072e+01L, 3.70329628948023016142035941015485370e+01L, 4.24557264474626791146220920324192917e+01L, 4.88367348033798558171280311705362727e+01L, 5.63712464058697542020818458752120814e+01L, 6.52994709275261034008086934786702551e+01L, 7.59180775569412283714380617539343408e+01L, 8.85949425239166382162609558265821220e+01L, 1.03788129500578812415162165531670704e+02L, 1.22070426396922674625756853326498468e+02L, 1.44161209813120053456742433728771078e+02L, 1.70968019124577351122499690038707734e+02L, 2.03641059384357556999222931732850856e+02L, 2.43645005870872364316059216110059642e+02L, 2.92854081218207610543177302881458406e+02L, 3.53678601915225339202500542949917795e+02L, 4.29234308396729693907268968564609660e+02L, 5.23570184048873302665650155276206906e+02L, 6.41976689800302457508415746115180260e+02L, 7.91405208366875928332161102969868782e+02L, 9.81042208908193163688535235538889459e+02L, 1.22309999499974039331272100414750813e+03L, 1.53391255542711212726525490457861725e+03L, 1.93546401360583033885511419988831009e+03L, 2.45753454991288685207196097797062484e+03L, 3.14073373162363551894782974867325472e+03L, 4.04081818856465189750723035050638141e+03L, 5.23488159971222568136194576211612571e+03L, 6.83029445760732922582000345557383347e+03L, 8.97771322864988714349790288910627671e+03L, 1.18901592096732683947870697270695144e+04L, 1.58712238704434696215746702894136306e+04L, 2.13571110644578933143540830593360855e+04L, 2.89798370518968143718297906801146350e+04L, 3.96630672679554794954087134590560762e+04L, 5.47687519375000078688553248953764732e+04L, 7.63235653938805568016142182690471993e+04L, 1.07371914975497695062170132456450593e+05L, 1.52531667455557415180420019888676134e+05L, 2.18877843474421658617449971461581691e+05L, 3.17362449601929560775572985879585343e+05L, 4.65120152586932846156175983364596723e+05L, 6.89253765628058057206329188782990860e+05L, 1.03311988512001998186230013733752720e+06L, 1.56688798104325249948154338241641806e+06L, 2.40549202702653179507492073842261453e+06L, 3.73952896481591033994026114668796352e+06L, 5.88912115489558003244667233279563785e+06L, 9.39904635192234203007457377008255614e+06L, 1.52090327612965351790614542733698474e+07L, 2.49628718729357616773929842263043964e+07L, 4.15775925996307484022703929049831425e+07L, 7.03070536695026731176158877103497776e+07L, 1.20759855845249336607363637052870598e+08L, 2.10788250946484683324104572583041111e+08L, 3.74104719902345786397351281755078701e+08L, 6.75449459498741557237788387723071522e+08L, 1.24131674041588053743260021864117384e+09L, 2.32331003264955286246594304305695965e+09L, 4.43117601902662575879840759020751450e+09L, 8.61744648740090012951326726568665021e+09L, 1.70983690660403151330619158427281665e+10L, 3.46357452188017133850611855017361923e+10L, 7.16760712379927072634183907084755700e+10L, 1.51634762091005407908273857408800162e+11L, 3.28172932323895052570169126695951209e+11L, 7.27110260029828078950026409435831711e+11L, 1.65049955237878037840731169761272102e+12L, 3.84133814950880391685509371196326109e+12L, 9.17374426778517657484962791255187134e+12L, 2.24990194635751997880832549111511175e+13L, 5.67153508990061173097292032404781538e+13L, 1.47074225030769701852963232235912597e+14L, 3.92701251846431177545392497147427712e+14L, 1.08063997739121282020832802862957248e+15L, 3.06767146672047518894275739534732971e+15L, 8.99238678919832842771174638355746631e+15L, 2.72472253652459211109041460799535823e+16L, 8.54294612226338925817358060817490416e+16L, 2.77461371872557475533476908014408616e+17L, 9.34529947938202912146296976663431863e+17L, 3.26799612298773188163350554315742192e+18L, 1.18791443345546831451732293519928714e+19L, 4.49405340841856421397062311314705655e+19L, 1.77170665219548674305185389795833488e+20L, 7.28810255288593152697603764235601397e+20L, 3.13251243081662534865188632436805529e+21L, 1.40874376795107311038838007000777184e+22L, 6.63829426823606041441317767891166205e+22L, 3.28254360840356501289107248021554584e+23L, 1.70592009803839406409667145645666005e+24L, 9.33225938514852428454935743602712728e+24L, 5.38272717587488831207327363463407970e+25L, 3.27895423512209324910006662705296242e+26L, 2.11319169795745809927716305122705952e+27L, 1.44341104149964304009687846325713305e+28L, 1.04686439465498242316197235200069352e+29L, 8.07731922695890570023291958025986094e+29L, 6.64314696343261627707440459400107155e+30L, 5.83567012135998626006817430636714368e+31L, 5.48689029679023079776199817150941362e+32L, 5.53372696850826161418229677716330718e+33L, 5.99973499641835283449509393028972981e+34L, 7.00917611946612256941556198729562373e+35L, 8.84406196642459749869759626748371565e+36L, 1.20822686086960596115573575744502341e+38L, 1.79164851431106333799499432947126299e+39L, 2.89131391671320576216903362266762013e+40L, 5.09145786021152729801159516043566174e+41L, 9.81063058840249655325327952160218101e+42L, 2.07444123914737886022245738089968362e+44L, 4.82765011693770054022189143000576390e+45L, 1.24028793911154902904261886940649724e+47L, 3.52878285864478461616951002487254771e+48L, 1.11544949047169665881036414807872651e+50L, 3.93051064332819631369914292573124112e+51L, 1.54924371295785233686867649142553059e+53L, 6.85499823804130100151231679166543611e+54L, 3.41747996158320770357877327002949632e+56L, 1.92690549864107998957222500013304086e+58L, 1.23358096300491944958557136475962190e+60L, 9.00281990289807691528078151573158069e+61L, 7.52141514125344164522463463202808470e+63L, 7.22427755490057899279344696654950663e+65L, 8.01283283053507860974456727997488253e+67L, 1.03099962028638036919997632019550562e+70L, 1.54617495707674867923983623892142209e+72L, 2.71580377261324869371341160824868908e+74L, 5.61508992057174643750226165228505259e+76L, 1.37366785934534333692942668275259398e+79L, 3.99754102076962512613158938364235073e+81L, 1.39150058933980008745266389466237314e+84L, 5.82669384491202289249159160687839973e+86L, 2.95227482092954909582266634062763990e+89L, 1.82102306147846628152669685943631657e+92L, 1.37597302213794152564743989887492097e+95L, 1.28185236754341294523601004808033157e+98L, 1.48213012720199050337233086306566580e+101L, 2.14157427379243531419232668034147566e+104L, 3.89449554094711237984570195229015661e+107L, 8.97864636258010296104790318951217808e+110L, 2.64413158980724405044777067425347595e+114L, 1.00240353984191383430257305957041439e+118L, 4.93141280490390525871801097705197944e+121L, 3.17440111243586504420672164931106998e+125L, 2.69662400176189239027511019786185589e+129L, 3.04979932232044716644635827452454425e+133L, 4.63404152681868778475392087605038845e+137L, 9.54898313480310651224157422560754643e+141L, 2.69440486619208982853089677098686964e+146L, 1.05150272003639532507210605903884076e+151L, 5.73417064062624495509840837865743050e+155L, 4.41627650777870044428827641421915327e+160L, 4.85653500442164862297918118887566388e+165L, 7.71243776020172406235461422008761914e+170L, 1.78944284768135145352387398006192815e+176L, 6.13948504948193852500464630902178966e+181L, 3.15374719244414866832063986813364807e+187L, 2.45678229633130089072342575625791640e+193L, 2.94097956743157560377748279040964662e+199L, 5.48435772238022826264635788020315114e+205L, 1.61576755939787162649511106856450099e+212L, 7.63055674811964328822328719215905762e+218L, 5.86357963426750903008317058039636736e+225L, 7.44578009523250679265610908767109796e+232L, 1.58753358925950887380498944645468602e+240L, 5.77757179750005470017336807397418313e+247L, 3.65046885264085030960970127282511879e+255L, 4.07509702021276189043935129812053895e+263L, 8.18389073292535025618266801702554839e+271L, 3.01238089652162618211263051563523370e+280L, 2.07176624104483264053704912869659325e+289L, 2.71562735784398218302697011744202385e+298L, 6.92451661016398143622710849660362520e+307L, 3.50810155650162047040906671177815417e+317L, 3.60896781300246599975888048597671985e+327L, 7.71058277826701049982730585006218034e+337L, 3.50154660288711246272389096490054302e+348L, 3.46175331564137723439223486579386975e+359L, 7.63696466254316472130052183903629062e+370L, 3.85655304044390258996784681505914035e+382L, 4.57665692577932081843759029527968784e+394L, 1.31143566628034307965133274338127595e+407L, 9.33142940209453779649608781259673613e+419L, 1.69703443400488874615229289912465401e+433L, 8.12664327627950884948530966790210152e+446L, 1.05671342182667061564323377987059929e+461L, 3.85123350151333031094457679550412807e+475L, 4.06487630836024540948583469098247829e+490L, 1.28516517984503545753808504263016648e+506L, 1.26025754690341684764700072541766676e+522L, 3.97331612896914344554453503890576277e+538L, 4.17965516524315248567041014799432863e+555L, 1.52416658652941127494202186163265994e+573L, 2.00432202283496263048589917253126663e+591L, 9.89983817930114056039301724151237036e+609L, 1.91539340453423886973992445388091844e+629L, 1.51593315523153267229971976448703684e+649L, 5.13233111267478387648166311677061530e+669L, 7.78392571224632702458474933380523830e+690L, 5.54632077048043201021342066119640603e+712L, 1.95012604607548018918112113273623192e+735L, 3.55940947870861006830654543397286882e+758L, 3.55349341454925685547195460273265331e+782L, 2.04795692045857243226580641802720017e+807L, 7.20348918974342452885439546130773017e+832L, 1.63778937282231874342883712446170710e+859L, 2.55384218509638087014670377175798088e+886L, 2.90332357089198897009653578594580665e+914L, 2.56300421336271050326091753908665515e+943L, 1.87504708602076913446948153935468528e+973L, 1.21573089114719501597325465689193734e+1004L, 7.48693407429699486755736805187051392e+1035L, 4.70376397570597947605315058283235338e+1068L, 3.24549375035327607806235059706162609e+1102L, 2.65365798053210741189633750297123713e+1137L, 2.78113361306514574568406809189880354e+1173L, 4.05114001708803517429009145027606492e+1210L, 8.91647476482514121118371429882160487e+1248L, 3.23223851331898724884680382253593571e+1288L, 2.10925909168894371224120829576314259e+1329L, 2.71594389750881594498007515800169231e+1371L, 7.58558239286242519535157411695442827e+1414L, 5.06701669031717221741926320252846248e+1459L, 8.95314256637167381172114473249653533e+1505L, 4.64314397380853725563695225910483395e+1553L, 7.86772811149376784892131781209226509e+1602L, 4.86578559687970087801384706555207321e+1653L, 1.23116054769360594876926981962811083e+1706L, 1.43383897399728293235616506956599019e+1760L, 8.67960762728500385489074199138374599e+1815L, 3.09584788327503858182429306492345781e+1873L, 7.40514657822678853879551103162851562e+1932L, 1.35750288266752565171774149402837640e+1994L, 2.18886955807028168114167639122307268e+2057L, 3.57839966436010585653478204799948336e+2122L, 6.86791017358151132323155526430183469e+2189L, 1.80021943882415618419042799861559854e+2259L, 7.53312429569410546159363413753399067e+2330L, 5.91165553375547478649257686857639971e+2404L, }, + { 1.57096255099783261137673508918980377e+00L, 1.57229290236721196082451564636254803e+00L, 1.57495658191266675503402671533627186e+00L, 1.57895955363616398471678434379990522e+00L, 1.58431078956361430514416599492388597e+00L, 1.59102230111703510742216272394562613e+00L, 1.59910918118616033722590556649394763e+00L, 1.60858965710906746764504456185444654e+00L, 1.61948515482641974319339137784305225e+00L, 1.63182037453073931785527493516038124e+00L, 1.64562337819112567903033806653906069e+00L, 1.66092568939542410935608828998468834e+00L, 1.67776240601646371733138779357535047e+00L, 1.69617232627708297296989766202480515e+00L, 1.71619808886073246730768842066355199e+00L, 1.73788632779101456236627555096372654e+00L, 1.76128784288515241044102589887617560e+00L, 1.78645778667368642025315725404601102e+00L, 1.81345586877233558659749539967614045e+00L, 1.84234657879265254187280543490489739e+00L, 1.87319942898662752121993510591579920e+00L, 1.90608921793761261888076943857856180e+00L, 1.94109631673677945144587926354356120e+00L, 1.97830697922181656566949720098719647e+00L, 2.01781367800384433737712026561151498e+00L, 2.05971546817081389507270282494773392e+00L, 2.10411838073232749275747224342524909e+00L, 2.15113584806337555354918618566085438e+00L, 2.20088916381459141771044083611555369e+00L, 2.25350797998611420231160903572594743e+00L, 2.30913084411305337537709048855358397e+00L, 2.36790577978511333384857209921738492e+00L, 2.42999091402365295350102767412517845e+00L, 2.49555515536908558968587982458158759e+00L, 2.56477892689313451429557802920827974e+00L, 2.63785495874745168415081659796280588e+00L, 2.71498914529626806741705564771250802e+00L, 2.79640147236028053619149909690973720e+00L, 2.88232702062657870038560203490158574e+00L, 2.97301705186029380311201985278736098e+00L, 3.06874018519362823755119514588303156e+00L, 3.16978367147348738564623946178566521e+00L, 3.27645477442732860056345607892739085e+00L, 3.38908226826615609816107421136979984e+00L, 3.50801806229286913554992299494422526e+00L, 3.63363896413353027399263692498221540e+00L, 3.76634859436988420367634452674074607e+00L, 3.90657946663630928939225987850575005e+00L, 4.05479524866754112035397645627643742e+00L, 4.21149322136091780158052739625729631e+00L, 4.37720695466646221916071477112304019e+00L, 4.55250922105994638849140210916632132e+00L, 4.73801516951078282566987752649050466e+00L, 4.93438578525358788671420711795537458e+00L, 5.14233166333819107447595069798421539e+00L, 5.36261712689997622445803908396748884e+00L, 5.59606472439710019418213140693069575e+00L, 5.84356014374437330661446789126222075e+00L, 6.10605758538173469317727364122669467e+00L, 6.38458564090067143612732202429488542e+00L, 6.68025372897382444864907987044889317e+00L, 6.99425914605841270881961646990609410e+00L, 7.32789479574890106033548644768353338e+00L, 7.68255766782458876413667730681699443e+00L, 8.05975814607113727007240055318338450e+00L, 8.46113023296234288939356989479671723e+00L, 8.88844278939567108027044653070693778e+00L, 9.34361189902548515485066576358196470e+00L, 9.82871447949462202212030994384949241e+00L, 1.03460032772138062549383568058709409e+01L, 1.08979233984912291622835480030167114e+01L, 1.14871305480132578973614919602781370e+01L, 1.21165111661978855517781913327317255e+01L, 1.27892046801009632078942555615288463e+01L, 1.35086281087128109623831457304510920e+01L, 1.42785032930533442126932924888187804e+01L, 1.51028870549318132669071327511660921e+01L, 1.59862046261270319640752848374642080e+01L, 1.69332867326908112807352382039426796e+01L, 1.79494107678000050622926329104204826e+01L, 1.90403465419082315888820165929975494e+01L, 2.02124071618296433363312214170232623e+01L, 2.14725056619224736964251610816575600e+01L, 2.28282180919971350546248653847563966e+01L, 2.42878538594168042463845071817020910e+01L, 2.58605342287811778487151334440784950e+01L, 2.75562800035467442565131080245429614e+01L, 2.93861095522110956389210768876799587e+01L, 3.13621484999095132865600012683857137e+01L, 3.34977525874991258153646142408367963e+01L, 3.58076454079962546803810835720597110e+01L, 3.83080729687253016658377309622401176e+01L, 4.10169773015547344709659456503154667e+01L, 4.39541916587611362308342994483809472e+01L, 4.71416601949419692729062784327679986e+01L, 5.06036854536665922553724504470269960e+01L, 5.43672074601944525232284101611170030e+01L, 5.84621187791213843904071404608607478e+01L, 6.29216205405812878410372213510070276e+01L, 6.77826251851241666263837617897404532e+01L, 7.30862125426522301461255132629846162e+01L, 7.88781468648814729209715096907821639e+01L, 8.52094635973465833426799692679733796e+01L, 9.21371360338777471668559829773781201e+01L, 9.97248335767075464896305315099053068e+01L, 1.08043785167904642576949987865910954e+02L, 1.17173763608862169247776700625586421e+02L, 1.27204208998868737227575356110541727e+02L, 1.38235512466410237338282474486031692e+02L, 1.50380484815148331050381123359927804e+02L, 1.63766038752610274212021042234298836e+02L, 1.78535118123338340289613569013808793e+02L, 1.94848913160728060357302969254459805e+02L, 2.12889407359835266977366307026062112e+02L, 2.32862309344799079018746113493039633e+02L, 2.55000432284328199435640048881527463e+02L, 2.79567594267244578195192766207761694e+02L, 3.06863125912428093434496643114651412e+02L, 3.37227086745120087399301385427960651e+02L, 3.71046309996557625549265358225650347e+02L, 4.08761417046617491055856040237506316e+02L, 4.50874968419459367009632339064163929e+02L, 4.97960948895977349122916983180817637e+02L, 5.50675820938578587679472462796822793e+02L, 6.09771424466317909206822143572649707e+02L, 6.76110053572647368547479902312230309e+02L, 7.50682103874142244645724064576848341e+02L, 8.34626760051808119187547981730818179e+02L, 9.29256284531554199823656475151338963e+02L, 1.03608457849823472804207172846963877e+03L, 1.15686081966189765730466332807313547e+03L, 1.29360914245380859999201252074469995e+03L, 1.44867552185420514387789438088656434e+03L, 1.62478325953219761549580736728832563e+03L, 1.82509875991531856022535679631713756e+03L, 2.05330963597261755441688599655848892e+03L, 2.31371761449477720025881552764731872e+03L, 2.61134923664018699944734187657483567e+03L, 2.95208799409362429898911389656789101e+03L, 3.34283233256054817982471990245472659e+03L, 3.79168492775659509883214798303432158e+03L, 4.30817983871631895490690508451026040e+03L, 4.90355562457020167332670064217006554e+03L, 5.59108434363481145162671079876733528e+03L, 6.38646862557124634146730890858054275e+03L, 7.30832182941297944038809179971510199e+03L, 8.37874981279970356111509048453001571e+03L, 9.62405721874963805881171453111047092e+03L, 1.10756066619114600841076275282388063e+04L, 1.27708660544590438787794590107117849e+04L, 1.47546879201948945213025955616435132e+04L, 1.70808753741706634268551294101897318e+04L, 1.98141030969548505096681178137364270e+04L, 2.30322788820475490754732581365999861e+04L, 2.68294531792863253502182123460963590e+04L, 3.13194117839842820030641964449539820e+04L, 3.66401220970699799668192565829190288e+04L, 4.29592483666869017028607105165763804e+04L, 5.04810088263984357248209974578040223e+04L, 5.94547213318005529011388227962133751e+04L, 7.01854787517268957919092596317475529e+04L, 8.30475172617569400265716546608431303e+04L, 9.85009980505357544638949542794405193e+04L, 1.17113126626176606026864191754698095e+05L, 1.39584798216058984483938678946454092e+05L, 1.66784301639307755633312351999980104e+05L, 1.99790062652052468605951710457597772e+05L, 2.39944994603299218686253514351518948e+05L, 2.88925793983801323167992289814829493e+05L, 3.48831530919430454806103930858415528e+05L, 4.22297220149677844682618484564386312e+05L, 5.12639824636925361908056913471196846e+05L, 6.24046487622198979196137566922551170e+05L, 7.61817907323361594136262168936978923e+05L, 9.32683930022411925704630601110030182e+05L, 1.14521400777429753902355978052778602e+06L, 1.41035264627423311876298925540665884e+06L, 1.74212004187586338510201667214170577e+06L, 2.15853171693428701405141183541166264e+06L, 2.68280941012642673073659887232388938e+06L, 3.34498056359541886091597912499527306e+06L, 4.18399797233770604788689812330719069e+06L, 5.25055800816550175243256559083639418e+06L, 6.61086017414168098803951872291131863e+06L, 8.35163942396755869310534556270941378e+06L, 1.05869253239392990034806970327887878e+07L, 1.34671523510623940861241599892229316e+07L, 1.71914827102426302145958883698307763e+07L, 2.20245344902770169422620623417295079e+07L, 2.83191730172433779681268016861978467e+07L, 3.65476782026834493187990343694010282e+07L, 4.73445265723062610640363034466641760e+07L, 6.15653406350951387288804933390908042e+07L, 8.03684302689786924828741611740519293e+07L, 1.05328028435969028854761469747289545e+08L, 1.38592168908412628618546923035162247e+08L, 1.83103698592568352374304770508191971e+08L, 2.42910945745864082034287213456845086e+08L, 3.23606239375966746282831194186614169e+08L, 4.32947521859998666323053129499091577e+08L, 5.81743296796292947920442886775592966e+08L, 7.85117978938819178602650773642870262e+08L, 1.06432919762707530726575966438229782e+09L, 1.44938958291294548467516226794019366e+09L, 1.98286646937799184909776706883985509e+09L, 2.72541431469809432350206616813747393e+09L, 3.76386796411162144400474070771015333e+09L, 5.22313881495099093715899688078276720e+09L, 7.28378581064439770444275729738468286e+09L, 1.02080964238115874250636198090464363e+10L, 1.43789931847051052135186583023967432e+10L, 2.03583681254363357780032810961889254e+10L, 2.89749982708002744366825785538936402e+10L, 4.14577375164549487752492409798515416e+10L, 5.96383768387242628650336526594122215e+10L, 8.62622848391553079951805623395652598e+10L, 1.25466704538982518000690409655705216e+11L, 1.83521298226491318558080545133554232e+11L, 2.69981220740015160361114268684563366e+11L, 3.99492845215192295441294253418780644e+11L, 5.94638055870143455023933020703444642e+11L, 8.90440996742409110650533033931653292e+11L, 1.34155194167777583831947241717631506e+12L, 2.03376855033215189170105222958089604e+12L, 3.10262795987575321360135087196684567e+12L, 4.76359832170586206290082815387968037e+12L, 7.36142036056081358397678626842794083e+12L, 1.14512696145655742338758840735549183e+13L, 1.79331418699627392634462052642542749e+13L, 2.82758550128579223200239017529280909e+13L, 4.48929705367844466861372765075631687e+13L, 7.17780287265849957064212371548037347e+13L, 1.15585509854582062520354852997620279e+14L, 1.87483388636788309288478433629583664e+14L, 3.06351035640217445409310567498133847e+14L, 5.04340065300597024230361727189343426e+14L, 8.36616339689242989007881200440488764e+14L, 1.39855635164094728875364679627485304e+15L, 2.35633574951616468243164849507855064e+15L, 4.00176516738263745645278590345795707e+15L, 6.85137512840494144543571512545601884e+15L, 1.18269011176154399046326619510431010e+16L, 2.05867352701380644281110910622942185e+16L, 3.61396878431490463311666873476678412e+16L, 6.39911218439421355095519025524482256e+16L, 1.14301618562837692261569180960886276e+17L, 2.05988138391566644299797673070467922e+17L, 3.74584678835368091393630059068193045e+17L, 6.87444303468314906803024757565005462e+17L, 1.27340764361348531366853034790770231e+18L, 2.38124191682989536626992792404294190e+18L, 4.49583561730710839927340662784958898e+18L, 8.57144202490195270096830399067728169e+18L, 1.65044358418165696532477771893166700e+19L, 3.21010035242131785085169993033188229e+19L, 6.30778012444270309076492866733769742e+19L, 1.25240403115766127899628450500249765e+20L, 2.51300529564998539443832117224536420e+20L, 5.09677625569083843571268035202853929e+20L, 1.04501920001667304566512216455267827e+21L, 2.16647647926087846601520265828431353e+21L, 4.54213814567839546278770815494416868e+21L, 9.63208232444913712819259248595549405e+21L, 2.06638653668825452816630915727527426e+22L, 4.48552978555442825059406438230470388e+22L, 9.85387957361097750825498509227133701e+22L, 2.19115887446437440814640517501285189e+23L, 4.93283596439097166796547625560314132e+23L, 1.12450152997177436346173556893175508e+24L, 2.59626913615675600812300017445220112e+24L, 6.07229293831362550112108555687653017e+24L, 1.43898906630800383562329122001513450e+25L, 3.45584195640657046905140678735606870e+25L, 8.41265519171357648977229820858109463e+25L, 2.07628906165081651016090959669418757e+26L, 5.19651502464022032237151119613068945e+26L, 1.31917319408964404296057699402007921e+27L, 3.39745589598038079361346075350889747e+27L, 8.87905745443850359109225209251728000e+27L, 2.35527236149206412607849676379867126e+28L, 6.34276200772262482389475687836384423e+28L, 1.73453109399085970484897533524593455e+29L, 4.81789317060683087119323058524624972e+29L, 1.35959734649014823198654051259347560e+30L, 3.89896968990650039174705544740914822e+30L, 1.13654298652998993600898528562905634e+31L, 3.36845004399178001650511659074612092e+31L, 1.01530408470981725989945294876828360e+32L, 3.11314437622191823730222798219255685e+32L, 9.71307273973014040273869048577801862e+32L, 3.08451764358172594571945077912559223e+33L, 9.97268213982049728423469082288644341e+33L, 3.28362505228849158612675319471610094e+34L, 1.10137878539082753552686700652535380e+35L, 3.76433336759271429732220889611944227e+35L, 1.31140346593824292621577115225698644e+36L, 4.65813571068281367213354863266427946e+36L, 1.68751734747051139203189162215633629e+37L, 6.23705368501832349017363870039959902e+37L, 2.35257131442774486893301429598817553e+38L, 9.05893824021969993626817980294413695e+38L, 3.56224909761113607077591549609142868e+39L, 1.43095929157855820977839447284784020e+40L, 5.87397458498437504922632656680942932e+40L, 2.46482854981128378684502286098690220e+41L, 1.05764920309085562822396787743332401e+42L, 4.64247563928107803530506772359734012e+42L, 2.08528711827242177927156523287132065e+43L, 9.58843998518663217709277358040461543e+43L, 4.51498201124609227956079072858258677e+44L, 2.17797404834197320411588567916752909e+45L, 1.07672097682290045825361349736107198e+46L, 5.45726743292908558875367244655615249e+46L, 2.83686927045578113375020568154351117e+47L, 1.51310320139201162564313806536303971e+48L, 8.28397466722561707458255405781541923e+48L, 4.65723949199597134403065145457979764e+49L, 2.68979637071283693718739500357715726e+50L, 1.59659784691197038762901224386099403e+51L, 9.74415453825658662874112107295166701e+51L, 6.11723839484331306452493250946377612e+52L, 3.95204965058524182677586041680204451e+53L, 2.62870159207425821306145211826683375e+54L, 1.80099019650267939321809025642439880e+55L, 1.27155446256306838318997486480890087e+56L, 9.25588010447776071059464920928086632e+56L, 6.94973792013391939342588109222317053e+57L, 5.38516720076996562080859176422021036e+58L, 4.30849366810297877444039522534393308e+59L, 3.56095155754217837059656555899190815e+60L, 3.04188852838464999204043663335571874e+61L, 2.68709444193083718922293037351168007e+62L, 2.45592053890000085507656649738841713e+63L, 2.32364825416864153745578539849845717e+64L, 2.27712974158489233058096874867974690e+65L, 2.31263355291322473374027008502422191e+66L, 2.43540759298129112939388619780518297e+67L, 2.66091038882246524570905302589811279e+68L, 3.01810594342353392025458974267831671e+69L, 3.55582348951019250289525994888733340e+70L, 4.35418887779384901315251041444022899e+71L, 5.54497579551181331524599144834616000e+72L, 7.34827648190988633565298908145357523e+73L, 1.01399802572242326074394064208241565e+75L, 1.45791146224460794340779409761344050e+76L, 2.18548887681950529537081926891986328e+77L, 3.41802215328662300798456454917771592e+78L, 5.58084392060183572830239216435019125e+79L, 9.51958650279973390758331753317257950e+80L, 1.69757357824719778562747265505252946e+82L, 3.16690667099018001388115076193097403e+83L, 6.18509910641867543038652223056425804e+84L, 1.26554113438693437654962757714903554e+86L, 2.71482896587775689871692274985919286e+87L, 6.11038680296449408162222719197467046e+88L, 1.44405408617108323852658132530082074e+90L, 3.58608372663838816495703910754396082e+91L, 9.36523186806323959966772742491929522e+92L, 2.57408011620512244881601880029319908e+94L, 7.45213468986230271920125476429174422e+95L, 2.27430990383616981910627355587444817e+97L, 7.32301113412116474943463116371095103e+98L, 2.48981642173793246167799170730006141e+100L, 8.94653338635928158843209476986997508e+101L, 3.40040137239116597862336436061445989e+103L, 1.36828818620892821730981225660157834e+105L, 5.83427748982959193060571787534606697e+106L, 2.63848693767238342424340754241860221e+108L, 1.26672888276713952132156406152434700e+110L, 6.46222517831418280306046165038174027e+111L, 3.50643232060757360375065377104810475e+113L, 2.02560893394326816509670349356333828e+115L, 1.24704167708478470702273287091045609e+117L, 8.18986518840527903795498196049278255e+118L, 5.74361089440609996487936977642920132e+120L, 4.30580893408448976261136511421423734e+122L, 3.45415696607949675499703108821962730e+124L, 2.96831660153035273688363706593385374e+126L, 2.73545624237218359223636851390580041e+128L, 2.70631717669007784745026117275242499e+130L, 2.87767991634206038473084413615742294e+132L, 3.29241287826810639047033778585737812e+134L, 4.05784096195372596931902665934287382e+136L, 5.39378304910573732382585500687737807e+138L, 7.74152390167223540621293648465491842e+140L, 1.20120996231066845642412985516875175e+143L, 2.01745607955680730064740044686640147e+145L, 3.67217662348306252636962893865111425e+147L, 7.25316379805857762968710347450256630e+149L, 1.55659153530257056999948366173645285e+152L, 3.63439983279039488510674235872123571e+154L, 9.24438760046827764031744167566698413e+156L, 2.56505460126015154661078513762260065e+159L, 7.77468767447849521051212939671796074e+161L, 2.57775340952739965069105894604883404e+164L, 9.36236559200171990439286451934391539e+166L, 3.73025928974609135812613567068392186e+169L, 1.63280699411172483017448754437467171e+172L, 7.86350685466830069681739337700194312e+174L, 4.17288659053103260909421860789088638e+177L, 2.44376468354452976432259429734905692e+180L, 1.58182604983516221850901239956537929e+183L, 1.13349408906485996833819126879692168e+186L, 9.00609317867158059779746161516574861e+188L, 7.94724581006520631483760616875503191e+191L, 7.80148734070770210787180909072341250e+194L, 8.53389980133319877537947288273508168e+197L, 1.04199907704816359699116619452657846e+201L, 1.42261945983107616739713958471131412e+204L, 2.17558254343347922345039318825837040e+207L, 3.73339221107050141050095672544726852e+210L, 7.20212971416878494124587287789857735e+213L, 1.56476087980246841023430707631510252e+217L, 3.83599289170088247519036274601375492e+220L, 1.06310518934360483187879118646180568e+224L, 3.33719954606082150504485397744546787e+227L, 1.18890644129926367056386614030943443e+231L, 4.81657405194041613555936914144916344e+234L, 2.22347874123114616622582251703709887e+238L, 1.17199258523361213934517364652872480e+242L, 7.06839671131322838482398929154588609e+245L, 4.88812662946732326430886472870070228e+249L, 3.88441192207630934518298772235960268e+253L, 3.55483921979499015020713995580889030e+257L, 3.75484510816250928148708038190395303e+261L, 4.58798720933643387311573482445886110e+265L, 6.49989966050568126079524541048529496e+269L, 1.07018103272413666142402906179157598e+274L, 2.05258799808849457042833394124187317e+278L, 4.59710306190259625117029822247574448e+282L, 1.20521640888055636836192268959955157e+287L, 3.70784262206985650361726040790594581e+291L, 1.34198324051735290325452259089861845e+296L, 5.72866922601176092550850127280325304e+300L, 2.89181208605318627652310091586335359e+305L, 1.73078309894901278503683645288680165e+310L, 1.23150483936231719457381379774516673e+315L, 1.04456022524616506171048138618772005e+320L, 1.05909848234544418123752752792015094e+325L, 1.28725694153849592436889057738754649e+330L, 1.88087499295689639308903342601320607e+335L, 3.31344446614783992260480183208324732e+340L, 7.05835740270200829603933852702222207e+345L, 1.82360609116987101874149506325271866e+351L, 5.73167527316999715111499624522524490e+356L, 2.19834460849656433024448179756162490e+362L, 1.03213196012299389398122351217909554e+368L, 5.95090459142945173642877532664315820e+373L, 4.22711326689560391486862730288730260e+379L, 3.71146073815998244096864189178283440e+385L, 4.04143285030597516778349567433491877e+391L, 5.47630493200706306950643242188138639e+397L, 9.26610183846830899934754118194991047e+403L, 1.96463867218278875638951764233831097e+410L, 5.23826401399289488725708314794013273e+416L, 1.76269979359229195206462702562496087e+423L, 7.51358974574222029659643352716721030e+429L, 4.07203690042780566335825621191079282e+436L, 2.81652392485993763998682010256080428e+443L, 2.49586432083962995754217338958145192e+450L, 2.84464997550187838898841424132533307e+457L, 4.18656911271834268911740204159815337e+464L, 7.98835944729121866190974499356597568e+471L, 1.98427885725374523364086923738598523e+479L, 6.44313780728812316513345459942694301e+486L, 2.74646447436726496994650106679472135e+494L, 1.54345331097536381511922890966406624e+502L, 1.14854061177091306735355343708426610e+510L, 1.13671799925771100929831048483235430e+518L, 1.50301408173820906903238314130252343e+526L, 2.66721742401349021977265127553699936e+534L, 6.38191727827371990119668697526910696e+542L, 2.06864189323929509313332139375745418e+551L, 9.12718925758572793769909253655546363e+559L, 5.50827087084343716443556503345322384e+568L, 4.56943096951975523591483538202467049e+577L, 5.23664812769936727945516120554813767e+586L, 8.33295831969513770916127078276468196e+595L, 1.85073603040006635508770638738735213e+605L, 5.76725912854578779706265298662279369e+614L, 2.53507221317613667093309510235117825e+624L, 1.58037348241924263546145926074674624e+634L, 1.40497098317887844492262106048698980e+644L, 1.79118532756424559114150403858023467e+654L, 3.29340233091271285034548969456076701e+664L, 8.78384225704905897945003526718634352e+674L, 3.41824790512159692619674889187554870e+685L, 1.95247619547378795632466874007982924e+696L, 1.64685615123975037569921507294781182e+707L, 2.06385512057306929298128483493412318e+718L, 3.86691162964076111860523245198584961e+729L, 1.09008736553561747232882422664193409e+741L, 4.65333391196364819411904308657257877e+752L, 3.02768585771015415481330091322447912e+764L, 3.02262040534180824988954474846992913e+776L, 4.66133722640174567906974646266839244e+788L, 1.11806119156969171229108916233644999e+801L, 4.20019655376202192049844032418033555e+813L, 2.48880615873773868126893696694455625e+826L, 2.34286193142054643224145247339492426e+839L, 3.52941162196327496812531706159176164e+852L, 8.57183106082165907783781027353105401e+865L, 3.38163627323872188047900717079347979e+879L, 2.18363447282104345585022834572887531e+893L, 2.32596275137292895223293068081362090e+907L, 4.11925247272574761366980289309686003e+921L, 1.22265489460258041690738897372130823e+936L, 6.13184165651799059701146847592463464e+950L, 5.23922303275545560334122760478493484e+965L, 7.69087233862553980667730597006685190e+980L, 1.95622275953749870274795206909257068e+996L, 8.69670052895401378378113763338699958e+1011L, 6.81715148318539616903616353647181598e+1027L, 9.50697711954141544724599553989093262e+1043L, 2.38019733682587370869498352841844428e+1060L, 1.07973324919847346937291516197684901e+1077L, 8.95814284819025403820872820042945790e+1093L, 1.37229192661307043018958002675397831e+1111L, 3.91918794622242371528673544888524419e+1128L, 2.10730218913863433412315532873510194e+1146L, 2.15459607934366008026324206138837528e+1164L, 4.23163839295623007237154131840451677e+1182L, 1.61294441956204958952970453918741185e+1201L, 1.20568335528354973250479511763057854e+1220L, 1.78630819666459637235669417819650103e+1239L, 5.30233997012953850434143324467683139e+1258L, 3.18800705045665419646272046839479382e+1278L, 3.92589619613994835597705628928304867e+1298L, 1.00145056975313260959947278741812233e+1319L, 5.35268808912615454171856125906228237e+1339L, 6.06491960606218539467705074145131193e+1360L, 1.47410187506507259371724909079906759e+1382L, 7.77855372825975976779550291054389078e+1403L, 9.02071339187528665617085297107535931e+1425L, 2.32776342394968427168699373890370933e+1448L, 1.35351409374730203846799381939288903e+1471L, 1.79625881886715571166142200348072039e+1494L, 5.51189494978629938318487744451579809e+1517L, 3.96270198063441303687686251379779681e+1541L, 6.76492837567767494547614386605795924e+1565L, 2.77991073110506719318274536923711255e+1590L, 2.78805951202715437087943440518839779e+1615L, 6.92116280606414755524296394791409952e+1640L, 4.31380309053366092943951122004431463e+1666L, 6.84923073262139995438889690748178280e+1692L, 2.81137418164430829179092468240459910e+1719L, 3.02821524237655652451836921974619657e+1746L, 8.69048903533522694231765189726868666e+1773L, 6.74828063313306417588175763238310325e+1801L, 1.44026065844141159256872926595644247e+1830L, 8.58426091495439408178371839859019039e+1858L, 1.45211919400936944187225846047638548e+1888L, 7.08718013380970011842483247147601395e+1917L, 1.01475962220405902523641440040104610e+1948L, 4.33542978691578087509838132034723750e+1978L, 5.62285772227295495777726116212032065e+2009L, 2.25285072921565445630031609130087435e+2041L, 2.83839050906274298341210206309759282e+2073L, 1.14501659579022194588844609345877849e+2106L, 1.50629562239998305958408533546634030e+2139L, 6.58342161306998815751663631350733541e+2172L, 9.74198999952210922892973281379349494e+2206L, 4.97552704772088889228035264268694867e+2241L, 8.94330619882842342247706838649878784e+2276L, 5.77072420156026800834371478648673792e+2312L, 1.36388225285320494361282201451878478e+2349L, 1.20508189950290985406298094670730466e+2386L, 4.06413362486490272506766749982212198e+2423L, 5.34308092015215251528601382597439463e+2461L, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 8.88600744303961370002819023592353264e+00L; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif +#ifdef BOOST_HAS_FLOAT128 +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828741797632286606397498241221385e+00Q, 1.48993184649209158013612709175719825e+02Q, 3.41228924788343710247727162226946917e+06Q, 2.06932576604261779073902718911207249e+18Q, 2.08700240760947556038306635808129743e+50Q, 2.01976616071790815078008252209994199e+137Q, 5.67213444764437168603513205349222232e+373Q, 3.06198394306784061113736467298565948e+1016Q, }, + { 9.13048762637669674838078869945948356e-01Q, 1.41578929466281159169215570833490092e+01Q, 6.70421551622327648231120321610008518e+03Q, 9.64172532715049941526010563818587232e+10Q, 2.50895076008577848514087028569888161e+30Q, 1.44726353571033714499079379626715686e+83Q, 3.75263401205045334128277886549019357e+226Q, 2.57846123932685341261715758547064293e+616Q, 1.25169402230987931584130068460134989e+1676Q, }, + { 4.07297690065758690150573950473604675e-01Q, 1.68206670702114874332932330092838356e+00Q, 6.15089798638672951539668935798437533e+00Q, 4.00396235192940022205839866641270319e+01Q, 7.92920024793102632052902471550336177e+02Q, 1.02984971333097958319686053784919407e+05Q, 3.03862310925243857437932941891415841e+08Q, 1.56544547436249486913719231527597560e+14Q, 4.04246509843021910355659662715183671e+23Q, 1.32170682742965817915034577861235933e+39Q, 4.99123178209955799774620736137366103e+64Q, 7.35294385035987596594501676609562008e+106Q, 2.45145417229813114714431821340237112e+176Q, 1.03030479197459267961759023741376327e+291Q, 9.88478945193556730604342445576518136e+479Q, 3.74498116076433060427765453233124618e+791Q, 1.90292390713026708045766158039087796e+1305Q, 1.72712488231809244721915842027236657e+2152Q, }, + { 1.98135272251478172615235718398538323e-01Q, 6.40155673500526017670785720911319502e-01Q, 1.24892869825397766254802900819319987e+00Q, 2.26608084094432123181038001270985037e+00Q, 4.29646269670232738148137717958679987e+00Q, 9.13029038709995569641811827045549232e+00Q, 2.31110765386427993316995139635470937e+01Q, 7.42770603432401243012214481410240677e+01Q, 3.26720920711525891697790966796945063e+02Q, 2.15948569431181871552028449867301828e+03Q, 2.41501526289641306037808670196966696e+04Q, 5.31819400275692915826269282626844010e+05Q, 2.80058685721704332307817790755562305e+07Q, 4.52406507979433877971977526863358905e+09Q, 3.08561257398067712180174566763237112e+12Q, 1.33882673301580747789133427708622972e+16Q, 6.25461717656234138147247754416652254e+20Q, 6.18209853581416475394863999233554548e+26Q, 3.07729364978845806686511011060697837e+34Q, 2.34895728937010430290698332595743680e+44Q, 1.14854319789946975790127332653552673e+57Q, 2.25530007001006986846545694404767295e+73Q, 1.87791950056919539419801461538703336e+94Q, 1.36747388793862427976781689638282239e+121Q, 4.24212177246407592514720294750151286e+155Q, 8.23473099012134325391170623028607158e+199Q, 6.06134211888406631001019923425936351e+256Q, 6.32519197436029413652766295658658263e+329Q, 3.61942292928205643948383705201563065e+423Q, 8.82464433126646489632943769283758364e+543Q, 3.35512488018651738642854323317447493e+698Q, 1.02411434678684822400261582079656500e+897Q, 7.40716670979374017620610271197945784e+1151Q, 1.30455147283895162835186634827124464e+1479Q, 2.02948723345659016173510134582487641e+1899Q, 6.99019443250345564805134094483457477e+2438Q, }, + { 9.83967894006732033862249554537934739e-02Q, 3.00605617659955035122465185012715805e-01Q, 5.19857978994938490000644785900799951e-01Q, 7.70362083298887700858583505753306721e-01Q, 1.07131136964131183026831222500748063e+00Q, 1.45056975808899844502126797109703210e+00Q, 1.95077854952036033400296546339240312e+00Q, 2.64003177369555146770080103921424631e+00Q, 3.63137237366741227331951933364601985e+00Q, 5.11991533090335057003526222543242753e+00Q, 7.45666098140488328926087222725984231e+00Q, 1.13022612688997262443461342203136009e+01Q, 1.79641069247277254966592982669611020e+01Q, 3.01781070460189822236726995418068214e+01Q, 5.40387580031237056709826662540066860e+01Q, 1.04107731447746954767459980678311109e+02Q, 2.18029520120262807725988909352359830e+02Q, 5.02155698625910164594509258651311707e+02Q, 1.28862131099822242045586488612672886e+03Q, 3.73921687080054832376623401153054636e+03Q, 1.24750729702019123239464970064060864e+04Q, 4.87639975322669212414357357061002683e+04Q, 2.28145658221913012154676335814417144e+05Q, 1.30877796006484301664040981436471740e+06Q, 9.46084663420966407698078336053299177e+06Q, 8.88883120363727962245667776649286152e+07Q, 1.12416882897434413447175648471746990e+09Q, 1.99127672953214446985509145592687205e+10Q, 5.16743469106098464964433058111638245e+11Q, 2.06721881420399088776240044545119948e+13Q, 1.35061503318410040604770421574064883e+15Q, 1.53854066283650818848773859278941683e+17Q, 3.29074729054035066052820102585085173e+19Q, 1.43729138188449881561963100200796631e+22Q, 1.40983244553034728562740932242727657e+25Q, 3.45913548027797144127990544649862792e+28Q, 2.39872058234095409213724024023509754e+32Q, 5.39880660461729295997086364918754801e+36Q, 4.61334000258062860955942270137550165e+41Q, 1.78768590966790245678294238939560892e+47Q, 3.84198437012433853552557148945213178e+53Q, 5.75279795570858370009870455748773410e+60Q, 7.77181203842728655149182334288749850e+68Q, 1.26967304420408162635234502672130357e+78Q, 3.49567677376573156773252547632961336e+88Q, 2.36251947497169244454694635287097330e+100Q, 6.00214389327365112307366927985587840e+113Q, 9.29071630346415553922675334522602561e+128Q, 1.51444223803384709004933819608345315e+146Q, 4.83290204410990250226310317342789471e+165Q, 6.09623012864338569215560315517200736e+187Q, 6.73889214277659359787962707085479315e+212Q, 1.60917893672694484647176104023542732e+241Q, 2.30724123468764987944582372785293125e+273Q, 6.32636439816284705814531208407868829e+309Q, 1.23274815890184688792156489065830724e+351Q, 7.55519778823055185901318833981345378e+397Q, 7.85730655106759111844772008129590573e+450Q, 9.36328400229780321059086898529742817e+510Q, 1.11332545426270395766246494603539938e+579Q, 1.53432069979625061288117473415446630e+656Q, 3.94622553764411915381186808199466267e+743Q, 4.41554290953392996069257034424439949e+842Q, 7.62037777854651720247173134262034607e+954Q, 1.15650294539918196985498353779647134e+1082Q, 1.50761161209705395018419027031866347e+1226Q, 3.03485088181756935935831645680716816e+1389Q, 3.38561189018537177501905611143498298e+1574Q, 1.64407968993192526511230001818530622e+1784Q, 6.63148743223242467667800355907041029e+2021Q, 1.15911606715877477373516464924821476e+2291Q, }, + { 4.91151003502902493004859475143401791e-02Q, 1.48013149674360733270682895306542340e-01Q, 2.48938813740683685679302156785267041e-01Q, 3.53325423692668437764413545980527251e-01Q, 4.62733556612235325924240102411897269e-01Q, 5.78912068164096306746325958452873475e-01Q, 7.03870253386062779930091622585657886e-01Q, 8.39965859144650568772715366992985538e-01Q, 9.90015066424437614655918533324528544e-01Q, 1.15743257014369913143250540144278056e+00Q, 1.34641275918536176274682426896283388e+00Q, 1.56216711390133555099139972670978661e+00Q, 1.81123885278232337973709010374295886e+00Q, 2.10192441900655030086142289233010995e+00Q, 2.44484388558419793403331221069953203e+00Q, 2.85372074663291502355627105440782037e+00Q, 3.34645891095535078662878051589922609e+00Q, 3.94664582105783838715586741669722603e+00Q, 4.68567310159667852940801410152900804e+00Q, 5.60576223090815117543658276010994803e+00Q, 6.76433233683057420359243855855175747e+00Q, 8.24038317537998522052755780107530197e+00Q, 1.01439435612985772971719760903679427e+01Q, 1.26302471433889247197016543768391586e+01Q, 1.59213039578034525767683420917805218e+01Q, 2.03392186192185718515730871595417962e+01Q, 2.63584644576063375239063530328964372e+01Q, 3.46892633322415240903243772580777748e+01Q, 4.64129146701972896279022543245987086e+01Q, 6.32055079389042420324823016892494512e+01Q, 8.77149726180890637368701810147417239e+01Q, 1.24209692624041149789460094889690346e+02Q, 1.79718634784512755704082576283626343e+02Q, 2.66081728332790018970422286819998479e+02Q, 4.03727302957571284052623415274320934e+02Q, 6.28811306654590870314912279241546792e+02Q, 1.00707983750749059403228978538051896e+03Q, 1.66156822918511428805794334715835287e+03Q, 2.82965144078658259775800007408843245e+03Q, 4.98438626658566913853681230634186899e+03Q, 9.10154692764781089316711776560031531e+03Q, 1.72689265547504972749956316341831556e+04Q, 3.41309957877860119013952370617496464e+04Q, 7.04566897705309280220071327032864763e+04Q, 1.52340421776127912819322591860346971e+05Q, 3.46047978289794741370038030428999755e+05Q, 8.28472420923318300234685980449600520e+05Q, 2.09759614660119394556971994518988102e+06Q, 5.63695079886127323617800640982012165e+06Q, 1.61407141085560724511058572293479599e+07Q, 4.94473067891506035994359725043521250e+07Q, 1.62781051682099135552732962095205423e+08Q, 5.78533297163228083837980097936281368e+08Q, 2.23083854068195568971189557384768608e+09Q, 9.38239130606473964277252886929412279e+09Q, 4.32814954477655169232818147143370442e+10Q, 2.20307274404924290439096300978395664e+11Q, 1.24524506710913641251205336694034299e+12Q, 7.86900053495782237478847410099854059e+12Q, 5.59953143297942246131549106648666176e+13Q, 4.52148694990209087674492643778610401e+14Q, 4.17688951654829326508268412199901397e+15Q, 4.45286775965049665585698503105745526e+16Q, 5.52914285314049806809138826588984682e+17Q, 8.07573251656285427526228838811700627e+18Q, 1.40204691626046869792238856080062664e+20Q, 2.92579141283223985009947325351094360e+21Q, 7.42643302933541088612408356755400686e+22Q, 2.32199633124573536432554419147246735e+24Q, 9.06419425063844243203436385576505269e+25Q, 4.48127904881944560890552322697008678e+27Q, 2.84904630472699064463968599282594753e+29Q, 2.36738115918335597454764956918757980e+31Q, 2.61582557845512122680388807973635504e+33Q, 3.91476494826329080795479762913295296e+35Q, 8.09204244855592921872201325412806040e+37Q, 2.35892132094063033238721339006551614e+40Q, 9.91521864853533259120934844876236731e+42Q, 6.15285105934265876352030730244956160e+45Q, 5.78027634014451538840307809528507880e+48Q, 8.44375173418648862568787172019022001e+51Q, 1.97334335089976670761175825761931164e+55Q, 7.60524737855621997973474323106432459e+58Q, 4.99205710493951041807363394610235299e+62Q, 5.77586342390391231642398949899839793e+66Q, 1.22180820194535560304052518248291191e+71Q, 4.91291723038713381630505551954597084e+75Q, 3.91397181373220237220120723831917341e+80Q, 6.45638806990528678730571952330861768e+85Q, 2.31122506852801035759561549878351498e+91Q, 1.88745815771943133919251977215527414e+97Q, 3.70848316543845309405007424631179900e+103Q, 1.85519881228353863491690263658048910e+110Q, 2.50978787317170531780713813087390423e+117Q, 9.79042375559121661656574862110333881e+124Q, 1.17908880794405074709159757136517906e+133Q, 4.71463184672247661988055185868884361e+141Q, 6.76265778595971324046101731037889126e+150Q, 3.77863792934416463055998231270977695e+160Q, 8.97819133628477274891556066769979914e+170Q, 9.95914407403494739885505580434362313e+181Q, 5.69630798679205432723450802096176313e+193Q, 1.86743452325707784871951519925288377e+206Q, 3.92719945859412568046939678789391943e+219Q, 5.97262802266570558434581771213406728e+233Q, 7.46293577265068378653739984957785219e+248Q, 8.77620026161886682323882402399676732e+264Q, 1.12240955327637524990782988952974327e+282Q, 1.82091452946462555573948654780251641e+300Q, 4.41446070956615785669448222555093749e+319Q, 1.90397541953366074155779318767572880e+340Q, 1.75902281129585020130874703618203168e+362Q, 4.24169226543235148528312412985493520e+385Q, 3.29481560149200680874049429678412127e+410Q, 1.03135148368973063748422508803572335e+437Q, 1.65119340908368036904973428016231291e+465Q, 1.74266589416784110509614783944413581e+495Q, 1.58844581452329281145953920728196433e+527Q, 1.66707913260906132496128590135534752e+561Q, 2.73591938942385354685476950777714705e+597Q, 9.72579530056263762611950442873242859e+635Q, 1.05939976357545005153997575210948938e+677Q, 5.11518133258374954640812727174811520e+720Q, 1.62189977683387633564608415164137138e+767Q, 5.13160378352024380054652132361473058e+816Q, 2.52913238575275285564889845966314333e+869Q, 3.11944472707029467274111976509771118e+925Q, 1.59495166899855372832309254674677663e+985Q, 5.78489108811836645985010918537259212e+1048Q, 2.63682062563962607583302320466728244e+1116Q, 2.77639914729635446526568065100606294e+1188Q, 1.29100591117079370649785145859270604e+1265Q, 5.28444381883484729377275155781628201e+1346Q, 3.96822241951490935324304074734991606e+1433Q, 1.19450143809568524145027520220707370e+1526Q, 3.31232848440880307300003548888720354e+1624Q, 2.05165402811808892980123939590704909e+1729Q, 7.28745294435475474950235921073537827e+1840Q, 4.04980582052614743975213722266303496e+1959Q, 1.02489069982330185861864247663932840e+2086Q, 3.68323339665104313610706754895420191e+2220Q, 6.30765607309438726154024457882187086e+2363Q, }, + { 2.45471558362986365068916495863375252e-02Q, 7.37246687390334622422734853496288652e-02Q, 1.23152530941676654318795303724845312e-01Q, 1.73000137771924855589325108501317324e-01Q, 2.23440664959686000105440799041805360e-01Q, 2.74652654971851825832501290298110601e-01Q, 3.26821679298064666878532098621581949e-01Q, 3.80142100980478924532143540106066542e-01Q, 4.34818963721561494844111167726460593e-01Q, 4.91070036509942840677161193401564426e-01Q, 5.49128045948021544092182270959032951e-01Q, 6.09243132438265439671151238479162657e-01Q, 6.71685571202114806905814141850507988e-01Q, 7.36748804906793864301473114817726587e-01Q, 8.04752841633695064447122683633828025e-01Q, 8.76048080248205070538153903222362252e-01Q, 9.51019635182333225305914695670696308e-01Q, 1.03009224453247006650365629888427541e+00Q, 1.11373585958868076495962122155474153e+00Q, 1.20247203091805887562283157205483916e+00Q, 1.29688122649686375081031224280895230e+00Q, 1.39761124182837302592381732283067440e+00Q, 1.50538689136054520464181654424860094e+00Q, 1.62102120589479802996006107398491112e+00Q, 1.74542840336904457155639617870301735e+00Q, 1.87963895203102933109827214352261973e+00Q, 2.02481710760932852386806039721112499e+00Q, 2.18228138214788418140109912591097815e+00Q, 2.35352849482388135462737441996874099e+00Q, 2.54026146822962645747200253699005204e+00Q, 2.74442267217147811137997080576917741e+00Q, 2.96823278719060661900608946565759698e+00Q, 3.21423686952065766588900110700898117e+00Q, 3.48535895790773046725176601804623352e+00Q, 3.78496698311737282096444166343378976e+00Q, 4.11695013894029509955211911245969952e+00Q, 4.48581136938823171042685637747918431e+00Q, 4.89677824656200181220988391922608405e+00Q, 5.35593629082672594809503436864536474e+00Q, 5.87038976260095690701450882557564694e+00Q, 6.44845618913111760490837120481487939e+00Q, 7.09990245267955823638498704195342171e+00Q, 7.83623225328284126133289428371735767e+00Q, 8.67103729357523063452024155765264339e+00Q, 9.62042777798599036292354986394365067e+00Q, 1.07035619887679953097266587864897721e+01Q, 1.19433000813944102150187593166292839e+01Q, 1.33670142103849964717469335941905385e+01Q, 1.50075961591439634296262105146352627e+01Q, 1.69047154820352837629069726738079470e+01Q, 1.91063966873168959742774555727687289e+01Q, 2.16710044321657799400571191555580338e+01Q, 2.46697527469509919694460528848277171e+01Q, 2.81898902515784535507915179415086299e+01Q, 3.23387613242940174515264777910328241e+01Q, 3.72490075809724574016769417176033924e+01Q, 4.30852608490774199699508301986096898e+01Q, 5.00527964765470397507453905247128474e+01Q, 5.84087760725387652778097774354827947e+01Q, 6.84769282153423986221602875181609661e+01Q, 8.06668177706071484780398912645020900e+01Q, 9.54992727020024926023862465179431320e+01Q, 1.13640119576948788485338465195796676e+02Q, 1.35945194497660320895127779474436433e+02Q, 1.63520745187974444650772294136165162e+02Q, 1.97804968791258694996900535479466855e+02Q, 2.40678753588977666070114453459006852e+02Q, 2.94617029293055502283701272741864024e+02Q, 3.62896953214712533295812475420140158e+02Q, 4.49886178271559690246754005443952599e+02Q, 5.61444735313349610605402755114132063e+02Q, 7.05489247089927142932822047183046835e+02Q, 8.92790773279996411641203534672635638e+02Q, 1.13811142497947837649816383892464930e+03Q, 1.46183599156360536709532001371341489e+03Q, 1.89233262344471618571971876282268943e+03Q, 2.46939603618613347923158360306283371e+03Q, 3.24931156929882473061795067124714454e+03Q, 4.31236711317028301201344127304044700e+03Q, 5.77409475450013966113987691727433327e+03Q, 7.80224723750085184509285318864950930e+03Q, 1.06426753097580697178856711472253120e+04Q, 1.46591538353567498972551254799117195e+04Q, 2.03952854123975483493635354197048606e+04Q, 2.86717062242155626463726121489695136e+04Q, 4.07403376218345329677215262695648133e+04Q, 5.85318231059692339303875522971681880e+04Q, 8.50568926526520663990658694675860445e+04Q, 1.25064926984785661460287048343378461e+05Q, 1.86137394316674976633487938076388915e+05Q, 2.80525577745201092730917964861422661e+05Q, 4.28278248608476174804382253986989659e+05Q, 6.62634050612765730354133581004327179e+05Q, 1.03944323965033956450234998906270616e+06Q, 1.65385742611296131560210844780522467e+06Q, 2.67031565012527916099202454680251592e+06Q, 4.37721202662435879490158484533403820e+06Q, 7.28807171369841382127860775464397414e+06Q, 1.23317299340033169377433189565436518e+07Q, 2.12155728576993369873860452866846505e+07Q, 3.71308625486153538260132253550700609e+07Q, 6.61457937735213553402161639469475625e+07Q, 1.20005529169491711045823979192639236e+08Q, 2.21862941029688069011551388945586459e+08Q, 4.18228293992868770261761230703186170e+08Q, 8.04370413249371480388874614907492609e+08Q, 1.57939298942566811374336496311019268e+09Q, 3.16812241552410463468859624242708347e+09Q, 6.49660681154986132317647460889788282e+09Q, 1.36285198835644448552647856869429224e+10Q, 2.92686389700870770766115985553270450e+10Q, 6.43979866520949373493178830943697748e+10Q, 1.45275523377290302218030864454825923e+11Q, 3.36285445938924657613055409970261746e+11Q, 7.99420278543347927144872935893265787e+11Q, 1.95326423336229196043471517599153542e+12Q, 4.90958186824255456862636657247754379e+12Q, 1.27062273076501561032764305894113023e+13Q, 3.38907098674298576400746683674724217e+13Q, 9.32508403020884483292253012776198040e+13Q, 2.64948942383453414004877623922649545e+14Q, 7.78129518409495719454885394657867226e+14Q, 2.36471505252735563941195059995826485e+15Q, 7.44413803146595825477962585154187758e+15Q, 2.43021724068474963516185214140527324e+16Q, 8.23706864153435776160816132466078110e+16Q, 2.90211705066454883998576313308511774e+17Q, 1.06415767940403701307268606275625099e+18Q, 4.06627710606196001743762877107146413e+18Q, 1.62127423363035909653152786372227505e+19Q, 6.75415683091545001302004267324917730e+19Q, 2.94405684173378191865875139697985419e+20Q, 1.34464013954910781728162580030274237e+21Q, 6.44458615894472329986968048792306357e+21Q, 3.24621866755460893428420802873638947e+22Q, 1.72123457955665353317614924039447693e+23Q, 9.62253389024047439092145016046085843e+23Q, 5.68140726041795667144549981860838281e+24Q, 3.54889077999592818369666361009585253e+25Q, 2.34950642567226956175428754094351900e+26Q, 1.65161813060520564300895544060422208e+27Q, 1.23514742649311305869239755896991097e+28Q, 9.84594723979205755046350596451684287e+28Q, 8.38313078198461041780434493882428621e+29Q, 7.63964946139917244491542497186650823e+30Q, 7.46786273223388520123213229503835823e+31Q, 7.84769148200499366026301301860529069e+32Q, 8.88603255762645470434690507794367917e+33Q, 1.08673489067830243582954987160820285e+35Q, 1.43896777703653845844251806933839180e+36Q, 2.06816886547560352123602144529722761e+37Q, 3.23488532022391238528760911223890778e+38Q, 5.52123364154262851432456431974095092e+39Q, 1.03114823119466385539623421556538031e+41Q, 2.11327203581636598172202380321061095e+42Q, 4.76672434548507751952154119062281282e+43Q, 1.18696155099021828703717401094811909e+45Q, 3.27317216920584757332668902845797411e+46Q, 1.00282122676916775281745610945056481e+48Q, 3.42493390393515647893744567642140320e+49Q, 1.30843601702642873582064430681159468e+51Q, 5.61137833004842050312648039721074217e+52Q, 2.71142480632713929135631433480050921e+54Q, 1.48177179364406644198189668782951739e+56Q, 9.19428207104277880378138495715383545e+57Q, 6.50366145587535556181715778862405651e+59Q, 5.26632998686862730262822409628217101e+61Q, 4.90266280796934735938520451826335739e+63Q, 5.27051105728955705039001489033126495e+65Q, 6.57285651167058331634360929791632134e+67Q, 9.55395603001322538662375429270666445e+69Q, 1.62649191115941161585027771743899152e+72Q, 3.25941091550095122341298778408441950e+74Q, 7.72846031811361427986096662411063427e+76Q, 2.17988199690591805869859473392710071e+79Q, 7.35448438837150591476717971591286847e+81Q, 2.98483127080395774595532033544389202e+84Q, 1.46582826781343896171132281512590065e+87Q, 8.76335597262986426104836504228132778e+89Q, 6.41790966584783113047113716478179340e+92Q, 5.79495864922989350993450871503126827e+95Q, 6.49422447231190836548908540847688948e+98Q, 9.09500015601643369774077853623649258e+101Q, 1.60305849845529910220272077472033035e+105Q, 3.58209911911932052869313856359636456e+108Q, 1.02244122713985468653173668554645414e+112Q, 3.75687218501508605716480350749498176e+115Q, 1.79136346383284915921138840751400855e+119Q, 1.11764188203947212384081419514165395e+123Q, 9.20215956554652828530686799399533824e+126Q, 1.00871647482788856814534779759128531e+131Q, 1.48554648708930180487801088228218062e+135Q, 2.96696153483056609742176098165601109e+139Q, 8.11420728466436936033056414100674073e+143Q, 3.06917808750766973862958599324080278e+148Q, 1.62222368114779147260405024572949430e+153Q, 1.21094608845400598319807865894230970e+158Q, 1.29069460371207764384235331328282226e+163Q, 1.98663030134211110165437011771903132e+168Q, 4.46757261704134429970068624260491498e+173Q, 1.48564187771108280640829188970287255e+179Q, 7.39669065831627851911038512117013389e+184Q, 5.58477447271859974925476129175614574e+190Q, 6.47976647473179732779115257999520915e+196Q, 1.17117420317317171387535528766936277e+203Q, 3.34428267755162742939489398076764840e+209Q, 1.53076558056194845489001829008909627e+216Q, 1.14010185551912954998170816176845430e+223Q, 1.40319939603195121408389523582430293e+230Q, 2.89974936197123389451668716314083017e+237Q, 1.02284833216532051937856086912560392e+245Q, 6.26387216223145817942640023700922965e+252Q, 6.77735971213475345230129326178116125e+260Q, 1.31920032114466459135766725110063188e+269Q, 4.70640341492973980389482209817290571e+277Q, 3.13724441498341266441161693520329378e+286Q, 3.98571382107801782113811082484615717e+295Q, 9.85039693194582447444400924997258508e+304Q, 4.83687381317675554709367324551273400e+314Q, 4.82285202614019890234802453942628315e+324Q, 9.98703239968301934722476402798215616e+334Q, 4.39579560388542750852159646726102667e+345Q, 4.21213245293498773753031381258995955e+356Q, 9.00647826017501992250418906434620537e+367Q, 4.40820570973056960340923739077146754e+379Q, 5.07036496321109968512657627671150030e+391Q, 1.40820593625978850981984707085120209e+404Q, 9.71170922560303314648712317222502389e+416Q, 1.71185299004740150846260848238269630e+430Q, 7.94539187117702846067322763172557224e+443Q, 1.00135866851780201306228838620557915e+458Q, 3.53720801942577272956188201390769482e+472Q, 3.61856514873836509067172206947444182e+487Q, 1.10885899005952624619970603738429749e+503Q, 1.05391354932473165812334641476989979e+519Q, 3.22052822779158301893419142803165095e+535Q, 3.28354332174247719776999412908271692e+552Q, 1.16054782509911106933820737153108500e+570Q, 1.47919833966504706156198174688381009e+588Q, 7.08133783868969672071172398101964598e+606Q, 1.32792489232842472677863721400834701e+626Q, 1.01864740027867286775312222487805144e+646Q, 3.34261841519397423195159276540555265e+666Q, 4.91359232957804830460198547632977969e+687Q, 3.39338961080932963058551495328009206e+709Q, 1.15643101006244038688616288204262882e+732Q, 2.04580060100421448267115092746141073e+755Q, 1.97956226677236405650286559215774642e+779Q, 1.10576482674657666978217926798043956e+804Q, 3.76975534316002585938373910751464161e+829Q, 8.30723712530280347580443574905340732e+855Q, 1.25551214072288994426628885709173410e+883Q, 1.38340901524945057559377504414014724e+911Q, 1.18367583857036159478030255830898223e+940Q, 8.39312984240762796712708279978405886e+969Q, 5.27445408794117779852142535860614541e+1000Q, 3.14827291975085189890248083313318702e+1032Q, 1.91708860929520191993037622102307238e+1065Q, 1.28205230070904948620917170049585485e+1099Q, 1.01601053886738575799673411634857928e+1134Q, 1.03205637073787228175634527391820202e+1170Q, 1.45709248520841293241982349536788740e+1207Q, 3.10836026767661586110721101783586616e+1245Q, 1.09211875259058272695772315187071594e+1285Q, 6.90756042513315914107755467851436390e+1325Q, 8.62072629674515227183116754798059355e+1367Q, 2.33367455582609053817676883927592981e+1411Q, 1.51088703661957707064674032871094166e+1456Q, 2.58751847359969149251723060639056652e+1502Q, 1.30061395127966085145757755976532379e+1550Q, 2.13606222552299322654005297188550444e+1599Q, 1.28040046650693999927593879574416998e+1650Q, 3.14004479696111085451082602060045251e+1702Q, 3.54445798947819813290733040762684700e+1756Q, 2.07959058928044687396800353571401401e+1812Q, 7.18928436789152221379187719747515467e+1869Q, 1.66674057039586083195182422956301841e+1929Q, 2.96144319154423967308042996118314268e+1990Q, 4.62818622228372755683383431403798070e+2053Q, 7.33344579812102490343077358675798902e+2118Q, 1.36418147108226874642787854899398972e+2186Q, 3.46578234556914165783357030404723460e+2255Q, 1.40565670831906218450256157719581702e+2327Q, 1.06915717420033634558717882909227336e+2401Q, }, + { 1.22722791705463782987186673092730169e-02Q, 3.68272289449259047084662870963424169e-02Q, 6.14133762687107999107794380606156658e-02Q, 8.60515970877820790729887694832007789e-02Q, 1.10762884001784544594356091768970671e-01Q, 1.35568393495778548180370153140547366e-01Q, 1.60489493745433548938038568465534727e-01Q, 1.85547813164508949628358434474487020e-01Q, 2.10765289867070052445854835116288718e-01Q, 2.36164222221462626796458521613760417e-01Q, 2.61767320678549526133854585166690062e-01Q, 2.87597761063134290040469640683594256e-01Q, 3.13679239524903564719983726260388052e-01Q, 3.40036029353663277020320913399073202e-01Q, 3.66693039873181019259593465683200480e-01Q, 3.93675877638645179710808224562806486e-01Q, 4.21010910174684626844126582677407364e-01Q, 4.48725332504145034061613569614932171e-01Q, 4.76847236732482946224267058692370227e-01Q, 5.05405684968820937507178521019349537e-01Q, 5.34430785882522907921272727308422687e-01Q, 5.63953775213726713429575640521392073e-01Q, 5.94007100577754899987320597582638522e-01Q, 6.24624510926871605306723866692531653e-01Q, 6.55841151058639796949436231740377164e-01Q, 6.87693661588351492208131027097817883e-01Q, 7.20220284833868340062109216385730821e-01Q, 7.53460977094957222390047011401038344e-01Q, 7.87457527846096346070444259791519611e-01Q, 8.22253686402049937748559808122413409e-01Q, 8.57895296659582580760899947902549978e-01Q, 8.94430440566859300921740259698532581e-01Q, 9.31909591024743548462187459499302759e-01Q, 9.70385774981792065875818381502464879e-01Q, 1.00991474754772858364115613090157760e+00Q, 1.05055517801908314962647763431650363e+00Q, 1.09236884878609257919070489976671100e+00Q, 1.13542086817251430035405051069824787e+00Q, 1.17977989835042446581611499466432280e+00Q, 1.22551839957114260989771330348614290e+00Q, 1.27271289206202647251525071825625510e+00Q, 1.32144423705798506493224886295961288e+00Q, 1.37179793856724595345645859982391269e+00Q, 1.42386446761438409645831411537400020e+00Q, 1.47773961086120811494347321807905579e+00Q, 1.53352484567928885758582112389540236e+00Q, 1.59132774393835509765516748425726982e+00Q, 1.65126240698431007605515051243084836e+00Q, 1.71344993451128821134705183982006487e+00Q, 1.77801893028625685775809622156398356e+00Q, 1.84510604796472086962932266394457464e+00Q, 1.91485658054495189874749078346703174e+00Q, 1.98742509734901709257017841100790150e+00Q, 2.06297613279527528332657028179424398e+00Q, 2.14168493164291678457053660944377397e+00Q, 2.22373825584899452105160804133355977e+00Q, 2.30933525868721379620595550412858017e+00Q, 2.39868843234110382076332419963510302e+00Q, 2.49202463580835609502681428341212971e+00Q, 2.58958621064512275641789028727789739e+00Q, 2.69163219284683244353140722232296853e+00Q, 2.79843963001449729057960489638268331e+00Q, 2.91030501390256265160483634586060233e+00Q, 3.02754583949736496303590546881335550e+00Q, 3.15050230294691972178684607549631061e+00Q, 3.27953915196739433034632435779672485e+00Q, 3.41504770380541061125886820639123018e+00Q, 3.55744804745655073349177433143963235e+00Q, 3.70719144864977981720917442750632409e+00Q, 3.86476297812834212534134362353667523e+00Q, 4.03068438601653134401780732606469366e+00Q, 4.20551724758861383531605318041260028e+00Q, 4.38986640858517245778656669889477004e+00Q, 4.58438376139193074830218319449001571e+00Q, 4.78977238695068769484017601922716285e+00Q, 5.00679110126136326392507134554822932e+00Q, 5.23625944981527405022093792997629943e+00Q, 5.47906319833752315041593490985864953e+00Q, 5.73616037388481741547685088499196591e+00Q, 6.00858791672861985829483499535828449e+00Q, 6.29746901064886304750229195240462364e+00Q, 6.60402116738092913326417425575120773e+00Q, 6.92956515012467783689325375523493772e+00Q, 7.27553483138386097168028487959046984e+00Q, 7.64348809212349206445236344518102598e+00Q, 8.03511888250245928810782085772095077e+00Q, 8.45227057947818812962999536922397314e+00Q, 8.89695079364178531317631891553840631e+00Q, 9.37134779701639517335117345438905815e+00Q, 9.87784876557344603277558247754926945e+00Q, 1.04190600552776203680920477623835667e+01Q, 1.09978297590083170587228134865897514e+01Q, 1.16172728242395225830192073579898657e+01Q, 1.22807990484892461058359016635119689e+01Q, 1.29921443119669104778276499842319618e+01Q, 1.37554054553562588138800381241813305e+01Q, 1.45750792662062131604851118656361439e+01Q, 1.54561061010485246793800779406223808e+01Q, 1.64039187433830292507497745621200597e+01Q, 1.74244971815420897003963134996594183e+01Q, 1.85244300868843752575149709549249943e+01Q, 1.97109838837826649364051644134983470e+01Q, 2.09921804308096164753912694285306280e+01Q, 2.23768844801398294581745473457799699e+01Q, 2.38749022527007382030837433327528532e+01Q, 2.54970926638043046429091560004131137e+01Q, 2.72554929623253155508089897070407353e+01Q, 2.91634608111962498675086489719161981e+01Q, 3.12358351442328496157597338087371982e+01Q, 3.34891184913680511842485226603345913e+01Q, 3.59416838798546509869193271004218290e+01Q, 3.86140099030723073708193155942738501e+01Q, 4.15289481132930302349687386068430483e+01Q, 4.47120275544153339602356644078995085e+01Q, 4.81918020222491017368298630788454953e+01Q, 5.20002465436155875740198471916042599e+01Q, 5.61732106253738449367657038097317749e+01Q, 6.07509370691878207865695555214723350e+01Q, 6.57786566116800396636894823760941404e+01Q, 7.13072703735772134302608508415302565e+01Q, 7.73941341346580579448409414339011685e+01Q, 8.41039608526963339165414121007032304e+01Q, 9.15098606849673444816151204282990934e+01Q, 9.96945411354770401552161275609161166e+01Q, 1.08751693942601889700382157585301539e+02Q, 1.18787600064303753208251167345242212e+02Q, 1.29922989761451637135259469378151165e+02Q, 1.42295201505637253678660735501099867e+02Q, 1.56060691466500267146385748883961050e+02Q, 1.71397954932643240617797882975933747e+02Q, 1.88510932515483007342988031066863162e+02Q, 2.07632987774012593538662727768467525e+02Q, 2.29031559465458736990493497603665470e+02Q, 2.53013611565567646662052901877967628e+02Q, 2.79932028239889691165098106403660221e+02Q, 3.10193129976673089035599193653267696e+02Q, 3.44265522210752989223327890530839313e+02Q, 3.82690530328937838722167127466549147e+02Q, 4.26094526620760770127774483839356753e+02Q, 4.75203517589290204505256185266901137e+02Q, 5.30860436623905886389110002239619071e+02Q, 5.94045680537299500918768911865886523e+02Q, 6.65901542833877826224842736585170818e+02Q, 7.47761336730915387004112664458834008e+02Q, 8.41184173047134302254019501114516601e+02Q, 9.47996569801374152415232558717779048e+02Q, 1.07034233137588184029692740932268166e+03Q, 1.21074245751858265959674123771999362e+03Q, 1.37216724155220581953081355884482812e+03Q, 1.55812321218769272183468357733000347e+03Q, 1.77275818866271628150109400030205931e+03Q, 2.02098848541186298361330491694554409e+03Q, 2.30865325932916315664195536323762336e+03Q, 2.64270218981368427312930076396387941e+03Q, 3.03142418286921021219727597009903791e+03Q, 3.48472667698575601755930501247710368e+03Q, 4.01447750473397350451805793460750946e+03Q, 4.63492426404939475098008035447052569e+03Q, 5.36320994977343974892087068772061383e+03Q, 6.22000841211434280322218569985211936e+03Q, 7.23030933285302995642999721294241650e+03Q, 8.42439021673521778311062568091410678e+03Q, 9.83902287153854178745596238243054980e+03Q, 1.15189746308311398832174294139085014e+04Q, 1.35188809887437420186309997879371889e+04Q, 1.59055874546006694678895534154510667e+04Q, 1.87610857276481617624948313285750831e+04Q, 2.21862046239336627450920062330548753e+04Q, 2.63052620505491535696779646542992118e+04Q, 3.12719440194171105738301413156011152e+04Q, 3.72767546125665292256151356126569138e+04Q, 4.45564828031227324859783992706804335e+04Q, 5.34062659201890392985687357687040023e+04Q, 6.41950058038891812326608231510870856e+04Q, 7.73851264238682005972799669756325711e+04Q, 9.35579699398172596314688114151429601e+04Q, 1.13446537582066946954261668152086820e+05Q, 1.37977827220974171292929858459577092e+05Q, 1.68327748580788705255881136304020641e+05Q, 2.05992574612073530499207561599578962e+05Q, 2.52882202450315825396186949822484192e+05Q, 3.11442271834772591489327431348343937e+05Q, 3.84814591343557073602914002196809171e+05Q, 4.77048586496682264260701809258611041e+05Q, 5.93380932472474085420815642783399996e+05Q, 7.40606619035166611456854888146209865e+05Q, 9.27573047147064337154043416441694054e+05Q, 1.16584026094018041532121013906762681e+06Q, 1.47056632211824613527279037871707355e+06Q, 1.86169889901492197099442712763381073e+06Q, 2.36558487029835449538535481946926618e+06Q, 3.01715269550576487659856266530294113e+06Q, 3.86288257359992924875408921517049995e+06Q, 4.96486430558975035817682789982702410e+06Q, 6.40636282995973660643182932326803288e+06Q, 8.29948184726130211549565432685136745e+06Q, 1.07957589264240185368036619492890404e+07Q, 1.41008732747460409136778616182972970e+07Q, 1.84951472441825010015226156029368615e+07Q, 2.43622441967080550013889014979179789e+07Q, 3.22295113186394123446611158573926085e+07Q, 4.28249388238592533660285754208101809e+07Q, 5.71579339433926763705565010979377786e+07Q, 7.66343793274545163464956180626615373e+07Q, 1.03221272549848969879325123115356857e+08Q, 1.39683399197619484239843178827556776e+08Q, 1.89925149766489273996177039954695089e+08Q, 2.59486539646750585135581953531723138e+08Q, 3.56266474246450149668190479113931322e+08Q, 4.91582541317241347106730357233806750e+08Q, 6.81731647011695814167689014048918740e+08Q, 9.50299810520254143758401252895411400e+08Q, 1.33159829534327753848250753466160796e+09Q, 1.87580197601045983131635998256926235e+09Q, 2.65667390770973148718390348704244405e+09Q, 3.78324021561636590874538087942452353e+09Q, 5.41753184850013697899991815866441223e+09Q, 7.80169536989284750988699417135654043e+09Q, 1.12996536895509883334977946121306167e+10Q, 1.64614916139082192438237472977949088e+10Q, 2.41235399573668769368537292636420902e+10Q, 3.55648689543192709406699873104224405e+10Q, 5.27534501409376051919461374149743655e+10Q, 7.87357210832537817724326568648616226e+10Q, 1.18256902031786360426341053633539951e+11Q, 1.78754944250836346103770384839274996e+11Q, 2.71963306497998614239753953623599024e+11Q, 4.16512215311989794586279802552971310e+11Q, 6.42178185820513419673438138950789714e+11Q, 9.96872549757627591785162935837099498e+11Q, 1.55821232712296039863279650270498705e+12Q, 2.45280998490709378571967041325143017e+12Q, 3.88865623282814020969225986222930869e+12Q, 6.20986899050942490907341584961146266e+12Q, 9.98992421629798366453910164990598035e+12Q, 1.61915800137861135092472802019186093e+13Q, 2.64432451866992655897802160266314720e+13Q, 4.35201884790437478598011793154963363e+13Q, 7.21888468820274170949384690425513293e+13Q, 1.20699764072734953803867091697058471e+14Q, 2.03448372244520740184714594138600722e+14Q, 3.45755310287440291972421764598644671e+14Q, 5.92524851195750570615520553006806424e+14Q, 1.02405779371303867152496937066868237e+15Q, 1.78517404594164216208571127025070841e+15Q, 3.13930698866849469593365078009075683e+15Q, 5.56985627017489012771720073467849986e+15Q, 9.97176335383446032822138577325280050e+15Q, 1.80168749111488309180201148764368470e+16Q, 3.28570985832256554206799328627718020e+16Q, 6.04901854091075971038418094513619254e+16Q, 1.12437528321136957183940077137648079e+17Q, 2.11044512595243530534854315009251863e+17Q, 4.00073700789122999206498186212756047e+17Q, 7.66084936156432930897007145016954725e+17Q, 1.48201877099617670026480296368024580e+18Q, 2.89694543391085794507262308584519511e+18Q, 5.72279016569347049314117808244814073e+18Q, 1.14268996043992146219736887475145416e+19Q, 2.30661655998410672274449611000740199e+19Q, 4.70785718461609386331913071438798214e+19Q, 9.71734634749534281292184698073106843e+19Q, 2.02873560562258544354738566036230939e+20Q, 4.28484025417100058060231110755876699e+20Q, 9.15702732902162383627232801008773485e+20Q, 1.98045783476641177674243338550380776e+21Q, 4.33560488670225200389961701585516223e+21Q, 9.60925855971422399500251930072135526e+21Q, 2.15660463060858699692371033788512835e+22Q, 4.90204590969527028901267517972005859e+22Q, 1.12874922712132846722486415215181510e+23Q, 2.63341462304993087921430516281962614e+23Q, 6.22633568449099854312810660038498408e+23Q, 1.49220527901414892100221726222044247e+24Q, 3.62576824971759010933939677750446994e+24Q, 8.93389976496144488245242728630867648e+24Q, 2.23278698168226238263925345166626442e+25Q, 5.66129533629398673236467837398265907e+25Q, 1.45661671029813314161310452512420504e+26Q, 3.80395985286848824540247897299973294e+26Q, 1.00853158560303648965770564091212618e+27Q, 2.71524742512942335771421173573350598e+27Q, 7.42507176676665196668682930989072343e+27Q, 2.06286071217322500340710263294206778e+28Q, 5.82405545879941331172090843001915861e+28Q, 1.67138883669643664401793246595736207e+29Q, 4.87683063202395639212825400688637822e+29Q, 1.44717007114610715647680482586441902e+30Q, 4.36856220892558378299543245366740004e+30Q, 1.34187380624925133807232471810065508e+31Q, 4.19525163275433868171703825329949387e+31Q, 1.33536013482821413616157861182819558e+32Q, 4.32868135071513633988478443702722304e+32Q, 1.42940186615031918577626278068758606e+33Q, 4.80973614622718069618478648576546160e+33Q, 1.64962411456760257539667516081290921e+34Q, 5.76867749241980146921395997917892869e+34Q, 2.05744285416276135030539237103441019e+35Q, 7.48642350991781106283346301415985262e+35Q, 2.78005279179115505131111680664033100e+36Q, 1.05390834766008187386632631340309755e+37Q, 4.08004633423575422346694643614725290e+37Q, 1.61355331159280537271141620030872711e+38Q, 6.52083633299761509812680604349515166e+38Q, 2.69384818625751099248700493623895698e+39Q, 1.13800240843071080011666704740931517e+40Q, 4.91774800881392461265365745148130197e+40Q, 2.17469107319135867637675221560360895e+41Q, 9.84452374543052650164816403972682005e+41Q, 4.56370746759011673249611086081412694e+42Q, 2.16735207370837913732627450052443800e+43Q, 1.05486019388717075432105322007580054e+44Q, 5.26358822556684736475437714203858810e+44Q, 2.69377245879791662278222405278060831e+45Q, 1.41450676056016307353065763949943988e+46Q, 7.62412676351201661991424110428992680e+46Q, 4.21982814876279441119734812029287822e+47Q, 2.39938766583179326419454951543637572e+48Q, 1.40213994725411743432292186837126106e+49Q, 8.42470632552542294312824936421510125e+49Q, 5.20691847994261931825305937850643235e+50Q, 3.31178786647771615130587348221001406e+51Q, 2.16868329550985915487173624396649870e+52Q, 1.46278636877920671278346292184781720e+53Q, 1.01676178457583836251098427369753410e+54Q, 7.28646099514504318390031595979099009e+54Q, 5.38619423744886540736133132036039525e+55Q, 4.10891748052874064027571987877723004e+56Q, 3.23644562594555272761751761693655719e+57Q, 2.63344065241761966896134121065725150e+58Q, 2.21470233935793926784783273212022849e+59Q, 1.92605899594826839190384056135440397e+60Q, 1.73306774041417493183516299971659594e+61Q, 1.61430716012442696900215232150692807e+62Q, 1.55746432848635213822960416335985349e+63Q, 1.55722615519719203130606727886637242e+64Q, 1.61447396270799534426677571780472075e+65Q, 1.73661740632738610492724345532304845e+66Q, 1.93920124345119052093186699988150897e+67Q, 2.24927773293662287552890832545827854e+68Q, 2.71159379871976559871119761600619238e+69Q, 3.39962873204868711911086284140566930e+70Q, 4.43538969673020629145547409643969707e+71Q, 6.02556607616400398134689309091612155e+72Q, 8.52916142538377984909758513093573554e+73Q, 1.25874632299298868846704179091958707e+75Q, 1.93811217518656021005493439215804850e+76Q, 3.11543236357261066088271223403230465e+77Q, 5.23179767443439001771782033104475730e+78Q, 9.18493020786068075728039142759876527e+79Q, 1.68692940478037877214426031162304858e+81Q, 3.24356562447423263461643222429327622e+82Q, 6.53381249893022007452896440352725950e+83Q, 1.37989882314462031449133502146398295e+85Q, 3.05765044484283991620932285441735220e+86Q, 7.11405054583917124472478320152556329e+87Q, 1.73927502444225867447030753694640018e+89Q, 4.47178291585317780365328749453520010e+90Q, 1.21003678949402814425759810458701117e+92Q, 3.44882804459086235858169840236819767e+93Q, 1.03622678375056156465794049465547871e+95Q, 3.28480191475120603834848118907352203e+96Q, 1.09951493360222463836336540053884847e+98Q, 3.88958173137824259730333790282903582e+99Q, 1.45543428790106999149108053530575702e+101Q, 5.76572993438741901863543434592570728e+102Q, 2.42034956874547558153049344213268717e+104Q, 1.07760662592977753585432532225577347e+106Q, 5.09334698869585184485524316150431382e+107Q, 2.55809082411032399725764692067377039e+109Q, 1.36651250871904796376617702296414102e+111Q, 7.77173580076352640634836399351925362e+112Q, 4.71039863879301491830684051990330316e+114Q, 3.04556388558701395434830609997782218e+116Q, 2.10276255286144299282309486039761104e+118Q, 1.55193753621259613591555622965540441e+120Q, 1.22567635442607596952721498552003566e+122Q, 1.03695094616970371146721395255392215e+124Q, 9.40788526897082771733750170914488215e+125Q, 9.16336910778509317089313688240113814e+127Q, 9.59253109567116892554520172575780003e+129Q, 1.08048629336182387529116109869898182e+132Q, 1.31103482955778245018110865569797769e+134Q, 1.71564297593263918799907327094023177e+136Q, 2.42423174270788187824126863980761699e+138Q, 3.70323122333312791897064549131589865e+140Q, 6.12322502740998890169801438496313135e+142Q, 1.09727104077119676484946099784861221e+145Q, 2.13369364324129597715060714813970067e+147Q, 4.50809918489577732767734472523944713e+149Q, 1.03625280668629118864461701581877696e+152Q, 2.59492839368798847123238762058931299e+154Q, 7.08856065084285960511459463166728250e+156Q, 2.11523492515131956204689196091626210e+159Q, 6.90448414659433816403326070235535578e+161Q, 2.46882138492543386747726128195908117e+164Q, 9.68405620339094731040251680095733169e+166Q, 4.17318211031646842247767173261932179e+169Q, 1.97862256312448325694613011941349554e+172Q, 1.03370703084875834422987498885049116e+175Q, 5.95983823379168614646426490979367954e+177Q, 3.79793920709700480341002000892325755e+180Q, 2.67930862060725892983600714882836079e+183Q, 2.09582063696050703960100191266610779e+186Q, 1.82074244214148973928235757920582367e+189Q, 1.75963855825241574501304502726864570e+192Q, 1.89499379332809905379546394212298551e+195Q, 2.27793735309853697376707463982899100e+198Q, 3.06180392186430523426845441481052145e+201Q, 4.60976071298011598021963844074936266e+204Q, 7.78790454205446308413194702704532804e+207Q, 1.47908157180353184742483342055946619e+211Q, 3.16368583872054810499056635486446885e+214Q, 7.63549763158546449019055671859541326e+217Q, 2.08329116709848069811436257881072129e+221Q, 6.43828341650089537912773112646579654e+224Q, 2.25813433461443519689405569138116459e+228Q, 9.00646808360283887236786414348123292e+231Q, 4.09320439419929471708152017376102969e+235Q, 2.12407325647515198386324613590453899e+239Q, 1.26118767744139661919617876453932054e+243Q, 8.58648519817790365555570528355195441e+246Q, 6.71757354945431655557160007037610215e+250Q, 6.05231172230061504649457274179966269e+254Q, 6.29372154343611302741074349158106138e+258Q, 7.57097597581835804454005529249965405e+262Q, 1.05596735728342565613175490019879868e+267Q, 1.71165116794080014782255848570375371e+271Q, 3.23201945416757368365209341689336569e+275Q, 7.12640648337469193163827718081711822e+279Q, 1.83935498907936650155252747841577857e+284Q, 5.57103618187823353431701691950875589e+288Q, 1.98507054903582594730288556561442957e+293Q, 8.34251060679185969108286852637314516e+297Q, 4.14598050279815660053056892060055710e+302Q, 2.44294673707515955659314553816687272e+307Q, 1.71128222954502480992240259231707340e+312Q, 1.42900308749681080618580596429329500e+317Q, 1.42642910690539638749189376290614404e+322Q, 1.70684173154227881505687976959428819e+327Q, 2.45528610324097413976825941240621397e+332Q, 4.25829782132342793910509184917611473e+337Q, 8.93046646026781112771479518830708119e+342Q, 2.27151544737307916343177075009962798e+348Q, 7.02878727199449743249339960113532074e+353Q, 2.65404789370370153123009487802961972e+359Q, 1.22676780524208968705932842819459632e+365Q, 6.96344727462083702750636558199408867e+370Q, 4.86966795424296645258294731476827244e+376Q, 4.20934473165669380666938166564826622e+382Q, 4.51252011030278817555903939588122000e+388Q, 6.01984854233799583525556662766352847e+394Q, 1.00278809583154248088779511185941092e+401Q, 2.09319142855536626778348201007914114e+407Q, 5.49449523120000769396463190666315855e+413Q, 1.82025791721843330667826837307018788e+420Q, 7.63864295498675379110157901286555290e+426Q, 4.07562853905456437955133694031162566e+433Q, 2.77530355159307878582751292111532382e+440Q, 2.42120842363222072539668100784464301e+447Q, 2.71677827391519917988250533365057684e+454Q, 3.93638693069501511102210790122717956e+461Q, 7.39454183839498133330514511562965145e+468Q, 1.80830021083203927258676228302841634e+476Q, 5.78068632124848075130373030745294118e+483Q, 2.42588452835387252450192322587436972e+491Q, 1.34215845252903171028854514732509154e+499Q, 9.83265508980143417319549250479290229e+506Q, 9.58056982887069577741485477351756765e+514Q, 1.24714172045678509784766926344381810e+523Q, 2.17883996343750012869434076146952309e+531Q, 5.13253875779605180900218275684122450e+539Q, 1.63787417999262086647656267832207076e+548Q, 7.11453353628067905769574986613707006e+556Q, 4.22706394134172663816196292889312018e+565Q, 3.45223064191878555675199989739485645e+574Q, 3.89497996822823191874712723630878414e+583Q, 6.10190158010921783812771061850774756e+592Q, 1.33421132288849391233542855134113771e+602Q, 4.09320749021551498574887738660496448e+611Q, 1.77132716471266560117452274418925035e+621Q, 1.08713213788405301831391213988591367e+631Q, 9.51489736810900467024086259204897883e+640Q, 1.19423949258625915586962226198410651e+651Q, 2.16177179741543970148744161752725437e+661Q, 5.67627906160460395827390123125168239e+671Q, 2.17468780419782497779087319492719363e+682Q, 1.22290652527655281598138666471594618e+693Q, 1.01549393259398829829790551999023256e+704Q, 1.25289600863132317250645757199143453e+715Q, 2.31107594661956354485796436668094840e+726Q, 6.41394790132987132728494077504399223e+737Q, 2.69551958118799603835043225368071745e+749Q, 1.72664572305999101481397361296053504e+761Q, 1.69703260411568714431268560545429241e+773Q, 2.57650655058878846949421879421719884e+785Q, 6.08415755628422694511089641903676709e+797Q, 2.25018717111577650332251351426363709e+810Q, 1.31266605271635406458566527913919394e+823Q, 1.21653337436496205608516398221959572e+836Q, 1.80423787152105848481394522091997928e+849Q, 4.31399102346512532331941966328171850e+862Q, 1.67550866484958200095075315692314084e+876Q, 1.06515761703845778105889680563699868e+890Q, 1.11699400379133199608851392356049526e+904Q, 1.94751426714424559351617923238456424e+918Q, 5.69089114062808012687080164398087070e+932Q, 2.80983921519267570591812248264495618e+947Q, 2.36358690419951504134253704409272547e+962Q, 3.41581578617948637677662230945252306e+977Q, 8.55364646944583859412326553382242541e+992Q, 3.74370530455423912034790817625191291e+1008Q, 2.88911104228589616462565573594290893e+1024Q, 3.96659525977064102663870040642245025e+1040Q, 9.77693110684684436928410437465483271e+1056Q, 4.36636679166615668883990202463770904e+1073Q, 3.56644781478399708285654633626787310e+1090Q, 5.37871519143314493436384142989505797e+1107Q, 1.51231507376826438439352643482625072e+1125Q, 8.00547597409214659416862336552752652e+1142Q, 8.05824292014776003962551051182620642e+1160Q, 1.55810667707874651581920999067306413e+1179Q, 5.84685322894210562805362663900103590e+1197Q, 4.30279053871861463775007328286068764e+1216Q, 6.27606568696844727186804750244767860e+1235Q, 1.83405691639178257209003812558712559e+1255Q, 1.08562206577049472147312923532596973e+1275Q, 1.31617110088183556471407953592008454e+1295Q, 3.30534811890625751178778666339188597e+1315Q, 1.73929710751143724152073404455311704e+1336Q, 1.94017558758640506527365311633351598e+1357Q, 4.64256117877888468390840687039281473e+1378Q, 2.41181028167559547953976181592626603e+1400Q, 2.75359028326650146526233980288420348e+1422Q, 6.99538184026698121966983693939988891e+1444Q, 4.00451124186760586509360315430592520e+1467Q, 5.23202484555080004711423052985251790e+1490Q, 1.58057811961053246035386581678791248e+1514Q, 1.11871792077110492782575037665515064e+1538Q, 1.88021076704060084216083677757823795e+1562Q, 7.60656064089491206752552083826812435e+1586Q, 7.51058336307020750806534892000369186e+1611Q, 1.83554419567039732901090730190332067e+1637Q, 1.12631598317224168716420027493130577e+1663Q, 1.76058045324267978077071148859252887e+1689Q, 7.11454090252573253550862708170430267e+1715Q, 7.54447665013986581882495689819567483e+1742Q, 2.13157561258614754140817896581925999e+1770Q, 1.62953544267683384450064825605699335e+1798Q, 3.42393824570039208761545128642814549e+1826Q, 2.00910152737038919233657554807306054e+1855Q, 3.34591874171713502502193846562110253e+1884Q, 1.60768420173566681503057284560969387e+1914Q, 2.26623321264716591681578650589551852e+1944Q, 9.53208108881430895613749023747672822e+1974Q, 1.21710154769951529957336846304572308e+2006Q, 4.80082954212402831503263841738379326e+2037Q, 5.95484092414598408997112765002169497e+2069Q, 2.36496081234284780469612914593602194e+2102Q, 3.06292618387296708176633714456063693e+2135Q, 1.31792936450130144017383754294435167e+2169Q, 1.92000470996606623202622993195686002e+2203Q, 9.65401246356529853165036795448719991e+2237Q, 1.70836636787270782624240314280943940e+2273Q, 1.08524396756651055665425968680627268e+2309Q, 2.52515527758383642102305453689375992e+2345Q, 2.19655419566926380800477364631433717e+2382Q, 7.29302139222844158929601074949211737e+2419Q, 9.43942215540978305304206842223557338e+2457Q, }, + }; + m_weights = { + { 7.86824160483962150718731247753528972e+00Q, 8.80516388073301111614873617217928009e+02Q, 5.39627832352070566780640331455747505e+07Q, 8.87651189696816131653619534136597185e+19Q, 2.43279187926922555339407396412240848e+52Q, 6.39971351208020291074628474066382445e+139Q, 4.88537754925138382971529406336289926e+376Q, 7.16883681174178397147232888689884595e+1019Q, }, + { 2.39852427630263521821751964327863340e+00Q, 5.24459642372668102196104972893810164e+01Q, 6.45788781959820175983419155536535220e+04Q, 2.50998524251137450575088710958358197e+12Q, 1.77402926932713870128394504873348147e+32Q, 2.78140611598309731397930137939524577e+85Q, 1.96038425539892219077400134901764646e+229Q, 3.66150166331050442649946863740591804e+619Q, 4.83160223742266359875093017291942249e+1679Q, }, + { 1.74936958310838685164948357553735581e+00Q, 3.97965898193460781260142246747934196e+00Q, 1.84851459857444957000370375296526856e+01Q, 1.86488071893206798762140574520079510e+02Q, 5.97420569526326585534733485801413054e+03Q, 1.27041263514462334076609190768051333e+06Q, 6.16419301429598407050713079962266577e+09Q, 5.23085003181122252980303620742723664e+15Q, 2.22626092994336977442577822584431966e+25Q, 1.19993110204218159156995352671876189e+41Q, 7.47060214427514621386633671542416223e+66Q, 1.81446586052841067579857900138568293e+109Q, 9.97368828205170536427067380214302839e+178Q, 6.91104863699861841609881512683369620e+293Q, 1.09318211394169115127064538702854062e+483Q, 6.82844528756738528157668552351754659e+794Q, 5.72058982179767644458682394627277737e+1308Q, 8.56032690374774097638382410967859196e+2155Q, }, + { 1.61385906218836617287347897159238284e+00Q, 1.99776729186967326240633804225996920e+00Q, 3.02023197990883422014272607858586524e+00Q, 5.47764184385905776136260784219973923e+00Q, 1.17966091649267167180700675171097629e+01Q, 3.03550484851859829445106624470076282e+01Q, 9.58442179379492086007230677188042206e+01Q, 3.89387023822999207648300659707623000e+02Q, 2.17919325035791134362027855479039721e+03Q, 1.83920812396413285238691815996130729e+04Q, 2.63212061259985616674528417452471371e+05Q, 7.42729650716946820985576548297567563e+06Q, 5.01587564834123235599460194208596041e+08Q, 1.03961086724154411336246801784030341e+11Q, 9.10032891181809197707572646881781254e+13Q, 5.06865116389023157141527800972456655e+17Q, 3.03996652071490261550678134010186516e+22Q, 3.85774019467200796234141077624516370e+28Q, 2.46554276366658108662483315347592086e+36Q, 2.41643944916779946083480638296809418e+46Q, 1.51709155392660414912154078562432491e+59Q, 3.82504341202141137966304147261186085e+75Q, 4.08958239682159863968142401533332977e+96Q, 3.82377589429556404969214069508991010e+123Q, 1.52310131188389950567280579870007714e+158Q, 3.79636429591225792206340580596443044e+202Q, 3.58806569407775804668752012761380285e+259Q, 4.80771394235873283225580334249205764e+332Q, 3.53246347094395956018650264083397114e+426Q, 1.10588270611697913736223556513462127e+547Q, 5.39876096236024571737551333865366627e+701Q, 2.11595993056851385189640470523173475e+900Q, 1.96510021934867185245970661270267904e+1155Q, 4.44393205109502635384704176698510343e+1482Q, 8.87699807096655545789464168899561262e+1902Q, 3.92593109193326452307669545677335709e+2442Q, }, + { 1.58146595953669474418006927755018553e+00Q, 1.66914991043853474595928766810899114e+00Q, 1.85752318859500577038805456054280667e+00Q, 2.17566262362699411973750280579195666e+00Q, 2.67590137521102056412774254907718688e+00Q, 3.44773868249879174414308452011308777e+00Q, 4.64394654035546412593428923628065357e+00Q, 6.53020449657424861626175040050215115e+00Q, 9.58228501556680496101434956408351228e+00Q, 1.46836140751544096048943311347045852e+01Q, 2.35444954874098753301967806270994218e+01Q, 3.96352727330516670475446596081886449e+01Q, 7.03763520626753854729866526912608057e+01Q, 1.32588012478483886772029444321222706e+02Q, 2.66962564954156917240259777486475719e+02Q, 5.79374919850847267642551329761882844e+02Q, 1.36869192832130360517783396696756604e+03Q, 3.55943572153313055370459329132660088e+03Q, 1.03218667727076331844496375241465304e+04Q, 3.38662130285874148722242481662728477e+04Q, 1.27816625984024682983932609690817446e+05Q, 5.65408251392669309819682774275375355e+05Q, 2.99446204478172183285915112991350446e+06Q, 1.94497502342191494704216422938073734e+07Q, 1.59219300769056058775193216743984073e+08Q, 1.69428881861745991307405037132734657e+09Q, 2.42715618231130327064401251217732118e+10Q, 4.87031784819945548978505622564878836e+11Q, 1.43181965622918179279761684530563788e+13Q, 6.48947152309930125567236832263111486e+14Q, 4.80375775250898910621624420686976943e+16Q, 6.20009636130533154063228597685772759e+18Q, 1.50256856243991489872472363253210358e+21Q, 7.43606136718968825065770257988550430e+23Q, 8.26476121867792860277670169213789988e+26Q, 2.29773502789780434527854280137181506e+30Q, 1.80544977956953499695878114747293447e+34Q, 4.60447236019906193095622500171344417e+38Q, 4.45837121203062685356208723886733392e+43Q, 1.95763826111480930920135175891530462e+49Q, 4.76736813716250076391436967954985413e+55Q, 8.08882013947672128478290968549029064e+62Q, 1.23826089734928635728800137667726115e+71Q, 2.29227250527884206154485624438166937e+80Q, 7.15139237374919354944182099110281069e+90Q, 5.47671485015604443103262357109062276e+102Q, 1.57665561837070068115746726288773175e+116Q, 2.76544859595785195782707224216472471e+131Q, 5.10805125528313267335507302418826239e+148Q, 1.84712724771593770593326127127227089e+168Q, 2.64019849791365137425805671512502957e+190Q, 3.30712207665004277982044248938187504e+215Q, 8.94854908018147130170828014681013313e+243Q, 1.45387781135416845215757148230318159e+276Q, 4.51726707740089625471551690811905600e+312Q, 9.97430447590682462482304866834403173e+353Q, 6.92693028486990716815899177110112886e+400Q, 8.16310561774970561761094556639568748e+453Q, 1.10229203674018117764688357752075301e+514Q, 1.48517414340573263317638725427854581e+582Q, 2.31930659130340479680373862468017961e+659Q, 6.75943980795305614491339585238335763e+746Q, 8.57037256903489416057847741388693004e+845Q, 1.67601881139415883633596646631875881e+958Q, 2.88227840597067494281761984210848274e+1085Q, 4.25760590360997372209644858208981618e+1229Q, 9.71180927884114514977776411099980676e+1392Q, 1.22768447544318231419683656745290694e+1578Q, 6.75552744777466879522724469574589977e+1787Q, 3.08769330528996647489562213811332711e+2025Q, 6.11556995885701147380172201043083647e+2294Q, }, + { 1.57345777357310838646187303563867071e+00Q, 1.59489275503866378652125176234375753e+00Q, 1.63853651553023474161201404240726646e+00Q, 1.70598040821221362042267472116012952e+00Q, 1.79972439460873727464624167982278042e+00Q, 1.92332285442565630724716834865923523e+00Q, 2.08159737331326817824115844787944556e+00Q, 2.28093488379007051069614759371332643e+00Q, 2.52969785238770465522974588384012833e+00Q, 2.83878478255295118549225363326336900e+00Q, 3.22239574502098061154099310373833179e+00Q, 3.69908135885423511174795221061725889e+00Q, 4.29318827433052679979662014839909054e+00Q, 5.03686535632233007617225633242190622e+00Q, 5.97287114091093219903794699750262296e+00Q, 7.15853842431107756435392592099817447e+00Q, 8.67142780089207638456187671594514668e+00Q, 1.06174736029792232565670017416978690e+01Q, 1.31428500226023559963724543395522033e+01Q, 1.64514562566842803959315507240301356e+01Q, 2.08309944999818906870911848992408145e+01Q, 2.66923598979164019005652953856219015e+01Q, 3.46299351479137818875120770497256101e+01Q, 4.55151836265366257897259922581190951e+01Q, 6.06440808776439211617961123881399848e+01Q, 8.19729691748584679772374579308014156e+01Q, 1.12502046808165256396405270593673624e+02Q, 1.56909655284471412314380735570422525e+02Q, 2.22620434786863827630193937721495593e+02Q, 3.21638548950407775497940425181412035e+02Q, 4.73757450594546173931972158718216152e+02Q, 7.12299454814699763671577043536625350e+02Q, 1.09460965268637655307120839628626644e+03Q, 1.72169778917604957594996919520027157e+03Q, 2.77592490925383514631415480161515100e+03Q, 4.59523006626814934713366494475518926e+03Q, 7.82342758664157367197225266771664916e+03Q, 1.37235743526910540538254088034330370e+04Q, 2.48518896164511955326091118611007805e+04Q, 4.65553874542597278270867281925971401e+04Q, 9.04176678213568688399001015321300800e+04Q, 1.82484396486272839208899824313480775e+05Q, 3.83680026409461402659414641247062580e+05Q, 8.42627197024516802563287310497296237e+05Q, 1.93843257415878263434890786889254173e+06Q, 4.68511284935648552770705724295731096e+06Q, 1.19352866721860792702129481323969824e+07Q, 3.21564375224798931587480096707273872e+07Q, 9.19600892838660038574630990314077029e+07Q, 2.80222317845755996380600711673673348e+08Q, 9.13611082526745888639724836491288094e+08Q, 3.20091090078314859097182280497599932e+09Q, 1.21076526423472368892320719657876832e+10Q, 4.96902474509310180847282308967509245e+10Q, 2.22431575186385521573661995325533148e+11Q, 1.09212534444931366008730317965795763e+12Q, 5.91688298001991935913437013926087352e+12Q, 3.55974343849457724875846980164154730e+13Q, 2.39435365294546519110955303872941851e+14Q, 1.81355107351750191688958030705258863e+15Q, 1.55873670616616573768075986251057862e+16Q, 1.53271487555511433265791312985848665e+17Q, 1.73927477619078921206684554401295421e+18Q, 2.29884121680221631264260395223605839e+19Q, 3.57403069883776266374408947394989771e+20Q, 6.60489970545141907950722926660909000e+21Q, 1.46715587959182065910258109064501314e+23Q, 3.96409496439850938104106380506197921e+24Q, 1.31934284059534879276193138323357204e+26Q, 5.48225197134040074244755342952808857e+27Q, 2.88513789472382751842871762855110475e+29Q, 1.95253984076539210960955400019857653e+31Q, 1.72705148903222279729658337426192599e+33Q, 2.03134350709543939580166226396358099e+35Q, 3.23607414697259998035422932108168633e+37Q, 7.12048741298349720027592249584649287e+39Q, 2.20955270741101726546978031488466999e+42Q, 9.88628264779138464833350749737352873e+44Q, 6.53051404878827352855218417636385136e+47Q, 6.53070667248154652797117704066842547e+50Q, 1.01551880743128195070423638840822631e+54Q, 2.52636677316239450980056816553072407e+57Q, 1.03645051990679029664966085872637264e+61Q, 7.24196603262713586073897504016245799e+64Q, 8.91940252076971493816577515322150818e+68Q, 2.00846361915299290502283821529295631e+73Q, 8.59691476483026002005094018998424562e+77Q, 7.29059954682949521964023913634428261e+82Q, 1.28019956321641911210408802307006043e+88Q, 4.87834928560320114983891893560226105e+93Q, 4.24082824806412793978885646592598549e+99Q, 8.86977176472159872046976711615695992e+105Q, 4.72334257574141766931261505651248075e+112Q, 6.80203596332618858057580041658814811e+119Q, 2.82453118099000954895979587744113614e+127Q, 3.62104921674598225195529453488856248e+135Q, 1.54127015033494251978994281882356439e+144Q, 2.35337699517436278507886852532825112e+153Q, 1.39975657916895026384257958622345253e+163Q, 3.54037503829826541837221286091526442e+173Q, 4.18047500721395810079642214620070836e+184Q, 2.54530778191403081572971577964641848e+196Q, 8.88250526322285889574436025179770286e+208Q, 1.98845751036127430533908054978079217e+222Q, 3.21915661509946819003841034873947498e+236Q, 4.28183215516658291456439674095688919e+251Q, 5.36006145974509206228714676601426569e+267Q, 7.29722806821457796264952588871034685e+284Q, 1.26019994797636341237075623262002305e+303Q, 3.25215241711283834871808603425369243e+322Q, 1.49313102632599158215031971670664716e+343Q, 1.46842377691796129245813472736592684e+365Q, 3.76931518236156669675469780787997744e+388Q, 3.11671991143285521404945273561352902e+413Q, 1.03852445906488241953781523768340610e+440Q, 1.76991068936691550622045923706396857e+468Q, 1.98843278522413458075823481121326426e+498Q, 1.92935688449069146367365017414279935e+530Q, 2.15545898606278242992831028009446695e+564Q, 3.76556572065746315676705102085514331e+600Q, 1.42493629186903074753303377268119903e+639Q, 1.65224172380259971159552714105694350e+680Q, 8.49215944410421946026158352935784666e+723Q, 2.86631893981320588349507785370693896e+770Q, 9.65377141044877270160840903468092119e+819Q, 5.06475979937176267805686278644876593e+872Q, 6.64979079902917739733555562625190968e+928Q, 3.61927525412094487856735509111512169e+988Q, 1.39737404381894022658529893979427383e+1052Q, 6.78018387620311055320186127570560827e+1119Q, 7.59952044103401209205510909410129754e+1191Q, 3.76162862667265940011010617225061429e+1268Q, 1.63904309514033654209643026524489542e+1350Q, 1.31017858257252889370615733020834140e+1437Q, 4.19821396072116298475329351264459339e+1529Q, 1.23923791809549425227491870065845752e+1628Q, 8.17087984671936465200033730232853592e+1732Q, 3.08946915513007963115203650683840400e+1844Q, 1.82761916569338643673217752139790470e+1963Q, 4.92348318803338950087945240543349430e+2089Q, 1.88350835331965060456271693216651123e+2224Q, 3.43360015586068277793841059306542129e+2367Q, }, + { 1.57146131655078329437644376888801138e+00Q, 1.57679016631693834484126246342345329e+00Q, 1.58749564037038331646069625234555521e+00Q, 1.60367395634137020950291269057600307e+00Q, 1.62547112545749394267938666988196139e+00Q, 1.65308501191593930171844822364141731e+00Q, 1.68676814252591123625053019619255158e+00Q, 1.72683132353751620184313195813656600e+00Q, 1.77364813866723660171326886678529701e+00Q, 1.82766042147866144821632902536146347e+00Q, 1.88938481704401819562549601165115021e+00Q, 1.95942057285503709111658357403615203e+00Q, 2.03845872804790892275259742585569433e+00Q, 2.12729290408384722476899855222432786e+00Q, 2.22683194019907694104850876757126753e+00Q, 2.33811466455513029581902771513343722e+00Q, 2.46232714872299130380967769641847017e+00Q, 2.60082286092708516436098022317536381e+00Q, 2.75514621481455435937229822050004007e+00Q, 2.92706010842448355516791030533685920e+00Q, 3.11857816624092195149666191379786472e+00Q, 3.33200254033950662971711811118318338e+00Q, 3.56996830041074027550628111498923678e+00Q, 3.83549565399644726181552365400966870e+00Q, 4.13205149651293488468153425460318353e+00Q, 4.46362210669906788115667211361364802e+00Q, 4.83479919100800655701530131187647507e+00Q, 5.25088195776567960767293727240320892e+00Q, 5.71799849087533312421158643544587353e+00Q, 6.24325042159856810533215887376856930e+00Q, 6.83488580122654183866366620676303900e+00Q, 7.50250620278934080195915244309172491e+00Q, 8.25731548449354420110207897041998984e+00Q, 9.11241940586464263380079984086513597e+00Q, 1.00831874954399775830998395457182684e+01Q, 1.11876913499386520162594085796167645e+01Q, 1.24472370591410688131760615976965093e+01Q, 1.38870139060550758665255786705519681e+01Q, 1.55368871591590018952847646637454593e+01Q, 1.74323700068094283108112572669239084e+01Q, 1.96158189482399342378436216339159090e+01Q, 2.21379088635427380602824337731297019e+01Q, 2.50594593467713760968808829296439171e+01Q, 2.84537037774213756120135736520435304e+01Q, 3.24091184596952483433430577491101072e+01Q, 3.70329628948023016142035941015485370e+01Q, 4.24557264474626791146220920324192917e+01Q, 4.88367348033798558171280311705362727e+01Q, 5.63712464058697542020818458752120814e+01Q, 6.52994709275261034008086934786702551e+01Q, 7.59180775569412283714380617539343408e+01Q, 8.85949425239166382162609558265821220e+01Q, 1.03788129500578812415162165531670704e+02Q, 1.22070426396922674625756853326498468e+02Q, 1.44161209813120053456742433728771078e+02Q, 1.70968019124577351122499690038707734e+02Q, 2.03641059384357556999222931732850856e+02Q, 2.43645005870872364316059216110059642e+02Q, 2.92854081218207610543177302881458406e+02Q, 3.53678601915225339202500542949917795e+02Q, 4.29234308396729693907268968564609660e+02Q, 5.23570184048873302665650155276206906e+02Q, 6.41976689800302457508415746115180260e+02Q, 7.91405208366875928332161102969868782e+02Q, 9.81042208908193163688535235538889459e+02Q, 1.22309999499974039331272100414750813e+03Q, 1.53391255542711212726525490457861725e+03Q, 1.93546401360583033885511419988831009e+03Q, 2.45753454991288685207196097797062484e+03Q, 3.14073373162363551894782974867325472e+03Q, 4.04081818856465189750723035050638141e+03Q, 5.23488159971222568136194576211612571e+03Q, 6.83029445760732922582000345557383347e+03Q, 8.97771322864988714349790288910627671e+03Q, 1.18901592096732683947870697270695144e+04Q, 1.58712238704434696215746702894136306e+04Q, 2.13571110644578933143540830593360855e+04Q, 2.89798370518968143718297906801146350e+04Q, 3.96630672679554794954087134590560762e+04Q, 5.47687519375000078688553248953764732e+04Q, 7.63235653938805568016142182690471993e+04Q, 1.07371914975497695062170132456450593e+05Q, 1.52531667455557415180420019888676134e+05Q, 2.18877843474421658617449971461581691e+05Q, 3.17362449601929560775572985879585343e+05Q, 4.65120152586932846156175983364596723e+05Q, 6.89253765628058057206329188782990860e+05Q, 1.03311988512001998186230013733752720e+06Q, 1.56688798104325249948154338241641806e+06Q, 2.40549202702653179507492073842261453e+06Q, 3.73952896481591033994026114668796352e+06Q, 5.88912115489558003244667233279563785e+06Q, 9.39904635192234203007457377008255614e+06Q, 1.52090327612965351790614542733698474e+07Q, 2.49628718729357616773929842263043964e+07Q, 4.15775925996307484022703929049831425e+07Q, 7.03070536695026731176158877103497776e+07Q, 1.20759855845249336607363637052870598e+08Q, 2.10788250946484683324104572583041111e+08Q, 3.74104719902345786397351281755078701e+08Q, 6.75449459498741557237788387723071522e+08Q, 1.24131674041588053743260021864117384e+09Q, 2.32331003264955286246594304305695965e+09Q, 4.43117601902662575879840759020751450e+09Q, 8.61744648740090012951326726568665021e+09Q, 1.70983690660403151330619158427281665e+10Q, 3.46357452188017133850611855017361923e+10Q, 7.16760712379927072634183907084755700e+10Q, 1.51634762091005407908273857408800162e+11Q, 3.28172932323895052570169126695951209e+11Q, 7.27110260029828078950026409435831711e+11Q, 1.65049955237878037840731169761272102e+12Q, 3.84133814950880391685509371196326109e+12Q, 9.17374426778517657484962791255187134e+12Q, 2.24990194635751997880832549111511175e+13Q, 5.67153508990061173097292032404781538e+13Q, 1.47074225030769701852963232235912597e+14Q, 3.92701251846431177545392497147427712e+14Q, 1.08063997739121282020832802862957248e+15Q, 3.06767146672047518894275739534732971e+15Q, 8.99238678919832842771174638355746631e+15Q, 2.72472253652459211109041460799535823e+16Q, 8.54294612226338925817358060817490416e+16Q, 2.77461371872557475533476908014408616e+17Q, 9.34529947938202912146296976663431863e+17Q, 3.26799612298773188163350554315742192e+18Q, 1.18791443345546831451732293519928714e+19Q, 4.49405340841856421397062311314705655e+19Q, 1.77170665219548674305185389795833488e+20Q, 7.28810255288593152697603764235601397e+20Q, 3.13251243081662534865188632436805529e+21Q, 1.40874376795107311038838007000777184e+22Q, 6.63829426823606041441317767891166205e+22Q, 3.28254360840356501289107248021554584e+23Q, 1.70592009803839406409667145645666005e+24Q, 9.33225938514852428454935743602712728e+24Q, 5.38272717587488831207327363463407970e+25Q, 3.27895423512209324910006662705296242e+26Q, 2.11319169795745809927716305122705952e+27Q, 1.44341104149964304009687846325713305e+28Q, 1.04686439465498242316197235200069352e+29Q, 8.07731922695890570023291958025986094e+29Q, 6.64314696343261627707440459400107155e+30Q, 5.83567012135998626006817430636714368e+31Q, 5.48689029679023079776199817150941362e+32Q, 5.53372696850826161418229677716330718e+33Q, 5.99973499641835283449509393028972981e+34Q, 7.00917611946612256941556198729562373e+35Q, 8.84406196642459749869759626748371565e+36Q, 1.20822686086960596115573575744502341e+38Q, 1.79164851431106333799499432947126299e+39Q, 2.89131391671320576216903362266762013e+40Q, 5.09145786021152729801159516043566174e+41Q, 9.81063058840249655325327952160218101e+42Q, 2.07444123914737886022245738089968362e+44Q, 4.82765011693770054022189143000576390e+45Q, 1.24028793911154902904261886940649724e+47Q, 3.52878285864478461616951002487254771e+48Q, 1.11544949047169665881036414807872651e+50Q, 3.93051064332819631369914292573124112e+51Q, 1.54924371295785233686867649142553059e+53Q, 6.85499823804130100151231679166543611e+54Q, 3.41747996158320770357877327002949632e+56Q, 1.92690549864107998957222500013304086e+58Q, 1.23358096300491944958557136475962190e+60Q, 9.00281990289807691528078151573158069e+61Q, 7.52141514125344164522463463202808470e+63Q, 7.22427755490057899279344696654950663e+65Q, 8.01283283053507860974456727997488253e+67Q, 1.03099962028638036919997632019550562e+70Q, 1.54617495707674867923983623892142209e+72Q, 2.71580377261324869371341160824868908e+74Q, 5.61508992057174643750226165228505259e+76Q, 1.37366785934534333692942668275259398e+79Q, 3.99754102076962512613158938364235073e+81Q, 1.39150058933980008745266389466237314e+84Q, 5.82669384491202289249159160687839973e+86Q, 2.95227482092954909582266634062763990e+89Q, 1.82102306147846628152669685943631657e+92Q, 1.37597302213794152564743989887492097e+95Q, 1.28185236754341294523601004808033157e+98Q, 1.48213012720199050337233086306566580e+101Q, 2.14157427379243531419232668034147566e+104Q, 3.89449554094711237984570195229015661e+107Q, 8.97864636258010296104790318951217808e+110Q, 2.64413158980724405044777067425347595e+114Q, 1.00240353984191383430257305957041439e+118Q, 4.93141280490390525871801097705197944e+121Q, 3.17440111243586504420672164931106998e+125Q, 2.69662400176189239027511019786185589e+129Q, 3.04979932232044716644635827452454425e+133Q, 4.63404152681868778475392087605038845e+137Q, 9.54898313480310651224157422560754643e+141Q, 2.69440486619208982853089677098686964e+146Q, 1.05150272003639532507210605903884076e+151Q, 5.73417064062624495509840837865743050e+155Q, 4.41627650777870044428827641421915327e+160Q, 4.85653500442164862297918118887566388e+165Q, 7.71243776020172406235461422008761914e+170Q, 1.78944284768135145352387398006192815e+176Q, 6.13948504948193852500464630902178966e+181Q, 3.15374719244414866832063986813364807e+187Q, 2.45678229633130089072342575625791640e+193Q, 2.94097956743157560377748279040964662e+199Q, 5.48435772238022826264635788020315114e+205Q, 1.61576755939787162649511106856450099e+212Q, 7.63055674811964328822328719215905762e+218Q, 5.86357963426750903008317058039636736e+225Q, 7.44578009523250679265610908767109796e+232Q, 1.58753358925950887380498944645468602e+240Q, 5.77757179750005470017336807397418313e+247Q, 3.65046885264085030960970127282511879e+255Q, 4.07509702021276189043935129812053895e+263Q, 8.18389073292535025618266801702554839e+271Q, 3.01238089652162618211263051563523370e+280Q, 2.07176624104483264053704912869659325e+289Q, 2.71562735784398218302697011744202385e+298Q, 6.92451661016398143622710849660362520e+307Q, 3.50810155650162047040906671177815417e+317Q, 3.60896781300246599975888048597671985e+327Q, 7.71058277826701049982730585006218034e+337Q, 3.50154660288711246272389096490054302e+348Q, 3.46175331564137723439223486579386975e+359Q, 7.63696466254316472130052183903629062e+370Q, 3.85655304044390258996784681505914035e+382Q, 4.57665692577932081843759029527968784e+394Q, 1.31143566628034307965133274338127595e+407Q, 9.33142940209453779649608781259673613e+419Q, 1.69703443400488874615229289912465401e+433Q, 8.12664327627950884948530966790210152e+446Q, 1.05671342182667061564323377987059929e+461Q, 3.85123350151333031094457679550412807e+475Q, 4.06487630836024540948583469098247829e+490Q, 1.28516517984503545753808504263016648e+506Q, 1.26025754690341684764700072541766676e+522Q, 3.97331612896914344554453503890576277e+538Q, 4.17965516524315248567041014799432863e+555Q, 1.52416658652941127494202186163265994e+573Q, 2.00432202283496263048589917253126663e+591Q, 9.89983817930114056039301724151237036e+609Q, 1.91539340453423886973992445388091844e+629Q, 1.51593315523153267229971976448703684e+649Q, 5.13233111267478387648166311677061530e+669Q, 7.78392571224632702458474933380523830e+690Q, 5.54632077048043201021342066119640603e+712Q, 1.95012604607548018918112113273623192e+735Q, 3.55940947870861006830654543397286882e+758Q, 3.55349341454925685547195460273265331e+782Q, 2.04795692045857243226580641802720017e+807Q, 7.20348918974342452885439546130773017e+832Q, 1.63778937282231874342883712446170710e+859Q, 2.55384218509638087014670377175798088e+886Q, 2.90332357089198897009653578594580665e+914Q, 2.56300421336271050326091753908665515e+943Q, 1.87504708602076913446948153935468528e+973Q, 1.21573089114719501597325465689193734e+1004Q, 7.48693407429699486755736805187051392e+1035Q, 4.70376397570597947605315058283235338e+1068Q, 3.24549375035327607806235059706162609e+1102Q, 2.65365798053210741189633750297123713e+1137Q, 2.78113361306514574568406809189880354e+1173Q, 4.05114001708803517429009145027606492e+1210Q, 8.91647476482514121118371429882160487e+1248Q, 3.23223851331898724884680382253593571e+1288Q, 2.10925909168894371224120829576314259e+1329Q, 2.71594389750881594498007515800169231e+1371Q, 7.58558239286242519535157411695442827e+1414Q, 5.06701669031717221741926320252846248e+1459Q, 8.95314256637167381172114473249653533e+1505Q, 4.64314397380853725563695225910483395e+1553Q, 7.86772811149376784892131781209226509e+1602Q, 4.86578559687970087801384706555207321e+1653Q, 1.23116054769360594876926981962811083e+1706Q, 1.43383897399728293235616506956599019e+1760Q, 8.67960762728500385489074199138374599e+1815Q, 3.09584788327503858182429306492345781e+1873Q, 7.40514657822678853879551103162851562e+1932Q, 1.35750288266752565171774149402837640e+1994Q, 2.18886955807028168114167639122307268e+2057Q, 3.57839966436010585653478204799948336e+2122Q, 6.86791017358151132323155526430183469e+2189Q, 1.80021943882415618419042799861559854e+2259Q, 7.53312429569410546159363413753399067e+2330Q, 5.91165553375547478649257686857639971e+2404Q, }, + { 1.57096255099783261137673508918980377e+00Q, 1.57229290236721196082451564636254803e+00Q, 1.57495658191266675503402671533627186e+00Q, 1.57895955363616398471678434379990522e+00Q, 1.58431078956361430514416599492388597e+00Q, 1.59102230111703510742216272394562613e+00Q, 1.59910918118616033722590556649394763e+00Q, 1.60858965710906746764504456185444654e+00Q, 1.61948515482641974319339137784305225e+00Q, 1.63182037453073931785527493516038124e+00Q, 1.64562337819112567903033806653906069e+00Q, 1.66092568939542410935608828998468834e+00Q, 1.67776240601646371733138779357535047e+00Q, 1.69617232627708297296989766202480515e+00Q, 1.71619808886073246730768842066355199e+00Q, 1.73788632779101456236627555096372654e+00Q, 1.76128784288515241044102589887617560e+00Q, 1.78645778667368642025315725404601102e+00Q, 1.81345586877233558659749539967614045e+00Q, 1.84234657879265254187280543490489739e+00Q, 1.87319942898662752121993510591579920e+00Q, 1.90608921793761261888076943857856180e+00Q, 1.94109631673677945144587926354356120e+00Q, 1.97830697922181656566949720098719647e+00Q, 2.01781367800384433737712026561151498e+00Q, 2.05971546817081389507270282494773392e+00Q, 2.10411838073232749275747224342524909e+00Q, 2.15113584806337555354918618566085438e+00Q, 2.20088916381459141771044083611555369e+00Q, 2.25350797998611420231160903572594743e+00Q, 2.30913084411305337537709048855358397e+00Q, 2.36790577978511333384857209921738492e+00Q, 2.42999091402365295350102767412517845e+00Q, 2.49555515536908558968587982458158759e+00Q, 2.56477892689313451429557802920827974e+00Q, 2.63785495874745168415081659796280588e+00Q, 2.71498914529626806741705564771250802e+00Q, 2.79640147236028053619149909690973720e+00Q, 2.88232702062657870038560203490158574e+00Q, 2.97301705186029380311201985278736098e+00Q, 3.06874018519362823755119514588303156e+00Q, 3.16978367147348738564623946178566521e+00Q, 3.27645477442732860056345607892739085e+00Q, 3.38908226826615609816107421136979984e+00Q, 3.50801806229286913554992299494422526e+00Q, 3.63363896413353027399263692498221540e+00Q, 3.76634859436988420367634452674074607e+00Q, 3.90657946663630928939225987850575005e+00Q, 4.05479524866754112035397645627643742e+00Q, 4.21149322136091780158052739625729631e+00Q, 4.37720695466646221916071477112304019e+00Q, 4.55250922105994638849140210916632132e+00Q, 4.73801516951078282566987752649050466e+00Q, 4.93438578525358788671420711795537458e+00Q, 5.14233166333819107447595069798421539e+00Q, 5.36261712689997622445803908396748884e+00Q, 5.59606472439710019418213140693069575e+00Q, 5.84356014374437330661446789126222075e+00Q, 6.10605758538173469317727364122669467e+00Q, 6.38458564090067143612732202429488542e+00Q, 6.68025372897382444864907987044889317e+00Q, 6.99425914605841270881961646990609410e+00Q, 7.32789479574890106033548644768353338e+00Q, 7.68255766782458876413667730681699443e+00Q, 8.05975814607113727007240055318338450e+00Q, 8.46113023296234288939356989479671723e+00Q, 8.88844278939567108027044653070693778e+00Q, 9.34361189902548515485066576358196470e+00Q, 9.82871447949462202212030994384949241e+00Q, 1.03460032772138062549383568058709409e+01Q, 1.08979233984912291622835480030167114e+01Q, 1.14871305480132578973614919602781370e+01Q, 1.21165111661978855517781913327317255e+01Q, 1.27892046801009632078942555615288463e+01Q, 1.35086281087128109623831457304510920e+01Q, 1.42785032930533442126932924888187804e+01Q, 1.51028870549318132669071327511660921e+01Q, 1.59862046261270319640752848374642080e+01Q, 1.69332867326908112807352382039426796e+01Q, 1.79494107678000050622926329104204826e+01Q, 1.90403465419082315888820165929975494e+01Q, 2.02124071618296433363312214170232623e+01Q, 2.14725056619224736964251610816575600e+01Q, 2.28282180919971350546248653847563966e+01Q, 2.42878538594168042463845071817020910e+01Q, 2.58605342287811778487151334440784950e+01Q, 2.75562800035467442565131080245429614e+01Q, 2.93861095522110956389210768876799587e+01Q, 3.13621484999095132865600012683857137e+01Q, 3.34977525874991258153646142408367963e+01Q, 3.58076454079962546803810835720597110e+01Q, 3.83080729687253016658377309622401176e+01Q, 4.10169773015547344709659456503154667e+01Q, 4.39541916587611362308342994483809472e+01Q, 4.71416601949419692729062784327679986e+01Q, 5.06036854536665922553724504470269960e+01Q, 5.43672074601944525232284101611170030e+01Q, 5.84621187791213843904071404608607478e+01Q, 6.29216205405812878410372213510070276e+01Q, 6.77826251851241666263837617897404532e+01Q, 7.30862125426522301461255132629846162e+01Q, 7.88781468648814729209715096907821639e+01Q, 8.52094635973465833426799692679733796e+01Q, 9.21371360338777471668559829773781201e+01Q, 9.97248335767075464896305315099053068e+01Q, 1.08043785167904642576949987865910954e+02Q, 1.17173763608862169247776700625586421e+02Q, 1.27204208998868737227575356110541727e+02Q, 1.38235512466410237338282474486031692e+02Q, 1.50380484815148331050381123359927804e+02Q, 1.63766038752610274212021042234298836e+02Q, 1.78535118123338340289613569013808793e+02Q, 1.94848913160728060357302969254459805e+02Q, 2.12889407359835266977366307026062112e+02Q, 2.32862309344799079018746113493039633e+02Q, 2.55000432284328199435640048881527463e+02Q, 2.79567594267244578195192766207761694e+02Q, 3.06863125912428093434496643114651412e+02Q, 3.37227086745120087399301385427960651e+02Q, 3.71046309996557625549265358225650347e+02Q, 4.08761417046617491055856040237506316e+02Q, 4.50874968419459367009632339064163929e+02Q, 4.97960948895977349122916983180817637e+02Q, 5.50675820938578587679472462796822793e+02Q, 6.09771424466317909206822143572649707e+02Q, 6.76110053572647368547479902312230309e+02Q, 7.50682103874142244645724064576848341e+02Q, 8.34626760051808119187547981730818179e+02Q, 9.29256284531554199823656475151338963e+02Q, 1.03608457849823472804207172846963877e+03Q, 1.15686081966189765730466332807313547e+03Q, 1.29360914245380859999201252074469995e+03Q, 1.44867552185420514387789438088656434e+03Q, 1.62478325953219761549580736728832563e+03Q, 1.82509875991531856022535679631713756e+03Q, 2.05330963597261755441688599655848892e+03Q, 2.31371761449477720025881552764731872e+03Q, 2.61134923664018699944734187657483567e+03Q, 2.95208799409362429898911389656789101e+03Q, 3.34283233256054817982471990245472659e+03Q, 3.79168492775659509883214798303432158e+03Q, 4.30817983871631895490690508451026040e+03Q, 4.90355562457020167332670064217006554e+03Q, 5.59108434363481145162671079876733528e+03Q, 6.38646862557124634146730890858054275e+03Q, 7.30832182941297944038809179971510199e+03Q, 8.37874981279970356111509048453001571e+03Q, 9.62405721874963805881171453111047092e+03Q, 1.10756066619114600841076275282388063e+04Q, 1.27708660544590438787794590107117849e+04Q, 1.47546879201948945213025955616435132e+04Q, 1.70808753741706634268551294101897318e+04Q, 1.98141030969548505096681178137364270e+04Q, 2.30322788820475490754732581365999861e+04Q, 2.68294531792863253502182123460963590e+04Q, 3.13194117839842820030641964449539820e+04Q, 3.66401220970699799668192565829190288e+04Q, 4.29592483666869017028607105165763804e+04Q, 5.04810088263984357248209974578040223e+04Q, 5.94547213318005529011388227962133751e+04Q, 7.01854787517268957919092596317475529e+04Q, 8.30475172617569400265716546608431303e+04Q, 9.85009980505357544638949542794405193e+04Q, 1.17113126626176606026864191754698095e+05Q, 1.39584798216058984483938678946454092e+05Q, 1.66784301639307755633312351999980104e+05Q, 1.99790062652052468605951710457597772e+05Q, 2.39944994603299218686253514351518948e+05Q, 2.88925793983801323167992289814829493e+05Q, 3.48831530919430454806103930858415528e+05Q, 4.22297220149677844682618484564386312e+05Q, 5.12639824636925361908056913471196846e+05Q, 6.24046487622198979196137566922551170e+05Q, 7.61817907323361594136262168936978923e+05Q, 9.32683930022411925704630601110030182e+05Q, 1.14521400777429753902355978052778602e+06Q, 1.41035264627423311876298925540665884e+06Q, 1.74212004187586338510201667214170577e+06Q, 2.15853171693428701405141183541166264e+06Q, 2.68280941012642673073659887232388938e+06Q, 3.34498056359541886091597912499527306e+06Q, 4.18399797233770604788689812330719069e+06Q, 5.25055800816550175243256559083639418e+06Q, 6.61086017414168098803951872291131863e+06Q, 8.35163942396755869310534556270941378e+06Q, 1.05869253239392990034806970327887878e+07Q, 1.34671523510623940861241599892229316e+07Q, 1.71914827102426302145958883698307763e+07Q, 2.20245344902770169422620623417295079e+07Q, 2.83191730172433779681268016861978467e+07Q, 3.65476782026834493187990343694010282e+07Q, 4.73445265723062610640363034466641760e+07Q, 6.15653406350951387288804933390908042e+07Q, 8.03684302689786924828741611740519293e+07Q, 1.05328028435969028854761469747289545e+08Q, 1.38592168908412628618546923035162247e+08Q, 1.83103698592568352374304770508191971e+08Q, 2.42910945745864082034287213456845086e+08Q, 3.23606239375966746282831194186614169e+08Q, 4.32947521859998666323053129499091577e+08Q, 5.81743296796292947920442886775592966e+08Q, 7.85117978938819178602650773642870262e+08Q, 1.06432919762707530726575966438229782e+09Q, 1.44938958291294548467516226794019366e+09Q, 1.98286646937799184909776706883985509e+09Q, 2.72541431469809432350206616813747393e+09Q, 3.76386796411162144400474070771015333e+09Q, 5.22313881495099093715899688078276720e+09Q, 7.28378581064439770444275729738468286e+09Q, 1.02080964238115874250636198090464363e+10Q, 1.43789931847051052135186583023967432e+10Q, 2.03583681254363357780032810961889254e+10Q, 2.89749982708002744366825785538936402e+10Q, 4.14577375164549487752492409798515416e+10Q, 5.96383768387242628650336526594122215e+10Q, 8.62622848391553079951805623395652598e+10Q, 1.25466704538982518000690409655705216e+11Q, 1.83521298226491318558080545133554232e+11Q, 2.69981220740015160361114268684563366e+11Q, 3.99492845215192295441294253418780644e+11Q, 5.94638055870143455023933020703444642e+11Q, 8.90440996742409110650533033931653292e+11Q, 1.34155194167777583831947241717631506e+12Q, 2.03376855033215189170105222958089604e+12Q, 3.10262795987575321360135087196684567e+12Q, 4.76359832170586206290082815387968037e+12Q, 7.36142036056081358397678626842794083e+12Q, 1.14512696145655742338758840735549183e+13Q, 1.79331418699627392634462052642542749e+13Q, 2.82758550128579223200239017529280909e+13Q, 4.48929705367844466861372765075631687e+13Q, 7.17780287265849957064212371548037347e+13Q, 1.15585509854582062520354852997620279e+14Q, 1.87483388636788309288478433629583664e+14Q, 3.06351035640217445409310567498133847e+14Q, 5.04340065300597024230361727189343426e+14Q, 8.36616339689242989007881200440488764e+14Q, 1.39855635164094728875364679627485304e+15Q, 2.35633574951616468243164849507855064e+15Q, 4.00176516738263745645278590345795707e+15Q, 6.85137512840494144543571512545601884e+15Q, 1.18269011176154399046326619510431010e+16Q, 2.05867352701380644281110910622942185e+16Q, 3.61396878431490463311666873476678412e+16Q, 6.39911218439421355095519025524482256e+16Q, 1.14301618562837692261569180960886276e+17Q, 2.05988138391566644299797673070467922e+17Q, 3.74584678835368091393630059068193045e+17Q, 6.87444303468314906803024757565005462e+17Q, 1.27340764361348531366853034790770231e+18Q, 2.38124191682989536626992792404294190e+18Q, 4.49583561730710839927340662784958898e+18Q, 8.57144202490195270096830399067728169e+18Q, 1.65044358418165696532477771893166700e+19Q, 3.21010035242131785085169993033188229e+19Q, 6.30778012444270309076492866733769742e+19Q, 1.25240403115766127899628450500249765e+20Q, 2.51300529564998539443832117224536420e+20Q, 5.09677625569083843571268035202853929e+20Q, 1.04501920001667304566512216455267827e+21Q, 2.16647647926087846601520265828431353e+21Q, 4.54213814567839546278770815494416868e+21Q, 9.63208232444913712819259248595549405e+21Q, 2.06638653668825452816630915727527426e+22Q, 4.48552978555442825059406438230470388e+22Q, 9.85387957361097750825498509227133701e+22Q, 2.19115887446437440814640517501285189e+23Q, 4.93283596439097166796547625560314132e+23Q, 1.12450152997177436346173556893175508e+24Q, 2.59626913615675600812300017445220112e+24Q, 6.07229293831362550112108555687653017e+24Q, 1.43898906630800383562329122001513450e+25Q, 3.45584195640657046905140678735606870e+25Q, 8.41265519171357648977229820858109463e+25Q, 2.07628906165081651016090959669418757e+26Q, 5.19651502464022032237151119613068945e+26Q, 1.31917319408964404296057699402007921e+27Q, 3.39745589598038079361346075350889747e+27Q, 8.87905745443850359109225209251728000e+27Q, 2.35527236149206412607849676379867126e+28Q, 6.34276200772262482389475687836384423e+28Q, 1.73453109399085970484897533524593455e+29Q, 4.81789317060683087119323058524624972e+29Q, 1.35959734649014823198654051259347560e+30Q, 3.89896968990650039174705544740914822e+30Q, 1.13654298652998993600898528562905634e+31Q, 3.36845004399178001650511659074612092e+31Q, 1.01530408470981725989945294876828360e+32Q, 3.11314437622191823730222798219255685e+32Q, 9.71307273973014040273869048577801862e+32Q, 3.08451764358172594571945077912559223e+33Q, 9.97268213982049728423469082288644341e+33Q, 3.28362505228849158612675319471610094e+34Q, 1.10137878539082753552686700652535380e+35Q, 3.76433336759271429732220889611944227e+35Q, 1.31140346593824292621577115225698644e+36Q, 4.65813571068281367213354863266427946e+36Q, 1.68751734747051139203189162215633629e+37Q, 6.23705368501832349017363870039959902e+37Q, 2.35257131442774486893301429598817553e+38Q, 9.05893824021969993626817980294413695e+38Q, 3.56224909761113607077591549609142868e+39Q, 1.43095929157855820977839447284784020e+40Q, 5.87397458498437504922632656680942932e+40Q, 2.46482854981128378684502286098690220e+41Q, 1.05764920309085562822396787743332401e+42Q, 4.64247563928107803530506772359734012e+42Q, 2.08528711827242177927156523287132065e+43Q, 9.58843998518663217709277358040461543e+43Q, 4.51498201124609227956079072858258677e+44Q, 2.17797404834197320411588567916752909e+45Q, 1.07672097682290045825361349736107198e+46Q, 5.45726743292908558875367244655615249e+46Q, 2.83686927045578113375020568154351117e+47Q, 1.51310320139201162564313806536303971e+48Q, 8.28397466722561707458255405781541923e+48Q, 4.65723949199597134403065145457979764e+49Q, 2.68979637071283693718739500357715726e+50Q, 1.59659784691197038762901224386099403e+51Q, 9.74415453825658662874112107295166701e+51Q, 6.11723839484331306452493250946377612e+52Q, 3.95204965058524182677586041680204451e+53Q, 2.62870159207425821306145211826683375e+54Q, 1.80099019650267939321809025642439880e+55Q, 1.27155446256306838318997486480890087e+56Q, 9.25588010447776071059464920928086632e+56Q, 6.94973792013391939342588109222317053e+57Q, 5.38516720076996562080859176422021036e+58Q, 4.30849366810297877444039522534393308e+59Q, 3.56095155754217837059656555899190815e+60Q, 3.04188852838464999204043663335571874e+61Q, 2.68709444193083718922293037351168007e+62Q, 2.45592053890000085507656649738841713e+63Q, 2.32364825416864153745578539849845717e+64Q, 2.27712974158489233058096874867974690e+65Q, 2.31263355291322473374027008502422191e+66Q, 2.43540759298129112939388619780518297e+67Q, 2.66091038882246524570905302589811279e+68Q, 3.01810594342353392025458974267831671e+69Q, 3.55582348951019250289525994888733340e+70Q, 4.35418887779384901315251041444022899e+71Q, 5.54497579551181331524599144834616000e+72Q, 7.34827648190988633565298908145357523e+73Q, 1.01399802572242326074394064208241565e+75Q, 1.45791146224460794340779409761344050e+76Q, 2.18548887681950529537081926891986328e+77Q, 3.41802215328662300798456454917771592e+78Q, 5.58084392060183572830239216435019125e+79Q, 9.51958650279973390758331753317257950e+80Q, 1.69757357824719778562747265505252946e+82Q, 3.16690667099018001388115076193097403e+83Q, 6.18509910641867543038652223056425804e+84Q, 1.26554113438693437654962757714903554e+86Q, 2.71482896587775689871692274985919286e+87Q, 6.11038680296449408162222719197467046e+88Q, 1.44405408617108323852658132530082074e+90Q, 3.58608372663838816495703910754396082e+91Q, 9.36523186806323959966772742491929522e+92Q, 2.57408011620512244881601880029319908e+94Q, 7.45213468986230271920125476429174422e+95Q, 2.27430990383616981910627355587444817e+97Q, 7.32301113412116474943463116371095103e+98Q, 2.48981642173793246167799170730006141e+100Q, 8.94653338635928158843209476986997508e+101Q, 3.40040137239116597862336436061445989e+103Q, 1.36828818620892821730981225660157834e+105Q, 5.83427748982959193060571787534606697e+106Q, 2.63848693767238342424340754241860221e+108Q, 1.26672888276713952132156406152434700e+110Q, 6.46222517831418280306046165038174027e+111Q, 3.50643232060757360375065377104810475e+113Q, 2.02560893394326816509670349356333828e+115Q, 1.24704167708478470702273287091045609e+117Q, 8.18986518840527903795498196049278255e+118Q, 5.74361089440609996487936977642920132e+120Q, 4.30580893408448976261136511421423734e+122Q, 3.45415696607949675499703108821962730e+124Q, 2.96831660153035273688363706593385374e+126Q, 2.73545624237218359223636851390580041e+128Q, 2.70631717669007784745026117275242499e+130Q, 2.87767991634206038473084413615742294e+132Q, 3.29241287826810639047033778585737812e+134Q, 4.05784096195372596931902665934287382e+136Q, 5.39378304910573732382585500687737807e+138Q, 7.74152390167223540621293648465491842e+140Q, 1.20120996231066845642412985516875175e+143Q, 2.01745607955680730064740044686640147e+145Q, 3.67217662348306252636962893865111425e+147Q, 7.25316379805857762968710347450256630e+149Q, 1.55659153530257056999948366173645285e+152Q, 3.63439983279039488510674235872123571e+154Q, 9.24438760046827764031744167566698413e+156Q, 2.56505460126015154661078513762260065e+159Q, 7.77468767447849521051212939671796074e+161Q, 2.57775340952739965069105894604883404e+164Q, 9.36236559200171990439286451934391539e+166Q, 3.73025928974609135812613567068392186e+169Q, 1.63280699411172483017448754437467171e+172Q, 7.86350685466830069681739337700194312e+174Q, 4.17288659053103260909421860789088638e+177Q, 2.44376468354452976432259429734905692e+180Q, 1.58182604983516221850901239956537929e+183Q, 1.13349408906485996833819126879692168e+186Q, 9.00609317867158059779746161516574861e+188Q, 7.94724581006520631483760616875503191e+191Q, 7.80148734070770210787180909072341250e+194Q, 8.53389980133319877537947288273508168e+197Q, 1.04199907704816359699116619452657846e+201Q, 1.42261945983107616739713958471131412e+204Q, 2.17558254343347922345039318825837040e+207Q, 3.73339221107050141050095672544726852e+210Q, 7.20212971416878494124587287789857735e+213Q, 1.56476087980246841023430707631510252e+217Q, 3.83599289170088247519036274601375492e+220Q, 1.06310518934360483187879118646180568e+224Q, 3.33719954606082150504485397744546787e+227Q, 1.18890644129926367056386614030943443e+231Q, 4.81657405194041613555936914144916344e+234Q, 2.22347874123114616622582251703709887e+238Q, 1.17199258523361213934517364652872480e+242Q, 7.06839671131322838482398929154588609e+245Q, 4.88812662946732326430886472870070228e+249Q, 3.88441192207630934518298772235960268e+253Q, 3.55483921979499015020713995580889030e+257Q, 3.75484510816250928148708038190395303e+261Q, 4.58798720933643387311573482445886110e+265Q, 6.49989966050568126079524541048529496e+269Q, 1.07018103272413666142402906179157598e+274Q, 2.05258799808849457042833394124187317e+278Q, 4.59710306190259625117029822247574448e+282Q, 1.20521640888055636836192268959955157e+287Q, 3.70784262206985650361726040790594581e+291Q, 1.34198324051735290325452259089861845e+296Q, 5.72866922601176092550850127280325304e+300Q, 2.89181208605318627652310091586335359e+305Q, 1.73078309894901278503683645288680165e+310Q, 1.23150483936231719457381379774516673e+315Q, 1.04456022524616506171048138618772005e+320Q, 1.05909848234544418123752752792015094e+325Q, 1.28725694153849592436889057738754649e+330Q, 1.88087499295689639308903342601320607e+335Q, 3.31344446614783992260480183208324732e+340Q, 7.05835740270200829603933852702222207e+345Q, 1.82360609116987101874149506325271866e+351Q, 5.73167527316999715111499624522524490e+356Q, 2.19834460849656433024448179756162490e+362Q, 1.03213196012299389398122351217909554e+368Q, 5.95090459142945173642877532664315820e+373Q, 4.22711326689560391486862730288730260e+379Q, 3.71146073815998244096864189178283440e+385Q, 4.04143285030597516778349567433491877e+391Q, 5.47630493200706306950643242188138639e+397Q, 9.26610183846830899934754118194991047e+403Q, 1.96463867218278875638951764233831097e+410Q, 5.23826401399289488725708314794013273e+416Q, 1.76269979359229195206462702562496087e+423Q, 7.51358974574222029659643352716721030e+429Q, 4.07203690042780566335825621191079282e+436Q, 2.81652392485993763998682010256080428e+443Q, 2.49586432083962995754217338958145192e+450Q, 2.84464997550187838898841424132533307e+457Q, 4.18656911271834268911740204159815337e+464Q, 7.98835944729121866190974499356597568e+471Q, 1.98427885725374523364086923738598523e+479Q, 6.44313780728812316513345459942694301e+486Q, 2.74646447436726496994650106679472135e+494Q, 1.54345331097536381511922890966406624e+502Q, 1.14854061177091306735355343708426610e+510Q, 1.13671799925771100929831048483235430e+518Q, 1.50301408173820906903238314130252343e+526Q, 2.66721742401349021977265127553699936e+534Q, 6.38191727827371990119668697526910696e+542Q, 2.06864189323929509313332139375745418e+551Q, 9.12718925758572793769909253655546363e+559Q, 5.50827087084343716443556503345322384e+568Q, 4.56943096951975523591483538202467049e+577Q, 5.23664812769936727945516120554813767e+586Q, 8.33295831969513770916127078276468196e+595Q, 1.85073603040006635508770638738735213e+605Q, 5.76725912854578779706265298662279369e+614Q, 2.53507221317613667093309510235117825e+624Q, 1.58037348241924263546145926074674624e+634Q, 1.40497098317887844492262106048698980e+644Q, 1.79118532756424559114150403858023467e+654Q, 3.29340233091271285034548969456076701e+664Q, 8.78384225704905897945003526718634352e+674Q, 3.41824790512159692619674889187554870e+685Q, 1.95247619547378795632466874007982924e+696Q, 1.64685615123975037569921507294781182e+707Q, 2.06385512057306929298128483493412318e+718Q, 3.86691162964076111860523245198584961e+729Q, 1.09008736553561747232882422664193409e+741Q, 4.65333391196364819411904308657257877e+752Q, 3.02768585771015415481330091322447912e+764Q, 3.02262040534180824988954474846992913e+776Q, 4.66133722640174567906974646266839244e+788Q, 1.11806119156969171229108916233644999e+801Q, 4.20019655376202192049844032418033555e+813Q, 2.48880615873773868126893696694455625e+826Q, 2.34286193142054643224145247339492426e+839Q, 3.52941162196327496812531706159176164e+852Q, 8.57183106082165907783781027353105401e+865Q, 3.38163627323872188047900717079347979e+879Q, 2.18363447282104345585022834572887531e+893Q, 2.32596275137292895223293068081362090e+907Q, 4.11925247272574761366980289309686003e+921Q, 1.22265489460258041690738897372130823e+936Q, 6.13184165651799059701146847592463464e+950Q, 5.23922303275545560334122760478493484e+965Q, 7.69087233862553980667730597006685190e+980Q, 1.95622275953749870274795206909257068e+996Q, 8.69670052895401378378113763338699958e+1011Q, 6.81715148318539616903616353647181598e+1027Q, 9.50697711954141544724599553989093262e+1043Q, 2.38019733682587370869498352841844428e+1060Q, 1.07973324919847346937291516197684901e+1077Q, 8.95814284819025403820872820042945790e+1093Q, 1.37229192661307043018958002675397831e+1111Q, 3.91918794622242371528673544888524419e+1128Q, 2.10730218913863433412315532873510194e+1146Q, 2.15459607934366008026324206138837528e+1164Q, 4.23163839295623007237154131840451677e+1182Q, 1.61294441956204958952970453918741185e+1201Q, 1.20568335528354973250479511763057854e+1220Q, 1.78630819666459637235669417819650103e+1239Q, 5.30233997012953850434143324467683139e+1258Q, 3.18800705045665419646272046839479382e+1278Q, 3.92589619613994835597705628928304867e+1298Q, 1.00145056975313260959947278741812233e+1319Q, 5.35268808912615454171856125906228237e+1339Q, 6.06491960606218539467705074145131193e+1360Q, 1.47410187506507259371724909079906759e+1382Q, 7.77855372825975976779550291054389078e+1403Q, 9.02071339187528665617085297107535931e+1425Q, 2.32776342394968427168699373890370933e+1448Q, 1.35351409374730203846799381939288903e+1471Q, 1.79625881886715571166142200348072039e+1494Q, 5.51189494978629938318487744451579809e+1517Q, 3.96270198063441303687686251379779681e+1541Q, 6.76492837567767494547614386605795924e+1565Q, 2.77991073110506719318274536923711255e+1590Q, 2.78805951202715437087943440518839779e+1615Q, 6.92116280606414755524296394791409952e+1640Q, 4.31380309053366092943951122004431463e+1666Q, 6.84923073262139995438889690748178280e+1692Q, 2.81137418164430829179092468240459910e+1719Q, 3.02821524237655652451836921974619657e+1746Q, 8.69048903533522694231765189726868666e+1773Q, 6.74828063313306417588175763238310325e+1801Q, 1.44026065844141159256872926595644247e+1830Q, 8.58426091495439408178371839859019039e+1858Q, 1.45211919400936944187225846047638548e+1888Q, 7.08718013380970011842483247147601395e+1917Q, 1.01475962220405902523641440040104610e+1948Q, 4.33542978691578087509838132034723750e+1978Q, 5.62285772227295495777726116212032065e+2009Q, 2.25285072921565445630031609130087435e+2041Q, 2.83839050906274298341210206309759282e+2073Q, 1.14501659579022194588844609345877849e+2106Q, 1.50629562239998305958408533546634030e+2139Q, 6.58342161306998815751663631350733541e+2172Q, 9.74198999952210922892973281379349494e+2206Q, 4.97552704772088889228035264268694867e+2241Q, 8.94330619882842342247706838649878784e+2276Q, 5.77072420156026800834371478648673792e+2312Q, 1.36388225285320494361282201451878478e+2349Q, 1.20508189950290985406298094670730466e+2386Q, 4.06413362486490272506766749982212198e+2423Q, 5.34308092015215251528601382597439463e+2461Q, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 8.88600744303961370002819023592353264e+00Q; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif + +}}}} + +#endif // BOOST_MATH_HAS_NVRTC + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace quadrature { +namespace detail { + +__constant__ float m_abscissas_float_1[4] = + { 3.08828742e+00f, 1.48993185e+02f, 3.41228925e+06f, 2.06932577e+18f, }; + +__constant__ float m_abscissas_float_2[4] = + { 9.13048763e-01f, 1.41578929e+01f, 6.70421552e+03f, 9.64172533e+10f, }; + +__constant__ float m_abscissas_float_3[8] = + { 4.07297690e-01f, 1.68206671e+00f, 6.15089799e+00f, 4.00396235e+01f, 7.92920025e+02f, 1.02984971e+05f, + 3.03862311e+08f, 1.56544547e+14f, }; + +__constant__ float m_abscissas_float_4[16] = + { 1.98135272e-01f, 6.40155674e-01f, 1.24892870e+00f, 2.26608084e+00f, 4.29646270e+00f, 9.13029039e+00f, + 2.31110765e+01f, 7.42770603e+01f, 3.26720921e+02f, 2.15948569e+03f, 2.41501526e+04f, 5.31819400e+05f, + 2.80058686e+07f, 4.52406508e+09f, 3.08561257e+12f, 1.33882673e+16f, }; + +__constant__ float m_abscissas_float_5[32] = + { 9.83967894e-02f, 3.00605618e-01f, 5.19857979e-01f, 7.70362083e-01f, 1.07131137e+00f, 1.45056976e+00f, + 1.95077855e+00f, 2.64003177e+00f, 3.63137237e+00f, 5.11991533e+00f, 7.45666098e+00f, 1.13022613e+01f, + 1.79641069e+01f, 3.01781070e+01f, 5.40387580e+01f, 1.04107731e+02f, 2.18029520e+02f, 5.02155699e+02f, + 1.28862131e+03f, 3.73921687e+03f, 1.24750730e+04f, 4.87639975e+04f, 2.28145658e+05f, 1.30877796e+06f, + 9.46084663e+06f, 8.88883120e+07f, 1.12416883e+09f, 1.99127673e+10f, 5.16743469e+11f, 2.06721881e+13f, + 1.35061503e+15f, 1.53854066e+17f, }; + +__constant__ float m_abscissas_float_6[65] = + { 4.91151004e-02f, 1.48013150e-01f, 2.48938814e-01f, 3.53325424e-01f, 4.62733557e-01f, 5.78912068e-01f, + 7.03870253e-01f, 8.39965859e-01f, 9.90015066e-01f, 1.15743257e+00f, 1.34641276e+00f, 1.56216711e+00f, + 1.81123885e+00f, 2.10192442e+00f, 2.44484389e+00f, 2.85372075e+00f, 3.34645891e+00f, 3.94664582e+00f, + 4.68567310e+00f, 5.60576223e+00f, 6.76433234e+00f, 8.24038318e+00f, 1.01439436e+01f, 1.26302471e+01f, + 1.59213040e+01f, 2.03392186e+01f, 2.63584645e+01f, 3.46892633e+01f, 4.64129147e+01f, 6.32055079e+01f, + 8.77149726e+01f, 1.24209693e+02f, 1.79718635e+02f, 2.66081728e+02f, 4.03727303e+02f, 6.28811307e+02f, + 1.00707984e+03f, 1.66156823e+03f, 2.82965144e+03f, 4.98438627e+03f, 9.10154693e+03f, 1.72689266e+04f, + 3.41309958e+04f, 7.04566898e+04f, 1.52340422e+05f, 3.46047978e+05f, 8.28472421e+05f, 2.09759615e+06f, + 5.63695080e+06f, 1.61407141e+07f, 4.94473068e+07f, 1.62781052e+08f, 5.78533297e+08f, 2.23083854e+09f, + 9.38239131e+09f, 4.32814954e+10f, 2.20307274e+11f, 1.24524507e+12f, 7.86900053e+12f, 5.59953143e+13f, + 4.52148695e+14f, 4.17688952e+15f, 4.45286776e+16f, 5.52914285e+17f, 8.07573252e+18f, }; + +__constant__ float m_abscissas_float_7[129] = + { 2.45471558e-02f, 7.37246687e-02f, 1.23152531e-01f, 1.73000138e-01f, 2.23440665e-01f, 2.74652655e-01f, + 3.26821679e-01f, 3.80142101e-01f, 4.34818964e-01f, 4.91070037e-01f, 5.49128046e-01f, 6.09243132e-01f, + 6.71685571e-01f, 7.36748805e-01f, 8.04752842e-01f, 8.76048080e-01f, 9.51019635e-01f, 1.03009224e+00f, + 1.11373586e+00f, 1.20247203e+00f, 1.29688123e+00f, 1.39761124e+00f, 1.50538689e+00f, 1.62102121e+00f, + 1.74542840e+00f, 1.87963895e+00f, 2.02481711e+00f, 2.18228138e+00f, 2.35352849e+00f, 2.54026147e+00f, + 2.74442267e+00f, 2.96823279e+00f, 3.21423687e+00f, 3.48535896e+00f, 3.78496698e+00f, 4.11695014e+00f, + 4.48581137e+00f, 4.89677825e+00f, 5.35593629e+00f, 5.87038976e+00f, 6.44845619e+00f, 7.09990245e+00f, + 7.83623225e+00f, 8.67103729e+00f, 9.62042778e+00f, 1.07035620e+01f, 1.19433001e+01f, 1.33670142e+01f, + 1.50075962e+01f, 1.69047155e+01f, 1.91063967e+01f, 2.16710044e+01f, 2.46697527e+01f, 2.81898903e+01f, + 3.23387613e+01f, 3.72490076e+01f, 4.30852608e+01f, 5.00527965e+01f, 5.84087761e+01f, 6.84769282e+01f, + 8.06668178e+01f, 9.54992727e+01f, 1.13640120e+02f, 1.35945194e+02f, 1.63520745e+02f, 1.97804969e+02f, + 2.40678754e+02f, 2.94617029e+02f, 3.62896953e+02f, 4.49886178e+02f, 5.61444735e+02f, 7.05489247e+02f, + 8.92790773e+02f, 1.13811142e+03f, 1.46183599e+03f, 1.89233262e+03f, 2.46939604e+03f, 3.24931157e+03f, + 4.31236711e+03f, 5.77409475e+03f, 7.80224724e+03f, 1.06426753e+04f, 1.46591538e+04f, 2.03952854e+04f, + 2.86717062e+04f, 4.07403376e+04f, 5.85318231e+04f, 8.50568927e+04f, 1.25064927e+05f, 1.86137394e+05f, + 2.80525578e+05f, 4.28278249e+05f, 6.62634051e+05f, 1.03944324e+06f, 1.65385743e+06f, 2.67031565e+06f, + 4.37721203e+06f, 7.28807171e+06f, 1.23317299e+07f, 2.12155729e+07f, 3.71308625e+07f, 6.61457938e+07f, + 1.20005529e+08f, 2.21862941e+08f, 4.18228294e+08f, 8.04370413e+08f, 1.57939299e+09f, 3.16812242e+09f, + 6.49660681e+09f, 1.36285199e+10f, 2.92686390e+10f, 6.43979867e+10f, 1.45275523e+11f, 3.36285446e+11f, + 7.99420279e+11f, 1.95326423e+12f, 4.90958187e+12f, 1.27062273e+13f, 3.38907099e+13f, 9.32508403e+13f, + 2.64948942e+14f, 7.78129518e+14f, 2.36471505e+15f, 7.44413803e+15f, 2.43021724e+16f, 8.23706864e+16f, + 2.90211705e+17f, 1.06415768e+18f, 4.06627711e+18f, }; + +__constant__ float m_abscissas_float_8[259] = + { 1.22722792e-02f, 3.68272289e-02f, 6.14133763e-02f, 8.60515971e-02f, 1.10762884e-01f, 1.35568393e-01f, + 1.60489494e-01f, 1.85547813e-01f, 2.10765290e-01f, 2.36164222e-01f, 2.61767321e-01f, 2.87597761e-01f, + 3.13679240e-01f, 3.40036029e-01f, 3.66693040e-01f, 3.93675878e-01f, 4.21010910e-01f, 4.48725333e-01f, + 4.76847237e-01f, 5.05405685e-01f, 5.34430786e-01f, 5.63953775e-01f, 5.94007101e-01f, 6.24624511e-01f, + 6.55841151e-01f, 6.87693662e-01f, 7.20220285e-01f, 7.53460977e-01f, 7.87457528e-01f, 8.22253686e-01f, + 8.57895297e-01f, 8.94430441e-01f, 9.31909591e-01f, 9.70385775e-01f, 1.00991475e+00f, 1.05055518e+00f, + 1.09236885e+00f, 1.13542087e+00f, 1.17977990e+00f, 1.22551840e+00f, 1.27271289e+00f, 1.32144424e+00f, + 1.37179794e+00f, 1.42386447e+00f, 1.47773961e+00f, 1.53352485e+00f, 1.59132774e+00f, 1.65126241e+00f, + 1.71344993e+00f, 1.77801893e+00f, 1.84510605e+00f, 1.91485658e+00f, 1.98742510e+00f, 2.06297613e+00f, + 2.14168493e+00f, 2.22373826e+00f, 2.30933526e+00f, 2.39868843e+00f, 2.49202464e+00f, 2.58958621e+00f, + 2.69163219e+00f, 2.79843963e+00f, 2.91030501e+00f, 3.02754584e+00f, 3.15050230e+00f, 3.27953915e+00f, + 3.41504770e+00f, 3.55744805e+00f, 3.70719145e+00f, 3.86476298e+00f, 4.03068439e+00f, 4.20551725e+00f, + 4.38986641e+00f, 4.58438376e+00f, 4.78977239e+00f, 5.00679110e+00f, 5.23625945e+00f, 5.47906320e+00f, + 5.73616037e+00f, 6.00858792e+00f, 6.29746901e+00f, 6.60402117e+00f, 6.92956515e+00f, 7.27553483e+00f, + 7.64348809e+00f, 8.03511888e+00f, 8.45227058e+00f, 8.89695079e+00f, 9.37134780e+00f, 9.87784877e+00f, + 1.04190601e+01f, 1.09978298e+01f, 1.16172728e+01f, 1.22807990e+01f, 1.29921443e+01f, 1.37554055e+01f, + 1.45750793e+01f, 1.54561061e+01f, 1.64039187e+01f, 1.74244972e+01f, 1.85244301e+01f, 1.97109839e+01f, + 2.09921804e+01f, 2.23768845e+01f, 2.38749023e+01f, 2.54970927e+01f, 2.72554930e+01f, 2.91634608e+01f, + 3.12358351e+01f, 3.34891185e+01f, 3.59416839e+01f, 3.86140099e+01f, 4.15289481e+01f, 4.47120276e+01f, + 4.81918020e+01f, 5.20002465e+01f, 5.61732106e+01f, 6.07509371e+01f, 6.57786566e+01f, 7.13072704e+01f, + 7.73941341e+01f, 8.41039609e+01f, 9.15098607e+01f, 9.96945411e+01f, 1.08751694e+02f, 1.18787600e+02f, + 1.29922990e+02f, 1.42295202e+02f, 1.56060691e+02f, 1.71397955e+02f, 1.88510933e+02f, 2.07632988e+02f, + 2.29031559e+02f, 2.53013612e+02f, 2.79932028e+02f, 3.10193130e+02f, 3.44265522e+02f, 3.82690530e+02f, + 4.26094527e+02f, 4.75203518e+02f, 5.30860437e+02f, 5.94045681e+02f, 6.65901543e+02f, 7.47761337e+02f, + 8.41184173e+02f, 9.47996570e+02f, 1.07034233e+03f, 1.21074246e+03f, 1.37216724e+03f, 1.55812321e+03f, + 1.77275819e+03f, 2.02098849e+03f, 2.30865326e+03f, 2.64270219e+03f, 3.03142418e+03f, 3.48472668e+03f, + 4.01447750e+03f, 4.63492426e+03f, 5.36320995e+03f, 6.22000841e+03f, 7.23030933e+03f, 8.42439022e+03f, + 9.83902287e+03f, 1.15189746e+04f, 1.35188810e+04f, 1.59055875e+04f, 1.87610857e+04f, 2.21862046e+04f, + 2.63052621e+04f, 3.12719440e+04f, 3.72767546e+04f, 4.45564828e+04f, 5.34062659e+04f, 6.41950058e+04f, + 7.73851264e+04f, 9.35579699e+04f, 1.13446538e+05f, 1.37977827e+05f, 1.68327749e+05f, 2.05992575e+05f, + 2.52882202e+05f, 3.11442272e+05f, 3.84814591e+05f, 4.77048586e+05f, 5.93380932e+05f, 7.40606619e+05f, + 9.27573047e+05f, 1.16584026e+06f, 1.47056632e+06f, 1.86169890e+06f, 2.36558487e+06f, 3.01715270e+06f, + 3.86288257e+06f, 4.96486431e+06f, 6.40636283e+06f, 8.29948185e+06f, 1.07957589e+07f, 1.41008733e+07f, + 1.84951472e+07f, 2.43622442e+07f, 3.22295113e+07f, 4.28249388e+07f, 5.71579339e+07f, 7.66343793e+07f, + 1.03221273e+08f, 1.39683399e+08f, 1.89925150e+08f, 2.59486540e+08f, 3.56266474e+08f, 4.91582541e+08f, + 6.81731647e+08f, 9.50299811e+08f, 1.33159830e+09f, 1.87580198e+09f, 2.65667391e+09f, 3.78324022e+09f, + 5.41753185e+09f, 7.80169537e+09f, 1.12996537e+10f, 1.64614916e+10f, 2.41235400e+10f, 3.55648690e+10f, + 5.27534501e+10f, 7.87357211e+10f, 1.18256902e+11f, 1.78754944e+11f, 2.71963306e+11f, 4.16512215e+11f, + 6.42178186e+11f, 9.96872550e+11f, 1.55821233e+12f, 2.45280998e+12f, 3.88865623e+12f, 6.20986899e+12f, + 9.98992422e+12f, 1.61915800e+13f, 2.64432452e+13f, 4.35201885e+13f, 7.21888469e+13f, 1.20699764e+14f, + 2.03448372e+14f, 3.45755310e+14f, 5.92524851e+14f, 1.02405779e+15f, 1.78517405e+15f, 3.13930699e+15f, + 5.56985627e+15f, 9.97176335e+15f, 1.80168749e+16f, 3.28570986e+16f, 6.04901854e+16f, 1.12437528e+17f, + 2.11044513e+17f, 4.00073701e+17f, 7.66084936e+17f, 1.48201877e+18f, 2.89694543e+18f, 5.72279017e+18f, + 1.14268996e+19f, }; + +__constant__ float* m_abscissas_float[8] = { + m_abscissas_float_1, + m_abscissas_float_2, + m_abscissas_float_3, + m_abscissas_float_4, + m_abscissas_float_5, + m_abscissas_float_6, + m_abscissas_float_7, + m_abscissas_float_8, +}; + +__constant__ float m_weights_float_1[4] = + { 7.86824160e+00f, 8.80516388e+02f, 5.39627832e+07f, 8.87651190e+19f, }; + +__constant__ float m_weights_float_2[4] = + { 2.39852428e+00f, 5.24459642e+01f, 6.45788782e+04f, 2.50998524e+12f, }; + +__constant__ float m_weights_float_3[8] = + { 1.74936958e+00f, 3.97965898e+00f, 1.84851460e+01f, 1.86488072e+02f, 5.97420570e+03f, 1.27041264e+06f, + 6.16419301e+09f, 5.23085003e+15f, }; + +__constant__ float m_weights_float_4[16] = + { 1.61385906e+00f, 1.99776729e+00f, 3.02023198e+00f, 5.47764184e+00f, 1.17966092e+01f, 3.03550485e+01f, + 9.58442179e+01f, 3.89387024e+02f, 2.17919325e+03f, 1.83920812e+04f, 2.63212061e+05f, 7.42729651e+06f, + 5.01587565e+08f, 1.03961087e+11f, 9.10032891e+13f, 5.06865116e+17f, }; + +__constant__ float m_weights_float_5[32] = + { 1.58146596e+00f, 1.66914991e+00f, 1.85752319e+00f, 2.17566262e+00f, 2.67590138e+00f, 3.44773868e+00f, + 4.64394654e+00f, 6.53020450e+00f, 9.58228502e+00f, 1.46836141e+01f, 2.35444955e+01f, 3.96352727e+01f, + 7.03763521e+01f, 1.32588012e+02f, 2.66962565e+02f, 5.79374920e+02f, 1.36869193e+03f, 3.55943572e+03f, + 1.03218668e+04f, 3.38662130e+04f, 1.27816626e+05f, 5.65408251e+05f, 2.99446204e+06f, 1.94497502e+07f, + 1.59219301e+08f, 1.69428882e+09f, 2.42715618e+10f, 4.87031785e+11f, 1.43181966e+13f, 6.48947152e+14f, + 4.80375775e+16f, 6.20009636e+18f, }; + +__constant__ float m_weights_float_6[65] = + { 1.57345777e+00f, 1.59489276e+00f, 1.63853652e+00f, 1.70598041e+00f, 1.79972439e+00f, 1.92332285e+00f, + 2.08159737e+00f, 2.28093488e+00f, 2.52969785e+00f, 2.83878478e+00f, 3.22239575e+00f, 3.69908136e+00f, + 4.29318827e+00f, 5.03686536e+00f, 5.97287114e+00f, 7.15853842e+00f, 8.67142780e+00f, 1.06174736e+01f, + 1.31428500e+01f, 1.64514563e+01f, 2.08309945e+01f, 2.66923599e+01f, 3.46299351e+01f, 4.55151836e+01f, + 6.06440809e+01f, 8.19729692e+01f, 1.12502047e+02f, 1.56909655e+02f, 2.22620435e+02f, 3.21638549e+02f, + 4.73757451e+02f, 7.12299455e+02f, 1.09460965e+03f, 1.72169779e+03f, 2.77592491e+03f, 4.59523007e+03f, + 7.82342759e+03f, 1.37235744e+04f, 2.48518896e+04f, 4.65553875e+04f, 9.04176678e+04f, 1.82484396e+05f, + 3.83680026e+05f, 8.42627197e+05f, 1.93843257e+06f, 4.68511285e+06f, 1.19352867e+07f, 3.21564375e+07f, + 9.19600893e+07f, 2.80222318e+08f, 9.13611083e+08f, 3.20091090e+09f, 1.21076526e+10f, 4.96902475e+10f, + 2.22431575e+11f, 1.09212534e+12f, 5.91688298e+12f, 3.55974344e+13f, 2.39435365e+14f, 1.81355107e+15f, + 1.55873671e+16f, 1.53271488e+17f, 1.73927478e+18f, 2.29884122e+19f, 3.57403070e+20f, }; + +__constant__ float m_weights_float_7[129] = + { 1.57146132e+00f, 1.57679017e+00f, 1.58749564e+00f, 1.60367396e+00f, 1.62547113e+00f, 1.65308501e+00f, + 1.68676814e+00f, 1.72683132e+00f, 1.77364814e+00f, 1.82766042e+00f, 1.88938482e+00f, 1.95942057e+00f, + 2.03845873e+00f, 2.12729290e+00f, 2.22683194e+00f, 2.33811466e+00f, 2.46232715e+00f, 2.60082286e+00f, + 2.75514621e+00f, 2.92706011e+00f, 3.11857817e+00f, 3.33200254e+00f, 3.56996830e+00f, 3.83549565e+00f, + 4.13205150e+00f, 4.46362211e+00f, 4.83479919e+00f, 5.25088196e+00f, 5.71799849e+00f, 6.24325042e+00f, + 6.83488580e+00f, 7.50250620e+00f, 8.25731548e+00f, 9.11241941e+00f, 1.00831875e+01f, 1.11876913e+01f, + 1.24472371e+01f, 1.38870139e+01f, 1.55368872e+01f, 1.74323700e+01f, 1.96158189e+01f, 2.21379089e+01f, + 2.50594593e+01f, 2.84537038e+01f, 3.24091185e+01f, 3.70329629e+01f, 4.24557264e+01f, 4.88367348e+01f, + 5.63712464e+01f, 6.52994709e+01f, 7.59180776e+01f, 8.85949425e+01f, 1.03788130e+02f, 1.22070426e+02f, + 1.44161210e+02f, 1.70968019e+02f, 2.03641059e+02f, 2.43645006e+02f, 2.92854081e+02f, 3.53678602e+02f, + 4.29234308e+02f, 5.23570184e+02f, 6.41976690e+02f, 7.91405208e+02f, 9.81042209e+02f, 1.22309999e+03f, + 1.53391256e+03f, 1.93546401e+03f, 2.45753455e+03f, 3.14073373e+03f, 4.04081819e+03f, 5.23488160e+03f, + 6.83029446e+03f, 8.97771323e+03f, 1.18901592e+04f, 1.58712239e+04f, 2.13571111e+04f, 2.89798371e+04f, + 3.96630673e+04f, 5.47687519e+04f, 7.63235654e+04f, 1.07371915e+05f, 1.52531667e+05f, 2.18877843e+05f, + 3.17362450e+05f, 4.65120153e+05f, 6.89253766e+05f, 1.03311989e+06f, 1.56688798e+06f, 2.40549203e+06f, + 3.73952896e+06f, 5.88912115e+06f, 9.39904635e+06f, 1.52090328e+07f, 2.49628719e+07f, 4.15775926e+07f, + 7.03070537e+07f, 1.20759856e+08f, 2.10788251e+08f, 3.74104720e+08f, 6.75449459e+08f, 1.24131674e+09f, + 2.32331003e+09f, 4.43117602e+09f, 8.61744649e+09f, 1.70983691e+10f, 3.46357452e+10f, 7.16760712e+10f, + 1.51634762e+11f, 3.28172932e+11f, 7.27110260e+11f, 1.65049955e+12f, 3.84133815e+12f, 9.17374427e+12f, + 2.24990195e+13f, 5.67153509e+13f, 1.47074225e+14f, 3.92701252e+14f, 1.08063998e+15f, 3.06767147e+15f, + 8.99238679e+15f, 2.72472254e+16f, 8.54294612e+16f, 2.77461372e+17f, 9.34529948e+17f, 3.26799612e+18f, + 1.18791443e+19f, 4.49405341e+19f, 1.77170665e+20f, }; + +__constant__ float m_weights_float_8[259] = + { 1.57096255e+00f, 1.57229290e+00f, 1.57495658e+00f, 1.57895955e+00f, 1.58431079e+00f, 1.59102230e+00f, + 1.59910918e+00f, 1.60858966e+00f, 1.61948515e+00f, 1.63182037e+00f, 1.64562338e+00f, 1.66092569e+00f, + 1.67776241e+00f, 1.69617233e+00f, 1.71619809e+00f, 1.73788633e+00f, 1.76128784e+00f, 1.78645779e+00f, + 1.81345587e+00f, 1.84234658e+00f, 1.87319943e+00f, 1.90608922e+00f, 1.94109632e+00f, 1.97830698e+00f, + 2.01781368e+00f, 2.05971547e+00f, 2.10411838e+00f, 2.15113585e+00f, 2.20088916e+00f, 2.25350798e+00f, + 2.30913084e+00f, 2.36790578e+00f, 2.42999091e+00f, 2.49555516e+00f, 2.56477893e+00f, 2.63785496e+00f, + 2.71498915e+00f, 2.79640147e+00f, 2.88232702e+00f, 2.97301705e+00f, 3.06874019e+00f, 3.16978367e+00f, + 3.27645477e+00f, 3.38908227e+00f, 3.50801806e+00f, 3.63363896e+00f, 3.76634859e+00f, 3.90657947e+00f, + 4.05479525e+00f, 4.21149322e+00f, 4.37720695e+00f, 4.55250922e+00f, 4.73801517e+00f, 4.93438579e+00f, + 5.14233166e+00f, 5.36261713e+00f, 5.59606472e+00f, 5.84356014e+00f, 6.10605759e+00f, 6.38458564e+00f, + 6.68025373e+00f, 6.99425915e+00f, 7.32789480e+00f, 7.68255767e+00f, 8.05975815e+00f, 8.46113023e+00f, + 8.88844279e+00f, 9.34361190e+00f, 9.82871448e+00f, 1.03460033e+01f, 1.08979234e+01f, 1.14871305e+01f, + 1.21165112e+01f, 1.27892047e+01f, 1.35086281e+01f, 1.42785033e+01f, 1.51028871e+01f, 1.59862046e+01f, + 1.69332867e+01f, 1.79494108e+01f, 1.90403465e+01f, 2.02124072e+01f, 2.14725057e+01f, 2.28282181e+01f, + 2.42878539e+01f, 2.58605342e+01f, 2.75562800e+01f, 2.93861096e+01f, 3.13621485e+01f, 3.34977526e+01f, + 3.58076454e+01f, 3.83080730e+01f, 4.10169773e+01f, 4.39541917e+01f, 4.71416602e+01f, 5.06036855e+01f, + 5.43672075e+01f, 5.84621188e+01f, 6.29216205e+01f, 6.77826252e+01f, 7.30862125e+01f, 7.88781469e+01f, + 8.52094636e+01f, 9.21371360e+01f, 9.97248336e+01f, 1.08043785e+02f, 1.17173764e+02f, 1.27204209e+02f, + 1.38235512e+02f, 1.50380485e+02f, 1.63766039e+02f, 1.78535118e+02f, 1.94848913e+02f, 2.12889407e+02f, + 2.32862309e+02f, 2.55000432e+02f, 2.79567594e+02f, 3.06863126e+02f, 3.37227087e+02f, 3.71046310e+02f, + 4.08761417e+02f, 4.50874968e+02f, 4.97960949e+02f, 5.50675821e+02f, 6.09771424e+02f, 6.76110054e+02f, + 7.50682104e+02f, 8.34626760e+02f, 9.29256285e+02f, 1.03608458e+03f, 1.15686082e+03f, 1.29360914e+03f, + 1.44867552e+03f, 1.62478326e+03f, 1.82509876e+03f, 2.05330964e+03f, 2.31371761e+03f, 2.61134924e+03f, + 2.95208799e+03f, 3.34283233e+03f, 3.79168493e+03f, 4.30817984e+03f, 4.90355562e+03f, 5.59108434e+03f, + 6.38646863e+03f, 7.30832183e+03f, 8.37874981e+03f, 9.62405722e+03f, 1.10756067e+04f, 1.27708661e+04f, + 1.47546879e+04f, 1.70808754e+04f, 1.98141031e+04f, 2.30322789e+04f, 2.68294532e+04f, 3.13194118e+04f, + 3.66401221e+04f, 4.29592484e+04f, 5.04810088e+04f, 5.94547213e+04f, 7.01854788e+04f, 8.30475173e+04f, + 9.85009981e+04f, 1.17113127e+05f, 1.39584798e+05f, 1.66784302e+05f, 1.99790063e+05f, 2.39944995e+05f, + 2.88925794e+05f, 3.48831531e+05f, 4.22297220e+05f, 5.12639825e+05f, 6.24046488e+05f, 7.61817907e+05f, + 9.32683930e+05f, 1.14521401e+06f, 1.41035265e+06f, 1.74212004e+06f, 2.15853172e+06f, 2.68280941e+06f, + 3.34498056e+06f, 4.18399797e+06f, 5.25055801e+06f, 6.61086017e+06f, 8.35163942e+06f, 1.05869253e+07f, + 1.34671524e+07f, 1.71914827e+07f, 2.20245345e+07f, 2.83191730e+07f, 3.65476782e+07f, 4.73445266e+07f, + 6.15653406e+07f, 8.03684303e+07f, 1.05328028e+08f, 1.38592169e+08f, 1.83103699e+08f, 2.42910946e+08f, + 3.23606239e+08f, 4.32947522e+08f, 5.81743297e+08f, 7.85117979e+08f, 1.06432920e+09f, 1.44938958e+09f, + 1.98286647e+09f, 2.72541431e+09f, 3.76386796e+09f, 5.22313881e+09f, 7.28378581e+09f, 1.02080964e+10f, + 1.43789932e+10f, 2.03583681e+10f, 2.89749983e+10f, 4.14577375e+10f, 5.96383768e+10f, 8.62622848e+10f, + 1.25466705e+11f, 1.83521298e+11f, 2.69981221e+11f, 3.99492845e+11f, 5.94638056e+11f, 8.90440997e+11f, + 1.34155194e+12f, 2.03376855e+12f, 3.10262796e+12f, 4.76359832e+12f, 7.36142036e+12f, 1.14512696e+13f, + 1.79331419e+13f, 2.82758550e+13f, 4.48929705e+13f, 7.17780287e+13f, 1.15585510e+14f, 1.87483389e+14f, + 3.06351036e+14f, 5.04340065e+14f, 8.36616340e+14f, 1.39855635e+15f, 2.35633575e+15f, 4.00176517e+15f, + 6.85137513e+15f, 1.18269011e+16f, 2.05867353e+16f, 3.61396878e+16f, 6.39911218e+16f, 1.14301619e+17f, + 2.05988138e+17f, 3.74584679e+17f, 6.87444303e+17f, 1.27340764e+18f, 2.38124192e+18f, 4.49583562e+18f, + 8.57144202e+18f, 1.65044358e+19f, 3.21010035e+19f, 6.30778012e+19f, 1.25240403e+20f, 2.51300530e+20f, + 5.09677626e+20f, }; + +__constant__ float* m_weights_float[8] = { + m_weights_float_1, + m_weights_float_2, + m_weights_float_3, + m_weights_float_4, + m_weights_float_5, + m_weights_float_6, + m_weights_float_7, + m_weights_float_8 +}; + +__constant__ double m_abscissas_double_1[6] = + { 3.088287417976322866e+00, 1.489931846492091580e+02, 3.412289247883437102e+06, 2.069325766042617791e+18, + 2.087002407609475560e+50, 2.019766160717908151e+137, }; + +__constant__ double m_abscissas_double_2[6] = + { 9.130487626376696748e-01, 1.415789294662811592e+01, 6.704215516223276482e+03, 9.641725327150499415e+10, + 2.508950760085778485e+30, 1.447263535710337145e+83, }; + +__constant__ double m_abscissas_double_3[12] = + { 4.072976900657586902e-01, 1.682066707021148743e+00, 6.150897986386729515e+00, 4.003962351929400222e+01, + 7.929200247931026321e+02, 1.029849713330979583e+05, 3.038623109252438574e+08, 1.565445474362494869e+14, + 4.042465098430219104e+23, 1.321706827429658179e+39, 4.991231782099557998e+64, 7.352943850359875966e+106, }; + +__constant__ double m_abscissas_double_4[24] = + { 1.981352722514781726e-01, 6.401556735005260177e-01, 1.248928698253977663e+00, 2.266080840944321232e+00, + 4.296462696702327381e+00, 9.130290387099955696e+00, 2.311107653864279933e+01, 7.427706034324012430e+01, + 3.267209207115258917e+02, 2.159485694311818716e+03, 2.415015262896413060e+04, 5.318194002756929158e+05, + 2.800586857217043323e+07, 4.524065079794338780e+09, 3.085612573980677122e+12, 1.338826733015807478e+16, + 6.254617176562341381e+20, 6.182098535814164754e+26, 3.077293649788458067e+34, 2.348957289370104303e+44, + 1.148543197899469758e+57, 2.255300070010069868e+73, 1.877919500569195394e+94, 1.367473887938624280e+121, }; + +__constant__ double m_abscissas_double_5[49] = + { 9.839678940067320339e-02, 3.006056176599550351e-01, 5.198579789949384900e-01, 7.703620832988877009e-01, + 1.071311369641311830e+00, 1.450569758088998445e+00, 1.950778549520360334e+00, 2.640031773695551468e+00, + 3.631372373667412273e+00, 5.119915330903350570e+00, 7.456660981404883289e+00, 1.130226126889972624e+01, + 1.796410692472772550e+01, 3.017810704601898222e+01, 5.403875800312370567e+01, 1.041077314477469548e+02, + 2.180295201202628077e+02, 5.021556986259101646e+02, 1.288621310998222420e+03, 3.739216870800548324e+03, + 1.247507297020191232e+04, 4.876399753226692124e+04, 2.281456582219130122e+05, 1.308777960064843017e+06, + 9.460846634209664077e+06, 8.888831203637279622e+07, 1.124168828974344134e+09, 1.991276729532144470e+10, + 5.167434691060984650e+11, 2.067218814203990888e+13, 1.350615033184100406e+15, 1.538540662836508188e+17, + 3.290747290540350661e+19, 1.437291381884498816e+22, 1.409832445530347286e+25, 3.459135480277971441e+28, + 2.398720582340954092e+32, 5.398806604617292960e+36, 4.613340002580628610e+41, 1.787685909667902457e+47, + 3.841984370124338536e+53, 5.752797955708583700e+60, 7.771812038427286551e+68, 1.269673044204081626e+78, + 3.495676773765731568e+88, 2.362519474971692445e+100, 6.002143893273651123e+113, 9.290716303464155539e+128, + 1.514442238033847090e+146, }; + +__constant__ double m_abscissas_double_6[98] = + { 4.911510035029024930e-02, 1.480131496743607333e-01, 2.489388137406836857e-01, 3.533254236926684378e-01, + 4.627335566122353259e-01, 5.789120681640963067e-01, 7.038702533860627799e-01, 8.399658591446505688e-01, + 9.900150664244376147e-01, 1.157432570143699131e+00, 1.346412759185361763e+00, 1.562167113901335551e+00, + 1.811238852782323380e+00, 2.101924419006550301e+00, 2.444843885584197934e+00, 2.853720746632915024e+00, + 3.346458910955350787e+00, 3.946645821057838387e+00, 4.685673101596678529e+00, 5.605762230908151175e+00, + 6.764332336830574204e+00, 8.240383175379985221e+00, 1.014394356129857730e+01, 1.263024714338892472e+01, + 1.592130395780345258e+01, 2.033921861921857185e+01, 2.635846445760633752e+01, 3.468926333224152409e+01, + 4.641291467019728963e+01, 6.320550793890424203e+01, 8.771497261808906374e+01, 1.242096926240411498e+02, + 1.797186347845127557e+02, 2.660817283327900190e+02, 4.037273029575712841e+02, 6.288113066545908703e+02, + 1.007079837507490594e+03, 1.661568229185114288e+03, 2.829651440786582598e+03, 4.984386266585669139e+03, + 9.101546927647810893e+03, 1.726892655475049727e+04, 3.413099578778601190e+04, 7.045668977053092802e+04, + 1.523404217761279128e+05, 3.460479782897947414e+05, 8.284724209233183002e+05, 2.097596146601193946e+06, + 5.636950798861273236e+06, 1.614071410855607245e+07, 4.944730678915060360e+07, 1.627810516820991356e+08, + 5.785332971632280838e+08, 2.230838540681955690e+09, 9.382391306064739643e+09, 4.328149544776551692e+10, + 2.203072744049242904e+11, 1.245245067109136413e+12, 7.869000534957822375e+12, 5.599531432979422461e+13, + 4.521486949902090877e+14, 4.176889516548293265e+15, 4.452867759650496656e+16, 5.529142853140498068e+17, + 8.075732516562854275e+18, 1.402046916260468698e+20, 2.925791412832239850e+21, 7.426433029335410886e+22, + 2.321996331245735364e+24, 9.064194250638442432e+25, 4.481279048819445609e+27, 2.849046304726990645e+29, + 2.367381159183355975e+31, 2.615825578455121227e+33, 3.914764948263290808e+35, 8.092042448555929219e+37, + 2.358921320940630332e+40, 9.915218648535332591e+42, 6.152851059342658764e+45, 5.780276340144515388e+48, + 8.443751734186488626e+51, 1.973343350899766708e+55, 7.605247378556219980e+58, 4.992057104939510418e+62, + 5.775863423903912316e+66, 1.221808201945355603e+71, 4.912917230387133816e+75, 3.913971813732202372e+80, + 6.456388069905286787e+85, 2.311225068528010358e+91, 1.887458157719431339e+97, 3.708483165438453094e+103, + 1.855198812283538635e+110, 2.509787873171705318e+117, 9.790423755591216617e+124, 1.179088807944050747e+133, + 4.714631846722476620e+141, 6.762657785959713240e+150, }; + +__constant__ double m_abscissas_double_7[196] = + { 2.454715583629863651e-02, 7.372466873903346224e-02, 1.231525309416766543e-01, 1.730001377719248556e-01, + 2.234406649596860001e-01, 2.746526549718518258e-01, 3.268216792980646669e-01, 3.801421009804789245e-01, + 4.348189637215614948e-01, 4.910700365099428407e-01, 5.491280459480215441e-01, 6.092431324382654397e-01, + 6.716855712021148069e-01, 7.367488049067938643e-01, 8.047528416336950644e-01, 8.760480802482050705e-01, + 9.510196351823332253e-01, 1.030092244532470067e+00, 1.113735859588680765e+00, 1.202472030918058876e+00, + 1.296881226496863751e+00, 1.397611241828373026e+00, 1.505386891360545205e+00, 1.621021205894798030e+00, + 1.745428403369044572e+00, 1.879638952031029331e+00, 2.024817107609328524e+00, 2.182281382147884181e+00, + 2.353528494823881355e+00, 2.540261468229626457e+00, 2.744422672171478111e+00, 2.968232787190606619e+00, + 3.214236869520657666e+00, 3.485358957907730467e+00, 3.784966983117372821e+00, 4.116950138940295100e+00, + 4.485811369388231710e+00, 4.896778246562001812e+00, 5.355936290826725948e+00, 5.870389762600956907e+00, + 6.448456189131117605e+00, 7.099902452679558236e+00, 7.836232253282841261e+00, 8.671037293575230635e+00, + 9.620427777985990363e+00, 1.070356198876799531e+01, 1.194330008139441022e+01, 1.336701421038499647e+01, + 1.500759615914396343e+01, 1.690471548203528376e+01, 1.910639668731689597e+01, 2.167100443216577994e+01, + 2.466975274695099197e+01, 2.818989025157845355e+01, 3.233876132429401745e+01, 3.724900758097245740e+01, + 4.308526084907741997e+01, 5.005279647654703975e+01, 5.840877607253876528e+01, 6.847692821534239862e+01, + 8.066681777060714848e+01, 9.549927270200249260e+01, 1.136401195769487885e+02, 1.359451944976603209e+02, + 1.635207451879744447e+02, 1.978049687912586950e+02, 2.406787535889776661e+02, 2.946170292930555023e+02, + 3.628969532147125333e+02, 4.498861782715596902e+02, 5.614447353133496106e+02, 7.054892470899271429e+02, + 8.927907732799964116e+02, 1.138111424979478376e+03, 1.461835991563605367e+03, 1.892332623444716186e+03, + 2.469396036186133479e+03, 3.249311569298824731e+03, 4.312367113170283012e+03, 5.774094754500139661e+03, + 7.802247237500851845e+03, 1.064267530975806972e+04, 1.465915383535674990e+04, 2.039528541239754835e+04, + 2.867170622421556265e+04, 4.074033762183453297e+04, 5.853182310596923393e+04, 8.505689265265206640e+04, + 1.250649269847856615e+05, 1.861373943166749766e+05, 2.805255777452010927e+05, 4.282782486084761748e+05, + 6.626340506127657304e+05, 1.039443239650339565e+06, 1.653857426112961316e+06, 2.670315650125279161e+06, + 4.377212026624358795e+06, 7.288071713698413821e+06, 1.233172993400331694e+07, 2.121557285769933699e+07, + 3.713086254861535383e+07, 6.614579377352135534e+07, 1.200055291694917110e+08, 2.218629410296880690e+08, + 4.182282939928687703e+08, 8.043704132493714804e+08, 1.579392989425668114e+09, 3.168122415524104635e+09, + 6.496606811549861323e+09, 1.362851988356444486e+10, 2.926863897008707708e+10, 6.439798665209493735e+10, + 1.452755233772903022e+11, 3.362854459389246576e+11, 7.994202785433479271e+11, 1.953264233362291960e+12, + 4.909581868242554569e+12, 1.270622730765015610e+13, 3.389070986742985764e+13, 9.325084030208844833e+13, + 2.649489423834534140e+14, 7.781295184094957195e+14, 2.364715052527355639e+15, 7.444138031465958255e+15, + 2.430217240684749635e+16, 8.237068641534357762e+16, 2.902117050664548840e+17, 1.064157679404037013e+18, + 4.066277106061960017e+18, 1.621274233630359097e+19, 6.754156830915450013e+19, 2.944056841733781919e+20, + 1.344640139549107817e+21, 6.444586158944723300e+21, 3.246218667554608934e+22, 1.721234579556653533e+23, + 9.622533890240474391e+23, 5.681407260417956671e+24, 3.548890779995928184e+25, 2.349506425672269562e+26, + 1.651618130605205643e+27, 1.235147426493113059e+28, 9.845947239792057550e+28, 8.383130781984610418e+29, + 7.639649461399172445e+30, 7.467862732233885201e+31, 7.847691482004993660e+32, 8.886032557626454704e+33, + 1.086734890678302436e+35, 1.438967777036538458e+36, 2.068168865475603521e+37, 3.234885320223912385e+38, + 5.521233641542628514e+39, 1.031148231194663855e+41, 2.113272035816365982e+42, 4.766724345485077520e+43, + 1.186961550990218287e+45, 3.273172169205847573e+46, 1.002821226769167753e+48, 3.424933903935156479e+49, + 1.308436017026428736e+51, 5.611378330048420503e+52, 2.711424806327139291e+54, 1.481771793644066442e+56, + 9.194282071042778804e+57, 6.503661455875355562e+59, 5.266329986868627303e+61, 4.902662807969347359e+63, + 5.270511057289557050e+65, 6.572856511670583316e+67, 9.553956030013225387e+69, 1.626491911159411616e+72, + 3.259410915500951223e+74, 7.728460318113614280e+76, 2.179881996905918059e+79, 7.354484388371505915e+81, + 2.984831270803957746e+84, 1.465828267813438962e+87, 8.763355972629864261e+89, 6.417909665847831130e+92, + 5.794958649229893510e+95, 6.494224472311908365e+98, 9.095000156016433698e+101, 1.603058498455299102e+105, + 3.582099119119320529e+108, 1.022441227139854687e+112, 3.756872185015086057e+115, 1.791363463832849159e+119, + 1.117641882039472124e+123, 9.202159565546528285e+126, 1.008716474827888568e+131, 1.485546487089301805e+135, + 2.966961534830566097e+139, 8.114207284664369360e+143, 3.069178087507669739e+148, 1.622223681147791473e+153, }; + +__constant__ double m_abscissas_double_8[391] = + { 1.227227917054637830e-02, 3.682722894492590471e-02, 6.141337626871079991e-02, 8.605159708778207907e-02, + 1.107628840017845446e-01, 1.355683934957785482e-01, 1.604894937454335489e-01, 1.855478131645089496e-01, + 2.107652898670700524e-01, 2.361642222214626268e-01, 2.617673206785495261e-01, 2.875977610631342900e-01, + 3.136792395249035647e-01, 3.400360293536632770e-01, 3.666930398731810193e-01, 3.936758776386451797e-01, + 4.210109101746846268e-01, 4.487253325041450341e-01, 4.768472367324829462e-01, 5.054056849688209375e-01, + 5.344307858825229079e-01, 5.639537752137267134e-01, 5.940071005777549000e-01, 6.246245109268716053e-01, + 6.558411510586397969e-01, 6.876936615883514922e-01, 7.202202848338683401e-01, 7.534609770949572224e-01, + 7.874575278460963461e-01, 8.222536864020499377e-01, 8.578952966595825808e-01, 8.944304405668593009e-01, + 9.319095910247435485e-01, 9.703857749817920659e-01, 1.009914747547728584e+00, 1.050555178019083150e+00, + 1.092368848786092579e+00, 1.135420868172514300e+00, 1.179779898350424466e+00, 1.225518399571142610e+00, + 1.272712892062026473e+00, 1.321444237057985065e+00, 1.371797938567245953e+00, 1.423864467614384096e+00, + 1.477739610861208115e+00, 1.533524845679288858e+00, 1.591327743938355098e+00, 1.651262406984310076e+00, + 1.713449934511288211e+00, 1.778018930286256858e+00, 1.845106047964720870e+00, 1.914856580544951899e+00, + 1.987425097349017093e+00, 2.062976132795275283e+00, 2.141684931642916785e+00, 2.223738255848994521e+00, + 2.309335258687213796e+00, 2.398688432341103821e+00, 2.492024635808356095e+00, 2.589586210645122756e+00, + 2.691632192846832444e+00, 2.798439630014497291e+00, 2.910305013902562652e+00, 3.027545839497364963e+00, + 3.150502302946919722e+00, 3.279539151967394330e+00, 3.415047703805410611e+00, 3.557448047456550733e+00, + 3.707191448649779817e+00, 3.864762978128342125e+00, 4.030684386016531344e+00, 4.205517247588613835e+00, + 4.389866408585172458e+00, 4.584383761391930748e+00, 4.789772386950687695e+00, 5.006791101261363264e+00, + 5.236259449815274050e+00, 5.479063198337523150e+00, 5.736160373884817415e+00, 6.008587916728619858e+00, + 6.297469010648863048e+00, 6.604021167380929133e+00, 6.929565150124677837e+00, 7.275534831383860972e+00, + 7.643488092123492064e+00, 8.035118882502459288e+00, 8.452270579478188130e+00, 8.896950793641785313e+00, + 9.371347797016395173e+00, 9.877848765573446033e+00, 1.041906005527762037e+01, 1.099782975900831706e+01, + 1.161727282423952258e+01, 1.228079904848924611e+01, 1.299214431196691048e+01, 1.375540545535625881e+01, + 1.457507926620621316e+01, 1.545610610104852468e+01, 1.640391874338302925e+01, 1.742449718154208970e+01, + 1.852443008688437526e+01, 1.971098388378266494e+01, 2.099218043080961648e+01, 2.237688448013982946e+01, + 2.387490225270073820e+01, 2.549709266380430464e+01, 2.725549296232531555e+01, 2.916346081119624987e+01, + 3.123583514423284962e+01, 3.348911849136805118e+01, 3.594168387985465099e+01, 3.861400990307230737e+01, + 4.152894811329303023e+01, 4.471202755441533396e+01, 4.819180202224910174e+01, 5.200024654361558757e+01, + 5.617321062537384494e+01, 6.075093706918782079e+01, 6.577865661168003966e+01, 7.130727037357721343e+01, + 7.739413413465805794e+01, 8.410396085269633392e+01, 9.150986068496734448e+01, 9.969454113547704016e+01, + 1.087516939426018897e+02, 1.187876000643037532e+02, 1.299229897614516371e+02, 1.422952015056372537e+02, + 1.560606914665002671e+02, 1.713979549326432406e+02, 1.885109325154830073e+02, 2.076329877740125935e+02, + 2.290315594654587370e+02, 2.530136115655676467e+02, 2.799320282398896912e+02, 3.101931299766730890e+02, + 3.442655222107529892e+02, 3.826905303289378387e+02, 4.260945266207607701e+02, 4.752035175892902045e+02, + 5.308604366239058864e+02, 5.940456805372995009e+02, 6.659015428338778262e+02, 7.477613367309153870e+02, + 8.411841730471343023e+02, 9.479965698013741524e+02, 1.070342331375881840e+03, 1.210742457518582660e+03, + 1.372167241552205820e+03, 1.558123212187692722e+03, 1.772758188662716282e+03, 2.020988485411862984e+03, + 2.308653259329163157e+03, 2.642702189813684273e+03, 3.031424182869210212e+03, 3.484726676985756018e+03, + 4.014477504733973505e+03, 4.634924264049394751e+03, 5.363209949773439749e+03, 6.220008412114342803e+03, + 7.230309332853029956e+03, 8.424390216735217783e+03, 9.839022871538541787e+03, 1.151897463083113988e+04, + 1.351888098874374202e+04, 1.590558745460066947e+04, 1.876108572764816176e+04, 2.218620462393366275e+04, + 2.630526205054915357e+04, 3.127194401941711057e+04, 3.727675461256652923e+04, 4.455648280312273249e+04, + 5.340626592018903930e+04, 6.419500580388918123e+04, 7.738512642386820060e+04, 9.355796993981725963e+04, + 1.134465375820669470e+05, 1.379778272209741713e+05, 1.683277485807887053e+05, 2.059925746120735305e+05, + 2.528822024503158254e+05, 3.114422718347725915e+05, 3.848145913435570736e+05, 4.770485864966822643e+05, + 5.933809324724740854e+05, 7.406066190351666115e+05, 9.275730471470643372e+05, 1.165840260940180415e+06, + 1.470566322118246135e+06, 1.861698899014921971e+06, 2.365584870298354495e+06, 3.017152695505764877e+06, + 3.862882573599929249e+06, 4.964864305589750358e+06, 6.406362829959736606e+06, 8.299481847261302115e+06, + 1.079575892642401854e+07, 1.410087327474604091e+07, 1.849514724418250100e+07, 2.436224419670805500e+07, + 3.222951131863941234e+07, 4.282493882385925337e+07, 5.715793394339267637e+07, 7.663437932745451635e+07, + 1.032212725498489699e+08, 1.396833991976194842e+08, 1.899251497664892740e+08, 2.594865396467505851e+08, + 3.562664742464501497e+08, 4.915825413172413471e+08, 6.817316470116958142e+08, 9.502998105202541438e+08, + 1.331598295343277538e+09, 1.875801976010459831e+09, 2.656673907709731487e+09, 3.783240215616365909e+09, + 5.417531848500136979e+09, 7.801695369892847510e+09, 1.129965368955098833e+10, 1.646149161390821924e+10, + 2.412353995736687694e+10, 3.556486895431927094e+10, 5.275345014093760519e+10, 7.873572108325378177e+10, + 1.182569020317863604e+11, 1.787549442508363461e+11, 2.719633064979986142e+11, 4.165122153119897946e+11, + 6.421781858205134197e+11, 9.968725497576275918e+11, 1.558212327122960399e+12, 2.452809984907093786e+12, + 3.888656232828140210e+12, 6.209868990509424909e+12, 9.989924216297983665e+12, 1.619158001378611351e+13, + 2.644324518669926559e+13, 4.352018847904374786e+13, 7.218884688202741709e+13, 1.206997640727349538e+14, + 2.034483722445207402e+14, 3.457553102874402920e+14, 5.925248511957505706e+14, 1.024057793713038672e+15, + 1.785174045941642162e+15, 3.139306988668494696e+15, 5.569856270174890128e+15, 9.971763353834460328e+15, + 1.801687491114883092e+16, 3.285709858322565542e+16, 6.049018540910759710e+16, 1.124375283211369572e+17, + 2.110445125952435305e+17, 4.000737007891229992e+17, 7.660849361564329309e+17, 1.482018770996176700e+18, + 2.896945433910857945e+18, 5.722790165693470493e+18, 1.142689960439921462e+19, 2.306616559984106723e+19, + 4.707857184616093863e+19, 9.717346347495342813e+19, 2.028735605622585444e+20, 4.284840254171000581e+20, + 9.157027329021623836e+20, 1.980457834766411777e+21, 4.335604886702252004e+21, 9.609258559714223995e+21, + 2.156604630608586997e+22, 4.902045909695270289e+22, 1.128749227121328467e+23, 2.633414623049930879e+23, + 6.226335684490998543e+23, 1.492205279014148921e+24, 3.625768249717590109e+24, 8.933899764961444882e+24, + 2.232786981682262383e+25, 5.661295336293986732e+25, 1.456616710298133142e+26, 3.803959852868488245e+26, + 1.008531585603036490e+27, 2.715247425129423358e+27, 7.425071766766651967e+27, 2.062860712173225003e+28, + 5.824055458799413312e+28, 1.671388836696436644e+29, 4.876830632023956392e+29, 1.447170071146107156e+30, + 4.368562208925583783e+30, 1.341873806249251338e+31, 4.195251632754338682e+31, 1.335360134828214136e+32, + 4.328681350715136340e+32, 1.429401866150319186e+33, 4.809736146227180696e+33, 1.649624114567602575e+34, + 5.768677492419801469e+34, 2.057442854162761350e+35, 7.486423509917811063e+35, 2.780052791791155051e+36, + 1.053908347660081874e+37, 4.080046334235754223e+37, 1.613553311592805373e+38, 6.520836332997615098e+38, + 2.693848186257510992e+39, 1.138002408430710800e+40, 4.917748008813924613e+40, 2.174691073191358676e+41, + 9.844523745430526502e+41, 4.563707467590116732e+42, 2.167352073708379137e+43, 1.054860193887170754e+44, + 5.263588225566847365e+44, 2.693772458797916623e+45, 1.414506760560163074e+46, 7.624126763512016620e+46, + 4.219828148762794411e+47, 2.399387665831793264e+48, 1.402139947254117434e+49, 8.424706325525422943e+49, + 5.206918479942619318e+50, 3.311787866477716151e+51, 2.168683295509859155e+52, 1.462786368779206713e+53, + 1.016761784575838363e+54, 7.286460995145043184e+54, 5.386194237448865407e+55, 4.108917480528740640e+56, + 3.236445625945552728e+57, 2.633440652417619669e+58, 2.214702339357939268e+59, 1.926058995948268392e+60, + 1.733067740414174932e+61, 1.614307160124426969e+62, 1.557464328486352138e+63, 1.557226155197192031e+64, + 1.614473962707995344e+65, 1.736617406327386105e+66, 1.939201243451190521e+67, 2.249277732936622876e+68, + 2.711593798719765599e+69, 3.399628732048687119e+70, 4.435389696730206291e+71, 6.025566076164003981e+72, + 8.529161425383779849e+73, 1.258746322992988688e+75, 1.938112175186560210e+76, 3.115432363572610661e+77, + 5.231797674434390018e+78, 9.184930207860680757e+79, 1.686929404780378772e+81, 3.243565624474232635e+82, + 6.533812498930220075e+83, 1.379898823144620314e+85, 3.057650444842839916e+86, 7.114050545839171245e+87, + 1.739275024442258674e+89, 4.471782915853177804e+90, 1.210036789494028144e+92, 3.448828044590862359e+93, + 1.036226783750561565e+95, 3.284801914751206038e+96, 1.099514933602224638e+98, 3.889581731378242597e+99, + 1.455434287901069991e+101, 5.765729934387419019e+102, 2.420349568745475582e+104, 1.077606625929777536e+106, + 5.093346988695851845e+107, 2.558090824110323997e+109, 1.366512508719047964e+111, 7.771735800763526406e+112, + 4.710398638793014918e+114, 3.045563885587013954e+116, 2.102762552861442993e+118, 1.551937536212596136e+120, + 1.225676354426075970e+122, 1.036950946169703711e+124, 9.407885268970827717e+125, 9.163369107785093171e+127, + 9.592531095671168926e+129, 1.080486293361823875e+132, 1.311034829557782450e+134, 1.715642975932639188e+136, + 2.424231742707881878e+138, 3.703231223333127919e+140, 6.123225027409988902e+142, 1.097271040771196765e+145, + 2.133693643241295977e+147, 4.508099184895777328e+149, 1.036252806686291189e+152, }; + +__constant__ double* m_abscissas_double[8] = { + m_abscissas_double_1, + m_abscissas_double_2, + m_abscissas_double_3, + m_abscissas_double_4, + m_abscissas_double_5, + m_abscissas_double_6, + m_abscissas_double_7, + m_abscissas_double_8, +}; + +__constant__ double m_weights_double_1[6] = + { 7.868241604839621507e+00, 8.805163880733011116e+02, 5.396278323520705668e+07, 8.876511896968161317e+19, + 2.432791879269225553e+52, 6.399713512080202911e+139, }; + +__constant__ double m_weights_double_2[6] = + { 2.398524276302635218e+00, 5.244596423726681022e+01, 6.457887819598201760e+04, 2.509985242511374506e+12, + 1.774029269327138701e+32, 2.781406115983097314e+85, }; + +__constant__ double m_weights_double_3[12] = + { 1.749369583108386852e+00, 3.979658981934607813e+00, 1.848514598574449570e+01, 1.864880718932067988e+02, + 5.974205695263265855e+03, 1.270412635144623341e+06, 6.164193014295984071e+09, 5.230850031811222530e+15, + 2.226260929943369774e+25, 1.199931102042181592e+41, 7.470602144275146214e+66, 1.814465860528410676e+109, }; + +__constant__ double m_weights_double_4[24] = + { 1.613859062188366173e+00, 1.997767291869673262e+00, 3.020231979908834220e+00, 5.477641843859057761e+00, + 1.179660916492671672e+01, 3.035504848518598294e+01, 9.584421793794920860e+01, 3.893870238229992076e+02, + 2.179193250357911344e+03, 1.839208123964132852e+04, 2.632120612599856167e+05, 7.427296507169468210e+06, + 5.015875648341232356e+08, 1.039610867241544113e+11, 9.100328911818091977e+13, 5.068651163890231571e+17, + 3.039966520714902616e+22, 3.857740194672007962e+28, 2.465542763666581087e+36, 2.416439449167799461e+46, + 1.517091553926604149e+59, 3.825043412021411380e+75, 4.089582396821598640e+96, 3.823775894295564050e+123, }; + +__constant__ double m_weights_double_5[49] = + { 1.581465959536694744e+00, 1.669149910438534746e+00, 1.857523188595005770e+00, 2.175662623626994120e+00, + 2.675901375211020564e+00, 3.447738682498791744e+00, 4.643946540355464126e+00, 6.530204496574248616e+00, + 9.582285015566804961e+00, 1.468361407515440960e+01, 2.354449548740987533e+01, 3.963527273305166705e+01, + 7.037635206267538547e+01, 1.325880124784838868e+02, 2.669625649541569172e+02, 5.793749198508472676e+02, + 1.368691928321303605e+03, 3.559435721533130554e+03, 1.032186677270763318e+04, 3.386621302858741487e+04, + 1.278166259840246830e+05, 5.654082513926693098e+05, 2.994462044781721833e+06, 1.944975023421914947e+07, + 1.592193007690560588e+08, 1.694288818617459913e+09, 2.427156182311303271e+10, 4.870317848199455490e+11, + 1.431819656229181793e+13, 6.489471523099301256e+14, 4.803757752508989106e+16, 6.200096361305331541e+18, + 1.502568562439914899e+21, 7.436061367189688251e+23, 8.264761218677928603e+26, 2.297735027897804345e+30, + 1.805449779569534997e+34, 4.604472360199061931e+38, 4.458371212030626854e+43, 1.957638261114809309e+49, + 4.767368137162500764e+55, 8.088820139476721285e+62, 1.238260897349286357e+71, 2.292272505278842062e+80, + 7.151392373749193549e+90, 5.476714850156044431e+102, 1.576655618370700681e+116, 2.765448595957851958e+131, + 5.108051255283132673e+148, }; + +__constant__ double m_weights_double_6[98] = + { 1.573457773573108386e+00, 1.594892755038663787e+00, 1.638536515530234742e+00, 1.705980408212213620e+00, + 1.799724394608737275e+00, 1.923322854425656307e+00, 2.081597373313268178e+00, 2.280934883790070511e+00, + 2.529697852387704655e+00, 2.838784782552951185e+00, 3.222395745020980612e+00, 3.699081358854235112e+00, + 4.293188274330526800e+00, 5.036865356322330076e+00, 5.972871140910932199e+00, 7.158538424311077564e+00, + 8.671427800892076385e+00, 1.061747360297922326e+01, 1.314285002260235600e+01, 1.645145625668428040e+01, + 2.083099449998189069e+01, 2.669235989791640190e+01, 3.462993514791378189e+01, 4.551518362653662579e+01, + 6.064408087764392116e+01, 8.197296917485846798e+01, 1.125020468081652564e+02, 1.569096552844714123e+02, + 2.226204347868638276e+02, 3.216385489504077755e+02, 4.737574505945461739e+02, 7.122994548146997637e+02, + 1.094609652686376553e+03, 1.721697789176049576e+03, 2.775924909253835146e+03, 4.595230066268149347e+03, + 7.823427586641573672e+03, 1.372357435269105405e+04, 2.485188961645119553e+04, 4.655538745425972783e+04, + 9.041766782135686884e+04, 1.824843964862728392e+05, 3.836800264094614027e+05, 8.426271970245168026e+05, + 1.938432574158782634e+06, 4.685112849356485528e+06, 1.193528667218607927e+07, 3.215643752247989316e+07, + 9.196008928386600386e+07, 2.802223178457559964e+08, 9.136110825267458886e+08, 3.200910900783148591e+09, + 1.210765264234723689e+10, 4.969024745093101808e+10, 2.224315751863855216e+11, 1.092125344449313660e+12, + 5.916882980019919359e+12, 3.559743438494577249e+13, 2.394353652945465191e+14, 1.813551073517501917e+15, + 1.558736706166165738e+16, 1.532714875555114333e+17, 1.739274776190789212e+18, 2.298841216802216313e+19, + 3.574030698837762664e+20, 6.604899705451419080e+21, 1.467155879591820659e+23, 3.964094964398509381e+24, + 1.319342840595348793e+26, 5.482251971340400742e+27, 2.885137894723827518e+29, 1.952539840765392110e+31, + 1.727051489032222797e+33, 2.031343507095439396e+35, 3.236074146972599980e+37, 7.120487412983497200e+39, + 2.209552707411017265e+42, 9.886282647791384648e+44, 6.530514048788273529e+47, 6.530706672481546528e+50, + 1.015518807431281951e+54, 2.526366773162394510e+57, 1.036450519906790297e+61, 7.241966032627135861e+64, + 8.919402520769714938e+68, 2.008463619152992905e+73, 8.596914764830260020e+77, 7.290599546829495220e+82, + 1.280199563216419112e+88, 4.878349285603201150e+93, 4.240828248064127940e+99, 8.869771764721598720e+105, + 4.723342575741417669e+112, 6.802035963326188581e+119, 2.824531180990009549e+127, 3.621049216745982252e+135, + 1.541270150334942520e+144, 2.353376995174362785e+153, }; + +__constant__ double m_weights_double_7[196] = + { 1.571461316550783294e+00, 1.576790166316938345e+00, 1.587495640370383316e+00, 1.603673956341370210e+00, + 1.625471125457493943e+00, 1.653085011915939302e+00, 1.686768142525911236e+00, 1.726831323537516202e+00, + 1.773648138667236602e+00, 1.827660421478661448e+00, 1.889384817044018196e+00, 1.959420572855037091e+00, + 2.038458728047908923e+00, 2.127292904083847225e+00, 2.226831940199076941e+00, 2.338114664555130296e+00, + 2.462327148722991304e+00, 2.600822860927085164e+00, 2.755146214814554359e+00, 2.927060108424483555e+00, + 3.118578166240921951e+00, 3.332002540339506630e+00, 3.569968300410740276e+00, 3.835495653996447262e+00, + 4.132051496512934885e+00, 4.463622106699067881e+00, 4.834799191008006557e+00, 5.250881957765679608e+00, + 5.717998490875333124e+00, 6.243250421598568105e+00, 6.834885801226541839e+00, 7.502506202789340802e+00, + 8.257315484493544201e+00, 9.112419405864642634e+00, 1.008318749543997758e+01, 1.118769134993865202e+01, + 1.244723705914106881e+01, 1.388701390605507587e+01, 1.553688715915900190e+01, 1.743237000680942831e+01, + 1.961581894823993424e+01, 2.213790886354273806e+01, 2.505945934677137610e+01, 2.845370377742137561e+01, + 3.240911845969524834e+01, 3.703296289480230161e+01, 4.245572644746267911e+01, 4.883673480337985582e+01, + 5.637124640586975420e+01, 6.529947092752610340e+01, 7.591807755694122837e+01, 8.859494252391663822e+01, + 1.037881295005788124e+02, 1.220704263969226746e+02, 1.441612098131200535e+02, 1.709680191245773511e+02, + 2.036410593843575570e+02, 2.436450058708723643e+02, 2.928540812182076105e+02, 3.536786019152253392e+02, + 4.292343083967296939e+02, 5.235701840488733027e+02, 6.419766898003024575e+02, 7.914052083668759283e+02, + 9.810422089081931637e+02, 1.223099994999740393e+03, 1.533912555427112127e+03, 1.935464013605830339e+03, + 2.457534549912886852e+03, 3.140733731623635519e+03, 4.040818188564651898e+03, 5.234881599712225681e+03, + 6.830294457607329226e+03, 8.977713228649887143e+03, 1.189015920967326839e+04, 1.587122387044346962e+04, + 2.135711106445789331e+04, 2.897983705189681437e+04, 3.966306726795547950e+04, 5.476875193750000787e+04, + 7.632356539388055680e+04, 1.073719149754976951e+05, 1.525316674555574152e+05, 2.188778434744216586e+05, + 3.173624496019295608e+05, 4.651201525869328462e+05, 6.892537656280580572e+05, 1.033119885120019982e+06, + 1.566887981043252499e+06, 2.405492027026531795e+06, 3.739528964815910340e+06, 5.889121154895580032e+06, + 9.399046351922342030e+06, 1.520903276129653518e+07, 2.496287187293576168e+07, 4.157759259963074840e+07, + 7.030705366950267312e+07, 1.207598558452493366e+08, 2.107882509464846833e+08, 3.741047199023457864e+08, + 6.754494594987415572e+08, 1.241316740415880537e+09, 2.323310032649552862e+09, 4.431176019026625759e+09, + 8.617446487400900130e+09, 1.709836906604031513e+10, 3.463574521880171339e+10, 7.167607123799270726e+10, + 1.516347620910054079e+11, 3.281729323238950526e+11, 7.271102600298280790e+11, 1.650499552378780378e+12, + 3.841338149508803917e+12, 9.173744267785176575e+12, 2.249901946357519979e+13, 5.671535089900611731e+13, + 1.470742250307697019e+14, 3.927012518464311775e+14, 1.080639977391212820e+15, 3.067671466720475189e+15, + 8.992386789198328428e+15, 2.724722536524592111e+16, 8.542946122263389258e+16, 2.774613718725574755e+17, + 9.345299479382029121e+17, 3.267996122987731882e+18, 1.187914433455468315e+19, 4.494053408418564214e+19, + 1.771706652195486743e+20, 7.288102552885931527e+20, 3.132512430816625349e+21, 1.408743767951073110e+22, + 6.638294268236060414e+22, 3.282543608403565013e+23, 1.705920098038394064e+24, 9.332259385148524285e+24, + 5.382727175874888312e+25, 3.278954235122093249e+26, 2.113191697957458099e+27, 1.443411041499643040e+28, + 1.046864394654982423e+29, 8.077319226958905700e+29, 6.643146963432616277e+30, 5.835670121359986260e+31, + 5.486890296790230798e+32, 5.533726968508261614e+33, 5.999734996418352834e+34, 7.009176119466122569e+35, + 8.844061966424597499e+36, 1.208226860869605961e+38, 1.791648514311063338e+39, 2.891313916713205762e+40, + 5.091457860211527298e+41, 9.810630588402496553e+42, 2.074441239147378860e+44, 4.827650116937700540e+45, + 1.240287939111549029e+47, 3.528782858644784616e+48, 1.115449490471696659e+50, 3.930510643328196314e+51, + 1.549243712957852337e+53, 6.854998238041301002e+54, 3.417479961583207704e+56, 1.926905498641079990e+58, + 1.233580963004919450e+60, 9.002819902898076915e+61, 7.521415141253441645e+63, 7.224277554900578993e+65, + 8.012832830535078610e+67, 1.030999620286380369e+70, 1.546174957076748679e+72, 2.715803772613248694e+74, + 5.615089920571746438e+76, 1.373667859345343337e+79, 3.997541020769625126e+81, 1.391500589339800087e+84, + 5.826693844912022892e+86, 2.952274820929549096e+89, 1.821023061478466282e+92, 1.375973022137941526e+95, + 1.281852367543412945e+98, 1.482130127201990503e+101, 2.141574273792435314e+104, 3.894495540947112380e+107, + 8.978646362580102961e+110, 2.644131589807244050e+114, 1.002403539841913834e+118, 4.931412804903905259e+121, + 3.174401112435865044e+125, 2.696624001761892390e+129, 3.049799322320447166e+133, 4.634041526818687785e+137, + 9.548983134803106512e+141, 2.694404866192089829e+146, 1.051502720036395325e+151, 5.734170640626244955e+155, }; + +__constant__ double m_weights_double_8[391] = + { 1.570962550997832611e+00, 1.572292902367211961e+00, 1.574956581912666755e+00, 1.578959553636163985e+00, + 1.584310789563614305e+00, 1.591022301117035107e+00, 1.599109181186160337e+00, 1.608589657109067468e+00, + 1.619485154826419743e+00, 1.631820374530739318e+00, 1.645623378191125679e+00, 1.660925689395424109e+00, + 1.677762406016463717e+00, 1.696172326277082973e+00, 1.716198088860732467e+00, 1.737886327791014562e+00, + 1.761287842885152410e+00, 1.786457786673686420e+00, 1.813455868772335587e+00, 1.842346578792652542e+00, + 1.873199428986627521e+00, 1.906089217937612619e+00, 1.941096316736779451e+00, 1.978306979221816566e+00, + 2.017813678003844337e+00, 2.059715468170813895e+00, 2.104118380732327493e+00, 2.151135848063375554e+00, + 2.200889163814591418e+00, 2.253507979986114202e+00, 2.309130844113053375e+00, 2.367905779785113334e+00, + 2.429990914023652954e+00, 2.495555155369085590e+00, 2.564778926893134514e+00, 2.637854958747451684e+00, + 2.714989145296268067e+00, 2.796401472360280536e+00, 2.882327020626578700e+00, 2.973017051860293803e+00, + 3.068740185193628238e+00, 3.169783671473487386e+00, 3.276454774427328601e+00, 3.389082268266156098e+00, + 3.508018062292869136e+00, 3.633638964133530274e+00, 3.766348594369884204e+00, 3.906579466636309289e+00, + 4.054795248667541120e+00, 4.211493221360917802e+00, 4.377206954666462219e+00, 4.552509221059946388e+00, + 4.738015169510782826e+00, 4.934385785253587887e+00, 5.142331663338191074e+00, 5.362617126899976224e+00, + 5.596064724397100194e+00, 5.843560143744373307e+00, 6.106057585381734693e+00, 6.384585640900671436e+00, + 6.680253728973824449e+00, 6.994259146058412709e+00, 7.327894795748901060e+00, 7.682557667824588764e+00, + 8.059758146071137270e+00, 8.461130232962342889e+00, 8.888442789395671080e+00, 9.343611899025485155e+00, + 9.828714479494622022e+00, 1.034600327721380625e+01, 1.089792339849122916e+01, 1.148713054801325790e+01, + 1.211651116619788555e+01, 1.278920468010096321e+01, 1.350862810871281096e+01, 1.427850329305334421e+01, + 1.510288705493181327e+01, 1.598620462612703196e+01, 1.693328673269081128e+01, 1.794941076780000506e+01, + 1.904034654190823159e+01, 2.021240716182964334e+01, 2.147250566192247370e+01, 2.282821809199713505e+01, + 2.428785385941680425e+01, 2.586053422878117785e+01, 2.755628000354674426e+01, 2.938610955221109564e+01, + 3.136214849990951329e+01, 3.349775258749912582e+01, 3.580764540799625468e+01, 3.830807296872530167e+01, + 4.101697730155473447e+01, 4.395419165876113623e+01, 4.714166019494196927e+01, 5.060368545366659226e+01, + 5.436720746019445252e+01, 5.846211877912138439e+01, 6.292162054058128784e+01, 6.778262518512416663e+01, + 7.308621254265223015e+01, 7.887814686488147292e+01, 8.520946359734658334e+01, 9.213713603387774717e+01, + 9.972483357670754649e+01, 1.080437851679046426e+02, 1.171737636088621692e+02, 1.272042089988687372e+02, + 1.382355124664102373e+02, 1.503804848151483311e+02, 1.637660387526102742e+02, 1.785351181233383403e+02, + 1.948489131607280604e+02, 2.128894073598352670e+02, 2.328623093447990790e+02, 2.550004322843281994e+02, + 2.795675942672445782e+02, 3.068631259124280934e+02, 3.372270867451200874e+02, 3.710463099965576255e+02, + 4.087614170466174911e+02, 4.508749684194593670e+02, 4.979609488959773491e+02, 5.506758209385785877e+02, + 6.097714244663179092e+02, 6.761100535726473685e+02, 7.506821038741422446e+02, 8.346267600518081192e+02, + 9.292562845315541998e+02, 1.036084578498234728e+03, 1.156860819661897657e+03, 1.293609142453808600e+03, + 1.448675521854205144e+03, 1.624783259532197615e+03, 1.825098759915318560e+03, 2.053309635972617554e+03, + 2.313717614494777200e+03, 2.611349236640186999e+03, 2.952087994093624299e+03, 3.342832332560548180e+03, + 3.791684927756595099e+03, 4.308179838716318955e+03, 4.903555624570201673e+03, 5.591084343634811452e+03, + 6.386468625571246341e+03, 7.308321829412979440e+03, 8.378749812799703561e+03, 9.624057218749638059e+03, + 1.107560666191146008e+04, 1.277086605445904388e+04, 1.475468792019489452e+04, 1.708087537417066343e+04, + 1.981410309695485051e+04, 2.303227888204754908e+04, 2.682945317928632535e+04, 3.131941178398428200e+04, + 3.664012209706997997e+04, 4.295924836668690170e+04, 5.048100882639843572e+04, 5.945472133180055290e+04, + 7.018547875172689579e+04, 8.304751726175694003e+04, 9.850099805053575446e+04, 1.171131266261766060e+05, + 1.395847982160589845e+05, 1.667843016393077556e+05, 1.997900626520524686e+05, 2.399449946032992187e+05, + 2.889257939838013232e+05, 3.488315309194304548e+05, 4.222972201496778447e+05, 5.126398246369253619e+05, + 6.240464876221989792e+05, 7.618179073233615941e+05, 9.326839300224119257e+05, 1.145214007774297539e+06, + 1.410352646274233119e+06, 1.742120041875863385e+06, 2.158531716934287014e+06, 2.682809410126426731e+06, + 3.344980563595418861e+06, 4.183997972337706048e+06, 5.250558008165501752e+06, 6.610860174141680988e+06, + 8.351639423967558693e+06, 1.058692532393929900e+07, 1.346715235106239409e+07, 1.719148271024263021e+07, + 2.202453449027701694e+07, 2.831917301724337797e+07, 3.654767820268344932e+07, 4.734452657230626106e+07, + 6.156534063509513873e+07, 8.036843026897869248e+07, 1.053280284359690289e+08, 1.385921689084126286e+08, + 1.831036985925683524e+08, 2.429109457458640820e+08, 3.236062393759667463e+08, 4.329475218599986663e+08, + 5.817432967962929479e+08, 7.851179789388191786e+08, 1.064329197627075307e+09, 1.449389582912945485e+09, + 1.982866469377991849e+09, 2.725414314698094324e+09, 3.763867964111621444e+09, 5.223138814950990937e+09, + 7.283785810644397704e+09, 1.020809642381158743e+10, 1.437899318470510521e+10, 2.035836812543633578e+10, + 2.897499827080027444e+10, 4.145773751645494878e+10, 5.963837683872426287e+10, 8.626228483915530800e+10, + 1.254667045389825180e+11, 1.835212982264913186e+11, 2.699812207400151604e+11, 3.994928452151922954e+11, + 5.946380558701434550e+11, 8.904409967424091107e+11, 1.341551941677775838e+12, 2.033768550332151892e+12, + 3.102627959875753214e+12, 4.763598321705862063e+12, 7.361420360560813584e+12, 1.145126961456557423e+13, + 1.793314186996273926e+13, 2.827585501285792232e+13, 4.489297053678444669e+13, 7.177802872658499571e+13, + 1.155855098545820625e+14, 1.874833886367883093e+14, 3.063510356402174454e+14, 5.043400653005970242e+14, + 8.366163396892429890e+14, 1.398556351640947289e+15, 2.356335749516164682e+15, 4.001765167382637456e+15, + 6.851375128404941445e+15, 1.182690111761543990e+16, 2.058673527013806443e+16, 3.613968784314904633e+16, + 6.399112184394213551e+16, 1.143016185628376923e+17, 2.059881383915666443e+17, 3.745846788353680914e+17, + 6.874443034683149068e+17, 1.273407643613485314e+18, 2.381241916829895366e+18, 4.495835617307108399e+18, + 8.571442024901952701e+18, 1.650443584181656965e+19, 3.210100352421317851e+19, 6.307780124442703091e+19, + 1.252404031157661279e+20, 2.513005295649985394e+20, 5.096776255690838436e+20, 1.045019200016673046e+21, + 2.166476479260878466e+21, 4.542138145678395463e+21, 9.632082324449137128e+21, 2.066386536688254528e+22, + 4.485529785554428251e+22, 9.853879573610977508e+22, 2.191158874464374408e+23, 4.932835964390971668e+23, + 1.124501529971774363e+24, 2.596269136156756008e+24, 6.072292938313625501e+24, 1.438989066308003836e+25, + 3.455841956406570469e+25, 8.412655191713576490e+25, 2.076289061650816510e+26, 5.196515024640220322e+26, + 1.319173194089644043e+27, 3.397455895980380794e+27, 8.879057454438503591e+27, 2.355272361492064126e+28, + 6.342762007722624824e+28, 1.734531093990859705e+29, 4.817893170606830871e+29, 1.359597346490148232e+30, + 3.898969689906500392e+30, 1.136542986529989936e+31, 3.368450043991780017e+31, 1.015304084709817260e+32, + 3.113144376221918237e+32, 9.713072739730140403e+32, 3.084517643581725946e+33, 9.972682139820497284e+33, + 3.283625052288491586e+34, 1.101378785390827536e+35, 3.764333367592714297e+35, 1.311403465938242926e+36, + 4.658135710682813672e+36, 1.687517347470511392e+37, 6.237053685018323490e+37, 2.352571314427744869e+38, + 9.058938240219699936e+38, 3.562249097611136071e+39, 1.430959291578558210e+40, 5.873974584984375049e+40, + 2.464828549811283787e+41, 1.057649203090855628e+42, 4.642475639281078035e+42, 2.085287118272421779e+43, + 9.588439985186632177e+43, 4.514982011246092280e+44, 2.177974048341973204e+45, 1.076720976822900458e+46, + 5.457267432929085589e+46, 2.836869270455781134e+47, 1.513103201392011626e+48, 8.283974667225617075e+48, + 4.657239491995971344e+49, 2.689796370712836937e+50, 1.596597846911970388e+51, 9.744154538256586629e+51, + 6.117238394843313065e+52, 3.952049650585241827e+53, 2.628701592074258213e+54, 1.800990196502679393e+55, + 1.271554462563068383e+56, 9.255880104477760711e+56, 6.949737920133919393e+57, 5.385167200769965621e+58, + 4.308493668102978774e+59, 3.560951557542178371e+60, 3.041888528384649992e+61, 2.687094441930837189e+62, + 2.455920538900000855e+63, 2.323648254168641537e+64, 2.277129741584892331e+65, 2.312633552913224734e+66, + 2.435407592981291129e+67, 2.660910388822465246e+68, 3.018105943423533920e+69, 3.555823489510192503e+70, + 4.354188877793849013e+71, 5.544975795511813315e+72, 7.348276481909886336e+73, 1.013998025722423261e+75, + 1.457911462244607943e+76, 2.185488876819505295e+77, 3.418022153286623008e+78, 5.580843920601835728e+79, + 9.519586502799733908e+80, 1.697573578247197786e+82, 3.166906670990180014e+83, 6.185099106418675430e+84, + 1.265541134386934377e+86, 2.714828965877756899e+87, 6.110386802964494082e+88, 1.444054086171083239e+90, + 3.586083726638388165e+91, 9.365231868063239600e+92, 2.574080116205122449e+94, 7.452134689862302719e+95, + 2.274309903836169819e+97, 7.323011134121164749e+98, 2.489816421737932462e+100, 8.946533386359281588e+101, + 3.400401372391165979e+103, 1.368288186208928217e+105, 5.834277489829591931e+106, 2.638486937672383424e+108, + 1.266728882767139521e+110, 6.462225178314182803e+111, 3.506432320607573604e+113, 2.025608933943268165e+115, + 1.247041677084784707e+117, 8.189865188405279038e+118, 5.743610894406099965e+120, 4.305808934084489763e+122, + 3.454156966079496755e+124, 2.968316601530352737e+126, 2.735456242372183592e+128, 2.706317176690077847e+130, + 2.877679916342060385e+132, 3.292412878268106390e+134, 4.057840961953725969e+136, 5.393783049105737324e+138, + 7.741523901672235406e+140, 1.201209962310668456e+143, 2.017456079556807301e+145, 3.672176623483062526e+147, + 7.253163798058577630e+149, 1.556591535302570570e+152, 3.634399832790394885e+154, }; + +__constant__ double* m_weights_double[8] = { + m_weights_double_1, + m_weights_double_2, + m_weights_double_3, + m_weights_double_4, + m_weights_double_5, + m_weights_double_6, + m_weights_double_7, + m_weights_double_8 +}; +__constant__ boost::math::size_t float_coefficients_size[8] = {4, 4, 8, 16, 32, 65, 129, 259}; + +__constant__ boost::math::size_t double_coefficients_size[8] = {6, 6, 12, 24, 49, 98, 196, 391}; + +template +struct coefficients_selector; + +template<> +struct coefficients_selector +{ + __device__ static const auto abscissas() { return m_abscissas_float; } + __device__ static const auto weights() { return m_weights_float; } + __device__ static const auto size() { return float_coefficients_size; } +}; + +template<> +struct coefficients_selector +{ + __device__ static const auto abscissas() { return m_abscissas_double; } + __device__ static const auto weights() { return m_weights_double; } + __device__ static const auto size() { return double_coefficients_size; } +}; + +template > +__device__ auto sinh_sinh_integrate_impl(const F& f, Real tolerance, Real* error, Real* L1, boost::math::size_t* levels) +{ + BOOST_MATH_STD_USING + using boost::math::constants::half; + using boost::math::constants::half_pi; + using boost::math::size_t; + + constexpr auto function = "boost::math::quadrature::sinh_sinh<%1%>::integrate"; + + using K = decltype(f(static_cast(0))); + static_assert(!boost::math::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + + K y_max = f(boost::math::tools::max_value()); + + if(abs(y_max) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", y_max, Policy())); + } + + K y_min = f(-boost::math::tools::max_value()); + + if(abs(y_min) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at -infinity, and instead evaluates to %1%", y_max, Policy())); + } + + // Get the party started with two estimates of the integral: + const auto m_abscissas = coefficients_selector::abscissas(); + const auto m_weights = coefficients_selector::weights(); + const auto m_size = coefficients_selector::size(); + + K I0 = f(0)*half_pi(); + Real L1_I0 = abs(I0); + for(size_t i = 0; i < m_size[0]; ++i) + { + Real x = m_abscissas[0][i]; + K yp = f(x); + K ym = f(-x); + I0 += (yp + ym)*m_weights[0][i]; + L1_I0 += (abs(yp)+abs(ym))*m_weights[0][i]; + } + + K I1 = I0; + Real L1_I1 = L1_I0; + for (size_t i = 0; i < m_size[1]; ++i) + { + Real x= m_abscissas[1][i]; + K yp = f(x); + K ym = f(-x); + I1 += (yp + ym)*m_weights[1][i]; + L1_I1 += (abs(yp) + abs(ym))*m_weights[1][i]; + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + + size_t i = 2; + for(; i <= 8U; ++i) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1) / static_cast(1 << i); + K sum = 0; + Real absum = 0; + + Real abterm1 = 1; + Real eps = boost::math::tools::epsilon()*L1_I1; + + auto abscissa_row = m_abscissas[i]; + auto weight_row = m_weights[i]; + + for(size_t j = 0; j < m_size[i]; ++j) + { + Real x = abscissa_row[j]; + K yp = f(x); + K ym = f(-x); + sum += (yp + ym)*weight_row[j]; + Real abterm0 = (abs(yp) + abs(ym))*weight_row[j]; + absum += abterm0; + + // We require two consecutive terms to be < eps in case we hit a zero of f. + if (x > static_cast(100) && abterm0 < eps && abterm1 < eps) + { + break; + } + abterm1 = abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + + if (!(boost::math::isfinite)(L1_I1)) + { + constexpr auto err_msg = "The sinh_sinh quadrature evaluated your function at a singular point, leading to the value %1%.\n" + "sinh_sinh quadrature cannot handle singularities in the domain.\n" + "If you are sure your function has no singularities, please submit a bug against boost.math\n"; + return static_cast(policies::raise_evaluation_error(function, err_msg, I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if (L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + +} // Namespace detail +} // Namespace quadrature +} // Namespace math +} // Namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif // BOOST_MATH_QUADRATURE_DETAIL_SINH_SINH_DETAIL_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/detail/tanh_sinh_detail.hpp b/third-party/boost-math/include/boost/math/quadrature/detail/tanh_sinh_detail.hpp new file mode 100644 index 0000000000000..47961423b4d2b --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/detail/tanh_sinh_detail.hpp @@ -0,0 +1,879 @@ +// Copyright Nick Thompson, 2017 +// 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) + +#ifndef BOOST_MATH_QUADRATURE_DETAIL_TANH_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_TANH_SINH_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + + +// Returns the tanh-sinh quadrature of a function f over the open interval (-1, 1) + +template +class tanh_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + tanh_sinh_detail(size_t max_refinements, const Real& min_complement) : m_max_refinements(max_refinements) + { + typedef std::integral_constant tag_type; + init(min_complement, tag_type()); + } + + template + decltype(std::declval()(std::declval(), std::declval())) integrate(const F f, Real* error, Real* L1, const char* function, Real left_min_complement, Real right_min_complement, Real tolerance, std::size_t* levels) const; + +private: + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + std::size_t get_first_complement_index(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_first_complements[n]; + } + + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const Real& min_complement, const std::integral_constant&); +#endif + void prune_to_min_complement(const Real& m); + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + ++m_committed_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + std::size_t row = m_committed_refinements.load(); +#else + std::size_t row = m_committed_refinements; +#endif + Real h = ldexp(static_cast(1), -static_cast(row)); + std::size_t first_complement = 0; + std::size_t n = boost::math::itrunc(ceil((m_t_max - h) / (2 * h))); + m_abscissas[row].reserve(n); + m_weights[row].reserve(n); + for (Real pos = h; pos < m_t_max; pos += 2 * h) + { + if (pos < m_t_crossover) + ++first_complement; + m_abscissas[row].push_back(pos < m_t_crossover ? abscissa_at_t(pos) : -abscissa_complement_at_t(pos)); + } + m_first_complements[row] = first_complement; + for (Real pos = h; pos < m_t_max; pos += 2 * h) + m_weights[row].push_back(weight_at_t(pos)); + } + + static inline Real abscissa_at_t(const Real& t) + { + using std::tanh; + using std::sinh; + using boost::math::constants::half_pi; + return tanh(half_pi()*sinh(t)); + } + static inline Real weight_at_t(const Real& t) + { + using std::cosh; + using std::sinh; + using boost::math::constants::half_pi; + Real cs = cosh(half_pi() * sinh(t)); + return half_pi() * cosh(t) / (cs * cs); + } + static inline Real abscissa_complement_at_t(const Real& t) + { + using std::cosh; + using std::exp; + using std::sinh; + using boost::math::constants::half_pi; + Real u2 = half_pi() * sinh(t); + return 1 / (exp(u2) *cosh(u2)); + } + static inline Real t_from_abscissa_complement(const Real& x) + { + using std::log; + using std::sqrt; + using boost::math::constants::pi; + Real l = log(2-x) - log(x); + return log((sqrt(l * l + pi() * pi()) + l) / pi()); + }; + + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + mutable std::vector m_first_complements; + std::size_t m_max_refinements, m_inital_row_length{}; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif + Real m_t_max, m_t_crossover; +}; + +template +template +decltype(std::declval()(std::declval(), std::declval())) tanh_sinh_detail::integrate(const F f, Real* error, Real* L1, const char* function, Real left_min_complement, Real right_min_complement, Real tolerance, std::size_t* levels) const +{ + using std::abs; + using std::fabs; + using std::floor; + using std::tanh; + using std::sinh; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + // + // The type of the result: + typedef decltype(std::declval()(std::declval(), std::declval())) result_type; + + Real h = m_t_max / m_inital_row_length; + result_type I0 = half_pi() * f(0, 1); + Real L1_I0 = abs(I0); + // + // We maintain 4 integer values: + // max_left_position is the logical index of the abscissa value closest to the + // left endpoint of the range that we can call f(x_i) on without rounding error + // inside f(x_i) causing evaluation at the endpoint. + // max_left_index is the actual position in the current row that has a logical index + // no higher than max_left_position. Remember that since we only store odd numbered + // indexes in each row, this may actually be one position to the left of max_left_position + // in the case that is even. Then, if we only evaluate f(-x_i) for abscissa values + // i <= max_left_index we will never evaluate f(-x_i) at the left endpoint. + // max_right_position and max_right_index are defined similarly for the right boundary + // and are used to guard evaluation of f(x_i). + // + // max_left_position and max_right_position start off as the last element in row zero: + // + std::size_t max_left_position(m_abscissas[0].size() - 1); + std::size_t max_left_index, max_right_position(max_left_position), max_right_index; + // + // Decrement max_left_position and max_right_position until the complement + // of the abscissa value is greater than the smallest permitted (as specified + // by the function caller): + // + while ((max_left_position > 1) && fabs(m_abscissas[0][max_left_position]) < left_min_complement) + --max_left_position; + while ((max_right_position > 1) && fabs(m_abscissas[0][max_right_position]) < right_min_complement) + --max_right_position; + // + // Check for non-finite values at the end points: + // + result_type yp{ f(-1 - m_abscissas[0][max_left_position], m_abscissas[0][max_left_position]) }; + result_type ym{ f(1 + m_abscissas[0][max_right_position], -m_abscissas[0][max_right_position]) }; + result_type tail_tolerance{ (std::max)(boost::math::tools::epsilon(), Real(tolerance * tolerance)) }; + while (max_left_position) + { + if ((boost::math::isfinite)(yp)) + break; + --max_left_position; + yp = f(-1 - m_abscissas[0][max_left_position], m_abscissas[0][max_left_position]); + } + // + // Also remove points which are insignificant or zero: + // + while (max_left_position > 1) + { + if (abs(yp * m_weights[0][max_left_position]) > abs(L1_I0 * tail_tolerance)) + break; + --max_left_position; + yp = f(-1 - m_abscissas[0][max_left_position], m_abscissas[0][max_left_position]); + } + // + // Over again for the right hand side: + // + while (max_right_position) + { + if ((boost::math::isfinite)(ym)) + break; + --max_right_position; + ym = f(1 + m_abscissas[0][max_right_position], -m_abscissas[0][max_right_position]); + } + while (max_right_position > 1) + { + if (abs(ym * m_weights[0][max_right_position]) > abs(L1_I0 * tail_tolerance)) + break; + --max_right_position; + ym = f(1 + m_abscissas[0][max_right_position], -m_abscissas[0][max_right_position]); + } + + if ((max_left_position == 0) || (max_right_position == 0)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature found your function to be non-finite everywhere! Please check your function for singularities.", ym, Policy()); + } + + I0 += yp * m_weights[0][max_left_position] + ym * m_weights[0][max_right_position]; + L1_I0 += abs(yp * m_weights[0][max_left_position]) + abs(ym * m_weights[0][max_right_position]); + // + // Assumption: left_min_complement/right_min_complement are sufficiently small that we only + // ever decrement through the stored values that are complements (the negative ones), and + // never ever hit the true abscissa values (positive stored values). + // + BOOST_MATH_ASSERT(m_abscissas[0][max_left_position] < 0); + BOOST_MATH_ASSERT(m_abscissas[0][max_right_position] < 0); + + for(size_t i = 1; i < m_abscissas[0].size(); ++i) + { + if ((i >= max_right_position) && (i >= max_left_position)) + break; + Real x = m_abscissas[0][i]; + Real xc = x; + Real w = m_weights[0][i]; + if ((boost::math::signbit)(x)) + { + // We have stored x - 1: + x = 1 + xc; + } + else + xc = x - 1; + yp = i < max_right_position ? f(x, -xc) : 0; + ym = i < max_left_position ? f(-x, xc) : 0; + I0 += (yp + ym)*w; + L1_I0 += (abs(yp) + abs(ym))*w; + } + // + // We have: + // k = current row. + // I0 = last integral value. + // I1 = current integral value. + // L1_I0 and L1_I1 are the absolute integral values. + // + size_t k = 1; + result_type I1 = I0; + Real L1_I1 = L1_I0; + Real err = 0; + // + // thrash_count is a heuristic - it counts how many time the error has actually increased + // rather than decreased, if this gets too high we abort... + // + unsigned thrash_count = 0; + + while (k < 4 || (k < m_weights.size() && k < m_max_refinements) ) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + h *= half(); + result_type sum = 0; + Real absum = 0; + Real endpoint_error = 0; + auto const& abscissa_row = this->get_abscissa_row(k); + auto const& weight_row = this->get_weight_row(k); + std::size_t first_complement_index = this->get_first_complement_index(k); + // + // At the start of each new row we need to update the max left/right indexes + // at which we can evaluate f(x_i). The new logical position is simply twice + // the old value. The new max index is one position to the left of the new + // logical value (remember each row contains only odd numbered positions). + // Then we have to make a single check, to see if one position to the right + // is also in bounds (this is the new abscissa value in this row which is + // known to be in between a value known to be in bounds, and one known to be + // not in bounds). + // Thus, we filter which abscissa values generate a call to f(x_i), with a single + // floating point comparison per loop. Everything else is integer logic. + // + BOOST_MATH_ASSERT(max_left_position); + max_left_index = max_left_position - 1; + max_left_position *= 2; + BOOST_MATH_ASSERT(max_right_position); + max_right_index = max_right_position - 1; + max_right_position *= 2; + if ((abscissa_row.size() > max_left_index + 1) && (fabs(abscissa_row[max_left_index + 1]) > left_min_complement)) + { + ++max_left_position; + ++max_left_index; + } + if ((abscissa_row.size() > max_right_index + 1) && (fabs(abscissa_row[max_right_index + 1]) > right_min_complement)) + { + ++max_right_position; + ++max_right_index; + } + // + // We also check that our endpoints don't hit singularities: + // + do + { + yp = f(-1 - abscissa_row[max_left_index], abscissa_row[max_left_index]); + if ((boost::math::isfinite)(yp)) + break; + if(max_left_position <= 2) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature found your function to be non-finite everywhere! Please check your function for singularities.", ym, Policy()); + } + max_left_position -= 2; + --max_left_index; + } while (abscissa_row[max_left_index] < 0); + bool truncate_left(false), truncate_right(false); + if (abs(L1_I1 * tail_tolerance) > abs(yp * weight_row[max_left_index])) + truncate_left = true; + do + { + ym = f(1 + abscissa_row[max_right_index], -abscissa_row[max_right_index]); + if ((boost::math::isfinite)(ym)) + break; + if (max_right_position <= 2) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature found your function to be non-finite everywhere! Please check your function for singularities.", ym, Policy()); + } + --max_right_index; + max_right_position -= 2; + } while (abscissa_row[max_right_index] < 0); + if (abs(L1_I1 * tail_tolerance) > abs(ym * weight_row[max_right_index])) + truncate_right = true; + + sum += yp * weight_row[max_left_index] + ym * weight_row[max_right_index]; + absum += abs(yp * weight_row[max_left_index]) + abs(ym * weight_row[max_right_index]); + // + // We estimate the error due to truncation as the value contributed by the two most extreme points. + // In most cases this is tiny and can be ignored, if it is significant then either the area of the + // integral is so far our in the tails that our exponent range can't reach it (example x^-p at double + // precision and p ~ 1), or our function is truncated near epsilon, and we have had to narrow our endpoints. + // In this latter case we may over-estimate the error, but this is the best we can do. + // In any event, we do not add endpoint_error to the error estimate until we terminate the main loop, + // otherwise it can make things appear to be non-converged, when in reality, they are as converged as they + // will ever be. + // + endpoint_error = absum; + + for(size_t j = 0; j < weight_row.size(); ++j) + { + // If both left and right abscissa values are out of bounds at this step + // we can just stop this loop right now: + if ((j >= max_left_index) && (j >= max_right_index)) + break; + Real x = abscissa_row[j]; + Real xc = x; + Real w = weight_row[j]; + if (j >= first_complement_index) + { + // We have stored x - 1: + BOOST_MATH_ASSERT(x < 0); + x = 1 + xc; + } + else + { + BOOST_MATH_ASSERT(x >= 0); + xc = x - 1; + } + + yp = j >= max_right_index ? 0 : f(x, -xc); + ym = j >= max_left_index ? 0 : f(-x, xc); + result_type term = (yp + ym)*w; + sum += term; + + // A question arises as to how accurately we actually need to estimate the L1 integral. + // For simple integrands, computing the L1 norm makes the integration 20% slower, + // but for more complicated integrands, this calculation is not noticeable. + Real abterm = (abs(yp) + abs(ym))*w; + absum += abterm; + } + + I1 += sum*h; + L1_I1 += absum*h; + + ++k; + Real last_err = err; + err = abs(I0 - I1); + + if (!(boost::math::isfinite)(I1)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Please narrow the bounds of integration or check your function for singularities.", I1, Policy()); + } + // + // If the error is increasing, and we're past level 4, something bad is very likely happening: + // + if ((err * 1.5 > last_err) && (k > 4)) + { + bool terminate = false; + if ((++thrash_count > 1) && (last_err < 1e-3)) + // Probably just thrashing, abort: + terminate = true; + else if(thrash_count > 2) + // OK, terrible error, but giving up anyway! + terminate = true; + else if (last_err < boost::math::tools::root_epsilon()) + // Trying to squeeze precision that probably isn't there, abort: + terminate = true; + else + { + // Take a look at the end points, if there's significant new area being + // discovered, then we're not able to get close enough to the endpoints + // to ever find the integral: + if (abs(endpoint_error / sum) > err) + terminate = true; + } + + if (terminate) + { + // We could raise an evaluation_error, but since we likely have some sort of result, just return the last one + // (ie before the error started going up) + I1 = I0; + L1_I1 = L1_I0; + --k; + err = last_err + endpoint_error; + break; + } + // Fall through and keep going, assume we've discovered a new feature of f(x).... + } + // + // Termination condition: + // No more levels are considered once the error is less than the specified tolerance. + // Note however, that we always go down at least 4 levels, otherwise we risk missing + // features of interest in f() - imagine for example a function which flatlines, except + // for a very small "spike". An example would be the incomplete beta integral with large + // parameters. We could keep hunting until we find something, but that would handicap + // integrals which really are zero.... so a compromise then! + // + if ((err <= abs(tolerance*L1_I1)) && (k >= 4)) + { + // + // A quick sanity check: have we at some point narrowed our boundaries as a result + // of non-finite values? If so let's check that the area isn't on an increasing + // trajectory at our new end point, and increase our error estimate by the last + // good value as an estimate for what we may have discarded. + // + if (max_left_index && (max_left_index < abscissa_row.size() - 1) && (abs(abscissa_row[max_left_index + 1]) > left_min_complement)) + { + yp = f(-1 - abscissa_row[max_left_index], abscissa_row[max_left_index]) * weight_row[max_left_index]; + ym = f(-1 - abscissa_row[max_left_index - 1], abscissa_row[max_left_index - 1]) * weight_row[max_left_index - 1]; + if (abs(yp) > abs(ym)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Integration bounds were automatically narrowed, but the integral was found to be increasing at the new endpoint. Please check your function, and consider providing a 2-argument functor.", I1, Policy()); + } + } + if (max_right_index && (max_right_index < abscissa_row.size() - 1) && (abs(abscissa_row[max_right_index + 1]) > right_min_complement)) + { + yp = f(1 + abscissa_row[max_right_index], -abscissa_row[max_right_index]) * weight_row[max_right_index]; + ym = f(1 + abscissa_row[max_right_index - 1], -abscissa_row[max_right_index - 1]) * weight_row[max_right_index - 1]; + if (abs(yp) > abs(ym)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Integration bounds were automatically narrowed, but the integral was found to be increasing at the new endpoint. Please check your function, and consider providing a 2-argument functor.", I1, Policy()); + } + } + err += endpoint_error; + break; + } + + if ((truncate_left) && (max_left_position > 1)) + --max_left_position; + if ((truncate_right) && (max_right_position > 1)) + --max_right_position; + + } + if (error) + { + *error = err; + } + + if (L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = k; + } + + return I1; +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + using std::tanh; + using std::sinh; + using std::asinh; + using std::atanh; + using std::ceil; + using boost::math::constants::half_pi; + using boost::math::constants::pi; + using boost::math::constants::two_div_pi; + using boost::math::lltrunc; + + m_committed_refinements = 4; + // + // Initial row length is one step to the right of the abscissa value + // that would go to the full extent of the requested range, we need this + // to ensure full precision as otherwise we chop off quite a chunk of the + // range in *subsequent* rows. + // + m_inital_row_length = lltrunc(ceil(t_from_abscissa_complement(min_complement))); + std::size_t first_complement = 0; + m_t_max = m_inital_row_length; + m_t_crossover = t_from_abscissa_complement(Real(0.5f)); + + m_abscissas.assign(m_max_refinements + 1, std::vector()); + m_weights.assign(m_max_refinements + 1, std::vector()); + m_first_complements.assign(m_max_refinements + 1, 0); + // + // First row is special: + // + Real h = m_t_max / m_inital_row_length; + + std::vector temp(m_inital_row_length + 1, Real(0)); + for (std::size_t i = 0; i < m_inital_row_length; ++i) + { + Real t = h * i; + if (t < m_t_crossover) + ++first_complement; + temp[i] = t < m_t_crossover ? abscissa_at_t(t) : -abscissa_complement_at_t(t); + } + temp[m_inital_row_length] = -abscissa_complement_at_t(m_t_max); + m_abscissas[0].swap(temp); + m_first_complements[0] = first_complement; + temp.assign(m_inital_row_length + 1, Real(0)); + for (std::size_t i = 0; i < m_inital_row_length; ++i) + temp[i] = weight_at_t(Real(h * i)); + temp[m_inital_row_length] = weight_at_t(m_t_max); + m_weights[0].swap(temp); + +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + for (std::size_t row = 1; row <= m_committed_refinements.load(); ++row) +#else + for (std::size_t row = 1; row <= m_committed_refinements; ++row) +#endif + { + h /= 2; + first_complement = 0; + + for (Real pos = h; pos < m_t_max; pos += 2 * h) + { + if (pos < m_t_crossover) + ++first_complement; + temp.push_back(pos < m_t_crossover ? abscissa_at_t(pos) : -abscissa_complement_at_t(pos)); + } + m_abscissas[row].swap(temp); + m_first_complements[row] = first_complement; + for (Real pos = h; pos < m_t_max; pos += 2 * h) + temp.push_back(weight_at_t(pos)); + m_weights[row].swap(temp); + } +} + +#ifdef __GNUC__ +// Selective warning disabling via: +// #pragma GCC diagnostic ignored "-Wliteral-range" +// #pragma GCC diagnostic ignored "-Woverflow" +// Seems not to work, so we're left with this: +#pragma GCC system_header +#endif + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 4; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0f, -0.04863203593f, -2.252280754e-05f, -4.294161056e-14f, -1.167648898e-37f, }, + { -0.3257285078f, -0.002485143543f, -1.112433512e-08f, -5.378491591e-23f, }, + { 0.3772097382f, -0.1404309413f, -0.01295943949f, -0.0003117359716f, -7.952628853e-07f, -4.714355182e-11f, -5.415222824e-18f, -2.040300394e-29f, }, + { 0.1943570033f, -0.4608532946f, -0.219392561f, -0.08512073674f, -0.0260331318f, -0.005944493369f, -0.0009348035442f, -9.061530486e-05f, -4.683958779e-06f, -1.072183876e-07f, -8.572949078e-10f, -1.767834693e-12f, -6.374878495e-16f, -2.442937279e-20f, -5.251546473e-26f, -2.789467162e-33f, }, + { 0.09792388529f, 0.2878799327f, 0.4612535439f, -0.3897263425f, -0.2689819652f, -0.1766829945f, -0.1101085972f, -0.06483914248f, -0.03588783578f, -0.01854517332f, -0.008873007558f, -0.003891334562f, -0.001545791232f, -0.0005485655647f, -0.0001711779271f, -4.612899437e-05f, -1.051798518e-05f, -1.982859405e-06f, -3.011058474e-07f, -3.576091908e-08f, -3.212800902e-09f, -2.102671378e-10f, -9.606066479e-12f, -2.919026641e-13f, -5.586116639e-15f, -6.328207135e-17f, -3.956461339e-19f, -1.260975845e-21f, -1.872492175e-24f, -1.170030294e-27f, -2.740986178e-31f, -2.112282721e-35f, }, + { 0.04905596731f, 0.1464179843f, 0.2415663195f, 0.3331422646f, 0.4199521113f, -0.4989866106f, -0.4244155094f, -0.356823241f, -0.2964499949f, -0.2433060914f, -0.1972012587f, -0.1577807536f, -0.1245646024f, -0.09698671849f, -0.07443136593f, -0.05626521395f, -0.04186397729f, -0.0306332671f, -0.02202376481f, -0.01554116883f, -0.01075156891f, -0.007283002803f, -0.004823973845f, -0.003119681872f, -0.001966663685f, -0.001206465701f, -0.0007188880782f, -0.0004152496485f, -0.0002320284004f, -0.0001251349512f, -6.498007492e-05f, -3.240693206e-05f, -1.548009773e-05f, -7.062123337e-06f, -3.06755081e-06f, -1.264528134e-06f, -4.929942806e-07f, -1.811062872e-07f, -6.244592163e-08f, -2.01254968e-08f, -6.035865798e-09f, -1.676638052e-09f, -4.292122274e-10f, -1.007222767e-10f, -2.154466259e-11f, -4.175393124e-12f, -7.284737264e-13f, -1.136386985e-13f, -1.57355351e-14f, -1.91921891e-15f, -2.044959541e-16f, -1.886958307e-17f, -1.493871649e-18f, -1.00469381e-19f, -5.679929178e-21f, -2.669103953e-22f, -1.030178138e-23f, -3.224484876e-25f, -8.0747829e-27f, -1.594654602e-28f, -2.445723975e-30f, -2.865919772e-32f, -2.521682525e-34f, -1.63551444e-36f, }, + { 0.02453976357f, 0.07352512299f, 0.1222291222f, 0.1704679724f, 0.2180634735f, 0.2648450766f, 0.3106517806f, 0.3553338252f, 0.3987541505f, 0.440789599f, 0.4813318461f, -0.4797119493f, -0.4424187717f, -0.4068496464f, -0.3730497919f, -0.3410490083f, -0.3108622749f, -0.2824905325f, -0.2559216165f, -0.2311313132f, -0.2080845076f, -0.1867363915f, -0.1670337061f, -0.148915992f, -0.1323168242f, -0.1171650118f, -0.1033857457f, -0.09090168184f, -0.07963394697f, -0.069503062f, -0.06042977607f, -0.05233580938f, -0.04514450419f, -0.03878138485f, -0.03317462969f, -0.02825545843f, -0.02395843974f, -0.0202217242f, -0.01698720852f, -0.01420063697f, -0.0118116462f, -0.009773759532f, -0.008044336997f, -0.006584486831f, -0.005358944287f, -0.004335923183f, -0.00348694536f, -0.002786652957f, -0.002212608041f, -0.001745083828f, -0.001366851359f, -0.001062965166f, -0.0008205510651f, -0.0006285988591f, -0.0004777623488f, -0.0003601686544f, -0.0002692384802f, -0.0001995185689f, -0.0001465272269f, -0.0001066134524f, -7.682987071e-05f, -5.481938554e-05f, -3.871519214e-05f, -2.705357477e-05f, -1.869872988e-05f, -1.2778718e-05f, -8.631551655e-06f, -5.760372383e-06f, -3.796652834e-06f, -2.470376195e-06f, -1.586189035e-06f, -1.00458931e-06f, -6.272926646e-07f, -3.860114498e-07f, -2.339766676e-07f, -1.396287854e-07f, -8.199520529e-08f, -4.735733554e-08f, -2.688676406e-08f, -1.499692369e-08f, -8.213543901e-09f, -4.414366384e-09f, -2.326763262e-09f, -1.2020165e-09f, -6.082231242e-10f, -3.012456307e-10f, -1.459438845e-10f, -6.911160499e-11f, -3.196678326e-11f, -1.443120992e-11f, -6.353676128e-12f, -2.725950519e-12f, -1.138734572e-12f, -4.627734622e-13f, -1.827990225e-13f, -7.012046738e-14f, -2.609605366e-14f, -9.413361335e-15f, -3.287925695e-15f, -1.11086294e-15f, -3.626602264e-16f, -1.142787653e-16f, -3.471902269e-17f, -1.015781907e-17f, -2.858532825e-18f, -7.727834787e-19f, -2.004423992e-19f, -4.981568376e-20f, -1.184668492e-20f, -2.691984904e-21f, -5.836667442e-22f, -1.205661589e-22f, -2.369109351e-23f, -4.421339462e-24f, -7.823835004e-25f, -1.310533144e-25f, -2.074345013e-26f, -3.096968326e-27f, -4.353200528e-28f, -5.749955668e-29f, -7.122715927e-30f, -8.25783542e-31f, -8.941541007e-32f, -9.02279665e-33f, -8.46603012e-34f, -7.369272807e-35f, -5.936632356e-36f, -4.415277839e-37f, }, + { 0.01227135512f, 0.03680228095f, 0.06129788941f, 0.08573475488f, 0.1100896299f, 0.1343395153f, 0.1584617283f, 0.1824339697f, 0.2062343883f, 0.2298416433f, 0.2532349634f, 0.2763942036f, 0.2992998981f, 0.3219333097f, 0.3442764756f, 0.3663122492f, 0.3880243378f, 0.4093973357f, 0.4304167537f, 0.4510690435f, 0.4713416183f, 0.4912228687f, -0.489297826f, -0.4702300899f, -0.4515825479f, -0.4333628262f, -0.4155775577f, -0.39823239f, -0.3813319982f, -0.3648801001f, -0.3488794756f, -0.3333319877f, -0.318238608f, -0.3035994429f, -0.2894137636f, -0.275680037f, -0.2623959593f, -0.2495584902f, -0.2371638893f, -0.2252077531f, -0.2136850525f, -0.2025901721f, -0.1919169483f, -0.1816587092f, -0.1718083133f, -0.1623581887f, -0.1533003716f, -0.1446265448f, -0.1363280753f, -0.1283960505f, -0.120821315f, -0.113594505f, -0.1067060822f, -0.1001463668f, -0.09390556883f, -0.08797381831f, -0.08234119416f, -0.07699775172f, -0.07193354881f, -0.06713867034f, -0.0626032516f, -0.0583175f, -0.0542717154f, -0.050456309f, -0.0468618209f, -0.0434789361f, -0.0402984993f, -0.03731152826f, -0.0345092259f, -0.03188299107f, -0.02942442821f, -0.02712535566f, -0.02497781299f, -0.02297406711f, -0.02110661737f, -0.01936819969f, -0.01775178968f, -0.01625060483f, -0.01485810598f, -0.01356799776f, -0.01237422849f, -0.01127098916f, -0.01025271192f, -0.009314067826f, -0.008449964034f, -0.007655540506f, -0.006926166179f, -0.006257434709f, -0.005645159804f, -0.005085370197f, -0.004574304294f, -0.004108404533f, -0.003684311494f, -0.003298857801f, -0.002949061834f, -0.002632121306f, -0.002345406714f, -0.002086454715f, -0.001852961444f, -0.001642775797f, -0.001453892723f, -0.001284446528f, -0.001132704236f, -0.0009970590063f, -0.0008760236476f, -0.0007682242321f, -0.0006723938372f, -0.000587366425f, -0.0005120708762f, -0.0004455251889f, -0.0003868308567f, -0.0003351674323f, -0.0002897872882f, -0.0002500105784f, -0.0002152204083f, -0.0001848582177f, -0.0001584193765f, -0.0001354489984f, -0.0001155379702f, -9.8319198e-05f, -8.346406605e-05f, -7.067910812e-05f, -5.970288552e-05f, -5.030306831e-05f, -4.227371392e-05f, -3.543273737e-05f, -2.961956641e-05f, -2.469297451e-05f, -2.052908425e-05f, -1.701953324e-05f, -1.406979453e-05f, -1.159764317e-05f, -9.531760786e-06f, -7.810469566e-06f, -6.380587461e-06f, -5.196396351e-06f, -4.218715072e-06f, -3.414069429e-06f, -2.753951574e-06f, -2.214161365e-06f, -1.774222689e-06f, -1.416868016e-06f, -1.127584838e-06f, -8.942180042e-07f, -7.066223315e-07f, -5.563602711e-07f, -4.364397681e-07f, -3.410878407e-07f, -2.65555767e-07f, -2.059521239e-07f, -1.591002641e-07f, -1.224171449e-07f, -9.381073151e-08f, -7.159348586e-08f, -5.440972705e-08f, -4.117489851e-08f, -3.102500976e-08f, -2.327473287e-08f, -1.738282654e-08f, -1.292373523e-08f, -9.564367214e-09f, -7.045195508e-09f, -5.164949276e-09f, -3.768272997e-09f, -2.735826254e-09f, -1.976380568e-09f, -1.420541964e-09f, -1.015790099e-09f, -7.225780068e-10f, -5.112816947e-10f, -3.598270551e-10f, -2.518536224e-10f, -1.753014775e-10f, -1.213298105e-10f, -8.349395075e-11f, -5.712266027e-11f, -3.8849686e-11f, -2.626342738e-11f, -1.764649978e-11f, -1.178329832e-11f, -7.818680628e-12f, -5.154836404e-12f, -3.376501461e-12f, -2.19707447e-12f, -1.420047367e-12f, -9.115800793e-13f, -5.811306251e-13f, -3.67867911e-13f, -2.312068904e-13f, -1.442617249e-13f, -8.934966665e-14f, -5.492567772e-14f, -3.35078831e-14f, -2.02840764e-14f, -1.218279513e-14f, -7.258853736e-15f, -4.290062787e-15f, -2.514652539e-15f, -1.461687113e-15f, -8.424330958e-16f, -4.81351759e-16f, -2.726317943e-16f, -1.530442297e-16f, -8.513785725e-17f, -4.692795039e-17f, -2.562597595e-17f, -1.386133467e-17f, -7.425750192e-18f, -3.939309402e-18f, -2.069079146e-18f, -1.075828622e-18f, -5.536671017e-19f, -2.819834004e-19f, -1.421006375e-19f, -7.084243878e-20f, -3.493350557e-20f, -1.703597751e-20f, -8.214706044e-21f, -3.915973438e-21f, -1.845149816e-21f, -8.591874581e-22f, -3.953006958e-22f, -1.7966698e-22f, -8.065408821e-23f, -3.575337212e-23f, -1.564782132e-23f, -6.760041764e-24f, -2.882136323e-24f, -1.212436233e-24f, -5.031421831e-25f, -2.059286312e-25f, -8.310787798e-26f, -3.306518068e-26f, -1.296597346e-26f, -5.010091032e-27f, -1.907179385e-27f, -7.150567334e-28f, -2.639906037e-28f, -9.594664542e-29f, -3.432078099e-29f, -1.207985066e-29f, -4.182464721e-30f, -1.424153707e-30f, -4.767833382e-31f, -1.568949178e-31f, -5.073438855e-32f, -1.611691916e-32f, -5.028356694e-33f, -1.540320437e-33f, -4.631392443e-34f, -1.366470225e-34f, -3.955008527e-35f, -1.122591825e-35f, -3.123848743e-36f, -8.519540247e-37f, -2.276473481e-37f, }, + }; + m_weights = { + { 1.570796327f, 0.2300223945f, 0.0002662005138f, 1.358178427e-12f, 1.001741678e-35f, }, + { 0.9659765794f, 0.01834316699f, 2.143120456e-07f, 2.800315102e-21f, }, + { 1.389614759f, 0.5310782754f, 0.07638574357f, 0.002902517748f, 1.198370136e-05f, 1.163116581e-09f, 2.197079236e-16f, 1.363510331e-27f, }, + { 1.523283719f, 1.193463026f, 0.7374378484f, 0.3604614185f, 0.1374221077f, 0.03917500549f, 0.007742601026f, 0.0009499468043f, 6.248255924e-05f, 1.826332059e-06f, 1.868728227e-08f, 4.937853878e-11f, 2.28349267e-14f, 1.122753143e-18f, 3.09765397e-24f, 2.112123344e-31f, }, + { 1.558773356f, 1.466014427f, 1.29747575f, 1.081634985f, 0.8501728565f, 0.6304051352f, 0.4408332363f, 0.2902406793f, 0.1793244121f, 0.1034321542f, 0.05528968374f, 0.02713351001f, 0.0120835436f, 0.004816298144f, 0.001690873998f, 0.0005133938241f, 0.0001320523413f, 2.811016433e-05f, 4.823718203e-06f, 6.477756604e-07f, 6.583518513e-08f, 4.876006097e-09f, 2.521634792e-10f, 8.675931415e-12f, 1.880207173e-13f, 2.412423038e-15f, 1.708453277e-17f, 6.168256849e-20f, 1.037679724e-22f, 7.345984103e-26f, 1.949783362e-29f, 1.702438776e-33f, }, + { 1.567781431f, 1.543881116f, 1.497226223f, 1.430008355f, 1.345278885f, 1.246701207f, 1.138272243f, 1.024044933f, 0.9078793792f, 0.7932427008f, 0.6830685163f, 0.5796781031f, 0.4847580912f, 0.3993847415f, 0.3240825396f, 0.2589046395f, 0.2035239989f, 0.1573262035f, 0.1194974113f, 0.08910313924f, 0.06515553343f, 0.04666820805f, 0.03269873273f, 0.02237947106f, 0.0149378351f, 0.009707223739f, 0.006130037632f, 0.003754250977f, 0.002225082706f, 0.001273327945f, 0.0007018595157f, 0.0003716669362f, 0.0001885644298f, 9.139081749e-05f, 4.218318384e-05f, 1.84818136e-05f, 7.659575853e-06f, 2.991661588e-06f, 1.096883513e-06f, 3.759541186e-07f, 1.199244278e-07f, 3.543477717e-08f, 9.649888896e-09f, 2.409177326e-09f, 5.48283578e-10f, 1.130605535e-10f, 2.09893354e-11f, 3.484193767e-12f, 5.134127525e-13f, 6.663992283e-14f, 7.556721776e-15f, 7.420993231e-16f, 6.252804845e-17f, 4.475759507e-18f, 2.693120661e-19f, 1.346994157e-20f, 5.533583499e-22f, 1.843546975e-23f, 4.913936871e-25f, 1.032939131e-26f, 1.686277004e-28f, 2.103305749e-30f, 1.96992098e-32f, 1.359989462e-34f, }, + { 1.570042029f, 1.564021404f, 1.55205317f, 1.534281738f, 1.510919723f, 1.482243298f, 1.448586255f, 1.410332971f, 1.367910512f, 1.321780117f, 1.272428346f, 1.22035811f, 1.16607987f, 1.110103194f, 1.05292888f, 0.995041804f, 0.9369046127f, 0.8789523456f, 0.8215880353f, 0.7651792989f, 0.7100559012f, 0.6565082461f, 0.6047867306f, 0.555101878f, 0.5076251588f, 0.4624903981f, 0.4197956684f, 0.3796055694f, 0.3419537959f, 0.3068459094f, 0.2742622297f, 0.2441607779f, 0.2164802091f, 0.1911426841f, 0.1680566379f, 0.1471194133f, 0.1282197336f, 0.111239999f, 0.09605839187f, 0.08255078811f, 0.07059246991f, 0.06005964236f, 0.05083075757f, 0.04278765216f, 0.0358165056f, 0.02980862812f, 0.02466108731f, 0.02027718382f, 0.01656678625f, 0.01344653661f, 0.01083993717f, 0.00867733075f, 0.006895785969f, 0.005438899798f, 0.004256529599f, 0.003304466994f, 0.002544065768f, 0.001941835776f, 0.00146901436f, 0.001101126113f, 0.0008175410133f, 0.0006010398799f, 0.0004373949562f, 0.0003149720919f, 0.0002243596521f, 0.000158027884f, 0.0001100211285f, 7.568399659e-05f, 5.142149745e-05f, 3.449212476e-05f, 2.283211811e-05f, 1.490851403e-05f, 9.598194128e-06f, 6.089910032e-06f, 3.806198326e-06f, 2.342166721e-06f, 1.418306716e-06f, 8.447375638e-07f, 4.94582887e-07f, 2.844992366e-07f, 1.606939458e-07f, 8.907139514e-08f, 4.84209502e-08f, 2.579956823e-08f, 1.346464552e-08f, 6.878461096e-09f, 3.437185674e-09f, 1.678889768e-09f, 8.009978448e-10f, 3.729950184e-10f, 1.693945779e-10f, 7.496739757e-11f, 3.230446433e-11f, 1.354251291e-11f, 5.518236947e-12f, 2.18359221e-12f, 8.383128961e-13f, 3.119497729e-13f, 1.124020896e-13f, 3.917679451e-14f, 1.319434223e-14f, 4.289196222e-15f, 1.344322288e-15f, 4.057557702e-16f, 1.177981213e-16f, 3.285386163e-17f, 8.791316559e-18f, 2.25407483e-18f, 5.530176913e-19f, 1.296452714e-19f, 2.899964556e-20f, 6.180143249e-21f, 1.252867643e-21f, 2.412250547e-22f, 4.4039067e-23f, 7.610577808e-24f, 1.242805165e-24f, 1.91431069e-25f, 2.776125103e-26f, 3.783124073e-27f, 4.834910155e-28f, 5.783178697e-29f, 6.460575703e-30f, 6.72603739e-31f, 6.511153451e-32f, 5.847409075e-33f, 4.860046055e-34f, 3.72923953e-35f, }, + { 1.570607717f, 1.569099695f, 1.566088239f, 1.561582493f, 1.555596115f, 1.548147191f, 1.539258145f, 1.528955608f, 1.517270275f, 1.504236738f, 1.489893298f, 1.474281762f, 1.457447221f, 1.439437815f, 1.420304486f, 1.400100716f, 1.378882264f, 1.35670689f, 1.333634075f, 1.309724744f, 1.285040985f, 1.259645765f, 1.233602657f, 1.206975567f, 1.179828472f, 1.152225159f, 1.124228984f, 1.09590263f, 1.067307886f, 1.038505436f, 1.00955466f, 0.9805134517f, 0.951438051f, 0.9223828892f, 0.8934004523f, 0.8645411596f, 0.8358532563f, 0.807382723f, 0.7791731997f, 0.7512659245f, 0.723699687f, 0.6965107951f, 0.6697330554f, 0.6433977657f, 0.6175337199f, 0.5921672237f, 0.5673221206f, 0.5430198278f, 0.5192793805f, 0.4961174844f, 0.4735485755f, 0.4515848861f, 0.4302365164f, 0.4095115109f, 0.3894159397f, 0.3699539819f, 0.3511280132f, 0.3329386948f, 0.3153850641f, 0.2984646265f, 0.2821734476f, 0.2665062456f, 0.2514564831f, 0.2370164583f, 0.2231773949f, 0.2099295305f, 0.1972622032f, 0.1851639366f, 0.1736225217f, 0.1626250975f, 0.1521582278f, 0.1422079761f, 0.1327599774f, 0.1237995069f, 0.1153115463f, 0.1072808458f, 0.09969198461f, 0.09252942711f, 0.08577757654f, 0.0794208254f, 0.07344360286f, 0.06783041903f, 0.06256590638f, 0.05763485811f, 0.05302226366f, 0.04871334138f, 0.04469356846f, 0.04094870813f, 0.0374648342f, 0.03422835312f, 0.03122602351f, 0.02844497325f, 0.02587271434f, 0.02349715546f, 0.02130661237f, 0.01928981624f, 0.01743592007f, 0.01573450311f, 0.01417557353f, 0.01274956936f, 0.01144735783f, 0.01026023317f, 0.009179912924f, 0.008198533005f, 0.007308641451f, 0.006503191044f, 0.005775530877f, 0.005119396961f, 0.004528901979f, 0.003998524263f, 0.00352309611f, 0.003097791523f, 0.002718113458f, 0.002379880688f, 0.002079214354f, 0.001812524299f, 0.001576495262f, 0.00136807301f, 0.001184450486f, 0.001023054043f, 0.0008815298242f, 0.0007577303578f, 0.0006497014187f, 0.0005556692074f, 0.000474027894f, 0.0004033275645f, 0.0003422626065f, 0.0002896605611f, 0.0002444714673f, 0.0002057577147f, 0.0001726844199f, 0.0001445103343f, 0.0001205792873f, 0.0001003121646f, 8.319941724e-05f, 6.879409311e-05f, 5.670537985e-05f, 4.659264463e-05f, 3.815995412e-05f, 3.115105568e-05f, 2.534479897e-05f, 2.055097594e-05f, 1.660655598e-05f, 1.337229228e-05f, 1.072967541e-05f, 8.578209354e-06f, 6.832986277e-06f, 5.422535892e-06f, 4.286926494e-06f, 3.376095235e-06f, 2.648386225e-06f, 2.069276126e-06f, 1.610268009e-06f, 1.247935512e-06f, 9.631005212e-07f, 7.401289349e-07f, 5.66330284e-07f, 4.314482559e-07f, 3.272303733e-07f, 2.470662451e-07f, 1.856849137e-07f, 1.3890287e-07f, 1.034152804e-07f, 7.662387397e-08f, 5.649576387e-08f, 4.144823356e-08f, 3.025519646e-08f, 2.197164892e-08f, 1.587297809e-08f, 1.140646555e-08f, 8.152746483e-09f, 5.795349573e-09f, 4.096757914e-09f, 2.879701346e-09f, 2.012621022e-09f, 1.398441431e-09f, 9.659485186e-10f, 6.632086347e-10f, 4.52575761e-10f, 3.069270208e-10f, 2.068420354e-10f, 1.385028753e-10f, 9.214056423e-11f, 6.089338706e-11f, 3.997338952e-11f, 2.60619605e-11f, 1.687451934e-11f, 1.084916183e-11f, 6.925528015e-12f, 4.38886519e-12f, 2.760858767e-12f, 1.723764404e-12f, 1.068075044e-12f, 6.56694435e-13f, 4.00598538e-13f, 2.424296605e-13f, 1.455249916e-13f, 8.663812725e-14f, 5.114974901e-14f, 2.99421776e-14f, 1.737681695e-14f, 9.99642401e-15f, 5.699626666e-15f, 3.220432513e-15f, 1.802958964e-15f, 9.999957344e-16f, 5.493978397e-16f, 2.989420886e-16f, 1.610765424e-16f, 8.593209748e-17f, 4.538246827e-17f, 2.372253167e-17f, 1.227167167e-17f, 6.281229049e-18f, 3.180614714e-18f, 1.593049257e-18f, 7.890855159e-19f, 3.864733103e-19f, 1.87127733e-19f, 8.955739455e-20f, 4.235742852e-20f, 1.979436202e-20f, 9.138078558e-21f, 4.166641158e-21f, 1.876075055e-21f, 8.339901949e-22f, 3.659575236e-22f, 1.584785218e-22f, 6.771575694e-23f, 2.854281708e-23f, 1.186583858e-23f, 4.864069936e-24f, 1.965643419e-24f, 7.829165625e-25f, 3.072789229e-25f, 1.188107615e-25f, 4.524619749e-26f, 1.696710187e-26f, 6.263641003e-27f, 2.275790793e-27f, 8.136077716e-28f, 2.861306549e-28f, 9.896184197e-29f, 3.365200893e-29f, 1.124807055e-29f, 3.694460433e-30f, 1.192093301e-30f, 3.777757876e-31f, 1.175436379e-31f, 3.589879078e-32f, 1.075842686e-32f, 3.162835126e-33f, 9.118674189e-34f, 2.577393168e-34f, 7.139829504e-35f, 1.937828921e-35f, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5f)); + + prune_to_min_complement(min_complement); + +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 6; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0, -0.0486320359272530543, -2.25228075384071351e-05, -4.29416105587824078e-14, -1.16764889750986093e-37, -1.14795299162938991e-101, -1.22565381365848647e-275, }, + { -0.325728507751564174, -0.00248514354277561317, -1.1124335118015332e-08, -5.37849159139368877e-23, -7.9430213192221161e-62, -2.38712281858192662e-167, }, + { 0.377209738164034174, -0.140430941310103365, -0.0129594394926231083, -0.000311735971646790949, -7.95262885287335534e-07, -4.71435518232225751e-11, -5.41522282380723085e-18, -2.04030039435249433e-29, -3.05969013536445003e-48, -2.86219841925875116e-79, -2.00703306915332264e-130, -9.24799327395281672e-215, }, + { 0.194357003324935432, -0.460853294612032231, -0.219392561016799701, -0.0851207367354253891, -0.0260331318043225514, -0.00594449336859785671, -0.000934803544214153575, -9.06153048560001614e-05, -4.68395877947156992e-06, -1.07218387581618094e-07, -8.57294907821677329e-10, -1.76783469283872037e-12, -6.37487849504443965e-16, -2.44293727908521732e-20, -5.25154647301957486e-26, -2.78946716228941774e-33, -1.2781108980938045e-42, -1.3082723368531808e-54, -5.27997812261025438e-70, -9.06191040541810149e-90, -3.79031527880246479e-115, -9.83017699648704421e-148, -1.41780355464723683e-189, -2.67381847626328947e-243, }, + { 0.0979238852878323333, 0.287879932742715915, 0.461253543939585704, -0.389726342499361055, -0.268981965207438489, -0.17668299449359763, -0.110108597215739802, -0.0648391424780153168, -0.0358878357764527081, -0.01854517332266483, -0.00887300755830119777, -0.00389133456249145746, -0.00154579123230226249, -0.000548565564725394158, -0.00017117792712505834, -4.61289943720392527e-05, -1.05179851814963885e-05, -1.98285940456792063e-06, -3.01105847388779655e-07, -3.57609190846577144e-08, -3.2128009016957605e-09, -2.10267137764114881e-10, -9.606066478508465e-12, -2.91902664101751393e-13, -5.58611663883822752e-15, -6.32820713468316824e-17, -3.95646133946764783e-19, -1.26097584471654847e-21, -1.87249217452760828e-24, -1.17003029391311908e-27, -2.74098617835124095e-31, -2.11228272144761198e-35, -4.61722394825950171e-40, -2.42036219762624008e-45, -2.5155618638019452e-51, -4.17863906970219404e-58, -8.6898180082116723e-66, -1.71543577650024789e-74, -2.34930324121953381e-84, -1.56454323889425122e-95, -3.38734020478683648e-108, -1.51081664710078465e-122, -8.27800009567041668e-139, -3.10160298195808184e-157, -4.09173469287244044e-178, -8.9581681449485487e-202, -1.3878968774299745e-228, -5.79257421293503894e-259, }, + { 0.0490559673050778863, 0.146417984290587941, 0.241566319538883658, 0.333142264577638092, 0.419952111278447158, -0.498986610620690898, -0.42441550936484834, -0.356823241014795299, -0.296449994852857984, -0.243306091366270051, -0.197201258656758734, -0.157780753649243136, -0.124564602369591322, -0.0969867184864261294, -0.0744313659313873335, -0.0562652139472428431, -0.0418639772897863099, -0.0306332671030826648, -0.022023764813335027, -0.0155411688325691691, -0.010751568909866104, -0.00728300280317271462, -0.00482397384467264574, -0.00311968187180812628, -0.00196666368456624598, -0.00120646570119410071, -0.000718888078208044591, -0.000415249648482412683, -0.000232028400439164939, -0.000125134951219653515, -6.49800749175763138e-05, -3.24069320565402357e-05, -1.5480097729175578e-05, -7.06212333711435226e-06, -3.06755080964249425e-06, -1.26452813409045827e-06, -4.92994280563111161e-07, -1.81106287232991369e-07, -6.24459216262249756e-08, -2.01254967982457957e-08, -6.03586579835227638e-09, -1.67663805174219429e-09, -4.29212227386388064e-10, -1.00722276743730848e-10, -2.15446625890420237e-11, -4.1753931241965133e-12, -7.28473726428773404e-13, -1.13638698543921915e-13, -1.57355350979265302e-14, -1.91921890971076214e-15, -2.04495954084673556e-16, -1.88695830672934097e-17, -1.4938716488357229e-18, -1.00469381000375765e-19, -5.6799291780731967e-21, -2.66910395261351514e-22, -1.03017813818941147e-23, -3.22448487639124621e-25, -8.07478290042168868e-27, -1.59465460199328555e-28, -2.44572397527528259e-30, -2.86591977190786557e-32, -2.52168252518289941e-34, -1.63551444031007274e-36, -7.66665909906783572e-39, -2.54357712881376935e-41, -5.84094722807164823e-44, -9.06586956479397026e-47, -9.27356981605885259e-50, -6.08571480420522776e-53, -2.48980897367221466e-56, -6.15986208631705443e-60, -8.92141270722267119e-64, -7.30722432600404514e-68, -3.26256086255138585e-72, -7.6357851449836225e-77, -8.9855174690288197e-82, -5.085871851548729e-87, -1.3207396001984761e-92, -1.49648649356105213e-98, -7.01292336693108804e-105, -1.2839990161964175e-111, -8.64456838410520022e-119, -2.00636948968315553e-126, -1.49877407961844478e-134, -3.34937621495896108e-143, -2.07152943814344815e-152, -3.26388325933199651e-162, -1.19947375988972346e-172, -9.36020855840271015e-184, -1.40350944280078664e-195, -3.63561076394912477e-208, -1.45274399574122646e-221, -7.93772358209223086e-236, -5.21635362297544998e-251, -3.59647437525778163e-267, }, + { 0.0245397635746491604, 0.0735251229856712945, 0.122229122201557642, 0.170467972382010518, 0.218063473469712005, 0.26484507658344795, 0.310651780552845961, 0.355333825165074533, 0.398754150467237756, 0.440789599033900866, 0.481331846116905044, -0.47971194930876984, -0.442418771739221769, -0.406849646408046841, -0.373049791948957121, -0.341049008256649876, -0.310862274938332328, -0.282490532512675873, -0.255921616452652601, -0.231131313231753415, -0.208084507623857886, -0.186736391497026148, -0.167033706080589124, -0.148915992012151267, -0.132316824224354013, -0.117165011755331045, -0.103385745719923974, -0.0909016818369795649, -0.0796339469680471977, -0.0695030620028465937, -0.0604297760667252446, -0.0523358093848469027, -0.0451445041949773146, -0.0387813848488835925, -0.0331746296876441472, -0.0282554584345126911, -0.0239584397434232607, -0.0202217241993842374, -0.0169872085188988944, -0.014200636974716564, -0.0118116461992573576, -0.00977375953247225306, -0.00804433699732238438, -0.006584486830735961, -0.00535894428748880328, -0.00433592318304683035, -0.00348694535974622683, -0.00278665295653129776, -0.00221260804109346917, -0.00174508382800370656, -0.00136685135932252238, -0.00106296516648782627, -0.000820551065114082842, -0.000628598859062313104, -0.000477762348782795776, -0.00036016865439963481, -0.00026923848019151737, -0.000199518568861613698, -0.000146527226888588285, -0.000106613452407435744, -7.68298707106713057e-05, -5.48193855413069104e-05, -3.87151921433338684e-05, -2.70535747677634357e-05, -1.86987298792732083e-05, -1.27787179993718896e-05, -8.63155165512655592e-06, -5.76037238336521799e-06, -3.79665283382324692e-06, -2.47037619483206967e-06, -1.5861890352645758e-06, -1.00458931003037651e-06, -6.27292664630529592e-07, -3.86011449757251023e-07, -2.33976667566879521e-07, -1.39628785400592289e-07, -8.19952052894377486e-08, -4.7357335538151974e-08, -2.68867640563769168e-08, -1.49969236882666325e-08, -8.21354390092801904e-09, -4.4143663841612464e-09, -2.32676326210046123e-09, -1.20201649960114077e-09, -6.08223124167786151e-10, -3.01245630748323226e-10, -1.45943884500128571e-10, -6.91116049852310787e-11, -3.19667832644453697e-11, -1.44312099240426525e-11, -6.35367612849118143e-12, -2.72595051887251972e-12, -1.13873457224078497e-12, -4.62773462176931343e-13, -1.82799022484311048e-13, -7.01204673849056861e-14, -2.60960536613795464e-14, -9.41336133528885558e-15, -3.28792569493649342e-15, -1.11086294018218984e-15, -3.6266022642032122e-16, -1.14278765250526699e-16, -3.47190226924949368e-17, -1.01578190683051246e-17, -2.85853282450814817e-18, -7.72783478738925526e-19, -2.00442399221751722e-19, -4.98156837646991149e-20, -1.18466849242234024e-20, -2.69198490361039057e-21, -5.83666744193394141e-22, -1.20566158865487235e-22, -2.36910935080780677e-23, -4.42133946172800178e-24, -7.82383500410868582e-25, -1.31053314412547815e-25, -2.07434501307351507e-26, -3.09696832555074958e-27, -4.35320052819675598e-28, -5.74995566807039229e-29, -7.12271592663817274e-30, -8.25783542035580458e-31, -8.94154100662495554e-32, -9.02279665003086697e-33, -8.46603011953159718e-34, -7.36927280656452982e-35, -5.93663235600887498e-36, -4.41527783869469595e-37, -3.02396013586353149e-38, -1.90220379165770488e-39, -1.09604332860345779e-40, -5.76869559800406948e-42, -2.76539938173771022e-43, -1.20387095285625741e-44, -4.74476232533549872e-46, -1.68767912810533091e-47, -5.39996699829972848e-49, -1.54902404944808261e-50, -3.96994725525613498e-52, -9.05767492652393586e-54, -1.83295043348369314e-55, -3.27742233239736439e-57, -5.15768715308393636e-59, -7.114715221408198e-61, -8.56688901712102493e-63, -8.96555855421136186e-65, -8.11869379690547438e-67, -6.33219388590773392e-69, -4.23372634246032809e-71, -2.41472604643767902e-73, -1.16895559109482145e-75, -4.77806689855264461e-78, -1.6402035716952159e-80, -4.70248914876421051e-83, -1.11959046700779807e-85, -2.2005433507330025e-88, -3.54892402406326365e-91, -4.66694093688365186e-94, -4.97190667459303363e-97, -4.26251200323736193e-100, -2.92055254102694012e-103, -1.58792835205206735e-106, -6.80103287742115697e-110, -2.2772324163917692e-113, -5.91472228162959818e-117, -1.18209982177688408e-120, -1.80282622739513989e-124, -2.08020413351101242e-128, -1.79996701563969356e-132, -1.15734196606825454e-136, -5.477766654144099e-141, -1.8900190812332373e-145, -4.70643183557466755e-150, -8.37112913643764166e-155, -1.05221390088176585e-159, -9.2441193400981258e-165, -5.61216501813263789e-170, -2.32703984243702941e-175, -6.5107211867430156e-181, -1.2138997008699256e-186, -1.48891299935269587e-192, -1.18553781867001071e-198, -6.04455846579323287e-205, -1.94567931886735567e-211, -3.8966805747095114e-218, -4.78292200095461437e-225, -3.54255959173241182e-232, -1.55812601911741406e-239, -4.00280716389675087e-247, -5.90460003827621713e-255, -4.91396180352002352e-263, -2.26567446980557423e-271, }, + { 0.012271355118082202, 0.036802280950025085, 0.0612978894136599758, 0.0857347548776510558, 0.110089629932628013, 0.134339515287672237, 0.158461728289299504, 0.18243396969028915, 0.206234388311028769, 0.229841643254360754, 0.253234963356000236, 0.276394203576178614, 0.299299898063960473, 0.321933309653369166, 0.344276475579704919, 0.366312249234904082, 0.388024337812117748, 0.409397335721529489, 0.430416753691437064, 0.451069043500451995, 0.471341618317998466, 0.491222868660811487, -0.489297825997441858, -0.470230089898225442, -0.451582547860207645, -0.433362826214981142, -0.415577557677336058, -0.398232389990366541, -0.381331998167271939, -0.364880100135578164, -0.34887947557569577, -0.333331987734262319, -0.318238607983572687, -0.303599442891540793, -0.289413763561994213, -0.27568003700259252, -0.262395959277174755, -0.249558490200759565, -0.237163889338607631, -0.22520775307556463, -0.213685052528180394, -0.202590172079687753, -0.191916948326661462, -0.181658709235902172, -0.171808313320642901, -0.162358188656399975, -0.153300371568536304, -0.144626544835728469, -0.136328075265894765, -0.128396050513622281, -0.12082131502061063, -0.113594504973021298, -0.106706082181789018, -0.100146366803829869, -0.0939055688335957994, -0.0879738183055131808, -0.0823411941584506602, -0.0769977517234455965, -0.0719335488054448738, -0.0671386703387599459, -0.0626032516042808619, -0.0583175000042306645, -0.0542717153973677599, -0.0504563090040636404, -0.0468618208966061973, -0.0434789360954190696, -0.0402984992966633908, -0.03731152826092173, -0.0345092258963795269, -0.0318829910731436838, -0.0294244282080995797, -0.0271253556620361184, -0.0249778129926936505, -0.0229740671089420425, -0.0211066173725059709, -0.019368199694551295, -0.0177517896750589349, -0.0162506048332687547, -0.0148581059776019712, -0.0135679977633915537, -0.0123742284864893156, -0.0112709891603976381, -0.0102527119240129037, -0.00931406782638492783, -0.00844996403410826525, -0.00765554050608182456, -0.00692616617941556874, -0.00625743470923838919, -0.00564515980407910996, -0.0050853701973611284, -0.00457430429437719331, -0.00410840453289979854, -0.00368431149433907478, -0.00329885780108739487, -0.00294906183439087047, -0.00263212130576456563, -0.0023454067136221407, -0.00208645471542297342, -0.0018529614442515744, -0.00164277579733623578, -0.00145389272258728331, -0.00128444652779115701, -0.0011327042356361947, -0.000997059006271141487, -0.000876023647610171022, -0.000768224232101148019, -0.00067239383717004608, -0.000587366425047420931, -0.000512070876176692876, -0.0004455251889032602, -0.00038683085665314189, -0.00033516743233532264, -0.000289787288248965581, -0.000250010578351141274, -0.000215220408348834122, -0.000184858217726938954, -0.000158419376517931266, -0.000135448998364931342, -0.000115537970233795639, -9.83191979971305535e-05, -8.3464066048770978e-05, -7.06791081158112189e-05, -5.97028855206253867e-05, -5.03030683106995953e-05, -4.22737139220181204e-05, -3.54327373739233618e-05, -2.96195664107243162e-05, -2.46929745079623587e-05, -2.05290842484436199e-05, -1.7019533243403755e-05, -1.40697945252075011e-05, -1.1597643166806137e-05, -9.53176078612253345e-06, -7.8104695663539219e-06, -6.38058746110851941e-06, -5.19639635112362769e-06, -4.21871507150727724e-06, -3.41406942921033546e-06, -2.75395157382161437e-06, -2.21416136477003485e-06, -1.77422268862384164e-06, -1.41686801551279912e-06, -1.12758483806512337e-06, -8.94218004200267166e-07, -7.066223315196142e-07, -5.56360271123123226e-07, -4.36439768090839962e-07, -3.41087840680835234e-07, -2.65555767043837624e-07, -2.0595212394180991e-07, -1.59100264054130123e-07, -1.22417144893368773e-07, -9.38107315112986677e-08, -7.15934858568207488e-08, -5.44097270488153164e-08, -4.11748985097450346e-08, -3.10250097588474058e-08, -2.32747328650517169e-08, -1.7382826537542006e-08, -1.29237352250289432e-08, -9.5643672141012476e-09, -7.04519550806302257e-09, -5.1649492757248395e-09, -3.76827299743367321e-09, -2.73582625416470426e-09, -1.97638056812945901e-09, -1.42054196354815056e-09, -1.01579009878587221e-09, -7.22578006796989773e-10, -5.11281694668026368e-10, -3.59827055120401645e-10, -2.51853622445542102e-10, -1.75301477503092556e-10, -1.21329810513247054e-10, -8.34939507523206686e-11, -5.71226602674819584e-11, -3.88496860027937659e-11, -2.62634273799497214e-11, -1.76464997763789762e-11, -1.17832983201206309e-11, -7.81868062832536264e-12, -5.15483640427513504e-12, -3.37650146080002947e-12, -2.19707446995923426e-12, -1.42004736695181269e-12, -9.11580079335777287e-13, -5.81130625055868083e-13, -3.6786791102075634e-13, -2.31206890357644477e-13, -1.44261724859223088e-13, -8.93496666512989392e-14, -5.49256777212567905e-14, -3.35078830951587706e-14, -2.02840764024440399e-14, -1.21827951289796445e-14, -7.25885373620523418e-15, -4.29006278660366691e-15, -2.51465253948077134e-15, -1.46168711284753358e-15, -8.42433095837469831e-16, -4.81351759040153145e-16, -2.7263179430684055e-16, -1.53044229739659322e-16, -8.5137857250384434e-17, -4.69279503896114271e-17, -2.56259759503200895e-17, -1.38613346679503967e-17, -7.42575019213846423e-18, -3.93930940244456018e-18, -2.06907914597742282e-18, -1.07582862164931383e-18, -5.53667101730119995e-19, -2.81983400378589843e-19, -1.42100637503135938e-19, -7.08424387814173802e-20, -3.49335055730950445e-20, -1.70359775108200994e-20, -8.21470604421218778e-21, -3.91597343841569897e-21, -1.84514981562718714e-21, -8.59187458062354013e-22, -3.95300695770657649e-22, -1.79666979951342614e-22, -8.06540882083892199e-23, -3.57533721226205606e-23, -1.5647821323387364e-23, -6.76004176421736964e-24, -2.88213632330255471e-24, -1.21243623290624178e-24, -5.03142183078805999e-25, -2.05928631224500678e-25, -8.31078779763998548e-26, -3.30651806761459413e-26, -1.29659734624673994e-26, -5.01009103239855231e-27, -1.90717938473556322e-27, -7.15056733398109736e-28, -2.63990603736826823e-28, -9.59466454215915903e-29, -3.43207809913106496e-29, -1.20798506630670813e-29, -4.18246472148817528e-30, -1.42415370668448176e-30, -4.76783338169881336e-31, -1.56894917819580623e-31, -5.07343885484964435e-32, -1.61169191609392457e-32, -5.02835669425437807e-33, -1.54032043714714164e-33, -4.63139244348179017e-34, -1.36647022505741948e-34, -3.95500852699898458e-35, -1.12259182536440082e-35, -3.12384874336168341e-36, -8.51954024720649026e-37, -2.27647348137758297e-37, -5.95784738583498423e-38, -1.5267023004586064e-38, -3.82924523738836913e-39, -9.39764841233127425e-40, -2.25591870233912475e-40, -5.29510577400702735e-41, -1.21484005139195805e-41, -2.72333290575638595e-42, -5.96294747245500166e-43, -1.27479045632084017e-43, -2.65993246477400726e-44, -5.41489757055003388e-45, -1.07505067837929222e-45, -2.0807277332937164e-46, -3.9244163140436388e-47, -7.20993781004693903e-48, -1.28974823309181237e-48, -2.24549897001720529e-49, -3.80338177519323738e-50, -6.2645207667921989e-51, -1.00294108349246457e-51, -1.5600495091009387e-52, -2.35656502929127819e-53, -3.45539861530099585e-54, -4.91576367443963002e-55, -6.78189690060837789e-56, -9.06919402024436437e-57, -1.17497924435643381e-57, -1.47407303120625938e-58, -1.78984329859422798e-59, -2.1022998433631042e-60, -2.3874311701754331e-61, -2.61994971132693976e-62, -2.77681312539698556e-63, -2.84088709628858008e-64, -2.80396888834653826e-65, -2.66844816022605403e-66, -2.44715408087085735e-67, -2.16136193986109549e-68, -1.83738434241422263e-69, -1.50251039384538056e-70, -1.18117553050091616e-71, -8.92115779194300367e-73, -6.469398720148732e-74, -4.50157318845664738e-75, -3.00358422099143309e-76, -1.92045159974146096e-77, -1.17588108496782645e-78, -6.89007215715517382e-80, -3.86085633874422728e-81, -2.06746164750454894e-82, -1.05724310335546675e-83, -5.159178839138868e-85, -2.40068073513892583e-86, -1.06441521301761484e-87, -4.49345292323654518e-89, -1.80470487227992129e-90, -6.89045955067325497e-92, -2.49896371014878691e-93, -8.60180884698632756e-95, -2.8078924862967821e-96, -8.68498675197961289e-98, -2.54323961092475611e-99, -7.04466689786197244e-101, -1.84420182558676709e-102, -4.55874167252535593e-104, -1.06310885552045921e-105, -2.33672817489640356e-107, -4.83650426311308612e-109, -9.41752356208775621e-111, -1.72347894616941773e-112, -2.96152337973418694e-114, -4.77346095185853133e-116, -7.20979528228986404e-118, -1.0193874335777637e-119, -1.34781669991634323e-121, -1.66471130073245645e-123, -1.91865839504763309e-125, -2.06126480152885691e-127, -2.06189537886634895e-129, -1.91826195552363599e-131, -1.65791287785192226e-133, -1.32960990700944959e-135, -9.8828871549374804e-138, -6.80018519366801829e-140, -4.32620427633799334e-142, -2.54159552852297217e-144, -1.37712796594958211e-146, -6.87317396243845786e-149, -3.15568448417183025e-151, -1.33110460150070095e-153, -5.15149580050109184e-156, -1.82670376280564422e-158, -5.92677285398580171e-161, -1.75701790578206368e-163, -4.75252736446443541e-166, -1.17121511806343118e-168, -2.62588387222030548e-171, -5.34803615842019053e-174, -9.87952606199786798e-177, -1.65285015577763281e-179, -2.50039475650869583e-182, -3.41485961919321622e-185, -4.20365360545913323e-188, -4.65650825702166728e-191, -4.63395309965355254e-194, -4.13587819260496962e-197, -3.30494472949500722e-200, -2.36039562085899995e-203, -1.5040470140688354e-206, -8.53520219585080464e-210, -4.3057568200632215e-213, -1.92736281851211248e-216, -7.64078684884150441e-220, -2.6775820096831777e-223, -8.27816250430073493e-227, -2.2534850368391124e-230, -5.39056859020767355e-234, -1.13080972768156503e-237, -2.07597218137054105e-241, -3.32826876045839753e-245, -4.65000671354536966e-249, -5.64918736922395969e-253, -5.95469666263319233e-257, -5.43379904255349279e-261, -4.28283635376386341e-265, -2.90898542515205486e-269, -1.69869798350729535e-273, }, + }; + m_weights = { + { 1.57079632679489662, 0.230022394514788685, 0.000266200513752716909, 1.35817842745390908e-12, 1.0017416784066253e-35, 2.6763080920617461e-99, 7.76707068863340629e-273, }, + { 0.965976579412301148, 0.0183431669899278421, 2.14312045569430394e-07, 2.80031510197758896e-21, 1.12327053454869188e-59, 9.17532687500178413e-165, }, + { 1.38961475924725632, 0.531078275428053975, 0.0763857435708323042, 0.00290251774790131359, 1.198370136317072e-05, 1.16311658142557828e-09, 2.19707923629797992e-16, 1.36351033076376154e-27, 3.3700568540419265e-46, 5.19697838008985521e-77, 6.00803417057135015e-128, 4.5642040563555991e-212, }, + { 1.52328371863470521, 1.19346302584915696, 0.737437848361547841, 0.360461418469343674, 0.137422107733167723, 0.0391750054936007791, 0.00774260102606424071, 0.000949946804283468717, 6.24825592407440829e-05, 1.82633205937106597e-06, 1.86872822687364101e-08, 4.9378538776631927e-11, 2.2834926702613954e-14, 1.12275314281815515e-18, 3.09765397011735437e-24, 2.11212334353722559e-31, 1.24241475706160524e-40, 1.63277073317994932e-52, 8.4606887310962138e-68, 1.86444920795886503e-87, 1.00131284686664302e-112, 3.33444354118689902e-145, 6.17515762254877653e-187, 1.49532400222570759e-240, }, + { 1.55877335553333015, 1.46601442671696578, 1.297475750424978, 1.08163498549007041, 0.850172856456620069, 0.630405135164743691, 0.440833236273858237, 0.290240679312454185, 0.179324412110728293, 0.103432154223332901, 0.0552896837422405838, 0.0271335100137120032, 0.0120835435991579535, 0.00481629814392846302, 0.00169087399814263965, 0.00051339382406790336, 0.000132052341256099749, 2.81101643279401347e-05, 4.82371820326155021e-06, 6.47775660359297199e-07, 6.58351851271833967e-08, 4.87600609742406259e-09, 2.52163479185301486e-10, 8.67593141497960465e-12, 1.88020717307506498e-13, 2.41242303843087864e-15, 1.70845327724057017e-17, 6.16825684907623826e-20, 1.03767972385287062e-22, 7.34598410322269356e-26, 1.94978336243351748e-29, 1.70243877612575472e-33, 4.21648637094842789e-38, 2.50442771162752843e-43, 2.94936014574619331e-49, 5.55133235696537106e-56, 1.30811651202108216e-63, 2.92608244638239753e-72, 4.54077346699978241e-82, 3.42656356920869877e-93, 8.406435948883177e-106, 4.24861926881986944e-120, 2.63782082635045215e-136, 1.11992914558412798e-154, 1.67415937867108893e-175, 4.15330608101949222e-199, 7.29151266090566043e-226, 3.44840283588682197e-256, }, + { 1.56778143130722186, 1.54388111617695922, 1.49722622254103629, 1.43000835487229967, 1.34527888476625166, 1.2467012074518577, 1.13827224337630537, 1.02404493311181145, 0.907879379154895317, 0.793242700820516718, 0.683068516344263755, 0.579678103087787647, 0.484758091214755393, 0.399384741525717135, 0.324082539611528904, 0.258904639514053516, 0.203523998858601745, 0.15732620348436615, 0.119497411288695924, 0.0891031392409414628, 0.065155533432536205, 0.0466682080548466136, 0.0326987327266090311, 0.0223794710636484765, 0.0149378350960501297, 0.00970722373939168927, 0.00613003763208303013, 0.0037542509774318343, 0.0022250827064786427, 0.0012733279447082382, 0.000701859515684242271, 0.000371666936216777603, 0.000188564429767003186, 9.13908174907101227e-05, 4.21831838417576006e-05, 1.84818135998792171e-05, 7.65957585252031626e-06, 2.99166158781387871e-06, 1.09688351259012647e-06, 3.75954118623606301e-07, 1.19924427829027702e-07, 3.5434777171421953e-08, 9.64988889610896336e-09, 2.40917732564759408e-09, 5.48283577970949776e-10, 1.13060553474946805e-10, 2.09893354045114691e-11, 3.48419376702610597e-12, 5.13412752450142075e-13, 6.66399228330876532e-14, 7.55672177578056519e-15, 7.42099323099221676e-16, 6.25280484461045536e-17, 4.47575950666909697e-18, 2.69312066148696951e-19, 1.34699415695422861e-20, 5.53358349941557115e-22, 1.84354697471814938e-23, 4.91393687126490401e-25, 1.03293913069285754e-26, 1.68627700384926065e-28, 2.10330574900180895e-30, 1.96992097962323433e-32, 1.35998946163037957e-34, 6.78597883755924791e-37, 2.39650636994432174e-39, 5.85795694830842108e-42, 9.67839277557170956e-45, 1.05383611325642088e-47, 7.36158583097876492e-51, 3.20597853528338661e-54, 8.44308926618642561e-58, 1.3016694874428173e-61, 1.13489850483720466e-65, 5.39388136951158084e-70, 1.3438019476233711e-74, 1.68330959366332403e-79, 1.01420590744681585e-84, 2.80361361934498745e-90, 3.38153878938366947e-96, 1.68686995979731349e-102, 3.28767160546365504e-109, 2.35618039758663049e-116, 5.82127142688641827e-124, 4.62897694169420155e-132, 1.10117124175309668e-140, 7.2497708296024464e-150, 1.2159344493950079e-159, 4.75673322877850563e-170, 3.95135613192899529e-181, 6.3069398037899023e-193, 1.73909581157725484e-205, 7.39738244904451982e-219, 4.3025693007354699e-233, 3.00982956958324877e-248, 2.20899573159075297e-264, }, + { 1.57004202927959315, 1.5640214037732321, 1.55205316984541212, 1.53428173815430343, 1.51091972307416971, 1.48224329788553807, 1.44858625496132259, 1.41033297144625901, 1.36791051168089649, 1.32178011744377286, 1.27242834553786271, 1.22035810957935822, 1.16607986993243458, 1.11010319396534038, 1.05292887995526666, 0.995041804046132715, 0.936904612745667934, 0.87895234555278212, 0.821588035266964703, 0.765179298908956137, 0.710055901205468984, 0.656508246131627531, 0.604786730578403622, 0.55510187800363351, 0.5076251588319081, 0.462490398055367761, 0.419795668445015481, 0.37960556938665161, 0.341953795923016832, 0.306845909417916949, 0.274262229689068106, 0.244160777869839909, 0.21648020911729617, 0.191142684133427495, 0.168056637948269162, 0.147119413257856932, 0.128219733631200987, 0.11123999898874453, 0.0960583918651894678, 0.0825507881107017377, 0.0705924699068669994, 0.0600596423586363003, 0.0508307575725704711, 0.042787652157725676, 0.0358165056041964365, 0.029808628117310127, 0.0246610873147532825, 0.0202771838175001239, 0.0165667862542475754, 0.0134465366052857307, 0.0108399371682559072, 0.00867733074953918159, 0.00689578596906600353, 0.00543889979762399843, 0.00425652959901785802, 0.00330446699403483024, 0.00254406576752917297, 0.00194183577598436758, 0.00146901435994297911, 0.00110112611345193839, 0.000817541013324694931, 0.000601039879911474226, 0.000437394956159116878, 0.000314972091860212003, 0.000224359652050085491, 0.000158027884007011919, 0.000110021128466666972, 7.56839965862014778e-05, 5.14214974476588021e-05, 3.44921247593431977e-05, 2.28321181090361466e-05, 1.49085140318706084e-05, 9.59819412837847108e-06, 6.08991003209490393e-06, 3.8061983264644899e-06, 2.34216672085280968e-06, 1.41830671554939175e-06, 8.44737563848598635e-07, 4.94582887027541985e-07, 2.84499236591598063e-07, 1.60693945790762249e-07, 8.90713951402423871e-08, 4.84209501980723697e-08, 2.57995682295358924e-08, 1.34646455223020388e-08, 6.87846109558990011e-09, 3.43718567446500905e-09, 1.67888976821619068e-09, 8.00997844797296654e-10, 3.729950184305279e-10, 1.69394577894116469e-10, 7.49673975738182245e-11, 3.23044643332523658e-11, 1.35425129123362744e-11, 5.51823694681748858e-12, 2.18359220992336091e-12, 8.38312896050266709e-13, 3.11949772868480812e-13, 1.12402089599228615e-13, 3.91767945060164679e-14, 1.31943422319679894e-14, 4.289196222067908e-15, 1.34432228753952215e-15, 4.05755770226285762e-16, 1.17798121272483481e-16, 3.28538616288470066e-17, 8.79131655891989009e-18, 2.25407483043688194e-18, 5.53017691284033759e-19, 1.29645271406893694e-19, 2.89996455643157199e-20, 6.18014324933998845e-21, 1.25286764322732104e-21, 2.41225054683610101e-22, 4.40390669993986809e-23, 7.61057780758206258e-24, 1.24280516521231649e-24, 1.91431069022397607e-25, 2.77612510258505832e-26, 3.78312407281377971e-27, 4.83491015481884767e-28, 5.78317869722905296e-29, 6.46057570344172199e-30, 6.72603738958794054e-31, 6.51115345113745165e-32, 5.84740907454810199e-33, 4.86004605514227334e-34, 3.72923952984360242e-35, 2.63512306168036669e-36, 1.71019264014906972e-37, 1.01666853095521272e-38, 5.52069094434276257e-40, 2.73047551166050082e-41, 1.22638096665251285e-42, 4.98683929835361257e-44, 1.8300654157711633e-45, 6.04135032250826404e-47, 1.78800030852571268e-48, 4.72782066352906336e-50, 1.1129101718049772e-51, 2.32360072879360546e-53, 4.28657921354384008e-55, 6.95987352255375155e-57, 9.90539981286746442e-59, 1.23056903223701726e-60, 1.32870554636824381e-62, 1.24138446090017621e-64, 9.9894889830989163e-67, 6.89097928902098062e-69, 4.05504128376793915e-71, 2.02532547805183379e-73, 8.54119386081712901e-76, 3.02505849584780752e-78, 8.94815749837378473e-81, 2.19803659571925209e-83, 4.45733908425182132e-86, 7.41673167121007253e-89, 1.00627894464704291e-91, 1.10606170248612031e-94, 9.78345817231037531e-98, 6.91611604032706014e-101, 3.87970491925780374e-104, 1.71440443580946886e-107, 5.92265513981439625e-111, 1.58713616826240749e-114, 3.2726893534998181e-118, 5.14962203948078777e-122, 6.13053461759876059e-126, 5.47303084654380852e-130, 3.63074753096835834e-134, 1.77300075376963467e-138, 6.31164645321273548e-143, 1.62158369391922019e-147, 2.97579351328298596e-152, 3.85917057654421516e-157, 3.49805556185897821e-162, 2.19110324175719591e-167, 9.37362347961089205e-173, 2.70585229333265743e-178, 5.20510049827160481e-184, 6.58698972266196046e-190, 5.41133533489527735e-196, 2.84659058487511908e-202, 9.45372790667779433e-209, 1.95343097467687228e-215, 2.47381948587608999e-222, 1.89044188887636326e-229, 8.57867513484860174e-237, 2.27380804498007095e-244, 3.46059771526558578e-252, 2.97141917521293704e-260, 1.41351747260411324e-268, }, + { 1.57060771653827522, 1.56909969535166913, 1.56608823891746137, 1.56158249349181062, 1.55559611463166042, 1.54814719123555733, 1.53925814531188183, 1.52895560835458072, 1.51727027540505468, 1.50423673806367721, 1.48989329788329712, 1.47428176172807973, 1.45744722081254867, 1.43943781524640698, 1.42030448599969118, 1.40010071626944465, 1.37888226427313752, 1.35670688951560547, 1.33363407457575614, 1.30972474443743974, 1.28504098534672723, 1.2596457651166706, 1.23360265672194671, 1.20697556693130823, 1.17982847161733374, 1.15222515926254743, 1.12422898405060326, 1.09590262979297221, 1.06730788579750387, 1.03850543563739233, 1.00955465962942982, 0.980513451680855025, 0.951438051016352709, 0.922382889152455146, 0.893400452347195998, 0.864541159619668999, 0.835853256308267131, 0.807382723018763038, 0.779173199704797981, 0.751265924524356859, 0.723699687026830293, 0.696510795146546885, 0.669733055410290998, 0.643397765708252856, 0.6175337199299089, 0.592167223728206949, 0.567322120646738718, 0.543019827824842867, 0.519279380484246331, 0.496117484397316214, 0.473548575540614005, 0.451584886147544914, 0.430236516389788978, 0.409511510938193634, 0.389415939679212028, 0.369953981892113872, 0.351128013224425247, 0.332938694837747795, 0.315385064132678135, 0.298464626499444984, 0.282173447579596105, 0.266506245563135161, 0.251456483084510398, 0.237016458319418989, 0.223177394922184588, 0.209929530480207537, 0.197262203197437199, 0.185163936552775515, 0.173622521711631303, 0.162625097499384324, 0.15215822777419972, 0.142207976063401831, 0.132759977352445526, 0.123799506938412961, 0.115311546280937337, 0.107280845802556434, 0.0996919846077885777, 0.0925294271057784639, 0.0857775765352681898, 0.0794208254030081551, 0.0734436028576387748, 0.0678304190306579665, 0.0625659063844551083, 0.057634858114654727, 0.0530222636602871787, 0.0487133413807014315, 0.0446935684627655335, 0.0409487081258673025, 0.0374648341956289728, 0.0342283531201756966, 0.0312260235053317411, 0.0284449732473342374, 0.0258727143436176445, 0.0234971554639885273, 0.0213066123661260705, 0.0192898162408456015, 0.0174359200739774613, 0.0157345031130597965, 0.0141755735283304602, 0.0127495693587311627, 0.0114473578347997563, 0.0102602331714107689, 0.00917991292431090168, 0.00819853300526119991, 0.00730864145131324803, 0.00650319104428257946, 0.00577553087680654914, 0.00511939696145378187, 0.00452890197915628912, 0.00399852426273353105, 0.00352309611044298632, 0.00309779152330082066, 0.00271811345835022642, 0.00237988068810043825, 0.00207921435400866615, 0.00181252429912886427, 0.00157649526191055605, 0.00136807300960970396, 0.00118445048589027722, 0.00102305404297454109, 0.000881529824172970023, 0.000757730357827359211, 0.000649701418674290374, 0.000555669207425785582, 0.000474027894018167196, 0.000403327564549540929, 0.000342262606462976881, 0.000289660561088771743, 0.000244471467286891624, 0.000205757714679988186, 0.000172684419885929228, 0.000144510334290945865, 0.000120579287290569961, 0.000100312164601124202, 8.31994172400364807e-05, 6.8794093113496377e-05, 5.67053798539328775e-05, 4.65926446304946187e-05, 3.81599541202457603e-05, 3.11510556774483529e-05, 2.534479896885011e-05, 2.05509759449342446e-05, 1.66065559765083359e-05, 1.33722922845323726e-05, 1.07296754068523407e-05, 8.57820935370790825e-06, 6.83298627742185068e-06, 5.42253589182403319e-06, 4.28692649399982268e-06, 3.37609523480551097e-06, 2.64838622540434106e-06, 2.06927612573646709e-06, 1.61026800945076506e-06, 1.24793551211774519e-06, 9.63100521176592526e-07, 7.40128934909086142e-07, 5.66330284020507752e-07, 4.31448255871653806e-07, 3.27230373305175589e-07, 2.47066245112497007e-07, 1.85684913700251324e-07, 1.3890286996035953e-07, 1.03415280407456071e-07, 7.66238739748175847e-08, 5.64957638716706215e-08, 4.14482335585053839e-08, 3.02551964648994672e-08, 2.19716489170893499e-08, 1.58729780909682326e-08, 1.14064655548504821e-08, 8.15274648285765377e-09, 5.79534957309660641e-09, 4.0967579139685198e-09, 2.87970134644711047e-09, 2.01262102188671729e-09, 1.3984414312565442e-09, 9.65948518580993005e-10, 6.63208634701620998e-10, 4.5257576104153822e-10, 3.06927020787233287e-10, 2.06842035390292175e-10, 1.38502875258341451e-10, 9.21405642265188841e-11, 6.08933870643806705e-11, 3.99733895199302696e-11, 2.60619605028052933e-11, 1.68745193439150252e-11, 1.08491618343371201e-11, 6.92552801526813823e-12, 4.3888651899779304e-12, 2.76085876713982836e-12, 1.72376440360427176e-12, 1.06807504365414595e-12, 6.56694434965737702e-13, 4.00598537995324327e-13, 2.42429660454424091e-13, 1.45524991577718379e-13, 8.66381272543578617e-14, 5.11497490112370359e-14, 2.99421775950314841e-14, 1.73768169460742936e-14, 9.99642400989942931e-15, 5.69962666605779177e-15, 3.22043251327094293e-15, 1.80295896389489942e-15, 9.9999573441511328e-16, 5.49397839735005513e-16, 2.98942088568360808e-16, 1.6107654243893339e-16, 8.59320974827080203e-17, 4.53824682671384867e-17, 2.37225316709140862e-17, 1.22716716699576843e-17, 6.28122904855397546e-18, 3.18061471372875766e-18, 1.59304925747919683e-18, 7.89085515934558414e-19, 3.86473310301407342e-19, 1.87127732997090861e-19, 8.95573945523139025e-20, 4.23574285194563761e-20, 1.97943620153417501e-20, 9.1380785584698727e-21, 4.16664115847730492e-21, 1.87607505526684708e-21, 8.33990194865253314e-22, 3.65957523624367309e-22, 1.58478521833259782e-22, 6.77157569443439638e-23, 2.85428170793711408e-23, 1.18658385809475687e-23, 4.86406993570804503e-24, 1.96564341924698522e-24, 7.82916562469586207e-25, 3.07278922881727027e-25, 1.18810761472137628e-25, 4.52461974876349341e-26, 1.69671018684788546e-26, 6.26364100322911832e-27, 2.27579079285739671e-27, 8.13607771590443142e-28, 2.86130654929539103e-28, 9.89618419694378756e-29, 3.36520089316413987e-29, 1.12480705460763553e-29, 3.69446043271393344e-30, 1.19209330134653648e-30, 3.77775787601831979e-31, 1.17543637867784723e-31, 3.58987907782846159e-32, 1.07584268621427998e-32, 3.16283512594659586e-33, 9.11867418907406595e-34, 2.57739316844162499e-34, 7.1398295043464041e-35, 1.93782892101998192e-35, 5.15137910137900834e-36, 1.34081832632372396e-36, 3.41594078513204744e-37, 8.51526274133751428e-38, 2.07627148236909967e-38, 4.95013783834481588e-39, 1.15356967695693221e-39, 2.62668296485366097e-40, 5.8418474765546355e-41, 1.26855835228178392e-41, 2.68859122451013341e-42, 5.5593886486694507e-43, 1.12111057861687088e-43, 2.20403043717381214e-44, 4.22240917613642503e-45, 7.87952006236087725e-46, 1.4317140234575382e-46, 2.53190480341727998e-47, 4.35599819582008424e-48, 7.28767439600814101e-49, 1.18511349577795095e-49, 1.87243345837735946e-50, 2.872969414982913e-51, 4.27891206602476651e-52, 6.1831517263855102e-53, 8.66470653206476218e-54, 1.17694237323367861e-54, 1.54881873834810793e-55, 1.97366460880734193e-56, 2.43418383962132076e-57, 2.90413694228353275e-58, 3.34994299201193299e-59, 3.73408060580539564e-60, 4.01995891804574233e-61, 4.1774687856674289e-62, 4.18809723670882773e-63, 4.0484306973548958e-64, 3.77114883236106507e-65, 3.38317388825833663e-66, 2.92133483455321543e-67, 2.4265171108768021e-68, 1.93760346159320028e-69, 1.48647054250017705e-70, 1.09492322559900645e-71, 7.7387134447881401e-73, 5.24480082054261184e-74, 3.40625629278303564e-75, 2.11846924392585922e-76, 1.2608614434809477e-77, 7.17649031262087557e-79, 3.90346976562660287e-80, 2.02755734043105449e-81, 1.0049948164305939e-82, 4.75009864715140751e-84, 2.13926360994608328e-85, 9.17314929286727873e-87, 3.74222173296279272e-88, 1.4512980036440355e-89, 5.34630175749911307e-91, 1.8692545071988721e-92, 6.19789589312738535e-94, 1.94723396955242345e-95, 5.79190528725131719e-97, 1.62959562674195777e-98, 4.33324326423632619e-100, 1.08801494300863546e-101, 2.57722826273521138e-103, 5.75398380064511214e-105, 1.20969900172483152e-106, 2.39258726643450458e-108, 4.44756592826448755e-110, 7.76277384222654792e-112, 1.27092673030838632e-113, 1.9498242131608832e-115, 2.80025255319740608e-117, 3.76074748562275474e-119, 4.7181060260584104e-121, 5.5234683214250331e-123, 6.02744769044586333e-125, 6.1242336828836774e-127, 5.78733363277456218e-129, 5.08063271088400746e-131, 4.13871801736087986e-133, 3.12471881752233827e-135, 2.18390311640240775e-137, 1.41125398621265234e-139, 8.42151329455492477e-142, 4.63493394973768902e-144, 2.34969854645219935e-146, 1.09580671068190257e-148, 4.69502753712715875e-151, 1.84563108198977552e-153, 6.64760587741882562e-156, 2.19079138839584829e-158, 6.59697046136299986e-161, 1.81250242223442328e-163, 4.53707818939648398e-166, 1.03323888357107399e-168, 2.13749544976958983e-171, 4.0108149042055623e-174, 6.81578124552971753e-177, 1.04731276526762e-179, 1.45286859403218762e-182, 1.81662828371734628e-185, 2.04402028828248565e-188, 2.06615138595524586e-191, 1.87311279320577987e-194, 1.52035876371838628e-197, 1.10294124238752463e-200, 7.1386269709902758e-204, 4.11483850807611072e-207, 2.10850283455308121e-210, 9.58680472859715381e-214, 3.86041689304663802e-217, 1.37411989131828493e-220, 4.3152058575378643e-224, 1.19318553486394228e-227, 2.89916952664044891e-231, 6.17752210069930949e-235, 1.15194579122953133e-238, 1.87592143430152533e-242, 2.66216877009057987e-246, 3.28513888332404399e-250, 3.51733028987600599e-254, 3.26018945745222711e-258, 2.61009614898002005e-262, 1.80074547979629024e-266, 1.06810199062668946e-270, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 9; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0L, -0.048632035927253054272944637095360333L, -2.2522807538407135100363691311150714e-05L, -4.2941610558782407776948098746194498e-14L, -1.1676488975098609327433648963732896e-37L, -1.1479529916293899121630752460973831e-101L, -1.2256538136584864685624805213855318e-275L, -1.5540928823936461440049038613030612e-748L, -5.3329091650553293055512604419528931e-2034L, -2.9720916290005160834428657415764727e-5528L, }, + { -0.32572850775156417391957990936794786L, -0.0024851435427756131672825807611796319L, -1.1124335118015331984966677262985097e-08L, -5.3784915913936887745567608333252923e-23L, -7.9430213192221161033965793076252082e-62L, -2.3871228185819266205711383850686192e-167L, -3.5505659459518255844385870776118831e-454L, -7.5205359182648710139026226942624688e-1234L, -3.1913442054759083418654684997091651e-3353L, }, + { 0.37720973816403417379147863762593439L, -0.14043094131010336482533980273793048L, -0.012959439492623108312614281385864999L, -0.00031173597164679094947882131119246211L, -7.9526288528733553445705754617783867e-07L, -4.7143551823222575055542137870412504e-11L, -5.4152228238072308459654515228487702e-18L, -2.0403003943524943294070815498839042e-29L, -3.0596901353644500298194434206758382e-48L, -2.8621984192587511612196829791231642e-79L, -2.0070330691533226369447382138318798e-130L, -9.24799327395281672235465186719e-215L, -8.3199831454007319575241484332973316e-354L, -4.7101915049286172051527740304785445e-583L, -5.1172326001331791544221573365516138e-961L, -3.565091902092693101170960484903703e-1584L, -1.380788494593788864141714339603113e-2611L, -1.676187209363792948538214808034106e-4305L, }, + { 0.19435700332493543161464358543736564L, -0.46085329461203223095024473969116941L, -0.21939256101679970074520301166037226L, -0.085120736735425389092624476255089179L, -0.026033131804322551436697210776387341L, -0.0059444933685978567073105981025861939L, -0.00093480354421415357524054329032500553L, -9.0615304856000161419338663865283889e-05L, -4.6839587794715699213295541472938628e-06L, -1.0721838758161809434047961979486614e-07L, -8.572949078216773291904741005771376e-10L, -1.7678346928387203697450793420511691e-12L, -6.374878495044439647822814562601604e-16L, -2.4429372790852173177460412747369906e-20L, -5.2515464730195748562913138330508827e-26L, -2.7894671622894177442056826817468893e-33L, -1.2781108980938044979748713346336601e-42L, -1.3082723368531808046381743164626179e-54L, -5.2799781226102543764849911449215675e-70L, -9.0619104054181014912823874637681869e-90L, -3.7903152788024647936360099425967319e-115L, -9.8301769964870442146689481371228979e-148L, -1.4178035546472368325653350149379565e-189L, -2.6738184762632894703182151426789471e-243L, -2.7784573988900744903717061581976306e-312L, -7.3734573357629727800590803405661863e-401L, -1.3609194136463888140125728088459369e-514L, -1.2497483783949474937966696885440387e-660L, -3.8167291133270025322500901161738939e-848L, -6.4205995373383705446145927875493146e-1089L, -4.4417348039463271683501804024826735e-1398L, -4.7673068229426388972968294463896211e-1795L, -9.1130922352573668488349663479480507e-2305L, -2.9379714111577752802646622386752463e-2959L, -1.2139403773313257256483385510112958e-3799L, -1.0232729473573403414331717146692674e-4878L, }, + { 0.097923885287832333262426257841800739L, 0.28787993274271591456404741264058453L, 0.46125354393958570440308960547891476L, -0.38972634249936105511770480385767707L, -0.26898196520743848851375682587352696L, -0.17668299449359762993747017866341472L, -0.11010859721573980192313081408407809L, -0.064839142478015316771395646494440585L, -0.035887835776452708068531865802344445L, -0.018545173322664829973291436321723213L, -0.0088730075583011977688563205451530858L, -0.0038913345624914574643783628537015109L, -0.0015457912323022624891555460019043471L, -0.00054856556472539415808492760717674295L, -0.00017117792712505834023311917084994073L, -4.6128994372039252659199558313379019e-05L, -1.0517985181496388528104100992279397e-05L, -1.9828594045679206280184825675885662e-06L, -3.0110584738877965497930108986179822e-07L, -3.5760919084657714373617064589353927e-08L, -3.2128009016957604999656591474001583e-09L, -2.1026713776411488104386696975012214e-10L, -9.606066478508465003238769873504248e-12L, -2.9190266410175139338365873758536822e-13L, -5.5861166388382275217411050967087276e-15L, -6.328207134683168236714250292398626e-17L, -3.9564613394676478284814817479958896e-19L, -1.2609758447165484726150111345292941e-21L, -1.8724921745276082830417983528796313e-24L, -1.1700302939131190810173673171853244e-27L, -2.7409861783512409524809986743233587e-31L, -2.1122827214476119769953891899502657e-35L, -4.6172239482595017143038368975612786e-40L, -2.4203621976262400766076976463254527e-45L, -2.5155618638019452025824211444543239e-51L, -4.1786390697021940369390798235100086e-58L, -8.6898180082116723025562943397702972e-66L, -1.7154357765002478902943183846995354e-74L, -2.3493032412195338067008854292230121e-84L, -1.5645432388942512177369950120860268e-95L, -3.3873402047868364753040883051129579e-108L, -1.5108166471007846474189907630676839e-122L, -8.2780000956704166841985762886452778e-139L, -3.1016029819580818393688194490134506e-157L, -4.0917346928724404440872286063293528e-178L, -8.9581681449485486979882444847795217e-202L, -1.3878968774299744972242822597861929e-228L, -5.7925742129350389434060147129950123e-259L, -2.1800405760909812340138469200688552e-293L, -2.1406911761156887130351179719470661e-332L, -1.3453872213865718752685710282193859e-376L, -1.101014385623064504263959341239785e-426L, -1.9309068614975016262992988189610055e-483L, -9.3925603630660026565835909833509362e-548L, -1.2492852059051478595312298290165577e-620L, -3.2901922810889194483613206478029049e-703L, -8.7594800494412338094846019359419219e-797L, -8.0988360915906760478163297865939266e-903L, -5.7031344694656922604093410430637095e-1023L, -4.0339055664976041957619784717611254e-1159L, -2.1239178549857743261952555619757156e-1313L, -3.2107478383582521299381622502244136e-1488L, -2.5644945785388919263865858785287637e-1686L, -8.6102745649577746230102198336971101e-1911L, -3.7383203767208973356368595261534058e-2165L, -2.1998398074691126029946216118342674e-2453L, -5.4286931050493856204731826640809476e-2780L, -4.3621004458123770532320189625677295e-3150L, -1.8497978727098997950183603712476515e-3569L, -1.1369676358500293654883467577244006e-4044L, -3.7214839695831726545775627850809865e-4583L, -2.4391504445900085306499460471723674e-5193L, }, + { 0.049055967305077886314518733812558024L, 0.14641798429058794052721556654753264L, 0.24156631953888365837930785879296225L, 0.33314226457763809243847911788190042L, 0.41995211127844715849198982824847239L, -0.49898661062069089848349381875489034L, -0.42441550936484834004641698479390102L, -0.35682324101479529871858133934192696L, -0.2964499948528579843445043147096805L, -0.24330609136627005059281117751078325L, -0.19720125865675873423611581820317215L, -0.15778075364924313618002648351129378L, -0.12456460236959132162770016658853563L, -0.096986718486426129363622040287916613L, -0.074431365931387333547858011705581591L, -0.056265213947242843145098876381950312L, -0.041863977289786309881823549732911528L, -0.030633267103082664829845578114893065L, -0.022023764813335027020322387941507847L, -0.015541168832569169131789346286900099L, -0.010751568909866103993013400883081643L, -0.0072830028031727146206149733302275483L, -0.004823973844672645743610027178935428L, -0.0031196818718081262793524354157388492L, -0.0019666636845662459778601079868649985L, -0.0012064657011941007112693927041613496L, -0.00071888807820804459144864726303695018L, -0.00041524964848241268314681568037451433L, -0.00023202840043916493872468513410105539L, -0.00012513495121965351530204004794322354L, -6.4980074917576313794386569166441844e-05L, -3.2406932056540235696910972894671255e-05L, -1.5480097729175578034178680349142798e-05L, -7.0621233371143522557906813506099499e-06L, -3.0675508096424942465066236512329746e-06L, -1.2645281340904582699398919033969316e-06L, -4.9299428056311116061802876221616736e-07L, -1.8110628723299136916197821516601534e-07L, -6.2445921626224975560761130514661379e-08L, -2.0125496798245795667718397386179161e-08L, -6.0358657983522763759573155859882131e-09L, -1.6766380517421942876239492441262369e-09L, -4.292122273863880635543266425012844e-10L, -1.0072227674373084849456997974551022e-10L, -2.154466258904202365369932629331438e-11L, -4.1753931241965133013258464583874422e-12L, -7.2847372642877340424635554069698771e-13L, -1.1363869854392191510522700311409067e-13L, -1.5735535097926530184856977764147682e-14L, -1.9192189097107621395219494827869742e-15L, -2.0449595408467355635051956217352212e-16L, -1.8869583067293409682109390382712203e-17L, -1.4938716488357228966449278404247075e-18L, -1.0046938100037576480510308414445084e-19L, -5.6799291780731967001285171683592406e-21L, -2.6691039526135151405184691859723367e-22L, -1.0301781381894114683480515283399996e-23L, -3.2244848763912462050246763811724513e-25L, -8.074782900421688680511360232922118e-27L, -1.5946546019932855470728505192034342e-28L, -2.4457239752752825879158721953606166e-30L, -2.8659197719078655681373680421610036e-32L, -2.5216825251828994098262358831122367e-34L, -1.6355144403100727446739341400788963e-36L, -7.6666590990678357226674242484094458e-39L, -2.5435771288137693474957657676429463e-41L, -5.8409472280716482316816237196206469e-44L, -9.0658695647939702552111019446179921e-47L, -9.2735698160588525904827667013324314e-50L, -6.0857148042052277604035466987369298e-53L, -2.4898089736722146606232085397625384e-56L, -6.1598620863170544290033299759018975e-60L, -8.9214127072226711903218542175348322e-64L, -7.3072243260040451389778049479673039e-68L, -3.2625608625513858480451119539754283e-72L, -7.635785144983622496088267971984613e-77L, -8.9855174690288197015625761302053014e-82L, -5.0858718515487289997949540667405475e-87L, -1.3207396001984761034417395177214725e-92L, -1.4964864935610521348123903353455889e-98L, -7.0129233669310880373145304240642606e-105L, -1.2839990161964174973579406866396101e-111L, -8.6445683841052002170413994851536565e-119L, -2.0063694896831555279614790770285332e-126L, -1.4987740796184447811135706015205434e-134L, -3.3493762149589610757447357005516387e-143L, -2.0715294381434481475176795645059666e-152L, -3.2638832593319965098529982282696874e-162L, -1.199473759889723458030222815758102e-172L, -9.3602085584027101517846387151893588e-184L, -1.4035094428007866386369967794759254e-195L, -3.6356107639491247696753307742986431e-208L, -1.452743995741226464980668915527686e-221L, -7.9377235820922308566742845525117486e-236L, -5.2163536229754499795136126103956784e-251L, -3.5964743752577816321270751238997225e-267L, -2.2494401025357803105700529744520824e-284L, -1.0932895122313467863909046216907507e-302L, -3.5018653663752920075194010313564247e-322L, -6.2028644584939181030730328594330175e-343L, -5.0411076779076593359744388314869213e-365L, -1.5409305985666377552321629186300452e-388L, -1.4337691700836957601785568351756479e-413L, -3.2419333785971000532922906392702739e-440L, -1.4016483469785082716612467122698103e-468L, -8.9774004157156246399741480681783078e-499L, -6.491677776744900396848653659323143e-531L, -3.968873851900238121124736680679859e-565L, -1.5079636812339879861399394077308116e-601L, -2.5657520984549883455506649942306167e-640L, -1.3792637739621433541997914448762973e-681L, -1.6159468091505698350217369718439518e-725L, -2.7790201117578232055517503438743301e-772L, -4.6058286485158911464074200874638533e-822L, -4.7006358553201903008219637676007764e-875L, -1.8338935012250262258997114428219912e-931L, -1.6464242001502528395088533240159331e-991L, -1.9816419848867601423745192888068803e-1055L, -1.7991094041844603532543957306249989e-1123L, -6.6797992361969494675858665124683032e-1196L, -5.2859098848402526633383865829249954e-1273L, -4.4550261847470794285196049926646754e-1355L, -1.9109438945105886059290808709178883e-1442L, -1.9007367698294334902014013473010713e-1535L, -1.8987324425640464476346787762173242e-1634L, -7.8167618149826855518169886771423511e-1740L, -5.1382521738908379784587542986497343e-1852L, -1.9655086052442019324819644975934904e-1971L, -1.4940998787039296124957637312415828e-2098L, -7.1913235695994009755126799768473976e-2234L, -6.4864369300175247147155547975053653e-2378L, -2.999946728125704672445599927700136e-2531L, -1.7904880802749365558709955426180586e-2694L, -3.1752504880744458148875772810912828e-2868L, -3.5042626554286023022035386575033303e-3053L, -4.5572536942770532680494362978923935e-3250L, -1.1878504044248058672204846884752448e-3459L, -9.4149599587707022465535580134518114e-3683L, -3.0486081328912260971936320312995529e-3920L, -4.7600871041282300101380551251356845e-4173L, -3.6856282214670996203899028095741989e-4442L, -1.2567068832608339131427238307321809e-4728L, -1.43352474798599180975125045215869e-5033L, -3.5192846690056568230804624618996538e-5358L, }, + { 0.024539763574649160378815204133417875L, 0.073525122985671294475493956399705179L, 0.12222912220155764235135543647484308L, 0.17046797238201051810697458795462942L, 0.21806347346971200463019772812275949L, 0.26484507658344795046121266511868619L, 0.31065178055284596083122357022827612L, 0.35533382516507453329875421158518394L, 0.39875415046723775644258197210456498L, 0.44078959903390086626728024419415105L, 0.48133184611690504421849248706653226L, -0.47971194930876984042437695635737165L, -0.44241877173922176919985653200857201L, -0.40684964640804684120174768961798095L, -0.37304979194895712050380997331064448L, -0.34104900825664987561685714614383599L, -0.3108622749383323282394733757479914L, -0.28249053251267587278787801637860204L, -0.25592161645265260087450443652530469L, -0.23113131323175341540544311864007538L, -0.20808450762385788552523390287482686L, -0.18673639149702614832471241636026165L, -0.16703370608058912436398702772140703L, -0.14891599201215126738569202826103709L, -0.13231682422435401330546108424048627L, -0.11716501175533104486690697891318309L, -0.10338574571992397421289522925754423L, -0.090901681836979564888397733057112044L, -0.07963394696804719765304016834176825L, -0.069503062002846593688614128282605538L, -0.06042977606672524461492007773726152L, -0.052335809384846902663067556129352578L, -0.045144504194977314593201232656013596L, -0.038781384848883592468460207166535186L, -0.033174629687644147159978329404393879L, -0.02825545843451269107668693235164557L, -0.02395843974342326066584697335177699L, -0.020221724199384237353497637367719603L, -0.016987208518898894423060324544850119L, -0.014200636974716564032303584519259449L, -0.011811646199257357569283265398947793L, -0.0097737595324722530639024866802767264L, -0.0080443369973223843798692318964963564L, -0.0065844868307359609987086057921138135L, -0.0053589442874888032779151584247851277L, -0.0043359231830468303521751643564073944L, -0.0034869453597462268271205586183706831L, -0.0027866529565312977632015610760207467L, -0.0022126080410934691734971443584643208L, -0.0017450838280037065615903399860968624L, -0.001366851359322522377124006197840537L, -0.0010629651664878262735108241097275379L, -0.00082055106511408284244272347987383953L, -0.00062859885906231310357940554216565142L, -0.00047776234878279577588863291489417448L, -0.00036016865439963480978268344017946398L, -0.00026923848019151736959880088820900265L, -0.00019951856886161369803218944988361524L, -0.00014652722688858828517464005147727694L, -0.00010661345240743574350860189665463426L, -7.6829870710671305672093252530903342e-05L, -5.4819385541306910394346187661030795e-05L, -3.8715192143333868407124859677345036e-05L, -2.7053574767763435703448594138071512e-05L, -1.8698729879273208281214887386151327e-05L, -1.2778717999371889596874911057724209e-05L, -8.631551655126555923485540179705975e-06L, -5.7603723833652179866412085097651011e-06L, -3.796652833823246921587494391038503e-06L, -2.4703761948320696741670218229372071e-06L, -1.5861890352645758023485712079757291e-06L, -1.0045893100303765084297472484854592e-06L, -6.27292664630529591934671730489378e-07L, -3.8601144975725102288841415591950667e-07L, -2.339766675668795211736366707138927e-07L, -1.396287854005922888135986291920763e-07L, -8.199520528943774856188619843122174e-08L, -4.7357335538151973999955685632054965e-08L, -2.6886764056376916830145130602254872e-08L, -1.4996923688266632451823595335560501e-08L, -8.2135439009280190432084662337190249e-09L, -4.4143663841612464008735244035118061e-09L, -2.3267632621004612298287053849704746e-09L, -1.2020164996011407668894632352766295e-09L, -6.0822312416778615105389374826677738e-10L, -3.0124563074832322562803735802769698e-10L, -1.4594388450012857143914599919653952e-10L, -6.9111604985231078666967248228438538e-11L, -3.1966783264445369722850429235278972e-11L, -1.4431209924042652494507345459464675e-11L, -6.3536761284911814276716019591237312e-12L, -2.7259505188725197201090431322689677e-12L, -1.1387345722407849659711071645809649e-12L, -4.6277346217693134290561172417433117e-13L, -1.8279902248431104840099026765769527e-13L, -7.0120467384905686087185698802558123e-14L, -2.6096053661379546374618820988626935e-14L, -9.4133613352888555760685465264560536e-15L, -3.2879256949364934203905795056053052e-15L, -1.1108629401821898431250973198964316e-15L, -3.6266022642032122019717830419062828e-16L, -1.1427876525052669863279877707280153e-16L, -3.4719022692494936795924113147604942e-17L, -1.0157819068305124587449297554375856e-17L, -2.8585328245081481739274807557448345e-18L, -7.7278347873892552568443785071813692e-19L, -2.0044239922175172204979314952837677e-19L, -4.9815683764699114931038226437577286e-20L, -1.184668492422340236764487382599448e-20L, -2.6919849036103905707012031384082434e-21L, -5.8366674419339414129894129738889481e-22L, -1.2056615886548723513354371860285751e-22L, -2.3691093508078067650593562318134397e-23L, -4.4213394617280017751359368167258193e-24L, -7.8238350041086858182189611432466241e-25L, -1.3105331441254781548552012055519121e-25L, -2.0743450130735150739962743364500278e-26L, -3.0969683255507495828369632528319965e-27L, -4.3532005281967559757740065310127852e-28L, -5.7499556680703922900693138751854555e-29L, -7.1227159266381727412068631384345687e-30L, -8.2578354203558045768004451321024521e-31L, -8.9415410066249555437647937669966689e-32L, -9.022796650030866974265443296162775e-33L, -8.4660301195315971752688615420135191e-34L, -7.3692728065645298168617836618124666e-35L, -5.9366323560088749776278557840220755e-36L, -4.4152778386946959545381237143455402e-37L, -3.0239601358635314916964716581634168e-38L, -1.9022037916577048792943667867798758e-39L, -1.0960433286034577882548963198643229e-40L, -5.7686955980040694827320797355280285e-42L, -2.7653993817377102211887943260200603e-43L, -1.2038709528562574051108458784307785e-44L, -4.7447623253354987177832150988795395e-46L, -1.6876791281053309141043851984778909e-47L, -5.3999669982997284808706183365024646e-49L, -1.549024049448082614346506969629423e-50L, -3.9699472552561349765465127201129129e-52L, -9.0576749265239358552559531050991564e-54L, -1.8329504334836931380757353284221911e-55L, -3.2774223323973643896776906795254206e-57L, -5.1576871530839363640889147624270212e-59L, -7.1147152214081979999932108600174644e-61L, -8.5668890171210249323533230713364891e-63L, -8.9655585542113618588233770236885955e-65L, -8.1186937969054743805236701211415782e-67L, -6.3321938859077339155825561128906228e-69L, -4.233726342460328087225876085667347e-71L, -2.4147260464376790196845134616759282e-73L, -1.1689555910948214525778546914101199e-75L, -4.7780668985526446079787318493898922e-78L, -1.6402035716952158990309656043758773e-80L, -4.7024891487642105081472609988004035e-83L, -1.1195904670077980724005196979590736e-85L, -2.2005433507330024992345876236265894e-88L, -3.5489240240632636451154177125584074e-91L, -4.666940936883651858001572120481125e-94L, -4.9719066745930336256015501390182822e-97L, -4.2625120032373619347908954864791867e-100L, -2.9205525410269401160683450458899041e-103L, -1.5879283520520673524672134768919763e-106L, -6.8010328774211569659959576053742516e-110L, -2.2772324163917691950189307132002393e-113L, -5.914722281629598175795438531560773e-117L, -1.1820998217768840832984056598978546e-120L, -1.8028262273951398891886168129927287e-124L, -2.0802041335110124193794970445396975e-128L, -1.7999670156396935596364355347029528e-132L, -1.1573419660682545435402292296632314e-136L, -5.4777666541440989994081254549149894e-141L, -1.8900190812332372959031760309750191e-145L, -4.7064318355746675546808068910291556e-150L, -8.3711291364376416570212981885601003e-155L, -1.0522139008817658534084763162543628e-159L, -9.2441193400981258043604322474285494e-165L, -5.6121650181326378940737135740792016e-170L, -2.3270398424370294077224375501608811e-175L, -6.510721186743015604234587537579044e-181L, -1.2138997008699255952666017192674735e-186L, -1.488912999352695867344311698561554e-192L, -1.1855378186700107100267028475666946e-198L, -6.0445584657932328676234962000989188e-205L, -1.9456793188673556729031520231103262e-211L, -3.8966805747095113950686230057410173e-218L, -4.7829220009546143710431038737748715e-225L, -3.5425595917324118172041028901087466e-232L, -1.5581260191174140607938473801301532e-239L, -4.0028071638967508676664829682660027e-247L, -5.9046000382762171283315920864186447e-255L, -4.9139618035200235196744932808885781e-263L, -2.2656744698055742315406349324984012e-271L, -5.679971707464259613069663431618014e-280L, -7.5941261723746109223402306020806232e-289L, -5.3079378188778939332566204780962363e-298L, -1.8999778173084169834715816327210827e-307L, -3.4097331110687592869362387676073128e-317L, -3.0013940393884085654083505783337316e-327L, -1.2668812065800974411227932737003665e-337L, -2.5051097865973858424963978994105679e-348L, -2.2653835286828392416879577941979414e-359L, -9.1389245527311981300218270087623242e-371L, -1.6030930250662823526442537954011133e-382L, -1.1908341901916029371925944757292412e-394L, -3.6452473980708905026093050166205199e-407L, -4.470581799337985564576477205041097e-420L, -2.1337946766915608745979583351759322e-433L, -3.8466502387371814478842876774875617e-447L, -2.539400648443551278595315008859673e-461L, -5.9463310120354055195604938583173969e-476L, -4.7791154462039743101535253283672216e-491L, -1.2743368238366444127980835826074082e-506L, -1.0885513756896925921766278125740167e-522L, -2.8730852174104725878401965901098976e-539L, -2.2573125874160702024258126565183851e-556L, -5.0801120877688108677556596022448958e-574L, -3.147442313458971094095441973453258e-592L, -5.1530284704707320518750575728196905e-611L, -2.1371769888513739266688394459294633e-630L, -2.1496221573881902238982422615825289e-650L, -5.0129928677987666360823382488243001e-671L, -2.5875873756026443959521949570534425e-692L, -2.8181620714067187431385929758736621e-714L, -6.1639625895204988083360964770898867e-737L, -2.5730385846926571409465774477581834e-760L, -1.9448744127295675669050254780849454e-784L, -2.5213762798933993822025230917884045e-809L, -5.3012546029922448380589857164083814e-835L, -1.7062280322013794538523703018620566e-861L, -7.920258584822147757302618208276618e-889L, -4.9864409544476492068060565707730923e-917L, -3.9962146024411971515483669014007722e-946L, -3.8185388383865818601310492618971832e-976L, -4.0664680142829823697989791072662443e-1007L, -4.5015287529024162764736783373823692e-1039L, -4.8207630344098447587536323292213823e-1072L, -4.6375061995611002272610193821937293e-1106L, -3.7123073076807703361397549566488692e-1141L, -2.2851629967300820983086928617773692e-1177L, -9.9710151392993821636927693831761909e-1215L, -2.8354564442635450405718863241322006e-1253L, -4.8186151533506508630367161348238245e-1293L, -4.4750346397724178706383092717200537e-1334L, -2.07096024490079588158927973820168e-1376L, -4.342127308884323517312819302082545e-1420L, -3.7387854726872903857603805318252205e-1465L, -1.1946574634186879393921342144260135e-1511L, -1.2759441657028066718211573051988164e-1559L, -4.0892575258067523665855842405306752e-1609L, -3.5183875354871145031995454351438789e-1660L, -7.2453069573873944421690184084196628e-1713L, -3.1719634253495420624848681187846285e-1767L, -2.6125752080330097261369292566212969e-1823L, -3.568653966381994484787922096951618e-1881L, -7.0977732480251336872758023077199559e-1941L, -1.7972768141068333989152413556564914e-2002L, -5.0445828237798979207114411387487754e-2066L, -1.3604595412453945762407996412329254e-2131L, -3.0419951659449528528023254177983519e-2199L, -4.8436592014037520285667566761754706e-2269L, -4.6942170473823597199914323005808658e-2341L, -2.3550263329098316285032485977513203e-2415L, -5.1749636831144475403049010950928176e-2492L, -4.1920868885180451051347682697190622e-2571L, -1.0479018787402586343779450171950524e-2652L, -6.7279428066803227116834111695132562e-2737L, -9.1809880505079118230638356660916729e-2824L, -2.1903121606778754894644610552460375e-2913L, -7.4679789664508998469723121247024705e-3006L, -2.9557873617341136266023224346917197e-3101L, -1.0958275239557229340575496309183988e-3199L, -3.0498491351714004349547292302889343e-3301L, -5.0710549490564658785365657190857463e-3406L, -3.9798833012314432652288251577412562e-3514L, -1.1561503564308970430488476029765637e-3625L, -9.6738350948812768619787679276120515e-3741L, -1.7998403785619766408556530850576782e-3859L, -5.7011595100947685691764189814097789e-3982L, -2.3342553026008523985584602356036335e-4108L, -9.2972354921660563358009254715497299e-4239L, -2.6867404349734172649970964993288437e-4373L, -4.1626263982921541967696302677355217e-4512L, -2.5305298537002028475606439113724333e-4655L, -4.374081747920579431517607591486263e-4803L, -1.5419945401212975573693263841002279e-4955L, -7.8687813783350283818994253864974705e-5113L, -4.0807753246747505208452672626580765e-5275L, -1.4931173692359951169542729406105663e-5442L, }, + { 0.01227135511808220203174030407830294L, 0.036802280950025085014502801868003454L, 0.061297889413659975774096037893250044L, 0.085734754877651055755695461536205953L, 0.11008962993262801258027823870142222L, 0.13433951528767223660361301319755489L, 0.15846172828929950397368299153321965L, 0.18243396969028915021484585689969531L, 0.20623438831102876939480559034293115L, 0.229841643254360753698787981399908L, 0.25323496335600023568199079816688852L, 0.27639420357617861412235821455333865L, 0.29929989806396047268181013419640459L, 0.32193330965336916623041220093195644L, 0.34427647557970491862490100675820811L, 0.36631224923490408185795345459447966L, 0.38802433781211774758659161520378721L, 0.40939733572152948912988463410721733L, 0.43041675369143706432580814661825066L, 0.45106904350045199476872844990592136L, 0.47134161831799846568675411549444037L, 0.49122286866081148740164998519670023L, -0.48929782599744185793989666371765164L, -0.47023008989822544160728474574480754L, -0.45158254786020764535461909038883739L, -0.43336282621498114195428483532083889L, -0.41557755767733605834276062792428588L, -0.39823238999036654097849262723755211L, -0.38133199816727193874162067315553426L, -0.36488010013557816387677409414947586L, -0.34887947557569577047526159126703565L, -0.33333198773426231868095335844342399L, -0.31823860798357268745316074354464261L, -0.3035994428915407927086292160567468L, -0.28941376356199421334543326775454705L, -0.27568003700259251963348266210052998L, -0.26239595927717475510166267033301246L, -0.24955849020075956493410868722363431L, -0.2371638893386076311859247952179354L, -0.22520775307556463019220672947952605L, -0.21368505252818039398938452749375662L, -0.20259017207968775297648115336201576L, -0.19191694832666146249702413953519866L, -0.1816587092359021720484117453151821L, -0.17180831332064290072992681330484534L, -0.16235818865639997533663276272992352L, -0.15330037156853630364404549106194642L, -0.14462654483572846910471674072111206L, -0.13632807526589476511715224673350004L, -0.12839605051362228117619033241835825L, -0.12082131502061062975401342241486234L, -0.11359450497302129819348705755904515L, -0.10670608218178901767108607508338614L, -0.10014636680382986857859380586600253L, -0.093905568833595799431451407446515619L, -0.087973818305513180839892673963966241L, -0.082341194158450660178436474882477694L, -0.076997751723445596499983664621487996L, -0.07193354880544487378738311657933671L, -0.067138670338759945862672351268719341L, -0.06260325160428086186052507865402345L, -0.058317500004230664509200379313199518L, -0.054271715397367759935086056389293555L, -0.050456309004063640355911746580908904L, -0.046861820896606197349996098751978814L, -0.043478936095419069610563231210812888L, -0.040298499296663390818673202062521126L, -0.037311528260921730030179369385366989L, -0.03450922589637952691206152682222172L, -0.031882991073143683811495499895307175L, -0.029424428208099579660135740086865642L, -0.0271253556620361184294276412754116L, -0.024977812992693650455170906326981392L, -0.022974067108942042492683430416652371L, -0.021106617372505970898624990276714523L, -0.019368199694551294992954740677403882L, -0.017751789675058934941049112986218163L, -0.016250604833268754660069071624504775L, -0.014858105977601971243228436688712421L, -0.013567997763391553658409398729735747L, -0.01237422848648931564729341766812544L, -0.011270989160397638106454864191015908L, -0.010252711924012903699062738821083185L, -0.0093140678263849278340314349076327353L, -0.008449964034108265248268117472003357L, -0.0076555405060818245590132017863229384L, -0.0069261661794155687412632471018391501L, -0.0062574347092383891891208397242483686L, -0.0056451598040791099606160787309638234L, -0.005085370197361128404963242365624777L, -0.0045743042943771933124154458548517366L, -0.0041084045328997985361611689079751989L, -0.003684311494339074782205923019899892L, -0.0032988578010873948724575222465114151L, -0.0029490618343908704733333873759063219L, -0.0026321213057645656305833925217639785L, -0.0023454067136221407000743728815804873L, -0.0020864547154229734242597171162514598L, -0.0018529614442515743960802739125590691L, -0.0016427757973362357767337812404644128L, -0.0014538927225872833069713654109330111L, -0.0012844465277911570122332123844688455L, -0.0011327042356361946956708854910717802L, -0.00099705900627114148706364731704457709L, -0.00087602364761017102176873850865987398L, -0.00076822423210114801927833212686428566L, -0.00067239383717004607961542674246453911L, -0.00058736642504742093080174568452091253L, -0.00051207087617669287572188257954358842L, -0.00044552518890326020005629570593666048L, -0.00038683085665314188976467566548793199L, -0.00033516743233532263998791108562179822L, -0.00028978728824896558062724060959821788L, -0.00025001057835114127416442774611755005L, -0.00021522040834883412191823299277438955L, -0.00018485821772693895358504217864611182L, -0.00015841937651793126628162990110989201L, -0.00013544899836493134204129687787204532L, -0.00011553797023379563893736144870607114L, -9.8319197997130553498037999641991487e-05L, -8.3464066048770978005196778706600799e-05L, -7.0679108115811218906095134416154613e-05L, -5.9702885520625386671791420435362921e-05L, -5.0303068310699595343932915440924077e-05L, -4.2273713922018120404243909635658711e-05L, -3.5432737373923361833214162324345645e-05L, -2.9619566410724316247858190357851524e-05L, -2.4692974507962358657498919760422057e-05L, -2.0529084248443619898457582669713841e-05L, -1.7019533243403755023062694063359981e-05L, -1.4069794525207501119432380528847431e-05L, -1.1597643166806136977541673876760615e-05L, -9.5317607861225334492481477207976067e-06L, -7.8104695663539218978433615931904191e-06L, -6.3805874611085194148542316667027636e-06L, -5.1963963511236276943307284768443108e-06L, -4.2187150715072772351343816215627715e-06L, -3.4140694292103354602072245113222152e-06L, -2.7539515738216143655929212361430556e-06L, -2.2141613647700348500196752438228238e-06L, -1.7742226886238416354636940930406071e-06L, -1.4168680155127991206906010386776301e-06L, -1.1275848380651233667302406751686147e-06L, -8.9421800420026716637883889021333717e-07L, -7.0662233151961419975116851767251182e-07L, -5.5636027112312322628504802544396849e-07L, -4.3643976809083996211611047940700884e-07L, -3.410878406808352344192770488162828e-07L, -2.6555576704383762368205974553664254e-07L, -2.0595212394180990975114609016580268e-07L, -1.5910026405413012262681483592072574e-07L, -1.2241714489336877307229490096356811e-07L, -9.3810731511298667657736474465916103e-08L, -7.1593485856820748829676007409030264e-08L, -5.440972704881531639917700413368612e-08L, -4.1174898509745034636641901499637178e-08L, -3.1025009758847405806336107058366646e-08L, -2.3274732865051716886351304700372955e-08L, -1.7382826537542006005418736935360821e-08L, -1.2923735225028943169773355461941788e-08L, -9.5643672141012475959697164491130902e-09L, -7.0451955080630225653421587634231792e-09L, -5.1649492757248395049197216720378741e-09L, -3.7682729974336732148768443187202036e-09L, -2.7358262541647042643058722243498035e-09L, -1.9763805681294590078061949445779507e-09L, -1.4205419635481505647172465852581089e-09L, -1.0157900987858722132374807163656952e-09L, -7.2257800679698977337008871109952299e-10L, -5.1128169466802636753557604076122797e-10L, -3.5982705512040164549431243047583567e-10L, -2.5185362244554210229589301236053854e-10L, -1.7530147750309255605734608915901604e-10L, -1.2132981051324705363357105718720941e-10L, -8.3493950752320668610647319362559637e-11L, -5.7122660267481958430713410881095016e-11L, -3.8849686002793765883588257767026493e-11L, -2.6263427379949721354783426839588953e-11L, -1.7646499776378976222245772521934802e-11L, -1.1783298320120630850539029584309311e-11L, -7.818680628325362638575521404267539e-12L, -5.1548364042751350429076854858018077e-12L, -3.3765014608000294669628289654725219e-12L, -2.1970744699592342642466439966825033e-12L, -1.4200473669518126870628306394495551e-12L, -9.1158007933577728676134065579326132e-13L, -5.8113062505586808310528553401168741e-13L, -3.6786791102075633999543555381361719e-13L, -2.312068903576444768213986586668492e-13L, -1.4426172485922308843621431499934686e-13L, -8.9349666651298939216456676750565829e-14L, -5.4925677721256790529564920614679325e-14L, -3.350788309515877062958811342787956e-14L, -2.0284076402444039895928235924589244e-14L, -1.2182795128979644452912696549518128e-14L, -7.2588537362052341752692102123089101e-15L, -4.2900627866036669128285279549303027e-15L, -2.514652539480771341683046756355483e-15L, -1.4616871128475335847732485959402402e-15L, -8.4243309583746983103209365972381765e-16L, -4.8135175904015314514321104340303263e-16L, -2.7263179430684054979795995181696999e-16L, -1.5304422973965932233677561227408377e-16L, -8.5137857250384433997363815737881969e-17L, -4.6927950389611427068741326969599031e-17L, -2.5625975950320089549856176296445119e-17L, -1.3861334667950396744809652330676689e-17L, -7.4257501921384642292801069180083189e-18L, -3.9393094024445601833019849790813999e-18L, -2.0690791459774228199242128751668536e-18L, -1.0758286216493138282150652273565844e-18L, -5.5366710173011999504598745894506669e-19L, -2.819834003785898432921699582824987e-19L, -1.4210063750313593796726974809925319e-19L, -7.0842438781417380233044623416891119e-20L, -3.4933505573095044526616590274445578e-20L, -1.7035977510820099431072120902417317e-20L, -8.2147060442121877800848286483420634e-21L, -3.9159734384156989690338293870539541e-21L, -1.8451498156271871363001830659526856e-21L, -8.591874580623540129167786895666899e-22L, -3.9530069577065764915635262899095704e-22L, -1.7966697995134261385398916631645912e-22L, -8.0654088208389219862969348472697735e-23L, -3.5753372122620560623243551587275021e-23L, -1.5647821323387363967354776667279086e-23L, -6.760041764217369644940988147273804e-24L, -2.8821363233025547133119762203866565e-24L, -1.2124362329062417813651773042222047e-24L, -5.0314218307880599929168429579030218e-25L, -2.0592863122450067780181162680466505e-25L, -8.310787797639985481399920298561774e-26L, -3.3065180676145941342573597126851257e-26L, -1.2965973462467399413826706323859068e-26L, -5.010091032398552312889055575499255e-27L, -1.9071793847355632162575945250968826e-27L, -7.1505673339810973649967867585100117e-28L, -2.6399060373682682300772738413986419e-28L, -9.5946645421591590272737060192787035e-29L, -3.4320780991310649618469641664780934e-29L, -1.2079850663067081309863651387341263e-29L, -4.1824647214881752797125541962674838e-30L, -1.4241537066844817617919365428875337e-30L, -4.7678333816988133611599026436806048e-31L, -1.5689491781958062283731284050971648e-31L, -5.0734388548496443499288192319785528e-32L, -1.6116919160939245706339600215608967e-32L, -5.0283566942543780691617432163678683e-33L, -1.540320437147141644686176099192533e-33L, -4.6313924434817901733319954389626016e-34L, -1.3664702250574194828136706303116849e-34L, -3.9550085269989845845237677023544696e-35L, -1.1225918253644008151328041096174431e-35L, -3.1238487433616834059785879847016762e-36L, -8.5195402472064902632510499781952803e-37L, -2.2764734813775829740707091909282255e-37L, -5.9578473858349842310952826931317941e-38L, -1.5267023004586063974485430859996629e-38L, -3.8292452373883691255032248372279562e-39L, -9.3976484123312742513645018653353223e-40L, -2.2559187023391247540357057603608445e-40L, -5.2951057740070273455910884012728247e-41L, -1.21484005139195805370253212205352e-41L, -2.7233329057563859457781652894773382e-42L, -5.9629474724550016648059026687365969e-43L, -1.2747904563208401684090170257821763e-43L, -2.6599324647740072572781740009475107e-44L, -5.4148975705500338800900730270033864e-45L, -1.0750506783792922201321365237207054e-45L, -2.0807277332937164031945232093695697e-46L, -3.9244163140436388041993251545689042e-47L, -7.2099378100469390278450504220931707e-48L, -1.2897482330918123669983337886382095e-48L, -2.2454989700172052890162893888242529e-49L, -3.8033817751932373827258462682395899e-50L, -6.2645207667921988981079909974995822e-51L, -1.0029410834924645721226614397473029e-51L, -1.5600495091009386993988441513950677e-52L, -2.3565650292912781888129806450540921e-53L, -3.4553986153009958542696149938952582e-54L, -4.9157636744396300209125008789737936e-55L, -6.781896900608377888472479708032872e-56L, -9.0691940202443643747199815355477207e-57L, -1.1749792443564338073595948464279018e-57L, -1.4740730312062593807916913990480482e-58L, -1.78984329859422798255692388149323e-59L, -2.1022998433631042036525885470222986e-60L, -2.3874311701754330999376394091254256e-61L, -2.6199497113269397601815392049767616e-62L, -2.7768131253969855575381129113408787e-63L, -2.8408870962885800781023815369817483e-64L, -2.8039688883465382638228147703461371e-65L, -2.6684481602260540322238895901981613e-66L, -2.447154080870857351995438102206883e-67L, -2.1613619398610954911634747438934054e-68L, -1.8373843424142226299889606750473108e-69L, -1.5025103938453805607949990395131202e-70L, -1.181175530500916159109188924367755e-71L, -8.9211577919430036730810594588108188e-73L, -6.4693987201487320046787049136480794e-74L, -4.5015731884566473782551022645592059e-75L, -3.0035842209914330912805318957189823e-76L, -1.9204515997414609573256145075523711e-77L, -1.1758810849678264495241195391760596e-78L, -6.8900721571551738196701537405845152e-80L, -3.8608563387442272849431335779050044e-81L, -2.067461647504548936055359104346581e-82L, -1.0572431033554667452601572946421337e-83L, -5.1591788391388680011549213529878416e-85L, -2.4006807351389258318746737135895233e-86L, -1.0644152130176148388326772258538689e-87L, -4.4934529232365451766727877769969084e-89L, -1.8047048722799212873442491872423271e-90L, -6.8904595506732549720140200562795596e-92L, -2.4989637101487869067392480430274382e-93L, -8.6018088469863275574189994840620463e-95L, -2.8078924862967821005632597982452309e-96L, -8.6849867519796128933390271698765342e-98L, -2.5432396109247561096829294407826966e-99L, -7.0446668978619724438762397385539258e-101L, -1.8442018255867670937882313596001159e-102L, -4.5587416725253559276425131397074849e-104L, -1.0631088555204592085750091746032982e-105L, -2.3367281748964035585738800969158434e-107L, -4.8365042631130861220456426369022544e-109L, -9.4175235620877562064839942442771856e-111L, -1.7234789461694177262894389768372263e-112L, -2.961523379734186944047236046386456e-114L, -4.7734609518585313301965336240248189e-116L, -7.2097952822898640408181240050284012e-118L, -1.0193874335777637006841936637337494e-119L, -1.3478166999163432272267137132118888e-121L, -1.664711300732456447679638084338044e-123L, -1.9186583950476330921591900813216499e-125L, -2.0612648015288569084831497840721453e-127L, -2.0618953788663489533345425995316527e-129L, -1.9182619555236359873955912398757981e-131L, -1.6579128778519222560290325566834437e-133L, -1.3296099070094495947742421798539638e-135L, -9.8828871549374803987116212190790475e-138L, -6.8001851936680182899829217843093739e-140L, -4.326204276337993340016401440114041e-142L, -2.541595528522972170757701141043585e-144L, -1.3771279659495821106478129347836407e-146L, -6.8731739624384578591538313057486772e-149L, -3.1556844841718302469140036866580175e-151L, -1.3311046015007009547835866736304136e-153L, -5.1514958005010918440961548583793399e-156L, -1.8267037628056442215789990487980127e-158L, -5.9267728539858017097499689403281403e-161L, -1.7570179057820636782453206639159588e-163L, -4.7525273644644354076088841580861234e-166L, -1.1712151180634311771192081451244071e-168L, -2.6258838722203054808989693856617573e-171L, -5.348036158420190530754215189932846e-174L, -9.8795260619978679822138888646044246e-177L, -1.6528501557776328068085680725354548e-179L, -2.5003947565086958266446692572037419e-182L, -3.414859619193216220277979880289186e-185L, -4.203653605459133226010277835528306e-188L, -4.656508257021667283525304276478024e-191L, -4.6339530996535525354074849617025537e-194L, -4.1358781926049696182200878642464924e-197L, -3.3049447294950072208241398344574307e-200L, -2.3603956208589999494122184847510332e-203L, -1.504047014068835401149660217771386e-206L, -8.5352021958508046391358762569456352e-210L, -4.3057568200632214990724928361534485e-213L, -1.9273628185121124753795720186090423e-216L, -7.6407868488415044113016735817166107e-220L, -2.677582009683177696032426651320389e-223L, -8.2781625043007349263821040953856809e-227L, -2.2534850368391124035175853226989187e-230L, -5.3905685902076735531578346280529237e-234L, -1.1308097276815650308355193143392165e-237L, -2.0759721813705410476824570327172646e-241L, -3.3282687604583975257076029809432931e-245L, -4.6500067135453696640703738061616968e-249L, -5.6491873692239596907540663618927003e-253L, -5.9546966626331923325761672881695778e-257L, -5.4337990425534927929347405657826422e-261L, -4.2828363537638634149994842306436067e-265L, -2.9089854251520548595336724777976923e-269L, -1.6986979835072953491948167874994245e-273L, -8.5078874736023215648629448861985246e-278L, -3.6459301611001785382074525089193986e-282L, -1.3335508003947114825747939690317958e-286L, -4.1528110309781799510004618371028852e-291L, -1.0982617987267680462918374327390562e-295L, -2.4602717457871291167756856167595572e-300L, -4.656274386497415739809125734407304e-305L, -7.4253896458167870494540985632704167e-310L, -9.9507057756639922437150285707977622e-315L, -1.1175135227544318386694717687968224e-319L, -1.048835867763772555877163638261832e-324L, -8.2033390786966798682011027925866189e-330L, -5.3315735131149564162074506318716251e-335L, -2.8710141330746883154448723258150022e-340L, -1.2771564172267081609509990200434409e-345L, -4.679237231988855089392537021634395e-351L, -1.4076706654157792032739797667966913e-356L, -3.4663625720057878756572289263095777e-362L, -6.965054539543846678373236132189486e-368L, -1.1383132196432715526434302555043402e-373L, -1.5082487448329479128870155332131625e-379L, -1.614816076667686258793882820784337e-385L, -1.3923692408287144362457422616397937e-391L, -9.6357705989726650954351553689911432e-398L, -5.3335362887861762022108923833857644e-404L, -2.3529529322735497728866304144280939e-410L, -8.2438250199447939690869259289572704e-417L, -2.2855238208173770201725378922268636e-423L, -4.9955499211081324148253281714818585e-430L, -8.5762081046608095383619080676476731e-437L, -1.1520466338982341020319294100361546e-443L, -1.2062291598612346324429863879453543e-450L, -9.8055160740422284599044523336543234e-458L, -6.1639765190753631642664330172075405e-465L, -2.9843045493133686661298629930164973e-472L, -1.10823285826398300175507717773449e-479L, -3.1434790244922162638267628745063788e-487L, -6.7817090417200778282332735946819014e-495L, -1.1080137352329998556662834370761201e-502L, -1.3649835831781010441492893639688094e-510L, -1.2622778335796144231373603506854352e-518L, -8.7230079476014413312144088584965706e-527L, -4.4840352485865235615809427931860355e-535L, -1.7066304212439665043951442710341263e-543L, -4.7865441809026242359826342326024693e-552L, -9.8452970343625269250999633839131245e-561L, -1.4778790578536059527306608667934244e-569L, -1.6110092952268207636105891878784886e-578L, -1.2688728710128977236628155987138424e-587L, -7.1841678295696924944920506687608424e-597L, -2.9088109305034413675847131931270509e-606L, -8.3780318645305679545954425238306175e-616L, -1.7073663715760515568257862032253151e-625L, -2.4485200806811154999909042531599294e-635L, -2.4573647256627145606915141874939106e-645L, -1.7162616532700922219515556951255632e-655L, -8.2940336462928562559347382857731944e-666L, -2.7573883713227551117703313812478972e-676L, -6.2693384642795198624500212806556514e-687L, -9.6903310752055252797176389760001952e-698L, -1.0120668627816313397657974563178381e-708L, -7.0982696439175036135044214112413552e-720L, -3.3223490979680344536621296663739436e-731L, -1.0311489910731877825037981367801772e-742L, -2.1084888364587342412345374253683016e-754L, -2.8218960738946335538305090801367889e-766L, -2.4554534404272344111007341068959851e-778L, -1.3797451463824018308120568764941013e-790L, -4.9722352119016468411483808073270903e-803L, -1.141174632389420312821039197546226e-815L, -1.6562061873208393415939125326414615e-828L, -1.5090517973695404620062521847072836e-841L, -8.5691467995207824570732116071300356e-855L, -3.0100992462861676532185696320551197e-868L, -6.4915591914227985933992989098330185e-882L, -8.5291480289311605733387922175211764e-896L, -6.7742561345607759008586516480118676e-910L, -3.2268177845742615217916640601654205e-924L, -9.1442367835386354685297667090946292e-939L, -1.5290755306231257347546172504187466e-953L, -1.4962742317658249855750971462991461e-968L, -8.4962983613273098681909435342233043e-984L, -2.7756354317962233287713988508361331e-999L, -5.1716412864088598574901876510481632e-1015L, -5.4473756239469544256829106354679121e-1031L, -3.2146847397534380657713310981627524e-1047L, -1.0532205872897567235295617558264118e-1063L, -1.8980407364210960924624682689327296e-1080L, -1.8638413013078585989318566769757098e-1097L, -9.878184707808045512821781472334627e-1115L, -2.7982877400590951555125003865089596e-1132L, -4.1953712551999192397935862947005203e-1150L, -3.2957901195530958784930344030449164e-1168L, -1.3428874261296622720955452657433921e-1186L, -2.8087996369552811844908096236163199e-1205L, -2.9843000347844479031722692316121269e-1224L, -1.5935747451543053300901499796204061e-1243L, -4.2306328294965009362324717933882302e-1263L, -5.5228314338471652594276889712636454e-1283L, -3.5058000799426290470482678197659356e-1303L, -1.0699175488609417213076569958022624e-1323L, -1.5518242259547372491845055361631511e-1344L, -1.0572462818562698193769229028835047e-1365L, -3.3433625974012960853422590535670218e-1387L, -4.8485886276278601232637821173583126e-1409L, -3.1852238059952872764052353398865978e-1431L, -9.361416530125180143871854771737577e-1454L, -1.2153997660730855590852157017720519e-1476L, -6.8815302334269492601957883930533625e-1500L, -1.6771176516091137975239852271122166e-1523L, -1.7361595430709725552633953103091938e-1547L, -7.5319512846392125534714956610857413e-1572L, -1.3507317243577349648175397566286196e-1596L, -9.8749002116827156793758713498543268e-1622L, -2.9017600444094134408965714990369305e-1647L, -3.3784846386968340746897973924953046e-1673L, -1.5359688750531830898643386942465616e-1699L, -2.6866527047176469998545109651176216e-1726L, -1.7810521996687791658708980830532171e-1753L, -4.4069918722394069695147388355206565e-1781L, -4.0074519225536368666632735822098734e-1809L, -1.3182831725717259025871898011803224e-1837L, -1.5438654487729921345949019930471491e-1866L, -6.332964675016807525269001303450335e-1896L, -8.9500787015064447527716544282145449e-1926L, -4.2852989232796780762796817666627905e-1956L, -6.8338809894056785809735926537843468e-1987L, -3.5675222855473848333391077011021476e-2018L, -5.9902029406713556414824109568504936e-2050L, -3.1778560977483191067544886656870642e-2082L, -5.2307612099795388778239926501377221e-2115L, -2.622585004749696786707859063948337e-2148L, -3.9309566721122472026471743065924237e-2182L, -1.7282752365752259330631889016659569e-2216L, -2.1861776117108222661355073061235227e-2251L, -7.8018157093958177389763723299669248e-2287L, -7.6999746209936272927151686536635957e-2323L, -2.0595655884579572710261610678442846e-2359L, -1.4626001721502482969651469854201664e-2396L, -2.7006580242811967764786623573354003e-2434L, -1.2693899148553691566069699600055988e-2472L, -1.4864297410986916900605959894904808e-2511L, -4.2424104158612592858897827763816223e-2551L, -2.886325476737890820535159860850169e-2591L, -4.5765223979102481270954678544866293e-2632L, -1.6528081850614599523381524655646053e-2673L, -1.328274798653407243855327660531847e-2715L, -2.3198223770931618563520410588946674e-2758L, -8.5957488899967850735558558018957728e-2802L, -6.5943404261286890309954636455911131e-2846L, -1.0217558991001370161903847475864815e-2890L, -3.1179630912672502182141115573865598e-2936L, -1.8265451376704665882357813599889357e-2982L, -2.0014192526716340395460104532447404e-3029L, -3.9951106676925283777648320420658919e-3077L, -1.4143501265341338386948746898388465e-3125L, -8.6415836958539035920266027922282148e-3175L, -8.8638553988044639042147624946934825e-3225L, -1.4840219096599721556289490714622718e-3275L, -3.9413909056885523526277851486916637e-3327L, -1.6130887141803206541250840542937335e-3379L, -9.8781642524919349085295532219577414e-3433L, -8.7843931949057976239401506792380659e-3487L, -1.1004454490075535460405971636548993e-3541L, -1.8829655853829584691138469084815955e-3597L, -4.2649913833758498152779971325727165e-3654L, -1.2387002826718376930423594688980877e-3711L, -4.4662108799989251681924501424182082e-3770L, -1.9344990293606773314152567555369947e-3829L, -9.7355570095915342874542008807254313e-3890L, -5.5029370896508671666190160013096548e-3951L, -3.3753310533018114196752016778611603e-4013L, -2.1693889909489136218749502032440802e-4076L, -1.4100342946015435859763977543837031e-4140L, -8.9396827455669883373190732493946026e-4206L, -5.3296285690324414372171445344916662e-4272L, -2.8786292587718554179132949540534825e-4339L, -1.3563301511005327997304553445712977e-4407L, -5.3648093624713363852431573541370394e-4477L, -1.713199655224600838900218899825865e-4547L, -4.245367036181261378573090733274636e-4619L, -7.8414039345064814928186445860311876e-4692L, -1.036301574835369426138520680597679e-4765L, -9.4005882200264089643362665220611737e-4841L, -5.6115028230432295314938587541868893e-4917L, -2.1117808872654504815205210716165957e-4994L, -4.7969059512296546218382678391152525e-5073L, -6.2923913054777813860480394257938674e-5153L, -4.557320132561115296699430714437428e-5234L, -1.7411358133348974154538037089867482e-5316L, -3.3501410753353566412413655174778596e-5400L, -3.097148592957890545441753638107994e-5485L, }, + }; + m_weights = { + { 1.5707963267948966192313216916397514L, 0.23002239451478868500041247042232167L, 0.00026620051375271690865701015937223316L, 1.3581784274539090834221967874745002e-12L, 1.001741678406625296380989561316704e-35L, 2.6763080920617460968679410949198166e-99L, 7.7670706886334062872146243844453043e-273L, 2.6770629459428179490864940513366914e-745L, 2.497123188557279400555877663164169e-2030L, 3.7829658019347837822103381908509695e-5524L, }, + { 0.96597657941230114801208692453802948L, 0.018343166989927842087331266912053799L, 2.1431204556943039357697233307232118e-07L, 2.8003151019775889582580016992170153e-21L, 1.123270534548691878982747435678734e-59L, 9.1753268750017841272445320853712195e-165L, 3.7096469071314047287189555701359196e-451L, 2.1358827779704788581082183250272886e-1230L, 2.4637500105830058174530832607403982e-3349L, }, + { 1.3896147592472563228608191295320513L, 0.53107827542805397476113231761531408L, 0.0763857435708323041883405748316428L, 0.0029025177479013135935932948904580215L, 1.198370136317072004690126421734261e-05L, 1.1631165814255782765597155262382926e-09L, 2.197079236297979917409204112478354e-16L, 1.3635103307637615413724747655081585e-27L, 3.3700568540419264989934173928550566e-46L, 5.1969783800898552138641449339116869e-77L, 6.0080341705713501485949327691027087e-128L, 4.564204056355599097208981999351872e-212L, 6.769934297924075481071769868728861e-351L, 6.3189772257105317991231885214248323e-580L, 1.1318535773666956837787222565063026e-957L, 1.300088515992481474129980450433913e-1580L, 8.3018817290920015915795630666821309e-2608L, 1.6615718540023971313123206033705184e-4301L, }, + { 1.5232837186347052131949627901588453L, 1.193463025849156963909371648222972L, 0.73743784836154784136450085848526681L, 0.36046141846934367416541940530511192L, 0.13742210773316772341110281600075763L, 0.039175005493600779071814125724013544L, 0.0077426010260642407123309111640668157L, 0.00094994680428346871690539180358829065L, 6.2482559240744082890784437584871091e-05L, 1.8263320593710659699109280974494727e-06L, 1.8687282268736410131523743935312467e-08L, 4.9378538776631926963708240981686386e-11L, 2.2834926702613953995564216678996858e-14L, 1.1227531428181551500942554523402945e-18L, 3.0976539701173543715458514327631078e-24L, 2.1121233435372255913526811977623162e-31L, 1.2424147570616052367007700396344415e-40L, 1.6327707331799493237812947626932747e-52L, 8.460688731096213796022276271481337e-68L, 1.8644492079588650273068038890475311e-87L, 1.0013128468666430206628687242136761e-112L, 3.3344435411868990213060767519646709e-145L, 6.1751576225487765303410376146008819e-187L, 1.4953240022257075856966174469213765e-240L, 1.995167671391421283850079422966012e-309L, 6.7986022131150125295165555843516628e-398L, 1.6112168443011532782661941324936245e-511L, 1.8998420056198456993096891152100817e-657L, 7.4500584401117916806764514072363403e-845L, 1.6092274599867451896713421807328385e-1085L, 1.4294469100875426784155324297970964e-1394L, 1.9699812322172327797426511042200449e-1791L, 4.8353547995000100603312087832016511e-2301L, 2.0016297694765957880783422493672502e-2955L, 1.0619575437766938720176582011701185e-3795L, 1.1494098249640889641399434474174788e-4874L, }, + { 1.5587733555333301450624222553039117L, 1.4660144267169657810275411936658895L, 1.2974757504249779979885383085284353L, 1.0816349854900704074448532749336471L, 0.8501728564566200689527310980522113L, 0.63040513516474369106015058023920241L, 0.44083323627385823706771270610993222L, 0.29024067931245418500061231479966878L, 0.17932441211072829296345978397121765L, 0.10343215422333290062482385052951418L, 0.055289683742240583845301977440481557L, 0.027133510013712003218708018921405436L, 0.012083543599157953493134951286413131L, 0.0048162981439284630172757660071387715L, 0.0016908739981426396472155417510249034L, 0.00051339382406790336016588906448858883L, 0.00013205234125609974878680402074340758L, 2.8110164327940134748736157546988307e-05L, 4.8237182032615502124025440343943169e-06L, 6.4777566035929719907733987417697432e-07L, 6.5835185127183396672340995882066949e-08L, 4.8760060974240625868904606426809347e-09L, 2.5216347918530148571826656491854398e-10L, 8.6759314149796046501956077624778843e-12L, 1.8802071730750649809476255843771975e-13L, 2.4124230384308786393899307730550295e-15L, 1.7084532772405701711664118263431986e-17L, 6.1682568490762382593952567143955272e-20L, 1.0376797238528706160610863270915827e-22L, 7.3459841032226935608549262812034877e-26L, 1.9497833624335174811763249596143101e-29L, 1.7024387761257547218675324410867209e-33L, 4.2164863709484278882204462399998679e-38L, 2.5044277116275284317811847533784782e-43L, 2.9493601457461933137195159567099426e-49L, 5.5513323569653710605229337238942258e-56L, 1.3081165120210821643686110907899211e-63L, 2.9260824463823975328629659452367614e-72L, 4.5407734669997824148941045053504133e-82L, 3.4265635692086987660673772586083229e-93L, 8.4064359488831769989074631453464805e-106L, 4.2486192688198694407012327873632857e-120L, 2.6378208263504521457685936139412266e-136L, 1.1199291455841279757620547508811484e-154L, 1.6741593786710889281267003484320699e-175L, 4.1533060810194922183660114746657927e-199L, 7.291512660905660427014583724901483e-226L, 3.4484028358868219730957875473275039e-256L, 1.470608613733186341839899819856118e-290L, 1.6363373245553192894384271318647291e-329L, 1.1653396430451048019810427186628332e-373L, 1.0806491346819681711718251969578419e-423L, 2.1475318157612117601623532784345252e-480L, 1.1837197513952188698387978224315556e-544L, 1.7840752052025753295716828917620433e-617L, 5.3242634124221408997248254448704286e-700L, 1.6062136117391783778620623735552911e-793L, 1.6828070526919983211589685788034629e-899L, 1.3428023135061849684751687999574317e-1019L, 1.0762445467071890806353267455766392e-1155L, 6.4211043768224511497561388149947945e-1310L, 1.0999298719684690155223457966483755e-1484L, 9.9551400313164741067089535072684105e-1683L, 3.7874715825152699680401002242066869e-1907L, 1.8633554093895907210742600678288691e-2161L, 1.2425018321859109200647073828888711e-2449L, 3.4744660691878314268031415759661457e-2776L, 3.1635539874917104171786237474568114e-3146L, 1.520164792309349080207015729831993e-3565L, 1.0587692108054511977730210493803509e-4040L, 3.9269571376984945676082618447700578e-4579L, 2.9165229925801338811576465571535852e-5189L, }, + { 1.56778143130722185718457839560813L, 1.5438811161769592204120195652304554L, 1.4972262225410362896175121106253706L, 1.4300083548722996676294145121698845L, 1.3452788847662516614631881421588284L, 1.2467012074518577048171373166756783L, 1.1382722433763053733718328301717509L, 1.0240449331118114482594022454942541L, 0.90787937915489531693097972059732257L, 0.79324270082051671787385259862995589L, 0.68306851634426375464118893187202369L, 0.5796781030877876470811045242977012L, 0.48475809121475539286590775419868886L, 0.39938474152571713514696619655275183L, 0.32408253961152890401776015000060852L, 0.25890463951405351600251387258910213L, 0.20352399885860174518647884913232324L, 0.15732620348436615026738563376259734L, 0.11949741128869592427594275905822144L, 0.089103139240941462840959442033942474L, 0.065155533432536205042255277931864103L, 0.046668208054846613643791300289316396L, 0.032698732726609031112522702100248949L, 0.022379471063648476483258477281403216L, 0.014937835096050129695520628452448085L, 0.0097072237393916892692355786307589937L, 0.0061300376320830301252445771940873246L, 0.0037542509774318343022967144602791306L, 0.0022250827064786427021584620411703896L, 0.0012733279447082382026740903535577353L, 0.00070185951568424227080474304718567332L, 0.00037166693621677760301295760218968355L, 0.00018856442976700318571529922115575474L, 9.1390817490710122732277133049597672e-05L, 4.2183183841757600604161049520839395e-05L, 1.8481813599879217116302847163026167e-05L, 7.6595758525203162561568606199506296e-06L, 2.991661587813878709443954037223499e-06L, 1.0968835125901264731967931401061751e-06L, 3.7595411862360630091183817668146341e-07L, 1.1992442782902770218679992206070689e-07L, 3.5434777171421953042822362946016499e-08L, 9.6498888961089633609206181967630592e-09L, 2.4091773256475940778596088439332178e-09L, 5.482835779709497755012456926288581e-10L, 1.1306055347494680535789879497045831e-10L, 2.0989335404511469108589724179284344e-11L, 3.4841937670261059685298917826974968e-12L, 5.1341275245014207474276938761808301e-13L, 6.6639922833087653243643099189129361e-14L, 7.5567217757805651894455261838657557e-15L, 7.4209932309922167588538662071098972e-16L, 6.2528048446104553564782731960667282e-17L, 4.4757595066690969713939566842636666e-18L, 2.6931206614869695057714525810417824e-19L, 1.3469941569542286092134858963015562e-20L, 5.5335834994155711455633228489644644e-22L, 1.843546974718149378096179376158747e-23L, 4.9139368712649040083308200957748574e-25L, 1.0329391306928575387668383646132905e-26L, 1.686277003849260652771901316947161e-28L, 2.1033057490018089523843332100004934e-30L, 1.9699209796232343253581550830906289e-32L, 1.3599894616303795697940905597197162e-34L, 6.7859788375592479085540582968820347e-37L, 2.3965063699443217406067231991536888e-39L, 5.8579569483084210846386345961131375e-42L, 9.6783927755717095571366983570964434e-45L, 1.0538361132564208838364959652125833e-47L, 7.3615858309787649210787574154381217e-51L, 3.2059785352833866133968160706885294e-54L, 8.4430892661864256082234111135836121e-58L, 1.301669487442817299199572925297743e-61L, 1.1348985048372046635260385887339235e-65L, 5.393881369511580841024486229556929e-70L, 1.3438019476233711028911671531262384e-74L, 1.6833095936633240263022508251714738e-79L, 1.0142059074468158538185578436642225e-84L, 2.8036136193449874498478125381332892e-90L, 3.3815387893836694650191340608232241e-96L, 1.6868699597973134851614068554314712e-102L, 3.2876716054636550397600067563177134e-109L, 2.3561803975866304919776634857937977e-116L, 5.8212714268864182676007475006940935e-124L, 4.6289769416942015466154791282940135e-132L, 1.1011712417530966759846558629187253e-140L, 7.2497708296024463973360079596584377e-150L, 1.2159344493950079010263214501254854e-159L, 4.7567332287785056252666937863445785e-170L, 3.9513561319289952903145090015894379e-181L, 6.3069398037899023031641976078084843e-193L, 1.7390958115772548420234336819215406e-205L, 7.3973824490445198187310257149181993e-219L, 4.3025693007354699025906405899973485e-233L, 3.0098295695832487716215316168466764e-248L, 2.2089957315907529731668895943677893e-264L, 1.4707383302537016829517267662493224e-281L, 7.6092047493292429607812922938663979e-300L, 2.5944582029845183791860228756757574e-319L, 4.8919577835343219860639698905291437e-340L, 4.2321357135722486316129327838961609e-362L, 1.377082367391413218915156512362392e-385L, 1.363952742750262175587655506596678e-410L, 3.282973957767873844612670506024268e-437L, 1.510934727927437884800902577518545e-465L, 1.0301501430760404101952742972682365e-495L, 7.9295801879971179076172461167077394e-528L, 5.1606434722064335409175586840009083e-562L, 2.0872322362104964031726231732635154e-598L, 3.7804014749166388131317806793058942e-637L, 2.1632858420984952938030309932161571e-678L, 2.697969237867160734724398915290777e-722L, 4.939067732330739558253971083984646e-769L, 8.7137367268607555569549275663836614e-819L, 9.4666568790742115790866970449104673e-872L, 3.9314930560193364712728646099681646e-928L, 3.7572363915786555422592370375561427e-988L, 4.8138810542737654527596947066774263e-1052L, 4.6523364803809138193102091214841167e-1120L, 1.8387400682879078406702806989874382e-1192L, 1.5488882086634896755007358131079033e-1269L, 1.3896133256118102918631384214217437e-1351L, 6.3450498372554790778619758345952674e-1439L, 6.718192925085413277150654870462718e-1532L, 7.1439377408604826875747242429241183e-1631L, 3.1307195483169831435149812630603435e-1736L, 2.1906656484419255825224621505729532e-1848L, 8.9202911849845695393803303860897414e-1968L, 7.2181700833126514821590990431204877e-2095L, 3.69827933239331943547271842529346e-2230L, 3.5509166675222604652849078491152928e-2374L, 1.7482004370958645792029686167921119e-2527L, 1.1106891190500999916896792610406226e-2690L, 2.0967298422181990469075373625054175e-2864L, 2.4632275747625679891658308849723178e-3049L, 3.4100009144092401643961247399658256e-3246L, 9.461422635018898458311235983749575e-3456L, 7.9828243452163492698389979442314978e-3679L, 2.751586075619233132202409409236628e-3916L, 4.573406478327970954594749406297331e-4169L, 3.7694660070555500868572517438534528e-4438L, 1.3681877706178551350653622286560967e-4724L, 1.6613468385141710911219854343435161e-5029L, 4.3416310672295866779590889330326041e-5354L, }, + { 1.5700420292795931467492986437735064L, 1.564021403773232099877114326609257L, 1.5520531698454121192208571607383634L, 1.5342817381543034316353772145375646L, 1.5109197230741697127061791873634288L, 1.4822432978855380699918515557505545L, 1.4485862549613225916106262684975582L, 1.410332971446259012949044799400295L, 1.3679105116808964880788896668731933L, 1.3217801174437728578945834791848425L, 1.2724283455378627082346213018713573L, 1.2203581095793582207386389532998567L, 1.1660798699324345766327658650910729L, 1.1101031939653403795568765186098518L, 1.0529288799552666555511877000344537L, 0.99504180404613271513656897365437693L, 0.93690461274566793365666309492163748L, 0.87895234555278212039056482196455926L, 0.82158803526696470334184690990337618L, 0.76517929890895613670160403610671453L, 0.7100559012054689838533558330696999L, 0.65650824613162753075637187406975179L, 0.60478673057840362157663695141011708L, 0.55510187800363350959266471517172014L, 0.50762515883190809969744129508607212L, 0.46249039805536776129564056825534108L, 0.41979566844501548065589545493380249L, 0.37960556938665160999227127370288764L, 0.34195379592301683230370363663700268L, 0.30684590941791694932077002517250017L, 0.27426222968906810637090960121437003L, 0.24416077786983990867520612813967892L, 0.21648020911729617038131524528780352L, 0.19114268413342749532225095746508781L, 0.16805663794826916233031413596643794L, 0.14711941325785693247796311096185123L, 0.12821973363120098675278273881295278L, 0.11123999898874453034874054225116091L, 0.096058391865189467849178662072631058L, 0.08255078811070173765353752357300814L, 0.070592469906866999351840896875301286L, 0.060059642358636300319399035772689021L, 0.050830757572570471070050742610585547L, 0.042787652157725676034469840927028069L, 0.035816505604196436523119991586426561L, 0.029808628117310126968601751537697736L, 0.024661087314753282510573737140694345L, 0.020277183817500123925718353350832364L, 0.016566786254247575375293749008565117L, 0.013446536605285730674148393318910799L, 0.010839937168255907210869762269731544L, 0.0086773307495391815853559138369297225L, 0.0068957859690660035329120415695881464L, 0.0054388997976239984331249261778682035L, 0.0042565295990178580164922070775372331L, 0.0033044669940348302363413922293941345L, 0.0025440657675291729677737674183717872L, 0.0019418357759843675814337234877431187L, 0.0014690143599429791058440789865212569L, 0.0011011261134519383861925290686638441L, 0.00081754101332469493114796258629778861L, 0.00060103987991147422573401527665731798L, 0.00043739495615911687786086941160964625L, 0.00031497209186021200273816328980956318L, 0.00022435965205008549104107147410537586L, 0.00015802788400701191949230617575051454L, 0.00011002112846666697224455022994264118L, 7.5683996586201477788165374446595019e-05L, 5.1421497447658802091816641948792101e-05L, 3.4492124759343197699875355951697823e-05L, 2.2832118109036146591351441225788429e-05L, 1.4908514031870608449073273504082825e-05L, 9.5981941283784710776464665022285646e-06L, 6.089910032094903925589071885768365e-06L, 3.806198326464489904501471179191111e-06L, 2.3421667208528096842717147966610279e-06L, 1.4183067155493917523149875336299115e-06L, 8.4473756384859863469243774523267053e-07L, 4.9458288702754198508296104158884319e-07L, 2.8449923659159806339254761906866073e-07L, 1.6069394579076224910854372243815059e-07L, 8.907139514024238712375244371846641e-08L, 4.8420950198072369668651027805560416e-08L, 2.5799568229535892380414249079124995e-08L, 1.3464645522302038795727293982948898e-08L, 6.878461095589900111136392082034183e-09L, 3.4371856744650090511359612982214485e-09L, 1.6788897682161906806903450478834801e-09L, 8.0099784479729665355704238927483163e-10L, 3.7299501843052790038025133658401989e-10L, 1.6939457789411646875651299532593942e-10L, 7.4967397573818224522463983518852213e-11L, 3.2304464333252365759775564205312505e-11L, 1.3542512912336274431500361753892705e-11L, 5.5182369468174885820640573102698266e-12L, 2.1835922099233609052099969606827855e-12L, 8.3831289605026670935474089966848491e-13L, 3.1194977286848081234778051650691241e-13L, 1.1240208959922861475529576279412917e-13L, 3.9176794506016467939451671035436525e-14L, 1.3194342231967989407842390664342776e-14L, 4.2891962220679080018159948630799523e-15L, 1.3443222875395221462210806176730482e-15L, 4.0575577022628576213784976604019497e-16L, 1.1779812127248348143079542926522782e-16L, 3.2853861628847006575461912014493979e-17L, 8.791316558919890092526902998792709e-18L, 2.2540748304368819446158103388678448e-18L, 5.5301769128403375894905317866280607e-19L, 1.2964527140689369428189650628176523e-19L, 2.8999645564315719864785175397007916e-20L, 6.1801432493399884472690523294170016e-21L, 1.2528676432273210433625630071013181e-21L, 2.4122505468361010054762467348044815e-22L, 4.4039066999398680900169681674054685e-23L, 7.6105778075820625755732634136772293e-24L, 1.2428051652123164945236765528871363e-24L, 1.9143106902239760676488034727771211e-25L, 2.7761251025850583169467065718383927e-26L, 3.7831240728137797052283562714381636e-27L, 4.8349101548188476652448113863661033e-28L, 5.7831786972290529603663947121744896e-29L, 6.4605757034417219896312763235825947e-30L, 6.7260373895879405356485977108634093e-31L, 6.5111534511374516546657070065569591e-32L, 5.8474090745481019884619654259625198e-33L, 4.8600460551422733352577609809902488e-34L, 3.7292395298436024198774848925631642e-35L, 2.6351230616803666949611566230315689e-36L, 1.7101926401490697241365293331985362e-37L, 1.0166685309552127228580017693019009e-38L, 5.5206909443427625675929025278647327e-40L, 2.7304755116605008208950089540576932e-41L, 1.226380966652512847885874020657185e-42L, 4.9868392983536125725869145787511357e-44L, 1.8300654157711633015675688730645846e-45L, 6.0413503225082640435207520715838788e-47L, 1.7880003085257126775048837670283103e-48L, 4.7278206635290633557485891499143011e-50L, 1.1129101718049771950203375840916927e-51L, 2.3236007287936054634490409808175661e-53L, 4.2865792135438400818864832679645293e-55L, 6.9598735225537515535247172084789902e-57L, 9.905399812867464416784441328019894e-59L, 1.2305690322370172647654483736261024e-60L, 1.3287055463682438112745418077294776e-62L, 1.2413844609001762091919818631042531e-64L, 9.9894889830989163005162036230629025e-67L, 6.8909792890209806239542239718708282e-69L, 4.0550412837679391530484571616360602e-71L, 2.025325478051833791855348665597344e-73L, 8.541193860817129005635611395334028e-76L, 3.0250584958478075188394058484674014e-78L, 8.9481574983737847286009199268691343e-81L, 2.1980365957192520850759686078382165e-83L, 4.457339084251821318983583351230449e-86L, 7.4167316712100725345384814229429518e-89L, 1.0062789446470429122974386215670469e-91L, 1.1060617024861203148604052551620709e-94L, 9.7834581723103753096719332058265664e-98L, 6.9161160403270601376643047091198938e-101L, 3.8797049192578037362892459079447827e-104L, 1.7144044358094688607777762897347039e-107L, 5.9226551398143962456841752185003654e-111L, 1.5871361682624074916136417159312335e-114L, 3.2726893534998181040216294108876001e-118L, 5.1496220394807877679493913965250783e-122L, 6.1305346175987605932476180523733874e-126L, 5.473030846543808520009167994615492e-130L, 3.6307475309683583384111588486160093e-134L, 1.7730007537696346688915570033698743e-138L, 6.3116464532127354831381913256985002e-143L, 1.621583693919220194566929433171311e-147L, 2.9757935132829859613289387859126523e-152L, 3.8591705765442151638142119206858087e-157L, 3.4980555618589782147605871793646301e-162L, 2.1911032417571959066795311563828556e-167L, 9.3736234796108920474724971094564098e-173L, 2.7058522933326574274299142121455261e-178L, 5.2051004982716048091082896972654894e-184L, 6.5869897226619604622569213699928695e-190L, 5.4113353348952773541650437440862393e-196L, 2.8465905848751190783736476660662487e-202L, 9.4537279066777943316631814110533656e-209L, 1.9534309746768722817386272635097574e-215L, 2.4738194858760899904808482337660157e-222L, 1.8904418888763632604075097028006049e-229L, 8.5786751348486017374921228218675884e-237L, 2.273808044980070953576133599904938e-244L, 3.4605977152655857787870383972443829e-252L, 2.9714191752129370394435745626764138e-260L, 1.4135174726041132417612082341294276e-268L, 3.6561278873359158194812461400887331e-277L, 5.0434133108713706852575809257966216e-286L, 3.6370069739853174907232860458211075e-295L, 1.3431929449017207014618114298104235e-304L, 2.4870346219017639693976883745872467e-314L, 2.2586869384020337841470045671934569e-324L, 9.8364979621195023902799369645695391e-335L, 2.0067948188168259586571751290590148e-345L, 1.8723608312818058521936506625581294e-356L, 7.7931764302539272294837164978121943e-368L, 1.4104242105367751421756306559719189e-379L, 1.0809707526373134180302026203191734e-391L, 3.413982422671325929147843223533059e-404L, 4.3198627266120931546631293969877099e-417L, 2.1273069601360357294162339387648629e-430L, 3.9566885872209056027370422510981332e-444L, 2.6949582298096968115536767242364878e-458L, 6.5109076931010576854739908270299986e-473L, 5.3989788614177770156022874990436434e-488L, 1.4853198669149487016912694923346188e-503L, 1.3090503251521584428930352496581121e-519L, 3.5647376837004158357511297570921346e-536L, 2.8896313028497521005627356654844694e-553L, 6.7095854399465738026181868874992309e-571L, 4.2889584337257558657454644184109877e-589L, 7.2448311439514538923291336946008664e-608L, 3.1001155749336353171177254469615123e-627L, 3.2171491615676533889663223546563542e-647L, 7.7406570695117283869992601856060778e-668L, 4.1223744692343859730646543586548491e-689L, 4.6322294010052851367822679106298139e-711L, 1.045335659900684312871171221243375e-733L, 4.5020856241223108492475174506019875e-757L, 3.5109989183708310084991820318792658e-781L, 4.6962204836998229475507359520919518e-806L, 1.0187348472076847046857363810773889e-831L, 3.3829163365599114939619605636207329e-858L, 1.6201873291670617651278341356078551e-885L, 1.052417929633641351707580294560769e-913L, 8.7019793416937745490332209560882093e-943L, 8.5790292111351760552267505428090183e-973L, 9.4260553303166607465714226577573373e-1004L, 1.0765751303003708312349678449534298e-1035L, 1.1895201137046793178631747385045816e-1068L, 1.180625613342395519601533530260917e-1102L, 9.7508687447891759767569844552344533e-1138L, 6.1928172812184124261845708258990883e-1174L, 2.7879318459600816091819660853849943e-1211L, 8.1797014327573742781475939847205791e-1250L, 1.4341956738449380463933781088853353e-1289L, 1.3742136648085548142182437043687567e-1330L, 6.5614725919712462874880606553304539e-1373L, 1.4193967474068871671305637677852339e-1416L, 1.260966346895598155305400631354573e-1461L, 4.1570767913697591845636153183534885e-1508L, 4.5808704947181685782204593123998747e-1556L, 1.5147204987797220696721543058866571e-1605L, 1.3446319068528240765599796700835479e-1656L, 2.8568551875090842255902159455984979e-1709L, 1.290420656637587734011142529706619e-1763L, 1.0965883695419688652509296670806449e-1819L, 1.5454358117029190110066857968185965e-1877L, 3.1713220921953507873149502965607843e-1937L, 8.2852363729842743064713740610323336e-1999L, 2.399312892921620764854020931161764e-2062L, 6.6760404808499701150348715300290141e-2128L, 1.5401518790175723653421594673899941e-2195L, 2.5301735371980282112359832727046555e-2265L, 2.5299480120770166824316075523796362e-2337L, 1.3095313462113548374850512340351666e-2411L, 2.9689243920149770430661749727744362e-2488L, 2.4813830291085919140036931759581715e-2567L, 6.3996445311970094107659804037592786e-2649L, 4.239251909781851582408879081262827e-2733L, 5.96853928335010438943934366176163e-2820L, 1.4691168838129215779634944240558196e-2909L, 5.1680311504236953911307750231831853e-3002L, 2.1104104354704386557845763111476113e-3097L, 8.0724923764466854235161222774323272e-3196L, 2.3180110258875131728741090820512076e-3297L, 3.9765565093255272984730390679523982e-3402L, 3.2199629992549034490326426922965119e-3510L, 9.6508721511747631002418659479792544e-3622L, 8.3314890242471693358884470423786766e-3737L, 1.5992989019877436694379940011582504e-3855L, 5.2267357291195312826488098055916878e-3978L, 2.2079407038664800796624257814276463e-4104L, 9.0732856778373185742790691459304111e-4235L, 2.7052547418764871675136904567273848e-4369L, 4.3243575109951310431228833829026739e-4508L, 2.7122975060794559909023695709869724e-4651L, 4.8370932158845122662637153824534517e-4799L, 1.7593494088080091822518592461420403e-4951L, 9.2629313370158738463326647490577837e-5109L, 4.9562745065321184922933588793911493e-5271L, 1.8710195150434747289751408668152425e-5438L, }, + { 1.5706077165382752220570950499753154L, 1.5690996953516691278086267057102919L, 1.5660882389174613671811758395264413L, 1.5615824934918106190924913174771039L, 1.555596114631660422166342990902623L, 1.5481471912355573327293783013569808L, 1.5392581453118818324345492520631963L, 1.5289556083545807159292699900112433L, 1.517270275405054680346497720954261L, 1.5042367380636772129345718219774013L, 1.4898932978832971219484878984168431L, 1.4742817617280797281467109946343097L, 1.4574472208125486663314082491076236L, 1.4394378152464069775161779990628486L, 1.4203044859996911837480782185431865L, 1.4001007162694446513758901419788661L, 1.3788822642731375176779450629832807L, 1.3567068895156054674526777181888561L, 1.333634074575756135382992612713127L, 1.3097247444374397383128243464895219L, 1.2850409853467272312421857577496357L, 1.2596457651166706020800416735545885L, 1.2336026567219467107844443624642869L, 1.2069755669313082254213358903568052L, 1.1798284716173337422807600081541025L, 1.1522251592625474295137962600991148L, 1.1242289840506032580653098282178496L, 1.0959026297929722120123658782081807L, 1.0673078857975038741099002717210955L, 1.0385054356373923292061824367921921L, 1.0095546596294298182250582016592233L, 0.98051345168085502517972727278507908L, 0.95143805101635270871239123838108163L, 0.92238288915245514551412028761663168L, 0.8934004523471959982711625120192134L, 0.86454115961966899850156197132807295L, 0.83585325630826713062996261999715574L, 0.80738272301876303826323728461609798L, 0.77917319970479798076341140529382576L, 0.75126592452435685914062625329355162L, 0.72369968702683029319553573992504406L, 0.69651079514654688482101628454709857L, 0.66973305541029099783625527361406845L, 0.6433977657082528556344204308635143L, 0.61753371992990889983731720244260268L, 0.59216722372820694935702418127019L, 0.5673221206467387178357679693601802L, 0.54301982782484286720274321665461387L, 0.51927938048424633084628868358974812L, 0.49611748439731621394870318175376878L, 0.47354857554061400457926695177211335L, 0.45158488614754491438064885165412276L, 0.43023651638978897817371690879635701L, 0.4095115109381936343721381503891959L, 0.38941593967921202782661222737925564L, 0.36995398189211387219291724401952693L, 0.35112801322442524717390619924264052L, 0.33293869483774779538113623624821976L, 0.31538506413267813525698287867505706L, 0.29846462649944498394951741316395666L, 0.28217344757959610491269401677566302L, 0.26650624556313516141887797351312194L, 0.25145648308451039819955104711453138L, 0.23701645831941898915989673276556716L, 0.22317739492218458776987874976238264L, 0.20992953048020753663062039840873861L, 0.19726220319743719884124330734112999L, 0.18516393655277551537189585427079996L, 0.17362252171163130317128688392273587L, 0.16262509749938432420455409981591821L, 0.15215822777419972032806536862862315L, 0.14220797606340183123695433555896409L, 0.13275997735244552637840297048350341L, 0.12379950693841296100725547935434371L, 0.11531154628093733739002418825877215L, 0.10728084580255643428531503966925542L, 0.099691984607788577667458210957830992L, 0.092529427105778463900867988199890184L, 0.085777576535268189772833000772228023L, 0.079420825403008155143300459369002492L, 0.073443602857638774779152196546779989L, 0.067830419030657966460701735648315918L, 0.062565906384455108312883097272720571L, 0.057634858114654726990360882355019006L, 0.053022263660287178654865336510427632L, 0.048713341380701431454862729860209054L, 0.044693568462765533522590231699541224L, 0.040948708125867302497552393088112476L, 0.037464834195628972796376547170838841L, 0.034228353120175696600101652094083332L, 0.031226023505331741095045556858942863L, 0.028444973247334237420578959776412296L, 0.025872714343617644485216127636544335L, 0.023497155463988527331246316453605283L, 0.021306612366126070465592025046447108L, 0.019289816240845601467614148418736892L, 0.017435920073977461259931130790681214L, 0.015734503113059796501938486945359929L, 0.014175573528330460201833138862417195L, 0.012749569358731162695972946581614495L, 0.011447357834799756252759767428888751L, 0.010260233171410768904966921400699131L, 0.0091799129243109016820036013086815458L, 0.0081985330052611999146716526049152539L, 0.0073086414513132480272928751787482011L, 0.0065031910442825794569735904252798084L, 0.0057755308768065491405505517951108403L, 0.0051193969614537818669843222017295048L, 0.0045289019791562891246666236654351803L, 0.0039985242627335310486699760330762132L, 0.0035230961104429863210055440392477764L, 0.003097791523300820656719025216576771L, 0.0027181134583502264180047688832185696L, 0.00237988068810043824649673132220802L, 0.0020792143540086661490040088456472881L, 0.0018125242991288642651054139496748517L, 0.0015764952619105560466714983901735372L, 0.001368073009609703955236179563862531L, 0.0011844504858902772190681005760231091L, 0.0010230540429745410945605352201833147L, 0.00088152982417297002262517617153839107L, 0.00075773035782735921074324212296621353L, 0.00064970141867429037384583446669345298L, 0.00055566920742578558188343231541026958L, 0.00047402789401816719609357067930453704L, 0.00040332756454954092910822407611191225L, 0.0003422626064629768809457896368129693L, 0.00028966056108877174342801893880690422L, 0.00024447146728689162442142144970348683L, 0.00020575771467998818628501233394779612L, 0.00017268441988592922811041420156552324L, 0.00014451033429094586468260075495740334L, 0.00012057928729056996115421473619828627L, 0.0001003121646011242017105871905771618L, 8.3199417240036480655327139421155229e-05L, 6.8794093113496376994935071214960655e-05L, 5.6705379853932877470011678973870605e-05L, 4.6592644630494618702241456703037532e-05L, 3.8159954120245760316298139014562893e-05L, 3.1151055677448352880855786865941099e-05L, 2.5344798968850110019503595997329621e-05L, 2.0550975944934244592401576964828471e-05L, 1.6606555976508335934243673648199596e-05L, 1.3372292284532372637222480551805329e-05L, 1.0729675406852340659025097863229453e-05L, 8.5782093537079082475098159798479489e-06L, 6.8329862774218506793384467861049682e-06L, 5.4225358918240331874795406776236123e-06L, 4.2869264939998226801201888531480146e-06L, 3.3760952348055109687047948553034167e-06L, 2.648386225404341059332347382668934e-06L, 2.0692761257364670911197722058327534e-06L, 1.6102680094507650586919500255804135e-06L, 1.2479355121177451927952866165256362e-06L, 9.6310052117659252623275411195037422e-07L, 7.4012893490908614244527654085271701e-07L, 5.6633028402050775174949474283673891e-07L, 4.3144825587165380566889409128276242e-07L, 3.2723037330517558940458575985214918e-07L, 2.4706624511249700700814105972385083e-07L, 1.8568491370025132363780817403060483e-07L, 1.3890286996035952957423247999266266e-07L, 1.0341528040745607124994759911720107e-07L, 7.6623873974817584699067130031657306e-08L, 5.6495763871670621475281493521314709e-08L, 4.1448233558505383939707940899336768e-08L, 3.0255196464899467188973440250947218e-08L, 2.1971648917089349870913690980235634e-08L, 1.5872978090968232625950436800137184e-08L, 1.1406465554850482080861078708713322e-08L, 8.1527464828576537674941124925699748e-09L, 5.7953495730966064129686023678242569e-09L, 4.0967579139685198004841429173893772e-09L, 2.8797013464471104655049488102491186e-09L, 2.0126210218867172874496187582569718e-09L, 1.3984414312565442025515753185221259e-09L, 9.6594851858099300536090988590771494e-10L, 6.6320863470162099803938291638680053e-10L, 4.5257576104153821951813027371570715e-10L, 3.0692702078723328679138233160912672e-10L, 2.0684203539029217544821684017571545e-10L, 1.3850287525834145108955800004991698e-10L, 9.214056422651888408320635035510389e-11L, 6.0893387064380670508776147108848386e-11L, 3.9973389519930269589286591598258413e-11L, 2.6061960502805293348144397281679947e-11L, 1.6874519343915025228826792012273533e-11L, 1.0849161834337120075418713193749676e-11L, 6.925528015268138234276418201069421e-12L, 4.3888651899779304012906781620222308e-12L, 2.7608587671398283608193689290767215e-12L, 1.7237644036042717645352410466671951e-12L, 1.0680750436541459501472279340038532e-12L, 6.5669443496573770247087892915106603e-13L, 4.0059853799532432743143892523313549e-13L, 2.4242966045442409054601213028173084e-13L, 1.455249915777183791487150796402817e-13L, 8.6638127254357861703205617203908732e-14L, 5.1149749011237035858347608326433163e-14L, 2.994217759503148409824465166785657e-14L, 1.7376816946074293584520159998670905e-14L, 9.9964240098994293054396937904035808e-15L, 5.6996266660577917745539527915605509e-15L, 3.2204325132709429326443049307963174e-15L, 1.8029589638948994224704223595333813e-15L, 9.9999573441511328003764710559432247e-16L, 5.4939783973500551313304111867037353e-16L, 2.9894208856836080833460170608635085e-16L, 1.610765424389333897595412933702905e-16L, 8.5932097482708020320234894915603507e-17L, 4.5382468267138486711718165281416612e-17L, 2.3722531670914086186505578503296188e-17L, 1.2271671669957684251768746309727359e-17L, 6.2812290485539754593993025086049784e-18L, 3.1806147137287576603303714266387884e-18L, 1.5930492574791968327078642420897427e-18L, 7.8908551593455841363543904697547233e-19L, 3.8647331030140734169770289169399394e-19L, 1.8712773299709086118483416095592492e-19L, 8.9557394552313902528032623648079256e-20L, 4.2357428519456376102962467454513856e-20L, 1.979436201534175012643985224780424e-20L, 9.1380785584698727034273276491713887e-21L, 4.1666411584773049229385926804715087e-21L, 1.8760750552668470771305003442308049e-21L, 8.3399019486525331443195597764274931e-22L, 3.6595752362436730932932611770341911e-22L, 1.5847852183325978194205652538004105e-22L, 6.7715756944343963844212791596730701e-23L, 2.8542817079371140817224171432389793e-23L, 1.1865838580947568695752893868758282e-23L, 4.8640699357080450262013571667032291e-24L, 1.9656434192469852200073765210097077e-24L, 7.8291656246958620676899939812206199e-25L, 3.0727892288172702707668669968129923e-25L, 1.1881076147213762784564203492918474e-25L, 4.5246197487634934114352468991264689e-26L, 1.6967101868478854591740026523544294e-26L, 6.2636410032291183199621894495108545e-27L, 2.275790792857396714851032797332432e-27L, 8.1360777159044314206100175821194793e-28L, 2.8613065492953910272350038532776635e-28L, 9.8961841969437875600155257339935786e-29L, 3.3652008931641398734060087635568974e-29L, 1.124807054607635533524732113721643e-29L, 3.6944604327139334398530256817969063e-30L, 1.1920933013465364813127655880555969e-30L, 3.7777578760183197857216889284069537e-31L, 1.1754363786778472289935929233399097e-31L, 3.5898790778284615893833448994196406e-32L, 1.0758426862142799782307176268359752e-32L, 3.1628351259465958616106447958915727e-33L, 9.1186741890740659476367230179943904e-34L, 2.5773931684416249884030668079887807e-34L, 7.1398295043464040965283248909128753e-35L, 1.9378289210199819221125431141075043e-35L, 5.1513791013790083352767878745680313e-36L, 1.3408183263237239554032545670003467e-36L, 3.4159407851320474430217223083201431e-37L, 8.5152627413375142768339982799164144e-38L, 2.076271482369099670696465965718329e-38L, 4.9501378383448158752628326041586328e-39L, 1.1535696769569322062307767078682896e-39L, 2.6266829648536609656499385130095636e-40L, 5.8418474765546354958505600321922284e-41L, 1.2685583522817839163209325300191513e-41L, 2.6885912245101334092484585567288326e-42L, 5.5593886486694506967808090446058169e-43L, 1.1211105786168708837628837423551506e-43L, 2.204030437173812137094585242452846e-44L, 4.2224091761364250309210368326791673e-45L, 7.879520062360877249284818876749499e-46L, 1.4317140234575381985434267597963095e-46L, 2.5319048034172799761988113239574673e-47L, 4.3559981958200842427093791079007571e-48L, 7.2876743960081410061189361036751606e-49L, 1.1851134957779509548750104934682377e-49L, 1.872433458377359457763352131002218e-50L, 2.8729694149829129971079440142039839e-51L, 4.2789120660247665069210975132651194e-52L, 6.1831517263855101991333477522333856e-53L, 8.664706532064762178060555848235158e-54L, 1.1769423732336786099340369561810161e-54L, 1.5488187383481079319128553087281025e-55L, 1.9736646088073419346394015708589866e-56L, 2.4341838396213207647077873905717686e-57L, 2.9041369422835327495394798923780893e-58L, 3.3499429920119329938613749830054234e-59L, 3.7340806058053956442103094318030179e-60L, 4.0199589180457423324670244391460705e-61L, 4.1774687856674289017944418799754548e-62L, 4.1880972367088277279311490203747192e-63L, 4.0484306973548957998328137903090132e-64L, 3.77114883236106507191241601008861e-65L, 3.3831738882583366253452262404438761e-66L, 2.9213348345532154319786866459214566e-67L, 2.4265171108768020980951563482987534e-68L, 1.9376034615932002776264780070086131e-69L, 1.4864705425001770514685771802938584e-70L, 1.0949232255990064493457806009226565e-71L, 7.7387134447881401018887497774386554e-73L, 5.2448008205426118383234631723504239e-74L, 3.4062562927830356374440099107130253e-75L, 2.1184692439258592242177714552745419e-76L, 1.2608614434809477030102983673195673e-77L, 7.1764903126208755695723110547276813e-79L, 3.9034697656266028736188479360578122e-80L, 2.0275573404310544862715347770507338e-81L, 1.004994816430593904290660376649901e-82L, 4.7500986471514075093717143999280406e-84L, 2.1392636099460832836078416112710222e-85L, 9.173149292867278730161085643245862e-87L, 3.7422217329627927169047643424111024e-88L, 1.4512980036440354977046772500061822e-89L, 5.3463017574991130746397399989936882e-91L, 1.8692545071988721039716330965097833e-92L, 6.1978958931273853497246435906829052e-94L, 1.9472339695524234456610961876127122e-95L, 5.7919052872513171909291273369047611e-97L, 1.6295956267419577729908767823766263e-98L, 4.3332432642363261903550403983227406e-100L, 1.0880149430086354606207846327564807e-101L, 2.5772282627352113781815039093907765e-103L, 5.7539838006451121430858484531452556e-105L, 1.2096990017248315153784188752260699e-106L, 2.3925872664345045807315831521649824e-108L, 4.4475659282644875495932738704595289e-110L, 7.7627738422265479186699876924736519e-112L, 1.2709267303083863208341290697181042e-113L, 1.9498242131608832039698501560236386e-115L, 2.8002525531974060834525812862103801e-117L, 3.7607474856227547424556497710309557e-119L, 4.7181060260584103957700726731938295e-121L, 5.5234683214250331048701341097289187e-123L, 6.0274476904458633271417170323324512e-125L, 6.1242336828836773956273877493935834e-127L, 5.7873336327745621779130244175524495e-129L, 5.080632710884007461562439620052701e-131L, 4.1387180173608798644427799558698992e-133L, 3.1247188175223382722031520705749413e-135L, 2.1839031164024077549981710942515192e-137L, 1.4112539862126523413412548851519319e-139L, 8.4215132945549247707528420294855683e-142L, 4.6349339497376890248654482771898709e-144L, 2.3496985464521993504910835710336684e-146L, 1.095806710681902573252914390685236e-148L, 4.6950275371271587533706139425003387e-151L, 1.8456310819897755187059215917442304e-153L, 6.6476058774188256202611396416535206e-156L, 2.1907913883958482863705726011811944e-158L, 6.5969704613629998580324088255164448e-161L, 1.8125024222344232769814833021310009e-163L, 4.5370781893964839845073953864812105e-166L, 1.0332388835710739936372904447767308e-168L, 2.1374954497695898284726118552680548e-171L, 4.0108149042055622979938927508096981e-174L, 6.8157812455297175262972900652817266e-177L, 1.0473127652676199964496156413213892e-179L, 1.4528685940321876156376494017441343e-182L, 1.8166282837173462776489744689123018e-185L, 2.0440202882824856548036164467448088e-188L, 2.0661513859552458565266153108297534e-191L, 1.8731127932057798663856916994067048e-194L, 1.5203587637183862829799380406495058e-197L, 1.1029412423875246289335781867943994e-200L, 7.138626970990275795307217364262657e-204L, 4.1148385080761107172311325770404465e-207L, 2.1085028345530812052701929614749437e-210L, 9.586804728597153811540457301738394e-214L, 3.8604168930466380230648935566836905e-217L, 1.3741198913182849308419643845423577e-220L, 4.3152058575378643032664917818412533e-224L, 1.19318553486394227968739928824324e-227L, 2.8991695266404489121362655770787829e-231L, 6.1775221006993094876500875992969792e-235L, 1.1519457912295313262297054573241955e-238L, 1.8759214343015253296548435854195451e-242L, 2.6621687700905798726983482845704724e-246L, 3.2851388833240439850794784627378447e-250L, 3.5173302898760059862233242135090423e-254L, 3.260189457452227113017033626415114e-258L, 2.6100961489800200467379180863184362e-262L, 1.8007454797962902444457099319194981e-266L, 1.0681019906266894643271137718146545e-270L, 5.4338051160125203325306044546291973e-275L, 2.3652466547636417935201205492175566e-279L, 8.7874613708003418754944028581674092e-284L, 2.7795968403545195493312606588081939e-288L, 7.4667445765219841782970695464816343e-293L, 1.6990035121087781757668989612218036e-297L, 3.2661456244114182842789617411036552e-302L, 5.2905644824269341726292739407836284e-307L, 7.2014912174357894815487914007866659e-312L, 8.2149916381513794689686855840667286e-317L, 7.8315488217791735530193073164613925e-322L, 6.221807701348355377240172152359918e-327L, 4.1074011155154758472047101692258134e-332L, 2.2466366589127674529456245569217313e-337L, 1.0151434061771573997492847262735324e-342L, 3.7778453114026807637246195807729534e-348L, 1.1543990703305213109241662519678786e-353L, 2.8874514917596574178755044320075352e-359L, 5.8931980361396154630354121875276487e-365L, 9.7830460697139640980628824283457061e-371L, 1.3166522887017193888073217487220663e-376L, 1.4318812372702150835656599374620546e-382L, 1.2540768871672304974301195995718396e-388L, 8.8153996483879828169726259431129063e-395L, 4.9562889772003524717252843516553902e-401L, 2.2209583723340796264599763080008776e-407L, 7.903905845967360394872219425003336e-414L, 2.2257919152191142215565812315993462e-420L, 4.9416038684875140142672214621735078e-427L, 8.6171916788075114925145119819509171e-434L, 1.1757806822258262957023704296248014e-440L, 1.2504660464052680899003468814266606e-447L, 1.0325197258632347378121850864959173e-454L, 6.5928728293837187402797552969580767e-462L, 3.2422215378060561710679179733872247e-469L, 1.222971654709343975246423698805888e-476L, 3.523560719191273512100160441884497e-484L, 7.7214021325433144875052949047234787e-492L, 1.2814096433117550022825846412075423e-499L, 1.6034524983169066795932277083952198e-507L, 1.506154257333325578480885384144555e-515L, 1.0572229793982283970011093126796893e-523L, 5.5202045762026741431740525809554222e-532L, 2.1340837910128019442948018148493991e-540L, 6.0796683172016911238300290124661526e-549L, 1.2702010542787853060770224333562558e-557L, 1.9367268433132755704840764854736682e-566L, 2.1444373126935426310796432391730652e-575L, 1.7156127051237753338771752429597998e-584L, 9.866507362005302302229219896627392e-594L, 4.0577781777778825723169578502780851e-603L, 1.1871364801794013747840938511563031e-612L, 2.4573736732127578624297116105185871e-622L, 3.5795957466771145363085369419550411e-632L, 3.6491000343716609306595204093204503e-642L, 2.5887224173643746039322073618863653e-652L, 1.2707309714711704379079743917253552e-662L, 4.2911292837382087644451178350840055e-673L, 9.9101724991114880676267115929463864e-684L, 1.5559081312551687762049592042215559e-694L, 1.6505944447381619620675148844917786e-705L, 1.1758976044388560589646808736426135e-716L, 5.5904673599123524828590221558073227e-728L, 1.762422841281411916279811438897522e-739L, 3.660545736359787919552147533680784e-751L, 4.9762407942794836638678732794521407e-763L, 4.3982297935392846258826361101417004e-775L, 2.5103306493196863847807186768995234e-787L, 9.1890276778950746130428977933070467e-800L, 2.1421794336828190981917187030902949e-812L, 3.1579407773552118084939940851249037e-825L, 2.9226685587591509131252404660323457e-838L, 1.6857720383594173922437511994184956e-851L, 6.0148932059792413237874599630717323e-865L, 1.3175950977896871810836083428540193e-878L, 1.7584274071402706626129462062711265e-892L, 1.4186205574627811155197950438077455e-906L, 6.863804756553040536363703712029114e-921L, 1.9757126782016829801994589969078639e-935L, 3.3557616466388148224311943077895109e-950L, 3.3354866661158784873247273739595471e-965L, 1.9238163515428741014100444007200552e-980L, 6.3838419214869081664291315367530963e-996L, 1.208186393746817780221157077221556e-1011L, 1.2926433460770675227136395965601267e-1027L, 7.7484641126890628613399212918871834e-1044L, 2.578590762872741885363873428172601e-1060L, 4.720135411440959292309368252688105e-1077L, 4.7080786123051904219070581932647786e-1094L, 2.5345319096404707885383043943244978e-1111L, 7.2928761242789730396354678181188802e-1129L, 1.1106128952895418090598971812669904e-1146L, 8.8621216538366976598099979452808551e-1165L, 3.6677828388640988980975786646419682e-1183L, 7.7923888084439739305704880307980387e-1202L, 8.4096550976573708334084140027496576e-1221L, 4.5613561814429013831962003215267279e-1240L, 1.2300215778004431684442502009102409e-1259L, 1.6310040159866857782581696492106591e-1279L, 1.0516379174444742948762886500817157e-1299L, 3.2599823473651125257811218258666689e-1320L, 4.8027868480449172060158102541122388e-1341L, 3.3236309884819155458562664594667437e-1362L, 1.0675935976034168796912624171598076e-1383L, 1.5726195400977448490722891999643084e-1405L, 1.0493832555753684651126599489805473e-1427L, 3.1327201084154872489458088843708842e-1450L, 4.1312837255709912970140480142041816e-1473L, 2.3759469769680296617336666937339053e-1496L, 5.8816760470052203616229940275916193e-1520L, 6.1846204357986408200352274197037853e-1544L, 2.7253154006156158167192213817170292e-1568L, 4.964370850871644112480158952518382e-1593L, 3.6864952720610418491857518517405997e-1618L, 1.1003435724966953469136035841615193e-1643L, 1.3012915572536198178305157209959287e-1669L, 6.0092590718277568469858434192698668e-1696L, 1.0676671777328477051443719591612721e-1722L, 7.1893041788265042697820383343649581e-1750L, 1.8069174401475778125395048319028868e-1777L, 1.6689765331128672749329764129278041e-1805L, 5.5766895369980043818737558535999006e-1834L, 6.6338104205654511592967377535571654e-1863L, 2.7640539994999072399732281044814252e-1892L, 3.9678218215367472586686997493459426e-1922L, 1.9297110274588854079208153981267479e-1952L, 3.125823255660491143824024380405163e-1983L, 1.6574847870654916983076674690989236e-2014L, 2.8268986732520512350429266473306993e-2046L, 1.5233117185863507338781156113800939e-2078L, 2.546861334196453858326476740489303e-2111L, 1.2970473455790653045919178951673388e-2144L, 1.9747419969447016216735762205746422e-2178L, 8.8188278044353709778558661887540083e-2213L, 1.1331026308914886857015956789021835e-2247L, 4.1073843396377054383734821718609159e-2283L, 4.1176061068991316842526396776090883e-2319L, 1.1187086154165438557157295454514512e-2355L, 8.0696152044407520449588862080186105e-2393L, 1.5135007846133660639825213215103939e-2430L, 7.2259333243684066847653432848351411e-2469L, 8.5946687461833096509693248289938412e-2508L, 2.4916284852956646502671815296350685e-2547L, 1.7218755528601187283427831366854425e-2587L, 2.7731789802471774097405514299103397e-2628L, 1.0173036737175759305843452255817661e-2669L, 8.3042791798168477802920353914502218e-2712L, 1.473175854535708068279125062330391e-2754L, 5.5445898944436653916624336507572418e-2798L, 4.320588676830861227044616106347197e-2842L, 6.7999319106199079525777026656783353e-2887L, 2.1077263780365503485840282493709679e-2932L, 1.2541789874677469018547003272238725e-2978L, 1.3958959110384407791740617210399902e-3025L, 2.8302814609077924874798718558506843e-3073L, 1.0177558252358910503169620579616733e-3121L, 6.316345161489586703263200702377878e-3171L, 6.5808353794152592529153513818570413e-3221L, 1.1191402820754794725611968922105955e-3271L, 3.0191144446114914489317417615052391e-3323L, 1.2550879768384736567252096901362895e-3375L, 7.8068891083719869927416696059040226e-3429L, 7.0517902304991510532607166162881123e-3483L, 8.9730892510839231589218006993975962e-3538L, 1.5595586152851619317721078977043233e-3593L, 3.5880900047081973177436521469002167e-3650L, 1.0585155878906962124317498469363852e-3707L, 3.8766455756851727310799307162918377e-3766L, 1.7055766393620807246392140051588691e-3825L, 8.7186526945824113614692955827617228e-3886L, 5.0057478847913665022916271652366648e-3947L, 3.118721903551705673676508466953291e-4009L, 2.0360271187838855169643637345546437e-4072L, 1.344193072571113944443469925533764e-4136L, 8.6564521926545774914724471102499854e-4202L, 5.2420435234912004640647252129478902e-4268L, 2.8759098307799421718470860096954611e-4335L, 1.3763877452472741048491095385711433e-4403L, 5.5298776937738818735087266649244396e-4473L, 1.7937216962986389293716315095996859e-4543L, 4.5149004338871753808860898565339903e-4615L, 8.4705695199542943533046216376760939e-4688L, 1.1370794062105632021349671352107651e-4761L, 1.0477206804639390072354388690482908e-4836L, 6.3526587059143165049479765478742544e-4913L, 2.4283486680552345908529800038916585e-4990L, 5.6028531999416699789095738832933157e-5069L, 7.4653403674710397422097751397913229e-5149L, 5.4919841992020489039553213694177019e-5230L, 2.1312688707736268785590779947753119e-5312L, 4.1653791598980828217930742787672032e-5396L, 3.9114639992058990826656399856975019e-5481L, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +#ifdef BOOST_HAS_FLOAT128 + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 9; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0Q, -0.048632035927253054272944637095360333Q, -2.2522807538407135100363691311150714e-05Q, -4.2941610558782407776948098746194498e-14Q, -1.1676488975098609327433648963732896e-37Q, -1.1479529916293899121630752460973831e-101Q, -1.2256538136584864685624805213855318e-275Q, -1.5540928823936461440049038613030612e-748Q, -5.3329091650553293055512604419528931e-2034Q, -2.9720916290005160834428657415764727e-5528Q, }, + { -0.32572850775156417391957990936794786Q, -0.0024851435427756131672825807611796319Q, -1.1124335118015331984966677262985097e-08Q, -5.3784915913936887745567608333252923e-23Q, -7.9430213192221161033965793076252082e-62Q, -2.3871228185819266205711383850686192e-167Q, -3.5505659459518255844385870776118831e-454Q, -7.5205359182648710139026226942624688e-1234Q, -3.1913442054759083418654684997091651e-3353Q, }, + { 0.37720973816403417379147863762593439Q, -0.14043094131010336482533980273793048Q, -0.012959439492623108312614281385864999Q, -0.00031173597164679094947882131119246211Q, -7.9526288528733553445705754617783867e-07Q, -4.7143551823222575055542137870412504e-11Q, -5.4152228238072308459654515228487702e-18Q, -2.0403003943524943294070815498839042e-29Q, -3.0596901353644500298194434206758382e-48Q, -2.8621984192587511612196829791231642e-79Q, -2.0070330691533226369447382138318798e-130Q, -9.24799327395281672235465186719e-215Q, -8.3199831454007319575241484332973316e-354Q, -4.7101915049286172051527740304785445e-583Q, -5.1172326001331791544221573365516138e-961Q, -3.565091902092693101170960484903703e-1584Q, -1.380788494593788864141714339603113e-2611Q, -1.676187209363792948538214808034106e-4305Q, }, + { 0.19435700332493543161464358543736564Q, -0.46085329461203223095024473969116941Q, -0.21939256101679970074520301166037226Q, -0.085120736735425389092624476255089179Q, -0.026033131804322551436697210776387341Q, -0.0059444933685978567073105981025861939Q, -0.00093480354421415357524054329032500553Q, -9.0615304856000161419338663865283889e-05Q, -4.6839587794715699213295541472938628e-06Q, -1.0721838758161809434047961979486614e-07Q, -8.572949078216773291904741005771376e-10Q, -1.7678346928387203697450793420511691e-12Q, -6.374878495044439647822814562601604e-16Q, -2.4429372790852173177460412747369906e-20Q, -5.2515464730195748562913138330508827e-26Q, -2.7894671622894177442056826817468893e-33Q, -1.2781108980938044979748713346336601e-42Q, -1.3082723368531808046381743164626179e-54Q, -5.2799781226102543764849911449215675e-70Q, -9.0619104054181014912823874637681869e-90Q, -3.7903152788024647936360099425967319e-115Q, -9.8301769964870442146689481371228979e-148Q, -1.4178035546472368325653350149379565e-189Q, -2.6738184762632894703182151426789471e-243Q, -2.7784573988900744903717061581976306e-312Q, -7.3734573357629727800590803405661863e-401Q, -1.3609194136463888140125728088459369e-514Q, -1.2497483783949474937966696885440387e-660Q, -3.8167291133270025322500901161738939e-848Q, -6.4205995373383705446145927875493146e-1089Q, -4.4417348039463271683501804024826735e-1398Q, -4.7673068229426388972968294463896211e-1795Q, -9.1130922352573668488349663479480507e-2305Q, -2.9379714111577752802646622386752463e-2959Q, -1.2139403773313257256483385510112958e-3799Q, -1.0232729473573403414331717146692674e-4878Q, }, + { 0.097923885287832333262426257841800739Q, 0.28787993274271591456404741264058453Q, 0.46125354393958570440308960547891476Q, -0.38972634249936105511770480385767707Q, -0.26898196520743848851375682587352696Q, -0.17668299449359762993747017866341472Q, -0.11010859721573980192313081408407809Q, -0.064839142478015316771395646494440585Q, -0.035887835776452708068531865802344445Q, -0.018545173322664829973291436321723213Q, -0.0088730075583011977688563205451530858Q, -0.0038913345624914574643783628537015109Q, -0.0015457912323022624891555460019043471Q, -0.00054856556472539415808492760717674295Q, -0.00017117792712505834023311917084994073Q, -4.6128994372039252659199558313379019e-05Q, -1.0517985181496388528104100992279397e-05Q, -1.9828594045679206280184825675885662e-06Q, -3.0110584738877965497930108986179822e-07Q, -3.5760919084657714373617064589353927e-08Q, -3.2128009016957604999656591474001583e-09Q, -2.1026713776411488104386696975012214e-10Q, -9.606066478508465003238769873504248e-12Q, -2.9190266410175139338365873758536822e-13Q, -5.5861166388382275217411050967087276e-15Q, -6.328207134683168236714250292398626e-17Q, -3.9564613394676478284814817479958896e-19Q, -1.2609758447165484726150111345292941e-21Q, -1.8724921745276082830417983528796313e-24Q, -1.1700302939131190810173673171853244e-27Q, -2.7409861783512409524809986743233587e-31Q, -2.1122827214476119769953891899502657e-35Q, -4.6172239482595017143038368975612786e-40Q, -2.4203621976262400766076976463254527e-45Q, -2.5155618638019452025824211444543239e-51Q, -4.1786390697021940369390798235100086e-58Q, -8.6898180082116723025562943397702972e-66Q, -1.7154357765002478902943183846995354e-74Q, -2.3493032412195338067008854292230121e-84Q, -1.5645432388942512177369950120860268e-95Q, -3.3873402047868364753040883051129579e-108Q, -1.5108166471007846474189907630676839e-122Q, -8.2780000956704166841985762886452778e-139Q, -3.1016029819580818393688194490134506e-157Q, -4.0917346928724404440872286063293528e-178Q, -8.9581681449485486979882444847795217e-202Q, -1.3878968774299744972242822597861929e-228Q, -5.7925742129350389434060147129950123e-259Q, -2.1800405760909812340138469200688552e-293Q, -2.1406911761156887130351179719470661e-332Q, -1.3453872213865718752685710282193859e-376Q, -1.101014385623064504263959341239785e-426Q, -1.9309068614975016262992988189610055e-483Q, -9.3925603630660026565835909833509362e-548Q, -1.2492852059051478595312298290165577e-620Q, -3.2901922810889194483613206478029049e-703Q, -8.7594800494412338094846019359419219e-797Q, -8.0988360915906760478163297865939266e-903Q, -5.7031344694656922604093410430637095e-1023Q, -4.0339055664976041957619784717611254e-1159Q, -2.1239178549857743261952555619757156e-1313Q, -3.2107478383582521299381622502244136e-1488Q, -2.5644945785388919263865858785287637e-1686Q, -8.6102745649577746230102198336971101e-1911Q, -3.7383203767208973356368595261534058e-2165Q, -2.1998398074691126029946216118342674e-2453Q, -5.4286931050493856204731826640809476e-2780Q, -4.3621004458123770532320189625677295e-3150Q, -1.8497978727098997950183603712476515e-3569Q, -1.1369676358500293654883467577244006e-4044Q, -3.7214839695831726545775627850809865e-4583Q, -2.4391504445900085306499460471723674e-5193Q, }, + { 0.049055967305077886314518733812558024Q, 0.14641798429058794052721556654753264Q, 0.24156631953888365837930785879296225Q, 0.33314226457763809243847911788190042Q, 0.41995211127844715849198982824847239Q, -0.49898661062069089848349381875489034Q, -0.42441550936484834004641698479390102Q, -0.35682324101479529871858133934192696Q, -0.2964499948528579843445043147096805Q, -0.24330609136627005059281117751078325Q, -0.19720125865675873423611581820317215Q, -0.15778075364924313618002648351129378Q, -0.12456460236959132162770016658853563Q, -0.096986718486426129363622040287916613Q, -0.074431365931387333547858011705581591Q, -0.056265213947242843145098876381950312Q, -0.041863977289786309881823549732911528Q, -0.030633267103082664829845578114893065Q, -0.022023764813335027020322387941507847Q, -0.015541168832569169131789346286900099Q, -0.010751568909866103993013400883081643Q, -0.0072830028031727146206149733302275483Q, -0.004823973844672645743610027178935428Q, -0.0031196818718081262793524354157388492Q, -0.0019666636845662459778601079868649985Q, -0.0012064657011941007112693927041613496Q, -0.00071888807820804459144864726303695018Q, -0.00041524964848241268314681568037451433Q, -0.00023202840043916493872468513410105539Q, -0.00012513495121965351530204004794322354Q, -6.4980074917576313794386569166441844e-05Q, -3.2406932056540235696910972894671255e-05Q, -1.5480097729175578034178680349142798e-05Q, -7.0621233371143522557906813506099499e-06Q, -3.0675508096424942465066236512329746e-06Q, -1.2645281340904582699398919033969316e-06Q, -4.9299428056311116061802876221616736e-07Q, -1.8110628723299136916197821516601534e-07Q, -6.2445921626224975560761130514661379e-08Q, -2.0125496798245795667718397386179161e-08Q, -6.0358657983522763759573155859882131e-09Q, -1.6766380517421942876239492441262369e-09Q, -4.292122273863880635543266425012844e-10Q, -1.0072227674373084849456997974551022e-10Q, -2.154466258904202365369932629331438e-11Q, -4.1753931241965133013258464583874422e-12Q, -7.2847372642877340424635554069698771e-13Q, -1.1363869854392191510522700311409067e-13Q, -1.5735535097926530184856977764147682e-14Q, -1.9192189097107621395219494827869742e-15Q, -2.0449595408467355635051956217352212e-16Q, -1.8869583067293409682109390382712203e-17Q, -1.4938716488357228966449278404247075e-18Q, -1.0046938100037576480510308414445084e-19Q, -5.6799291780731967001285171683592406e-21Q, -2.6691039526135151405184691859723367e-22Q, -1.0301781381894114683480515283399996e-23Q, -3.2244848763912462050246763811724513e-25Q, -8.074782900421688680511360232922118e-27Q, -1.5946546019932855470728505192034342e-28Q, -2.4457239752752825879158721953606166e-30Q, -2.8659197719078655681373680421610036e-32Q, -2.5216825251828994098262358831122367e-34Q, -1.6355144403100727446739341400788963e-36Q, -7.6666590990678357226674242484094458e-39Q, -2.5435771288137693474957657676429463e-41Q, -5.8409472280716482316816237196206469e-44Q, -9.0658695647939702552111019446179921e-47Q, -9.2735698160588525904827667013324314e-50Q, -6.0857148042052277604035466987369298e-53Q, -2.4898089736722146606232085397625384e-56Q, -6.1598620863170544290033299759018975e-60Q, -8.9214127072226711903218542175348322e-64Q, -7.3072243260040451389778049479673039e-68Q, -3.2625608625513858480451119539754283e-72Q, -7.635785144983622496088267971984613e-77Q, -8.9855174690288197015625761302053014e-82Q, -5.0858718515487289997949540667405475e-87Q, -1.3207396001984761034417395177214725e-92Q, -1.4964864935610521348123903353455889e-98Q, -7.0129233669310880373145304240642606e-105Q, -1.2839990161964174973579406866396101e-111Q, -8.6445683841052002170413994851536565e-119Q, -2.0063694896831555279614790770285332e-126Q, -1.4987740796184447811135706015205434e-134Q, -3.3493762149589610757447357005516387e-143Q, -2.0715294381434481475176795645059666e-152Q, -3.2638832593319965098529982282696874e-162Q, -1.199473759889723458030222815758102e-172Q, -9.3602085584027101517846387151893588e-184Q, -1.4035094428007866386369967794759254e-195Q, -3.6356107639491247696753307742986431e-208Q, -1.452743995741226464980668915527686e-221Q, -7.9377235820922308566742845525117486e-236Q, -5.2163536229754499795136126103956784e-251Q, -3.5964743752577816321270751238997225e-267Q, -2.2494401025357803105700529744520824e-284Q, -1.0932895122313467863909046216907507e-302Q, -3.5018653663752920075194010313564247e-322Q, -6.2028644584939181030730328594330175e-343Q, -5.0411076779076593359744388314869213e-365Q, -1.5409305985666377552321629186300452e-388Q, -1.4337691700836957601785568351756479e-413Q, -3.2419333785971000532922906392702739e-440Q, -1.4016483469785082716612467122698103e-468Q, -8.9774004157156246399741480681783078e-499Q, -6.491677776744900396848653659323143e-531Q, -3.968873851900238121124736680679859e-565Q, -1.5079636812339879861399394077308116e-601Q, -2.5657520984549883455506649942306167e-640Q, -1.3792637739621433541997914448762973e-681Q, -1.6159468091505698350217369718439518e-725Q, -2.7790201117578232055517503438743301e-772Q, -4.6058286485158911464074200874638533e-822Q, -4.7006358553201903008219637676007764e-875Q, -1.8338935012250262258997114428219912e-931Q, -1.6464242001502528395088533240159331e-991Q, -1.9816419848867601423745192888068803e-1055Q, -1.7991094041844603532543957306249989e-1123Q, -6.6797992361969494675858665124683032e-1196Q, -5.2859098848402526633383865829249954e-1273Q, -4.4550261847470794285196049926646754e-1355Q, -1.9109438945105886059290808709178883e-1442Q, -1.9007367698294334902014013473010713e-1535Q, -1.8987324425640464476346787762173242e-1634Q, -7.8167618149826855518169886771423511e-1740Q, -5.1382521738908379784587542986497343e-1852Q, -1.9655086052442019324819644975934904e-1971Q, -1.4940998787039296124957637312415828e-2098Q, -7.1913235695994009755126799768473976e-2234Q, -6.4864369300175247147155547975053653e-2378Q, -2.999946728125704672445599927700136e-2531Q, -1.7904880802749365558709955426180586e-2694Q, -3.1752504880744458148875772810912828e-2868Q, -3.5042626554286023022035386575033303e-3053Q, -4.5572536942770532680494362978923935e-3250Q, -1.1878504044248058672204846884752448e-3459Q, -9.4149599587707022465535580134518114e-3683Q, -3.0486081328912260971936320312995529e-3920Q, -4.7600871041282300101380551251356845e-4173Q, -3.6856282214670996203899028095741989e-4442Q, -1.2567068832608339131427238307321809e-4728Q, -1.43352474798599180975125045215869e-5033Q, -3.5192846690056568230804624618996538e-5358Q, }, + { 0.024539763574649160378815204133417875Q, 0.073525122985671294475493956399705179Q, 0.12222912220155764235135543647484308Q, 0.17046797238201051810697458795462942Q, 0.21806347346971200463019772812275949Q, 0.26484507658344795046121266511868619Q, 0.31065178055284596083122357022827612Q, 0.35533382516507453329875421158518394Q, 0.39875415046723775644258197210456498Q, 0.44078959903390086626728024419415105Q, 0.48133184611690504421849248706653226Q, -0.47971194930876984042437695635737165Q, -0.44241877173922176919985653200857201Q, -0.40684964640804684120174768961798095Q, -0.37304979194895712050380997331064448Q, -0.34104900825664987561685714614383599Q, -0.3108622749383323282394733757479914Q, -0.28249053251267587278787801637860204Q, -0.25592161645265260087450443652530469Q, -0.23113131323175341540544311864007538Q, -0.20808450762385788552523390287482686Q, -0.18673639149702614832471241636026165Q, -0.16703370608058912436398702772140703Q, -0.14891599201215126738569202826103709Q, -0.13231682422435401330546108424048627Q, -0.11716501175533104486690697891318309Q, -0.10338574571992397421289522925754423Q, -0.090901681836979564888397733057112044Q, -0.07963394696804719765304016834176825Q, -0.069503062002846593688614128282605538Q, -0.06042977606672524461492007773726152Q, -0.052335809384846902663067556129352578Q, -0.045144504194977314593201232656013596Q, -0.038781384848883592468460207166535186Q, -0.033174629687644147159978329404393879Q, -0.02825545843451269107668693235164557Q, -0.02395843974342326066584697335177699Q, -0.020221724199384237353497637367719603Q, -0.016987208518898894423060324544850119Q, -0.014200636974716564032303584519259449Q, -0.011811646199257357569283265398947793Q, -0.0097737595324722530639024866802767264Q, -0.0080443369973223843798692318964963564Q, -0.0065844868307359609987086057921138135Q, -0.0053589442874888032779151584247851277Q, -0.0043359231830468303521751643564073944Q, -0.0034869453597462268271205586183706831Q, -0.0027866529565312977632015610760207467Q, -0.0022126080410934691734971443584643208Q, -0.0017450838280037065615903399860968624Q, -0.001366851359322522377124006197840537Q, -0.0010629651664878262735108241097275379Q, -0.00082055106511408284244272347987383953Q, -0.00062859885906231310357940554216565142Q, -0.00047776234878279577588863291489417448Q, -0.00036016865439963480978268344017946398Q, -0.00026923848019151736959880088820900265Q, -0.00019951856886161369803218944988361524Q, -0.00014652722688858828517464005147727694Q, -0.00010661345240743574350860189665463426Q, -7.6829870710671305672093252530903342e-05Q, -5.4819385541306910394346187661030795e-05Q, -3.8715192143333868407124859677345036e-05Q, -2.7053574767763435703448594138071512e-05Q, -1.8698729879273208281214887386151327e-05Q, -1.2778717999371889596874911057724209e-05Q, -8.631551655126555923485540179705975e-06Q, -5.7603723833652179866412085097651011e-06Q, -3.796652833823246921587494391038503e-06Q, -2.4703761948320696741670218229372071e-06Q, -1.5861890352645758023485712079757291e-06Q, -1.0045893100303765084297472484854592e-06Q, -6.27292664630529591934671730489378e-07Q, -3.8601144975725102288841415591950667e-07Q, -2.339766675668795211736366707138927e-07Q, -1.396287854005922888135986291920763e-07Q, -8.199520528943774856188619843122174e-08Q, -4.7357335538151973999955685632054965e-08Q, -2.6886764056376916830145130602254872e-08Q, -1.4996923688266632451823595335560501e-08Q, -8.2135439009280190432084662337190249e-09Q, -4.4143663841612464008735244035118061e-09Q, -2.3267632621004612298287053849704746e-09Q, -1.2020164996011407668894632352766295e-09Q, -6.0822312416778615105389374826677738e-10Q, -3.0124563074832322562803735802769698e-10Q, -1.4594388450012857143914599919653952e-10Q, -6.9111604985231078666967248228438538e-11Q, -3.1966783264445369722850429235278972e-11Q, -1.4431209924042652494507345459464675e-11Q, -6.3536761284911814276716019591237312e-12Q, -2.7259505188725197201090431322689677e-12Q, -1.1387345722407849659711071645809649e-12Q, -4.6277346217693134290561172417433117e-13Q, -1.8279902248431104840099026765769527e-13Q, -7.0120467384905686087185698802558123e-14Q, -2.6096053661379546374618820988626935e-14Q, -9.4133613352888555760685465264560536e-15Q, -3.2879256949364934203905795056053052e-15Q, -1.1108629401821898431250973198964316e-15Q, -3.6266022642032122019717830419062828e-16Q, -1.1427876525052669863279877707280153e-16Q, -3.4719022692494936795924113147604942e-17Q, -1.0157819068305124587449297554375856e-17Q, -2.8585328245081481739274807557448345e-18Q, -7.7278347873892552568443785071813692e-19Q, -2.0044239922175172204979314952837677e-19Q, -4.9815683764699114931038226437577286e-20Q, -1.184668492422340236764487382599448e-20Q, -2.6919849036103905707012031384082434e-21Q, -5.8366674419339414129894129738889481e-22Q, -1.2056615886548723513354371860285751e-22Q, -2.3691093508078067650593562318134397e-23Q, -4.4213394617280017751359368167258193e-24Q, -7.8238350041086858182189611432466241e-25Q, -1.3105331441254781548552012055519121e-25Q, -2.0743450130735150739962743364500278e-26Q, -3.0969683255507495828369632528319965e-27Q, -4.3532005281967559757740065310127852e-28Q, -5.7499556680703922900693138751854555e-29Q, -7.1227159266381727412068631384345687e-30Q, -8.2578354203558045768004451321024521e-31Q, -8.9415410066249555437647937669966689e-32Q, -9.022796650030866974265443296162775e-33Q, -8.4660301195315971752688615420135191e-34Q, -7.3692728065645298168617836618124666e-35Q, -5.9366323560088749776278557840220755e-36Q, -4.4152778386946959545381237143455402e-37Q, -3.0239601358635314916964716581634168e-38Q, -1.9022037916577048792943667867798758e-39Q, -1.0960433286034577882548963198643229e-40Q, -5.7686955980040694827320797355280285e-42Q, -2.7653993817377102211887943260200603e-43Q, -1.2038709528562574051108458784307785e-44Q, -4.7447623253354987177832150988795395e-46Q, -1.6876791281053309141043851984778909e-47Q, -5.3999669982997284808706183365024646e-49Q, -1.549024049448082614346506969629423e-50Q, -3.9699472552561349765465127201129129e-52Q, -9.0576749265239358552559531050991564e-54Q, -1.8329504334836931380757353284221911e-55Q, -3.2774223323973643896776906795254206e-57Q, -5.1576871530839363640889147624270212e-59Q, -7.1147152214081979999932108600174644e-61Q, -8.5668890171210249323533230713364891e-63Q, -8.9655585542113618588233770236885955e-65Q, -8.1186937969054743805236701211415782e-67Q, -6.3321938859077339155825561128906228e-69Q, -4.233726342460328087225876085667347e-71Q, -2.4147260464376790196845134616759282e-73Q, -1.1689555910948214525778546914101199e-75Q, -4.7780668985526446079787318493898922e-78Q, -1.6402035716952158990309656043758773e-80Q, -4.7024891487642105081472609988004035e-83Q, -1.1195904670077980724005196979590736e-85Q, -2.2005433507330024992345876236265894e-88Q, -3.5489240240632636451154177125584074e-91Q, -4.666940936883651858001572120481125e-94Q, -4.9719066745930336256015501390182822e-97Q, -4.2625120032373619347908954864791867e-100Q, -2.9205525410269401160683450458899041e-103Q, -1.5879283520520673524672134768919763e-106Q, -6.8010328774211569659959576053742516e-110Q, -2.2772324163917691950189307132002393e-113Q, -5.914722281629598175795438531560773e-117Q, -1.1820998217768840832984056598978546e-120Q, -1.8028262273951398891886168129927287e-124Q, -2.0802041335110124193794970445396975e-128Q, -1.7999670156396935596364355347029528e-132Q, -1.1573419660682545435402292296632314e-136Q, -5.4777666541440989994081254549149894e-141Q, -1.8900190812332372959031760309750191e-145Q, -4.7064318355746675546808068910291556e-150Q, -8.3711291364376416570212981885601003e-155Q, -1.0522139008817658534084763162543628e-159Q, -9.2441193400981258043604322474285494e-165Q, -5.6121650181326378940737135740792016e-170Q, -2.3270398424370294077224375501608811e-175Q, -6.510721186743015604234587537579044e-181Q, -1.2138997008699255952666017192674735e-186Q, -1.488912999352695867344311698561554e-192Q, -1.1855378186700107100267028475666946e-198Q, -6.0445584657932328676234962000989188e-205Q, -1.9456793188673556729031520231103262e-211Q, -3.8966805747095113950686230057410173e-218Q, -4.7829220009546143710431038737748715e-225Q, -3.5425595917324118172041028901087466e-232Q, -1.5581260191174140607938473801301532e-239Q, -4.0028071638967508676664829682660027e-247Q, -5.9046000382762171283315920864186447e-255Q, -4.9139618035200235196744932808885781e-263Q, -2.2656744698055742315406349324984012e-271Q, -5.679971707464259613069663431618014e-280Q, -7.5941261723746109223402306020806232e-289Q, -5.3079378188778939332566204780962363e-298Q, -1.8999778173084169834715816327210827e-307Q, -3.4097331110687592869362387676073128e-317Q, -3.0013940393884085654083505783337316e-327Q, -1.2668812065800974411227932737003665e-337Q, -2.5051097865973858424963978994105679e-348Q, -2.2653835286828392416879577941979414e-359Q, -9.1389245527311981300218270087623242e-371Q, -1.6030930250662823526442537954011133e-382Q, -1.1908341901916029371925944757292412e-394Q, -3.6452473980708905026093050166205199e-407Q, -4.470581799337985564576477205041097e-420Q, -2.1337946766915608745979583351759322e-433Q, -3.8466502387371814478842876774875617e-447Q, -2.539400648443551278595315008859673e-461Q, -5.9463310120354055195604938583173969e-476Q, -4.7791154462039743101535253283672216e-491Q, -1.2743368238366444127980835826074082e-506Q, -1.0885513756896925921766278125740167e-522Q, -2.8730852174104725878401965901098976e-539Q, -2.2573125874160702024258126565183851e-556Q, -5.0801120877688108677556596022448958e-574Q, -3.147442313458971094095441973453258e-592Q, -5.1530284704707320518750575728196905e-611Q, -2.1371769888513739266688394459294633e-630Q, -2.1496221573881902238982422615825289e-650Q, -5.0129928677987666360823382488243001e-671Q, -2.5875873756026443959521949570534425e-692Q, -2.8181620714067187431385929758736621e-714Q, -6.1639625895204988083360964770898867e-737Q, -2.5730385846926571409465774477581834e-760Q, -1.9448744127295675669050254780849454e-784Q, -2.5213762798933993822025230917884045e-809Q, -5.3012546029922448380589857164083814e-835Q, -1.7062280322013794538523703018620566e-861Q, -7.920258584822147757302618208276618e-889Q, -4.9864409544476492068060565707730923e-917Q, -3.9962146024411971515483669014007722e-946Q, -3.8185388383865818601310492618971832e-976Q, -4.0664680142829823697989791072662443e-1007Q, -4.5015287529024162764736783373823692e-1039Q, -4.8207630344098447587536323292213823e-1072Q, -4.6375061995611002272610193821937293e-1106Q, -3.7123073076807703361397549566488692e-1141Q, -2.2851629967300820983086928617773692e-1177Q, -9.9710151392993821636927693831761909e-1215Q, -2.8354564442635450405718863241322006e-1253Q, -4.8186151533506508630367161348238245e-1293Q, -4.4750346397724178706383092717200537e-1334Q, -2.07096024490079588158927973820168e-1376Q, -4.342127308884323517312819302082545e-1420Q, -3.7387854726872903857603805318252205e-1465Q, -1.1946574634186879393921342144260135e-1511Q, -1.2759441657028066718211573051988164e-1559Q, -4.0892575258067523665855842405306752e-1609Q, -3.5183875354871145031995454351438789e-1660Q, -7.2453069573873944421690184084196628e-1713Q, -3.1719634253495420624848681187846285e-1767Q, -2.6125752080330097261369292566212969e-1823Q, -3.568653966381994484787922096951618e-1881Q, -7.0977732480251336872758023077199559e-1941Q, -1.7972768141068333989152413556564914e-2002Q, -5.0445828237798979207114411387487754e-2066Q, -1.3604595412453945762407996412329254e-2131Q, -3.0419951659449528528023254177983519e-2199Q, -4.8436592014037520285667566761754706e-2269Q, -4.6942170473823597199914323005808658e-2341Q, -2.3550263329098316285032485977513203e-2415Q, -5.1749636831144475403049010950928176e-2492Q, -4.1920868885180451051347682697190622e-2571Q, -1.0479018787402586343779450171950524e-2652Q, -6.7279428066803227116834111695132562e-2737Q, -9.1809880505079118230638356660916729e-2824Q, -2.1903121606778754894644610552460375e-2913Q, -7.4679789664508998469723121247024705e-3006Q, -2.9557873617341136266023224346917197e-3101Q, -1.0958275239557229340575496309183988e-3199Q, -3.0498491351714004349547292302889343e-3301Q, -5.0710549490564658785365657190857463e-3406Q, -3.9798833012314432652288251577412562e-3514Q, -1.1561503564308970430488476029765637e-3625Q, -9.6738350948812768619787679276120515e-3741Q, -1.7998403785619766408556530850576782e-3859Q, -5.7011595100947685691764189814097789e-3982Q, -2.3342553026008523985584602356036335e-4108Q, -9.2972354921660563358009254715497299e-4239Q, -2.6867404349734172649970964993288437e-4373Q, -4.1626263982921541967696302677355217e-4512Q, -2.5305298537002028475606439113724333e-4655Q, -4.374081747920579431517607591486263e-4803Q, -1.5419945401212975573693263841002279e-4955Q, -7.8687813783350283818994253864974705e-5113Q, -4.0807753246747505208452672626580765e-5275Q, -1.4931173692359951169542729406105663e-5442Q, }, + { 0.01227135511808220203174030407830294Q, 0.036802280950025085014502801868003454Q, 0.061297889413659975774096037893250044Q, 0.085734754877651055755695461536205953Q, 0.11008962993262801258027823870142222Q, 0.13433951528767223660361301319755489Q, 0.15846172828929950397368299153321965Q, 0.18243396969028915021484585689969531Q, 0.20623438831102876939480559034293115Q, 0.229841643254360753698787981399908Q, 0.25323496335600023568199079816688852Q, 0.27639420357617861412235821455333865Q, 0.29929989806396047268181013419640459Q, 0.32193330965336916623041220093195644Q, 0.34427647557970491862490100675820811Q, 0.36631224923490408185795345459447966Q, 0.38802433781211774758659161520378721Q, 0.40939733572152948912988463410721733Q, 0.43041675369143706432580814661825066Q, 0.45106904350045199476872844990592136Q, 0.47134161831799846568675411549444037Q, 0.49122286866081148740164998519670023Q, -0.48929782599744185793989666371765164Q, -0.47023008989822544160728474574480754Q, -0.45158254786020764535461909038883739Q, -0.43336282621498114195428483532083889Q, -0.41557755767733605834276062792428588Q, -0.39823238999036654097849262723755211Q, -0.38133199816727193874162067315553426Q, -0.36488010013557816387677409414947586Q, -0.34887947557569577047526159126703565Q, -0.33333198773426231868095335844342399Q, -0.31823860798357268745316074354464261Q, -0.3035994428915407927086292160567468Q, -0.28941376356199421334543326775454705Q, -0.27568003700259251963348266210052998Q, -0.26239595927717475510166267033301246Q, -0.24955849020075956493410868722363431Q, -0.2371638893386076311859247952179354Q, -0.22520775307556463019220672947952605Q, -0.21368505252818039398938452749375662Q, -0.20259017207968775297648115336201576Q, -0.19191694832666146249702413953519866Q, -0.1816587092359021720484117453151821Q, -0.17180831332064290072992681330484534Q, -0.16235818865639997533663276272992352Q, -0.15330037156853630364404549106194642Q, -0.14462654483572846910471674072111206Q, -0.13632807526589476511715224673350004Q, -0.12839605051362228117619033241835825Q, -0.12082131502061062975401342241486234Q, -0.11359450497302129819348705755904515Q, -0.10670608218178901767108607508338614Q, -0.10014636680382986857859380586600253Q, -0.093905568833595799431451407446515619Q, -0.087973818305513180839892673963966241Q, -0.082341194158450660178436474882477694Q, -0.076997751723445596499983664621487996Q, -0.07193354880544487378738311657933671Q, -0.067138670338759945862672351268719341Q, -0.06260325160428086186052507865402345Q, -0.058317500004230664509200379313199518Q, -0.054271715397367759935086056389293555Q, -0.050456309004063640355911746580908904Q, -0.046861820896606197349996098751978814Q, -0.043478936095419069610563231210812888Q, -0.040298499296663390818673202062521126Q, -0.037311528260921730030179369385366989Q, -0.03450922589637952691206152682222172Q, -0.031882991073143683811495499895307175Q, -0.029424428208099579660135740086865642Q, -0.0271253556620361184294276412754116Q, -0.024977812992693650455170906326981392Q, -0.022974067108942042492683430416652371Q, -0.021106617372505970898624990276714523Q, -0.019368199694551294992954740677403882Q, -0.017751789675058934941049112986218163Q, -0.016250604833268754660069071624504775Q, -0.014858105977601971243228436688712421Q, -0.013567997763391553658409398729735747Q, -0.01237422848648931564729341766812544Q, -0.011270989160397638106454864191015908Q, -0.010252711924012903699062738821083185Q, -0.0093140678263849278340314349076327353Q, -0.008449964034108265248268117472003357Q, -0.0076555405060818245590132017863229384Q, -0.0069261661794155687412632471018391501Q, -0.0062574347092383891891208397242483686Q, -0.0056451598040791099606160787309638234Q, -0.005085370197361128404963242365624777Q, -0.0045743042943771933124154458548517366Q, -0.0041084045328997985361611689079751989Q, -0.003684311494339074782205923019899892Q, -0.0032988578010873948724575222465114151Q, -0.0029490618343908704733333873759063219Q, -0.0026321213057645656305833925217639785Q, -0.0023454067136221407000743728815804873Q, -0.0020864547154229734242597171162514598Q, -0.0018529614442515743960802739125590691Q, -0.0016427757973362357767337812404644128Q, -0.0014538927225872833069713654109330111Q, -0.0012844465277911570122332123844688455Q, -0.0011327042356361946956708854910717802Q, -0.00099705900627114148706364731704457709Q, -0.00087602364761017102176873850865987398Q, -0.00076822423210114801927833212686428566Q, -0.00067239383717004607961542674246453911Q, -0.00058736642504742093080174568452091253Q, -0.00051207087617669287572188257954358842Q, -0.00044552518890326020005629570593666048Q, -0.00038683085665314188976467566548793199Q, -0.00033516743233532263998791108562179822Q, -0.00028978728824896558062724060959821788Q, -0.00025001057835114127416442774611755005Q, -0.00021522040834883412191823299277438955Q, -0.00018485821772693895358504217864611182Q, -0.00015841937651793126628162990110989201Q, -0.00013544899836493134204129687787204532Q, -0.00011553797023379563893736144870607114Q, -9.8319197997130553498037999641991487e-05Q, -8.3464066048770978005196778706600799e-05Q, -7.0679108115811218906095134416154613e-05Q, -5.9702885520625386671791420435362921e-05Q, -5.0303068310699595343932915440924077e-05Q, -4.2273713922018120404243909635658711e-05Q, -3.5432737373923361833214162324345645e-05Q, -2.9619566410724316247858190357851524e-05Q, -2.4692974507962358657498919760422057e-05Q, -2.0529084248443619898457582669713841e-05Q, -1.7019533243403755023062694063359981e-05Q, -1.4069794525207501119432380528847431e-05Q, -1.1597643166806136977541673876760615e-05Q, -9.5317607861225334492481477207976067e-06Q, -7.8104695663539218978433615931904191e-06Q, -6.3805874611085194148542316667027636e-06Q, -5.1963963511236276943307284768443108e-06Q, -4.2187150715072772351343816215627715e-06Q, -3.4140694292103354602072245113222152e-06Q, -2.7539515738216143655929212361430556e-06Q, -2.2141613647700348500196752438228238e-06Q, -1.7742226886238416354636940930406071e-06Q, -1.4168680155127991206906010386776301e-06Q, -1.1275848380651233667302406751686147e-06Q, -8.9421800420026716637883889021333717e-07Q, -7.0662233151961419975116851767251182e-07Q, -5.5636027112312322628504802544396849e-07Q, -4.3643976809083996211611047940700884e-07Q, -3.410878406808352344192770488162828e-07Q, -2.6555576704383762368205974553664254e-07Q, -2.0595212394180990975114609016580268e-07Q, -1.5910026405413012262681483592072574e-07Q, -1.2241714489336877307229490096356811e-07Q, -9.3810731511298667657736474465916103e-08Q, -7.1593485856820748829676007409030264e-08Q, -5.440972704881531639917700413368612e-08Q, -4.1174898509745034636641901499637178e-08Q, -3.1025009758847405806336107058366646e-08Q, -2.3274732865051716886351304700372955e-08Q, -1.7382826537542006005418736935360821e-08Q, -1.2923735225028943169773355461941788e-08Q, -9.5643672141012475959697164491130902e-09Q, -7.0451955080630225653421587634231792e-09Q, -5.1649492757248395049197216720378741e-09Q, -3.7682729974336732148768443187202036e-09Q, -2.7358262541647042643058722243498035e-09Q, -1.9763805681294590078061949445779507e-09Q, -1.4205419635481505647172465852581089e-09Q, -1.0157900987858722132374807163656952e-09Q, -7.2257800679698977337008871109952299e-10Q, -5.1128169466802636753557604076122797e-10Q, -3.5982705512040164549431243047583567e-10Q, -2.5185362244554210229589301236053854e-10Q, -1.7530147750309255605734608915901604e-10Q, -1.2132981051324705363357105718720941e-10Q, -8.3493950752320668610647319362559637e-11Q, -5.7122660267481958430713410881095016e-11Q, -3.8849686002793765883588257767026493e-11Q, -2.6263427379949721354783426839588953e-11Q, -1.7646499776378976222245772521934802e-11Q, -1.1783298320120630850539029584309311e-11Q, -7.818680628325362638575521404267539e-12Q, -5.1548364042751350429076854858018077e-12Q, -3.3765014608000294669628289654725219e-12Q, -2.1970744699592342642466439966825033e-12Q, -1.4200473669518126870628306394495551e-12Q, -9.1158007933577728676134065579326132e-13Q, -5.8113062505586808310528553401168741e-13Q, -3.6786791102075633999543555381361719e-13Q, -2.312068903576444768213986586668492e-13Q, -1.4426172485922308843621431499934686e-13Q, -8.9349666651298939216456676750565829e-14Q, -5.4925677721256790529564920614679325e-14Q, -3.350788309515877062958811342787956e-14Q, -2.0284076402444039895928235924589244e-14Q, -1.2182795128979644452912696549518128e-14Q, -7.2588537362052341752692102123089101e-15Q, -4.2900627866036669128285279549303027e-15Q, -2.514652539480771341683046756355483e-15Q, -1.4616871128475335847732485959402402e-15Q, -8.4243309583746983103209365972381765e-16Q, -4.8135175904015314514321104340303263e-16Q, -2.7263179430684054979795995181696999e-16Q, -1.5304422973965932233677561227408377e-16Q, -8.5137857250384433997363815737881969e-17Q, -4.6927950389611427068741326969599031e-17Q, -2.5625975950320089549856176296445119e-17Q, -1.3861334667950396744809652330676689e-17Q, -7.4257501921384642292801069180083189e-18Q, -3.9393094024445601833019849790813999e-18Q, -2.0690791459774228199242128751668536e-18Q, -1.0758286216493138282150652273565844e-18Q, -5.5366710173011999504598745894506669e-19Q, -2.819834003785898432921699582824987e-19Q, -1.4210063750313593796726974809925319e-19Q, -7.0842438781417380233044623416891119e-20Q, -3.4933505573095044526616590274445578e-20Q, -1.7035977510820099431072120902417317e-20Q, -8.2147060442121877800848286483420634e-21Q, -3.9159734384156989690338293870539541e-21Q, -1.8451498156271871363001830659526856e-21Q, -8.591874580623540129167786895666899e-22Q, -3.9530069577065764915635262899095704e-22Q, -1.7966697995134261385398916631645912e-22Q, -8.0654088208389219862969348472697735e-23Q, -3.5753372122620560623243551587275021e-23Q, -1.5647821323387363967354776667279086e-23Q, -6.760041764217369644940988147273804e-24Q, -2.8821363233025547133119762203866565e-24Q, -1.2124362329062417813651773042222047e-24Q, -5.0314218307880599929168429579030218e-25Q, -2.0592863122450067780181162680466505e-25Q, -8.310787797639985481399920298561774e-26Q, -3.3065180676145941342573597126851257e-26Q, -1.2965973462467399413826706323859068e-26Q, -5.010091032398552312889055575499255e-27Q, -1.9071793847355632162575945250968826e-27Q, -7.1505673339810973649967867585100117e-28Q, -2.6399060373682682300772738413986419e-28Q, -9.5946645421591590272737060192787035e-29Q, -3.4320780991310649618469641664780934e-29Q, -1.2079850663067081309863651387341263e-29Q, -4.1824647214881752797125541962674838e-30Q, -1.4241537066844817617919365428875337e-30Q, -4.7678333816988133611599026436806048e-31Q, -1.5689491781958062283731284050971648e-31Q, -5.0734388548496443499288192319785528e-32Q, -1.6116919160939245706339600215608967e-32Q, -5.0283566942543780691617432163678683e-33Q, -1.540320437147141644686176099192533e-33Q, -4.6313924434817901733319954389626016e-34Q, -1.3664702250574194828136706303116849e-34Q, -3.9550085269989845845237677023544696e-35Q, -1.1225918253644008151328041096174431e-35Q, -3.1238487433616834059785879847016762e-36Q, -8.5195402472064902632510499781952803e-37Q, -2.2764734813775829740707091909282255e-37Q, -5.9578473858349842310952826931317941e-38Q, -1.5267023004586063974485430859996629e-38Q, -3.8292452373883691255032248372279562e-39Q, -9.3976484123312742513645018653353223e-40Q, -2.2559187023391247540357057603608445e-40Q, -5.2951057740070273455910884012728247e-41Q, -1.21484005139195805370253212205352e-41Q, -2.7233329057563859457781652894773382e-42Q, -5.9629474724550016648059026687365969e-43Q, -1.2747904563208401684090170257821763e-43Q, -2.6599324647740072572781740009475107e-44Q, -5.4148975705500338800900730270033864e-45Q, -1.0750506783792922201321365237207054e-45Q, -2.0807277332937164031945232093695697e-46Q, -3.9244163140436388041993251545689042e-47Q, -7.2099378100469390278450504220931707e-48Q, -1.2897482330918123669983337886382095e-48Q, -2.2454989700172052890162893888242529e-49Q, -3.8033817751932373827258462682395899e-50Q, -6.2645207667921988981079909974995822e-51Q, -1.0029410834924645721226614397473029e-51Q, -1.5600495091009386993988441513950677e-52Q, -2.3565650292912781888129806450540921e-53Q, -3.4553986153009958542696149938952582e-54Q, -4.9157636744396300209125008789737936e-55Q, -6.781896900608377888472479708032872e-56Q, -9.0691940202443643747199815355477207e-57Q, -1.1749792443564338073595948464279018e-57Q, -1.4740730312062593807916913990480482e-58Q, -1.78984329859422798255692388149323e-59Q, -2.1022998433631042036525885470222986e-60Q, -2.3874311701754330999376394091254256e-61Q, -2.6199497113269397601815392049767616e-62Q, -2.7768131253969855575381129113408787e-63Q, -2.8408870962885800781023815369817483e-64Q, -2.8039688883465382638228147703461371e-65Q, -2.6684481602260540322238895901981613e-66Q, -2.447154080870857351995438102206883e-67Q, -2.1613619398610954911634747438934054e-68Q, -1.8373843424142226299889606750473108e-69Q, -1.5025103938453805607949990395131202e-70Q, -1.181175530500916159109188924367755e-71Q, -8.9211577919430036730810594588108188e-73Q, -6.4693987201487320046787049136480794e-74Q, -4.5015731884566473782551022645592059e-75Q, -3.0035842209914330912805318957189823e-76Q, -1.9204515997414609573256145075523711e-77Q, -1.1758810849678264495241195391760596e-78Q, -6.8900721571551738196701537405845152e-80Q, -3.8608563387442272849431335779050044e-81Q, -2.067461647504548936055359104346581e-82Q, -1.0572431033554667452601572946421337e-83Q, -5.1591788391388680011549213529878416e-85Q, -2.4006807351389258318746737135895233e-86Q, -1.0644152130176148388326772258538689e-87Q, -4.4934529232365451766727877769969084e-89Q, -1.8047048722799212873442491872423271e-90Q, -6.8904595506732549720140200562795596e-92Q, -2.4989637101487869067392480430274382e-93Q, -8.6018088469863275574189994840620463e-95Q, -2.8078924862967821005632597982452309e-96Q, -8.6849867519796128933390271698765342e-98Q, -2.5432396109247561096829294407826966e-99Q, -7.0446668978619724438762397385539258e-101Q, -1.8442018255867670937882313596001159e-102Q, -4.5587416725253559276425131397074849e-104Q, -1.0631088555204592085750091746032982e-105Q, -2.3367281748964035585738800969158434e-107Q, -4.8365042631130861220456426369022544e-109Q, -9.4175235620877562064839942442771856e-111Q, -1.7234789461694177262894389768372263e-112Q, -2.961523379734186944047236046386456e-114Q, -4.7734609518585313301965336240248189e-116Q, -7.2097952822898640408181240050284012e-118Q, -1.0193874335777637006841936637337494e-119Q, -1.3478166999163432272267137132118888e-121Q, -1.664711300732456447679638084338044e-123Q, -1.9186583950476330921591900813216499e-125Q, -2.0612648015288569084831497840721453e-127Q, -2.0618953788663489533345425995316527e-129Q, -1.9182619555236359873955912398757981e-131Q, -1.6579128778519222560290325566834437e-133Q, -1.3296099070094495947742421798539638e-135Q, -9.8828871549374803987116212190790475e-138Q, -6.8001851936680182899829217843093739e-140Q, -4.326204276337993340016401440114041e-142Q, -2.541595528522972170757701141043585e-144Q, -1.3771279659495821106478129347836407e-146Q, -6.8731739624384578591538313057486772e-149Q, -3.1556844841718302469140036866580175e-151Q, -1.3311046015007009547835866736304136e-153Q, -5.1514958005010918440961548583793399e-156Q, -1.8267037628056442215789990487980127e-158Q, -5.9267728539858017097499689403281403e-161Q, -1.7570179057820636782453206639159588e-163Q, -4.7525273644644354076088841580861234e-166Q, -1.1712151180634311771192081451244071e-168Q, -2.6258838722203054808989693856617573e-171Q, -5.348036158420190530754215189932846e-174Q, -9.8795260619978679822138888646044246e-177Q, -1.6528501557776328068085680725354548e-179Q, -2.5003947565086958266446692572037419e-182Q, -3.414859619193216220277979880289186e-185Q, -4.203653605459133226010277835528306e-188Q, -4.656508257021667283525304276478024e-191Q, -4.6339530996535525354074849617025537e-194Q, -4.1358781926049696182200878642464924e-197Q, -3.3049447294950072208241398344574307e-200Q, -2.3603956208589999494122184847510332e-203Q, -1.504047014068835401149660217771386e-206Q, -8.5352021958508046391358762569456352e-210Q, -4.3057568200632214990724928361534485e-213Q, -1.9273628185121124753795720186090423e-216Q, -7.6407868488415044113016735817166107e-220Q, -2.677582009683177696032426651320389e-223Q, -8.2781625043007349263821040953856809e-227Q, -2.2534850368391124035175853226989187e-230Q, -5.3905685902076735531578346280529237e-234Q, -1.1308097276815650308355193143392165e-237Q, -2.0759721813705410476824570327172646e-241Q, -3.3282687604583975257076029809432931e-245Q, -4.6500067135453696640703738061616968e-249Q, -5.6491873692239596907540663618927003e-253Q, -5.9546966626331923325761672881695778e-257Q, -5.4337990425534927929347405657826422e-261Q, -4.2828363537638634149994842306436067e-265Q, -2.9089854251520548595336724777976923e-269Q, -1.6986979835072953491948167874994245e-273Q, -8.5078874736023215648629448861985246e-278Q, -3.6459301611001785382074525089193986e-282Q, -1.3335508003947114825747939690317958e-286Q, -4.1528110309781799510004618371028852e-291Q, -1.0982617987267680462918374327390562e-295Q, -2.4602717457871291167756856167595572e-300Q, -4.656274386497415739809125734407304e-305Q, -7.4253896458167870494540985632704167e-310Q, -9.9507057756639922437150285707977622e-315Q, -1.1175135227544318386694717687968224e-319Q, -1.048835867763772555877163638261832e-324Q, -8.2033390786966798682011027925866189e-330Q, -5.3315735131149564162074506318716251e-335Q, -2.8710141330746883154448723258150022e-340Q, -1.2771564172267081609509990200434409e-345Q, -4.679237231988855089392537021634395e-351Q, -1.4076706654157792032739797667966913e-356Q, -3.4663625720057878756572289263095777e-362Q, -6.965054539543846678373236132189486e-368Q, -1.1383132196432715526434302555043402e-373Q, -1.5082487448329479128870155332131625e-379Q, -1.614816076667686258793882820784337e-385Q, -1.3923692408287144362457422616397937e-391Q, -9.6357705989726650954351553689911432e-398Q, -5.3335362887861762022108923833857644e-404Q, -2.3529529322735497728866304144280939e-410Q, -8.2438250199447939690869259289572704e-417Q, -2.2855238208173770201725378922268636e-423Q, -4.9955499211081324148253281714818585e-430Q, -8.5762081046608095383619080676476731e-437Q, -1.1520466338982341020319294100361546e-443Q, -1.2062291598612346324429863879453543e-450Q, -9.8055160740422284599044523336543234e-458Q, -6.1639765190753631642664330172075405e-465Q, -2.9843045493133686661298629930164973e-472Q, -1.10823285826398300175507717773449e-479Q, -3.1434790244922162638267628745063788e-487Q, -6.7817090417200778282332735946819014e-495Q, -1.1080137352329998556662834370761201e-502Q, -1.3649835831781010441492893639688094e-510Q, -1.2622778335796144231373603506854352e-518Q, -8.7230079476014413312144088584965706e-527Q, -4.4840352485865235615809427931860355e-535Q, -1.7066304212439665043951442710341263e-543Q, -4.7865441809026242359826342326024693e-552Q, -9.8452970343625269250999633839131245e-561Q, -1.4778790578536059527306608667934244e-569Q, -1.6110092952268207636105891878784886e-578Q, -1.2688728710128977236628155987138424e-587Q, -7.1841678295696924944920506687608424e-597Q, -2.9088109305034413675847131931270509e-606Q, -8.3780318645305679545954425238306175e-616Q, -1.7073663715760515568257862032253151e-625Q, -2.4485200806811154999909042531599294e-635Q, -2.4573647256627145606915141874939106e-645Q, -1.7162616532700922219515556951255632e-655Q, -8.2940336462928562559347382857731944e-666Q, -2.7573883713227551117703313812478972e-676Q, -6.2693384642795198624500212806556514e-687Q, -9.6903310752055252797176389760001952e-698Q, -1.0120668627816313397657974563178381e-708Q, -7.0982696439175036135044214112413552e-720Q, -3.3223490979680344536621296663739436e-731Q, -1.0311489910731877825037981367801772e-742Q, -2.1084888364587342412345374253683016e-754Q, -2.8218960738946335538305090801367889e-766Q, -2.4554534404272344111007341068959851e-778Q, -1.3797451463824018308120568764941013e-790Q, -4.9722352119016468411483808073270903e-803Q, -1.141174632389420312821039197546226e-815Q, -1.6562061873208393415939125326414615e-828Q, -1.5090517973695404620062521847072836e-841Q, -8.5691467995207824570732116071300356e-855Q, -3.0100992462861676532185696320551197e-868Q, -6.4915591914227985933992989098330185e-882Q, -8.5291480289311605733387922175211764e-896Q, -6.7742561345607759008586516480118676e-910Q, -3.2268177845742615217916640601654205e-924Q, -9.1442367835386354685297667090946292e-939Q, -1.5290755306231257347546172504187466e-953Q, -1.4962742317658249855750971462991461e-968Q, -8.4962983613273098681909435342233043e-984Q, -2.7756354317962233287713988508361331e-999Q, -5.1716412864088598574901876510481632e-1015Q, -5.4473756239469544256829106354679121e-1031Q, -3.2146847397534380657713310981627524e-1047Q, -1.0532205872897567235295617558264118e-1063Q, -1.8980407364210960924624682689327296e-1080Q, -1.8638413013078585989318566769757098e-1097Q, -9.878184707808045512821781472334627e-1115Q, -2.7982877400590951555125003865089596e-1132Q, -4.1953712551999192397935862947005203e-1150Q, -3.2957901195530958784930344030449164e-1168Q, -1.3428874261296622720955452657433921e-1186Q, -2.8087996369552811844908096236163199e-1205Q, -2.9843000347844479031722692316121269e-1224Q, -1.5935747451543053300901499796204061e-1243Q, -4.2306328294965009362324717933882302e-1263Q, -5.5228314338471652594276889712636454e-1283Q, -3.5058000799426290470482678197659356e-1303Q, -1.0699175488609417213076569958022624e-1323Q, -1.5518242259547372491845055361631511e-1344Q, -1.0572462818562698193769229028835047e-1365Q, -3.3433625974012960853422590535670218e-1387Q, -4.8485886276278601232637821173583126e-1409Q, -3.1852238059952872764052353398865978e-1431Q, -9.361416530125180143871854771737577e-1454Q, -1.2153997660730855590852157017720519e-1476Q, -6.8815302334269492601957883930533625e-1500Q, -1.6771176516091137975239852271122166e-1523Q, -1.7361595430709725552633953103091938e-1547Q, -7.5319512846392125534714956610857413e-1572Q, -1.3507317243577349648175397566286196e-1596Q, -9.8749002116827156793758713498543268e-1622Q, -2.9017600444094134408965714990369305e-1647Q, -3.3784846386968340746897973924953046e-1673Q, -1.5359688750531830898643386942465616e-1699Q, -2.6866527047176469998545109651176216e-1726Q, -1.7810521996687791658708980830532171e-1753Q, -4.4069918722394069695147388355206565e-1781Q, -4.0074519225536368666632735822098734e-1809Q, -1.3182831725717259025871898011803224e-1837Q, -1.5438654487729921345949019930471491e-1866Q, -6.332964675016807525269001303450335e-1896Q, -8.9500787015064447527716544282145449e-1926Q, -4.2852989232796780762796817666627905e-1956Q, -6.8338809894056785809735926537843468e-1987Q, -3.5675222855473848333391077011021476e-2018Q, -5.9902029406713556414824109568504936e-2050Q, -3.1778560977483191067544886656870642e-2082Q, -5.2307612099795388778239926501377221e-2115Q, -2.622585004749696786707859063948337e-2148Q, -3.9309566721122472026471743065924237e-2182Q, -1.7282752365752259330631889016659569e-2216Q, -2.1861776117108222661355073061235227e-2251Q, -7.8018157093958177389763723299669248e-2287Q, -7.6999746209936272927151686536635957e-2323Q, -2.0595655884579572710261610678442846e-2359Q, -1.4626001721502482969651469854201664e-2396Q, -2.7006580242811967764786623573354003e-2434Q, -1.2693899148553691566069699600055988e-2472Q, -1.4864297410986916900605959894904808e-2511Q, -4.2424104158612592858897827763816223e-2551Q, -2.886325476737890820535159860850169e-2591Q, -4.5765223979102481270954678544866293e-2632Q, -1.6528081850614599523381524655646053e-2673Q, -1.328274798653407243855327660531847e-2715Q, -2.3198223770931618563520410588946674e-2758Q, -8.5957488899967850735558558018957728e-2802Q, -6.5943404261286890309954636455911131e-2846Q, -1.0217558991001370161903847475864815e-2890Q, -3.1179630912672502182141115573865598e-2936Q, -1.8265451376704665882357813599889357e-2982Q, -2.0014192526716340395460104532447404e-3029Q, -3.9951106676925283777648320420658919e-3077Q, -1.4143501265341338386948746898388465e-3125Q, -8.6415836958539035920266027922282148e-3175Q, -8.8638553988044639042147624946934825e-3225Q, -1.4840219096599721556289490714622718e-3275Q, -3.9413909056885523526277851486916637e-3327Q, -1.6130887141803206541250840542937335e-3379Q, -9.8781642524919349085295532219577414e-3433Q, -8.7843931949057976239401506792380659e-3487Q, -1.1004454490075535460405971636548993e-3541Q, -1.8829655853829584691138469084815955e-3597Q, -4.2649913833758498152779971325727165e-3654Q, -1.2387002826718376930423594688980877e-3711Q, -4.4662108799989251681924501424182082e-3770Q, -1.9344990293606773314152567555369947e-3829Q, -9.7355570095915342874542008807254313e-3890Q, -5.5029370896508671666190160013096548e-3951Q, -3.3753310533018114196752016778611603e-4013Q, -2.1693889909489136218749502032440802e-4076Q, -1.4100342946015435859763977543837031e-4140Q, -8.9396827455669883373190732493946026e-4206Q, -5.3296285690324414372171445344916662e-4272Q, -2.8786292587718554179132949540534825e-4339Q, -1.3563301511005327997304553445712977e-4407Q, -5.3648093624713363852431573541370394e-4477Q, -1.713199655224600838900218899825865e-4547Q, -4.245367036181261378573090733274636e-4619Q, -7.8414039345064814928186445860311876e-4692Q, -1.036301574835369426138520680597679e-4765Q, -9.4005882200264089643362665220611737e-4841Q, -5.6115028230432295314938587541868893e-4917Q, -2.1117808872654504815205210716165957e-4994Q, -4.7969059512296546218382678391152525e-5073Q, -6.2923913054777813860480394257938674e-5153Q, -4.557320132561115296699430714437428e-5234Q, -1.7411358133348974154538037089867482e-5316Q, -3.3501410753353566412413655174778596e-5400Q, -3.097148592957890545441753638107994e-5485Q, }, + }; + m_weights = { + { 1.5707963267948966192313216916397514Q, 0.23002239451478868500041247042232167Q, 0.00026620051375271690865701015937223316Q, 1.3581784274539090834221967874745002e-12Q, 1.001741678406625296380989561316704e-35Q, 2.6763080920617460968679410949198166e-99Q, 7.7670706886334062872146243844453043e-273Q, 2.6770629459428179490864940513366914e-745Q, 2.497123188557279400555877663164169e-2030Q, 3.7829658019347837822103381908509695e-5524Q, }, + { 0.96597657941230114801208692453802948Q, 0.018343166989927842087331266912053799Q, 2.1431204556943039357697233307232118e-07Q, 2.8003151019775889582580016992170153e-21Q, 1.123270534548691878982747435678734e-59Q, 9.1753268750017841272445320853712195e-165Q, 3.7096469071314047287189555701359196e-451Q, 2.1358827779704788581082183250272886e-1230Q, 2.4637500105830058174530832607403982e-3349Q, }, + { 1.3896147592472563228608191295320513Q, 0.53107827542805397476113231761531408Q, 0.0763857435708323041883405748316428Q, 0.0029025177479013135935932948904580215Q, 1.198370136317072004690126421734261e-05Q, 1.1631165814255782765597155262382926e-09Q, 2.197079236297979917409204112478354e-16Q, 1.3635103307637615413724747655081585e-27Q, 3.3700568540419264989934173928550566e-46Q, 5.1969783800898552138641449339116869e-77Q, 6.0080341705713501485949327691027087e-128Q, 4.564204056355599097208981999351872e-212Q, 6.769934297924075481071769868728861e-351Q, 6.3189772257105317991231885214248323e-580Q, 1.1318535773666956837787222565063026e-957Q, 1.300088515992481474129980450433913e-1580Q, 8.3018817290920015915795630666821309e-2608Q, 1.6615718540023971313123206033705184e-4301Q, }, + { 1.5232837186347052131949627901588453Q, 1.193463025849156963909371648222972Q, 0.73743784836154784136450085848526681Q, 0.36046141846934367416541940530511192Q, 0.13742210773316772341110281600075763Q, 0.039175005493600779071814125724013544Q, 0.0077426010260642407123309111640668157Q, 0.00094994680428346871690539180358829065Q, 6.2482559240744082890784437584871091e-05Q, 1.8263320593710659699109280974494727e-06Q, 1.8687282268736410131523743935312467e-08Q, 4.9378538776631926963708240981686386e-11Q, 2.2834926702613953995564216678996858e-14Q, 1.1227531428181551500942554523402945e-18Q, 3.0976539701173543715458514327631078e-24Q, 2.1121233435372255913526811977623162e-31Q, 1.2424147570616052367007700396344415e-40Q, 1.6327707331799493237812947626932747e-52Q, 8.460688731096213796022276271481337e-68Q, 1.8644492079588650273068038890475311e-87Q, 1.0013128468666430206628687242136761e-112Q, 3.3344435411868990213060767519646709e-145Q, 6.1751576225487765303410376146008819e-187Q, 1.4953240022257075856966174469213765e-240Q, 1.995167671391421283850079422966012e-309Q, 6.7986022131150125295165555843516628e-398Q, 1.6112168443011532782661941324936245e-511Q, 1.8998420056198456993096891152100817e-657Q, 7.4500584401117916806764514072363403e-845Q, 1.6092274599867451896713421807328385e-1085Q, 1.4294469100875426784155324297970964e-1394Q, 1.9699812322172327797426511042200449e-1791Q, 4.8353547995000100603312087832016511e-2301Q, 2.0016297694765957880783422493672502e-2955Q, 1.0619575437766938720176582011701185e-3795Q, 1.1494098249640889641399434474174788e-4874Q, }, + { 1.5587733555333301450624222553039117Q, 1.4660144267169657810275411936658895Q, 1.2974757504249779979885383085284353Q, 1.0816349854900704074448532749336471Q, 0.8501728564566200689527310980522113Q, 0.63040513516474369106015058023920241Q, 0.44083323627385823706771270610993222Q, 0.29024067931245418500061231479966878Q, 0.17932441211072829296345978397121765Q, 0.10343215422333290062482385052951418Q, 0.055289683742240583845301977440481557Q, 0.027133510013712003218708018921405436Q, 0.012083543599157953493134951286413131Q, 0.0048162981439284630172757660071387715Q, 0.0016908739981426396472155417510249034Q, 0.00051339382406790336016588906448858883Q, 0.00013205234125609974878680402074340758Q, 2.8110164327940134748736157546988307e-05Q, 4.8237182032615502124025440343943169e-06Q, 6.4777566035929719907733987417697432e-07Q, 6.5835185127183396672340995882066949e-08Q, 4.8760060974240625868904606426809347e-09Q, 2.5216347918530148571826656491854398e-10Q, 8.6759314149796046501956077624778843e-12Q, 1.8802071730750649809476255843771975e-13Q, 2.4124230384308786393899307730550295e-15Q, 1.7084532772405701711664118263431986e-17Q, 6.1682568490762382593952567143955272e-20Q, 1.0376797238528706160610863270915827e-22Q, 7.3459841032226935608549262812034877e-26Q, 1.9497833624335174811763249596143101e-29Q, 1.7024387761257547218675324410867209e-33Q, 4.2164863709484278882204462399998679e-38Q, 2.5044277116275284317811847533784782e-43Q, 2.9493601457461933137195159567099426e-49Q, 5.5513323569653710605229337238942258e-56Q, 1.3081165120210821643686110907899211e-63Q, 2.9260824463823975328629659452367614e-72Q, 4.5407734669997824148941045053504133e-82Q, 3.4265635692086987660673772586083229e-93Q, 8.4064359488831769989074631453464805e-106Q, 4.2486192688198694407012327873632857e-120Q, 2.6378208263504521457685936139412266e-136Q, 1.1199291455841279757620547508811484e-154Q, 1.6741593786710889281267003484320699e-175Q, 4.1533060810194922183660114746657927e-199Q, 7.291512660905660427014583724901483e-226Q, 3.4484028358868219730957875473275039e-256Q, 1.470608613733186341839899819856118e-290Q, 1.6363373245553192894384271318647291e-329Q, 1.1653396430451048019810427186628332e-373Q, 1.0806491346819681711718251969578419e-423Q, 2.1475318157612117601623532784345252e-480Q, 1.1837197513952188698387978224315556e-544Q, 1.7840752052025753295716828917620433e-617Q, 5.3242634124221408997248254448704286e-700Q, 1.6062136117391783778620623735552911e-793Q, 1.6828070526919983211589685788034629e-899Q, 1.3428023135061849684751687999574317e-1019Q, 1.0762445467071890806353267455766392e-1155Q, 6.4211043768224511497561388149947945e-1310Q, 1.0999298719684690155223457966483755e-1484Q, 9.9551400313164741067089535072684105e-1683Q, 3.7874715825152699680401002242066869e-1907Q, 1.8633554093895907210742600678288691e-2161Q, 1.2425018321859109200647073828888711e-2449Q, 3.4744660691878314268031415759661457e-2776Q, 3.1635539874917104171786237474568114e-3146Q, 1.520164792309349080207015729831993e-3565Q, 1.0587692108054511977730210493803509e-4040Q, 3.9269571376984945676082618447700578e-4579Q, 2.9165229925801338811576465571535852e-5189Q, }, + { 1.56778143130722185718457839560813Q, 1.5438811161769592204120195652304554Q, 1.4972262225410362896175121106253706Q, 1.4300083548722996676294145121698845Q, 1.3452788847662516614631881421588284Q, 1.2467012074518577048171373166756783Q, 1.1382722433763053733718328301717509Q, 1.0240449331118114482594022454942541Q, 0.90787937915489531693097972059732257Q, 0.79324270082051671787385259862995589Q, 0.68306851634426375464118893187202369Q, 0.5796781030877876470811045242977012Q, 0.48475809121475539286590775419868886Q, 0.39938474152571713514696619655275183Q, 0.32408253961152890401776015000060852Q, 0.25890463951405351600251387258910213Q, 0.20352399885860174518647884913232324Q, 0.15732620348436615026738563376259734Q, 0.11949741128869592427594275905822144Q, 0.089103139240941462840959442033942474Q, 0.065155533432536205042255277931864103Q, 0.046668208054846613643791300289316396Q, 0.032698732726609031112522702100248949Q, 0.022379471063648476483258477281403216Q, 0.014937835096050129695520628452448085Q, 0.0097072237393916892692355786307589937Q, 0.0061300376320830301252445771940873246Q, 0.0037542509774318343022967144602791306Q, 0.0022250827064786427021584620411703896Q, 0.0012733279447082382026740903535577353Q, 0.00070185951568424227080474304718567332Q, 0.00037166693621677760301295760218968355Q, 0.00018856442976700318571529922115575474Q, 9.1390817490710122732277133049597672e-05Q, 4.2183183841757600604161049520839395e-05Q, 1.8481813599879217116302847163026167e-05Q, 7.6595758525203162561568606199506296e-06Q, 2.991661587813878709443954037223499e-06Q, 1.0968835125901264731967931401061751e-06Q, 3.7595411862360630091183817668146341e-07Q, 1.1992442782902770218679992206070689e-07Q, 3.5434777171421953042822362946016499e-08Q, 9.6498888961089633609206181967630592e-09Q, 2.4091773256475940778596088439332178e-09Q, 5.482835779709497755012456926288581e-10Q, 1.1306055347494680535789879497045831e-10Q, 2.0989335404511469108589724179284344e-11Q, 3.4841937670261059685298917826974968e-12Q, 5.1341275245014207474276938761808301e-13Q, 6.6639922833087653243643099189129361e-14Q, 7.5567217757805651894455261838657557e-15Q, 7.4209932309922167588538662071098972e-16Q, 6.2528048446104553564782731960667282e-17Q, 4.4757595066690969713939566842636666e-18Q, 2.6931206614869695057714525810417824e-19Q, 1.3469941569542286092134858963015562e-20Q, 5.5335834994155711455633228489644644e-22Q, 1.843546974718149378096179376158747e-23Q, 4.9139368712649040083308200957748574e-25Q, 1.0329391306928575387668383646132905e-26Q, 1.686277003849260652771901316947161e-28Q, 2.1033057490018089523843332100004934e-30Q, 1.9699209796232343253581550830906289e-32Q, 1.3599894616303795697940905597197162e-34Q, 6.7859788375592479085540582968820347e-37Q, 2.3965063699443217406067231991536888e-39Q, 5.8579569483084210846386345961131375e-42Q, 9.6783927755717095571366983570964434e-45Q, 1.0538361132564208838364959652125833e-47Q, 7.3615858309787649210787574154381217e-51Q, 3.2059785352833866133968160706885294e-54Q, 8.4430892661864256082234111135836121e-58Q, 1.301669487442817299199572925297743e-61Q, 1.1348985048372046635260385887339235e-65Q, 5.393881369511580841024486229556929e-70Q, 1.3438019476233711028911671531262384e-74Q, 1.6833095936633240263022508251714738e-79Q, 1.0142059074468158538185578436642225e-84Q, 2.8036136193449874498478125381332892e-90Q, 3.3815387893836694650191340608232241e-96Q, 1.6868699597973134851614068554314712e-102Q, 3.2876716054636550397600067563177134e-109Q, 2.3561803975866304919776634857937977e-116Q, 5.8212714268864182676007475006940935e-124Q, 4.6289769416942015466154791282940135e-132Q, 1.1011712417530966759846558629187253e-140Q, 7.2497708296024463973360079596584377e-150Q, 1.2159344493950079010263214501254854e-159Q, 4.7567332287785056252666937863445785e-170Q, 3.9513561319289952903145090015894379e-181Q, 6.3069398037899023031641976078084843e-193Q, 1.7390958115772548420234336819215406e-205Q, 7.3973824490445198187310257149181993e-219Q, 4.3025693007354699025906405899973485e-233Q, 3.0098295695832487716215316168466764e-248Q, 2.2089957315907529731668895943677893e-264Q, 1.4707383302537016829517267662493224e-281Q, 7.6092047493292429607812922938663979e-300Q, 2.5944582029845183791860228756757574e-319Q, 4.8919577835343219860639698905291437e-340Q, 4.2321357135722486316129327838961609e-362Q, 1.377082367391413218915156512362392e-385Q, 1.363952742750262175587655506596678e-410Q, 3.282973957767873844612670506024268e-437Q, 1.510934727927437884800902577518545e-465Q, 1.0301501430760404101952742972682365e-495Q, 7.9295801879971179076172461167077394e-528Q, 5.1606434722064335409175586840009083e-562Q, 2.0872322362104964031726231732635154e-598Q, 3.7804014749166388131317806793058942e-637Q, 2.1632858420984952938030309932161571e-678Q, 2.697969237867160734724398915290777e-722Q, 4.939067732330739558253971083984646e-769Q, 8.7137367268607555569549275663836614e-819Q, 9.4666568790742115790866970449104673e-872Q, 3.9314930560193364712728646099681646e-928Q, 3.7572363915786555422592370375561427e-988Q, 4.8138810542737654527596947066774263e-1052Q, 4.6523364803809138193102091214841167e-1120Q, 1.8387400682879078406702806989874382e-1192Q, 1.5488882086634896755007358131079033e-1269Q, 1.3896133256118102918631384214217437e-1351Q, 6.3450498372554790778619758345952674e-1439Q, 6.718192925085413277150654870462718e-1532Q, 7.1439377408604826875747242429241183e-1631Q, 3.1307195483169831435149812630603435e-1736Q, 2.1906656484419255825224621505729532e-1848Q, 8.9202911849845695393803303860897414e-1968Q, 7.2181700833126514821590990431204877e-2095Q, 3.69827933239331943547271842529346e-2230Q, 3.5509166675222604652849078491152928e-2374Q, 1.7482004370958645792029686167921119e-2527Q, 1.1106891190500999916896792610406226e-2690Q, 2.0967298422181990469075373625054175e-2864Q, 2.4632275747625679891658308849723178e-3049Q, 3.4100009144092401643961247399658256e-3246Q, 9.461422635018898458311235983749575e-3456Q, 7.9828243452163492698389979442314978e-3679Q, 2.751586075619233132202409409236628e-3916Q, 4.573406478327970954594749406297331e-4169Q, 3.7694660070555500868572517438534528e-4438Q, 1.3681877706178551350653622286560967e-4724Q, 1.6613468385141710911219854343435161e-5029Q, 4.3416310672295866779590889330326041e-5354Q, }, + { 1.5700420292795931467492986437735064Q, 1.564021403773232099877114326609257Q, 1.5520531698454121192208571607383634Q, 1.5342817381543034316353772145375646Q, 1.5109197230741697127061791873634288Q, 1.4822432978855380699918515557505545Q, 1.4485862549613225916106262684975582Q, 1.410332971446259012949044799400295Q, 1.3679105116808964880788896668731933Q, 1.3217801174437728578945834791848425Q, 1.2724283455378627082346213018713573Q, 1.2203581095793582207386389532998567Q, 1.1660798699324345766327658650910729Q, 1.1101031939653403795568765186098518Q, 1.0529288799552666555511877000344537Q, 0.99504180404613271513656897365437693Q, 0.93690461274566793365666309492163748Q, 0.87895234555278212039056482196455926Q, 0.82158803526696470334184690990337618Q, 0.76517929890895613670160403610671453Q, 0.7100559012054689838533558330696999Q, 0.65650824613162753075637187406975179Q, 0.60478673057840362157663695141011708Q, 0.55510187800363350959266471517172014Q, 0.50762515883190809969744129508607212Q, 0.46249039805536776129564056825534108Q, 0.41979566844501548065589545493380249Q, 0.37960556938665160999227127370288764Q, 0.34195379592301683230370363663700268Q, 0.30684590941791694932077002517250017Q, 0.27426222968906810637090960121437003Q, 0.24416077786983990867520612813967892Q, 0.21648020911729617038131524528780352Q, 0.19114268413342749532225095746508781Q, 0.16805663794826916233031413596643794Q, 0.14711941325785693247796311096185123Q, 0.12821973363120098675278273881295278Q, 0.11123999898874453034874054225116091Q, 0.096058391865189467849178662072631058Q, 0.08255078811070173765353752357300814Q, 0.070592469906866999351840896875301286Q, 0.060059642358636300319399035772689021Q, 0.050830757572570471070050742610585547Q, 0.042787652157725676034469840927028069Q, 0.035816505604196436523119991586426561Q, 0.029808628117310126968601751537697736Q, 0.024661087314753282510573737140694345Q, 0.020277183817500123925718353350832364Q, 0.016566786254247575375293749008565117Q, 0.013446536605285730674148393318910799Q, 0.010839937168255907210869762269731544Q, 0.0086773307495391815853559138369297225Q, 0.0068957859690660035329120415695881464Q, 0.0054388997976239984331249261778682035Q, 0.0042565295990178580164922070775372331Q, 0.0033044669940348302363413922293941345Q, 0.0025440657675291729677737674183717872Q, 0.0019418357759843675814337234877431187Q, 0.0014690143599429791058440789865212569Q, 0.0011011261134519383861925290686638441Q, 0.00081754101332469493114796258629778861Q, 0.00060103987991147422573401527665731798Q, 0.00043739495615911687786086941160964625Q, 0.00031497209186021200273816328980956318Q, 0.00022435965205008549104107147410537586Q, 0.00015802788400701191949230617575051454Q, 0.00011002112846666697224455022994264118Q, 7.5683996586201477788165374446595019e-05Q, 5.1421497447658802091816641948792101e-05Q, 3.4492124759343197699875355951697823e-05Q, 2.2832118109036146591351441225788429e-05Q, 1.4908514031870608449073273504082825e-05Q, 9.5981941283784710776464665022285646e-06Q, 6.089910032094903925589071885768365e-06Q, 3.806198326464489904501471179191111e-06Q, 2.3421667208528096842717147966610279e-06Q, 1.4183067155493917523149875336299115e-06Q, 8.4473756384859863469243774523267053e-07Q, 4.9458288702754198508296104158884319e-07Q, 2.8449923659159806339254761906866073e-07Q, 1.6069394579076224910854372243815059e-07Q, 8.907139514024238712375244371846641e-08Q, 4.8420950198072369668651027805560416e-08Q, 2.5799568229535892380414249079124995e-08Q, 1.3464645522302038795727293982948898e-08Q, 6.878461095589900111136392082034183e-09Q, 3.4371856744650090511359612982214485e-09Q, 1.6788897682161906806903450478834801e-09Q, 8.0099784479729665355704238927483163e-10Q, 3.7299501843052790038025133658401989e-10Q, 1.6939457789411646875651299532593942e-10Q, 7.4967397573818224522463983518852213e-11Q, 3.2304464333252365759775564205312505e-11Q, 1.3542512912336274431500361753892705e-11Q, 5.5182369468174885820640573102698266e-12Q, 2.1835922099233609052099969606827855e-12Q, 8.3831289605026670935474089966848491e-13Q, 3.1194977286848081234778051650691241e-13Q, 1.1240208959922861475529576279412917e-13Q, 3.9176794506016467939451671035436525e-14Q, 1.3194342231967989407842390664342776e-14Q, 4.2891962220679080018159948630799523e-15Q, 1.3443222875395221462210806176730482e-15Q, 4.0575577022628576213784976604019497e-16Q, 1.1779812127248348143079542926522782e-16Q, 3.2853861628847006575461912014493979e-17Q, 8.791316558919890092526902998792709e-18Q, 2.2540748304368819446158103388678448e-18Q, 5.5301769128403375894905317866280607e-19Q, 1.2964527140689369428189650628176523e-19Q, 2.8999645564315719864785175397007916e-20Q, 6.1801432493399884472690523294170016e-21Q, 1.2528676432273210433625630071013181e-21Q, 2.4122505468361010054762467348044815e-22Q, 4.4039066999398680900169681674054685e-23Q, 7.6105778075820625755732634136772293e-24Q, 1.2428051652123164945236765528871363e-24Q, 1.9143106902239760676488034727771211e-25Q, 2.7761251025850583169467065718383927e-26Q, 3.7831240728137797052283562714381636e-27Q, 4.8349101548188476652448113863661033e-28Q, 5.7831786972290529603663947121744896e-29Q, 6.4605757034417219896312763235825947e-30Q, 6.7260373895879405356485977108634093e-31Q, 6.5111534511374516546657070065569591e-32Q, 5.8474090745481019884619654259625198e-33Q, 4.8600460551422733352577609809902488e-34Q, 3.7292395298436024198774848925631642e-35Q, 2.6351230616803666949611566230315689e-36Q, 1.7101926401490697241365293331985362e-37Q, 1.0166685309552127228580017693019009e-38Q, 5.5206909443427625675929025278647327e-40Q, 2.7304755116605008208950089540576932e-41Q, 1.226380966652512847885874020657185e-42Q, 4.9868392983536125725869145787511357e-44Q, 1.8300654157711633015675688730645846e-45Q, 6.0413503225082640435207520715838788e-47Q, 1.7880003085257126775048837670283103e-48Q, 4.7278206635290633557485891499143011e-50Q, 1.1129101718049771950203375840916927e-51Q, 2.3236007287936054634490409808175661e-53Q, 4.2865792135438400818864832679645293e-55Q, 6.9598735225537515535247172084789902e-57Q, 9.905399812867464416784441328019894e-59Q, 1.2305690322370172647654483736261024e-60Q, 1.3287055463682438112745418077294776e-62Q, 1.2413844609001762091919818631042531e-64Q, 9.9894889830989163005162036230629025e-67Q, 6.8909792890209806239542239718708282e-69Q, 4.0550412837679391530484571616360602e-71Q, 2.025325478051833791855348665597344e-73Q, 8.541193860817129005635611395334028e-76Q, 3.0250584958478075188394058484674014e-78Q, 8.9481574983737847286009199268691343e-81Q, 2.1980365957192520850759686078382165e-83Q, 4.457339084251821318983583351230449e-86Q, 7.4167316712100725345384814229429518e-89Q, 1.0062789446470429122974386215670469e-91Q, 1.1060617024861203148604052551620709e-94Q, 9.7834581723103753096719332058265664e-98Q, 6.9161160403270601376643047091198938e-101Q, 3.8797049192578037362892459079447827e-104Q, 1.7144044358094688607777762897347039e-107Q, 5.9226551398143962456841752185003654e-111Q, 1.5871361682624074916136417159312335e-114Q, 3.2726893534998181040216294108876001e-118Q, 5.1496220394807877679493913965250783e-122Q, 6.1305346175987605932476180523733874e-126Q, 5.473030846543808520009167994615492e-130Q, 3.6307475309683583384111588486160093e-134Q, 1.7730007537696346688915570033698743e-138Q, 6.3116464532127354831381913256985002e-143Q, 1.621583693919220194566929433171311e-147Q, 2.9757935132829859613289387859126523e-152Q, 3.8591705765442151638142119206858087e-157Q, 3.4980555618589782147605871793646301e-162Q, 2.1911032417571959066795311563828556e-167Q, 9.3736234796108920474724971094564098e-173Q, 2.7058522933326574274299142121455261e-178Q, 5.2051004982716048091082896972654894e-184Q, 6.5869897226619604622569213699928695e-190Q, 5.4113353348952773541650437440862393e-196Q, 2.8465905848751190783736476660662487e-202Q, 9.4537279066777943316631814110533656e-209Q, 1.9534309746768722817386272635097574e-215Q, 2.4738194858760899904808482337660157e-222Q, 1.8904418888763632604075097028006049e-229Q, 8.5786751348486017374921228218675884e-237Q, 2.273808044980070953576133599904938e-244Q, 3.4605977152655857787870383972443829e-252Q, 2.9714191752129370394435745626764138e-260Q, 1.4135174726041132417612082341294276e-268Q, 3.6561278873359158194812461400887331e-277Q, 5.0434133108713706852575809257966216e-286Q, 3.6370069739853174907232860458211075e-295Q, 1.3431929449017207014618114298104235e-304Q, 2.4870346219017639693976883745872467e-314Q, 2.2586869384020337841470045671934569e-324Q, 9.8364979621195023902799369645695391e-335Q, 2.0067948188168259586571751290590148e-345Q, 1.8723608312818058521936506625581294e-356Q, 7.7931764302539272294837164978121943e-368Q, 1.4104242105367751421756306559719189e-379Q, 1.0809707526373134180302026203191734e-391Q, 3.413982422671325929147843223533059e-404Q, 4.3198627266120931546631293969877099e-417Q, 2.1273069601360357294162339387648629e-430Q, 3.9566885872209056027370422510981332e-444Q, 2.6949582298096968115536767242364878e-458Q, 6.5109076931010576854739908270299986e-473Q, 5.3989788614177770156022874990436434e-488Q, 1.4853198669149487016912694923346188e-503Q, 1.3090503251521584428930352496581121e-519Q, 3.5647376837004158357511297570921346e-536Q, 2.8896313028497521005627356654844694e-553Q, 6.7095854399465738026181868874992309e-571Q, 4.2889584337257558657454644184109877e-589Q, 7.2448311439514538923291336946008664e-608Q, 3.1001155749336353171177254469615123e-627Q, 3.2171491615676533889663223546563542e-647Q, 7.7406570695117283869992601856060778e-668Q, 4.1223744692343859730646543586548491e-689Q, 4.6322294010052851367822679106298139e-711Q, 1.045335659900684312871171221243375e-733Q, 4.5020856241223108492475174506019875e-757Q, 3.5109989183708310084991820318792658e-781Q, 4.6962204836998229475507359520919518e-806Q, 1.0187348472076847046857363810773889e-831Q, 3.3829163365599114939619605636207329e-858Q, 1.6201873291670617651278341356078551e-885Q, 1.052417929633641351707580294560769e-913Q, 8.7019793416937745490332209560882093e-943Q, 8.5790292111351760552267505428090183e-973Q, 9.4260553303166607465714226577573373e-1004Q, 1.0765751303003708312349678449534298e-1035Q, 1.1895201137046793178631747385045816e-1068Q, 1.180625613342395519601533530260917e-1102Q, 9.7508687447891759767569844552344533e-1138Q, 6.1928172812184124261845708258990883e-1174Q, 2.7879318459600816091819660853849943e-1211Q, 8.1797014327573742781475939847205791e-1250Q, 1.4341956738449380463933781088853353e-1289Q, 1.3742136648085548142182437043687567e-1330Q, 6.5614725919712462874880606553304539e-1373Q, 1.4193967474068871671305637677852339e-1416Q, 1.260966346895598155305400631354573e-1461Q, 4.1570767913697591845636153183534885e-1508Q, 4.5808704947181685782204593123998747e-1556Q, 1.5147204987797220696721543058866571e-1605Q, 1.3446319068528240765599796700835479e-1656Q, 2.8568551875090842255902159455984979e-1709Q, 1.290420656637587734011142529706619e-1763Q, 1.0965883695419688652509296670806449e-1819Q, 1.5454358117029190110066857968185965e-1877Q, 3.1713220921953507873149502965607843e-1937Q, 8.2852363729842743064713740610323336e-1999Q, 2.399312892921620764854020931161764e-2062Q, 6.6760404808499701150348715300290141e-2128Q, 1.5401518790175723653421594673899941e-2195Q, 2.5301735371980282112359832727046555e-2265Q, 2.5299480120770166824316075523796362e-2337Q, 1.3095313462113548374850512340351666e-2411Q, 2.9689243920149770430661749727744362e-2488Q, 2.4813830291085919140036931759581715e-2567Q, 6.3996445311970094107659804037592786e-2649Q, 4.239251909781851582408879081262827e-2733Q, 5.96853928335010438943934366176163e-2820Q, 1.4691168838129215779634944240558196e-2909Q, 5.1680311504236953911307750231831853e-3002Q, 2.1104104354704386557845763111476113e-3097Q, 8.0724923764466854235161222774323272e-3196Q, 2.3180110258875131728741090820512076e-3297Q, 3.9765565093255272984730390679523982e-3402Q, 3.2199629992549034490326426922965119e-3510Q, 9.6508721511747631002418659479792544e-3622Q, 8.3314890242471693358884470423786766e-3737Q, 1.5992989019877436694379940011582504e-3855Q, 5.2267357291195312826488098055916878e-3978Q, 2.2079407038664800796624257814276463e-4104Q, 9.0732856778373185742790691459304111e-4235Q, 2.7052547418764871675136904567273848e-4369Q, 4.3243575109951310431228833829026739e-4508Q, 2.7122975060794559909023695709869724e-4651Q, 4.8370932158845122662637153824534517e-4799Q, 1.7593494088080091822518592461420403e-4951Q, 9.2629313370158738463326647490577837e-5109Q, 4.9562745065321184922933588793911493e-5271Q, 1.8710195150434747289751408668152425e-5438Q, }, + { 1.5706077165382752220570950499753154Q, 1.5690996953516691278086267057102919Q, 1.5660882389174613671811758395264413Q, 1.5615824934918106190924913174771039Q, 1.555596114631660422166342990902623Q, 1.5481471912355573327293783013569808Q, 1.5392581453118818324345492520631963Q, 1.5289556083545807159292699900112433Q, 1.517270275405054680346497720954261Q, 1.5042367380636772129345718219774013Q, 1.4898932978832971219484878984168431Q, 1.4742817617280797281467109946343097Q, 1.4574472208125486663314082491076236Q, 1.4394378152464069775161779990628486Q, 1.4203044859996911837480782185431865Q, 1.4001007162694446513758901419788661Q, 1.3788822642731375176779450629832807Q, 1.3567068895156054674526777181888561Q, 1.333634074575756135382992612713127Q, 1.3097247444374397383128243464895219Q, 1.2850409853467272312421857577496357Q, 1.2596457651166706020800416735545885Q, 1.2336026567219467107844443624642869Q, 1.2069755669313082254213358903568052Q, 1.1798284716173337422807600081541025Q, 1.1522251592625474295137962600991148Q, 1.1242289840506032580653098282178496Q, 1.0959026297929722120123658782081807Q, 1.0673078857975038741099002717210955Q, 1.0385054356373923292061824367921921Q, 1.0095546596294298182250582016592233Q, 0.98051345168085502517972727278507908Q, 0.95143805101635270871239123838108163Q, 0.92238288915245514551412028761663168Q, 0.8934004523471959982711625120192134Q, 0.86454115961966899850156197132807295Q, 0.83585325630826713062996261999715574Q, 0.80738272301876303826323728461609798Q, 0.77917319970479798076341140529382576Q, 0.75126592452435685914062625329355162Q, 0.72369968702683029319553573992504406Q, 0.69651079514654688482101628454709857Q, 0.66973305541029099783625527361406845Q, 0.6433977657082528556344204308635143Q, 0.61753371992990889983731720244260268Q, 0.59216722372820694935702418127019Q, 0.5673221206467387178357679693601802Q, 0.54301982782484286720274321665461387Q, 0.51927938048424633084628868358974812Q, 0.49611748439731621394870318175376878Q, 0.47354857554061400457926695177211335Q, 0.45158488614754491438064885165412276Q, 0.43023651638978897817371690879635701Q, 0.4095115109381936343721381503891959Q, 0.38941593967921202782661222737925564Q, 0.36995398189211387219291724401952693Q, 0.35112801322442524717390619924264052Q, 0.33293869483774779538113623624821976Q, 0.31538506413267813525698287867505706Q, 0.29846462649944498394951741316395666Q, 0.28217344757959610491269401677566302Q, 0.26650624556313516141887797351312194Q, 0.25145648308451039819955104711453138Q, 0.23701645831941898915989673276556716Q, 0.22317739492218458776987874976238264Q, 0.20992953048020753663062039840873861Q, 0.19726220319743719884124330734112999Q, 0.18516393655277551537189585427079996Q, 0.17362252171163130317128688392273587Q, 0.16262509749938432420455409981591821Q, 0.15215822777419972032806536862862315Q, 0.14220797606340183123695433555896409Q, 0.13275997735244552637840297048350341Q, 0.12379950693841296100725547935434371Q, 0.11531154628093733739002418825877215Q, 0.10728084580255643428531503966925542Q, 0.099691984607788577667458210957830992Q, 0.092529427105778463900867988199890184Q, 0.085777576535268189772833000772228023Q, 0.079420825403008155143300459369002492Q, 0.073443602857638774779152196546779989Q, 0.067830419030657966460701735648315918Q, 0.062565906384455108312883097272720571Q, 0.057634858114654726990360882355019006Q, 0.053022263660287178654865336510427632Q, 0.048713341380701431454862729860209054Q, 0.044693568462765533522590231699541224Q, 0.040948708125867302497552393088112476Q, 0.037464834195628972796376547170838841Q, 0.034228353120175696600101652094083332Q, 0.031226023505331741095045556858942863Q, 0.028444973247334237420578959776412296Q, 0.025872714343617644485216127636544335Q, 0.023497155463988527331246316453605283Q, 0.021306612366126070465592025046447108Q, 0.019289816240845601467614148418736892Q, 0.017435920073977461259931130790681214Q, 0.015734503113059796501938486945359929Q, 0.014175573528330460201833138862417195Q, 0.012749569358731162695972946581614495Q, 0.011447357834799756252759767428888751Q, 0.010260233171410768904966921400699131Q, 0.0091799129243109016820036013086815458Q, 0.0081985330052611999146716526049152539Q, 0.0073086414513132480272928751787482011Q, 0.0065031910442825794569735904252798084Q, 0.0057755308768065491405505517951108403Q, 0.0051193969614537818669843222017295048Q, 0.0045289019791562891246666236654351803Q, 0.0039985242627335310486699760330762132Q, 0.0035230961104429863210055440392477764Q, 0.003097791523300820656719025216576771Q, 0.0027181134583502264180047688832185696Q, 0.00237988068810043824649673132220802Q, 0.0020792143540086661490040088456472881Q, 0.0018125242991288642651054139496748517Q, 0.0015764952619105560466714983901735372Q, 0.001368073009609703955236179563862531Q, 0.0011844504858902772190681005760231091Q, 0.0010230540429745410945605352201833147Q, 0.00088152982417297002262517617153839107Q, 0.00075773035782735921074324212296621353Q, 0.00064970141867429037384583446669345298Q, 0.00055566920742578558188343231541026958Q, 0.00047402789401816719609357067930453704Q, 0.00040332756454954092910822407611191225Q, 0.0003422626064629768809457896368129693Q, 0.00028966056108877174342801893880690422Q, 0.00024447146728689162442142144970348683Q, 0.00020575771467998818628501233394779612Q, 0.00017268441988592922811041420156552324Q, 0.00014451033429094586468260075495740334Q, 0.00012057928729056996115421473619828627Q, 0.0001003121646011242017105871905771618Q, 8.3199417240036480655327139421155229e-05Q, 6.8794093113496376994935071214960655e-05Q, 5.6705379853932877470011678973870605e-05Q, 4.6592644630494618702241456703037532e-05Q, 3.8159954120245760316298139014562893e-05Q, 3.1151055677448352880855786865941099e-05Q, 2.5344798968850110019503595997329621e-05Q, 2.0550975944934244592401576964828471e-05Q, 1.6606555976508335934243673648199596e-05Q, 1.3372292284532372637222480551805329e-05Q, 1.0729675406852340659025097863229453e-05Q, 8.5782093537079082475098159798479489e-06Q, 6.8329862774218506793384467861049682e-06Q, 5.4225358918240331874795406776236123e-06Q, 4.2869264939998226801201888531480146e-06Q, 3.3760952348055109687047948553034167e-06Q, 2.648386225404341059332347382668934e-06Q, 2.0692761257364670911197722058327534e-06Q, 1.6102680094507650586919500255804135e-06Q, 1.2479355121177451927952866165256362e-06Q, 9.6310052117659252623275411195037422e-07Q, 7.4012893490908614244527654085271701e-07Q, 5.6633028402050775174949474283673891e-07Q, 4.3144825587165380566889409128276242e-07Q, 3.2723037330517558940458575985214918e-07Q, 2.4706624511249700700814105972385083e-07Q, 1.8568491370025132363780817403060483e-07Q, 1.3890286996035952957423247999266266e-07Q, 1.0341528040745607124994759911720107e-07Q, 7.6623873974817584699067130031657306e-08Q, 5.6495763871670621475281493521314709e-08Q, 4.1448233558505383939707940899336768e-08Q, 3.0255196464899467188973440250947218e-08Q, 2.1971648917089349870913690980235634e-08Q, 1.5872978090968232625950436800137184e-08Q, 1.1406465554850482080861078708713322e-08Q, 8.1527464828576537674941124925699748e-09Q, 5.7953495730966064129686023678242569e-09Q, 4.0967579139685198004841429173893772e-09Q, 2.8797013464471104655049488102491186e-09Q, 2.0126210218867172874496187582569718e-09Q, 1.3984414312565442025515753185221259e-09Q, 9.6594851858099300536090988590771494e-10Q, 6.6320863470162099803938291638680053e-10Q, 4.5257576104153821951813027371570715e-10Q, 3.0692702078723328679138233160912672e-10Q, 2.0684203539029217544821684017571545e-10Q, 1.3850287525834145108955800004991698e-10Q, 9.214056422651888408320635035510389e-11Q, 6.0893387064380670508776147108848386e-11Q, 3.9973389519930269589286591598258413e-11Q, 2.6061960502805293348144397281679947e-11Q, 1.6874519343915025228826792012273533e-11Q, 1.0849161834337120075418713193749676e-11Q, 6.925528015268138234276418201069421e-12Q, 4.3888651899779304012906781620222308e-12Q, 2.7608587671398283608193689290767215e-12Q, 1.7237644036042717645352410466671951e-12Q, 1.0680750436541459501472279340038532e-12Q, 6.5669443496573770247087892915106603e-13Q, 4.0059853799532432743143892523313549e-13Q, 2.4242966045442409054601213028173084e-13Q, 1.455249915777183791487150796402817e-13Q, 8.6638127254357861703205617203908732e-14Q, 5.1149749011237035858347608326433163e-14Q, 2.994217759503148409824465166785657e-14Q, 1.7376816946074293584520159998670905e-14Q, 9.9964240098994293054396937904035808e-15Q, 5.6996266660577917745539527915605509e-15Q, 3.2204325132709429326443049307963174e-15Q, 1.8029589638948994224704223595333813e-15Q, 9.9999573441511328003764710559432247e-16Q, 5.4939783973500551313304111867037353e-16Q, 2.9894208856836080833460170608635085e-16Q, 1.610765424389333897595412933702905e-16Q, 8.5932097482708020320234894915603507e-17Q, 4.5382468267138486711718165281416612e-17Q, 2.3722531670914086186505578503296188e-17Q, 1.2271671669957684251768746309727359e-17Q, 6.2812290485539754593993025086049784e-18Q, 3.1806147137287576603303714266387884e-18Q, 1.5930492574791968327078642420897427e-18Q, 7.8908551593455841363543904697547233e-19Q, 3.8647331030140734169770289169399394e-19Q, 1.8712773299709086118483416095592492e-19Q, 8.9557394552313902528032623648079256e-20Q, 4.2357428519456376102962467454513856e-20Q, 1.979436201534175012643985224780424e-20Q, 9.1380785584698727034273276491713887e-21Q, 4.1666411584773049229385926804715087e-21Q, 1.8760750552668470771305003442308049e-21Q, 8.3399019486525331443195597764274931e-22Q, 3.6595752362436730932932611770341911e-22Q, 1.5847852183325978194205652538004105e-22Q, 6.7715756944343963844212791596730701e-23Q, 2.8542817079371140817224171432389793e-23Q, 1.1865838580947568695752893868758282e-23Q, 4.8640699357080450262013571667032291e-24Q, 1.9656434192469852200073765210097077e-24Q, 7.8291656246958620676899939812206199e-25Q, 3.0727892288172702707668669968129923e-25Q, 1.1881076147213762784564203492918474e-25Q, 4.5246197487634934114352468991264689e-26Q, 1.6967101868478854591740026523544294e-26Q, 6.2636410032291183199621894495108545e-27Q, 2.275790792857396714851032797332432e-27Q, 8.1360777159044314206100175821194793e-28Q, 2.8613065492953910272350038532776635e-28Q, 9.8961841969437875600155257339935786e-29Q, 3.3652008931641398734060087635568974e-29Q, 1.124807054607635533524732113721643e-29Q, 3.6944604327139334398530256817969063e-30Q, 1.1920933013465364813127655880555969e-30Q, 3.7777578760183197857216889284069537e-31Q, 1.1754363786778472289935929233399097e-31Q, 3.5898790778284615893833448994196406e-32Q, 1.0758426862142799782307176268359752e-32Q, 3.1628351259465958616106447958915727e-33Q, 9.1186741890740659476367230179943904e-34Q, 2.5773931684416249884030668079887807e-34Q, 7.1398295043464040965283248909128753e-35Q, 1.9378289210199819221125431141075043e-35Q, 5.1513791013790083352767878745680313e-36Q, 1.3408183263237239554032545670003467e-36Q, 3.4159407851320474430217223083201431e-37Q, 8.5152627413375142768339982799164144e-38Q, 2.076271482369099670696465965718329e-38Q, 4.9501378383448158752628326041586328e-39Q, 1.1535696769569322062307767078682896e-39Q, 2.6266829648536609656499385130095636e-40Q, 5.8418474765546354958505600321922284e-41Q, 1.2685583522817839163209325300191513e-41Q, 2.6885912245101334092484585567288326e-42Q, 5.5593886486694506967808090446058169e-43Q, 1.1211105786168708837628837423551506e-43Q, 2.204030437173812137094585242452846e-44Q, 4.2224091761364250309210368326791673e-45Q, 7.879520062360877249284818876749499e-46Q, 1.4317140234575381985434267597963095e-46Q, 2.5319048034172799761988113239574673e-47Q, 4.3559981958200842427093791079007571e-48Q, 7.2876743960081410061189361036751606e-49Q, 1.1851134957779509548750104934682377e-49Q, 1.872433458377359457763352131002218e-50Q, 2.8729694149829129971079440142039839e-51Q, 4.2789120660247665069210975132651194e-52Q, 6.1831517263855101991333477522333856e-53Q, 8.664706532064762178060555848235158e-54Q, 1.1769423732336786099340369561810161e-54Q, 1.5488187383481079319128553087281025e-55Q, 1.9736646088073419346394015708589866e-56Q, 2.4341838396213207647077873905717686e-57Q, 2.9041369422835327495394798923780893e-58Q, 3.3499429920119329938613749830054234e-59Q, 3.7340806058053956442103094318030179e-60Q, 4.0199589180457423324670244391460705e-61Q, 4.1774687856674289017944418799754548e-62Q, 4.1880972367088277279311490203747192e-63Q, 4.0484306973548957998328137903090132e-64Q, 3.77114883236106507191241601008861e-65Q, 3.3831738882583366253452262404438761e-66Q, 2.9213348345532154319786866459214566e-67Q, 2.4265171108768020980951563482987534e-68Q, 1.9376034615932002776264780070086131e-69Q, 1.4864705425001770514685771802938584e-70Q, 1.0949232255990064493457806009226565e-71Q, 7.7387134447881401018887497774386554e-73Q, 5.2448008205426118383234631723504239e-74Q, 3.4062562927830356374440099107130253e-75Q, 2.1184692439258592242177714552745419e-76Q, 1.2608614434809477030102983673195673e-77Q, 7.1764903126208755695723110547276813e-79Q, 3.9034697656266028736188479360578122e-80Q, 2.0275573404310544862715347770507338e-81Q, 1.004994816430593904290660376649901e-82Q, 4.7500986471514075093717143999280406e-84Q, 2.1392636099460832836078416112710222e-85Q, 9.173149292867278730161085643245862e-87Q, 3.7422217329627927169047643424111024e-88Q, 1.4512980036440354977046772500061822e-89Q, 5.3463017574991130746397399989936882e-91Q, 1.8692545071988721039716330965097833e-92Q, 6.1978958931273853497246435906829052e-94Q, 1.9472339695524234456610961876127122e-95Q, 5.7919052872513171909291273369047611e-97Q, 1.6295956267419577729908767823766263e-98Q, 4.3332432642363261903550403983227406e-100Q, 1.0880149430086354606207846327564807e-101Q, 2.5772282627352113781815039093907765e-103Q, 5.7539838006451121430858484531452556e-105Q, 1.2096990017248315153784188752260699e-106Q, 2.3925872664345045807315831521649824e-108Q, 4.4475659282644875495932738704595289e-110Q, 7.7627738422265479186699876924736519e-112Q, 1.2709267303083863208341290697181042e-113Q, 1.9498242131608832039698501560236386e-115Q, 2.8002525531974060834525812862103801e-117Q, 3.7607474856227547424556497710309557e-119Q, 4.7181060260584103957700726731938295e-121Q, 5.5234683214250331048701341097289187e-123Q, 6.0274476904458633271417170323324512e-125Q, 6.1242336828836773956273877493935834e-127Q, 5.7873336327745621779130244175524495e-129Q, 5.080632710884007461562439620052701e-131Q, 4.1387180173608798644427799558698992e-133Q, 3.1247188175223382722031520705749413e-135Q, 2.1839031164024077549981710942515192e-137Q, 1.4112539862126523413412548851519319e-139Q, 8.4215132945549247707528420294855683e-142Q, 4.6349339497376890248654482771898709e-144Q, 2.3496985464521993504910835710336684e-146Q, 1.095806710681902573252914390685236e-148Q, 4.6950275371271587533706139425003387e-151Q, 1.8456310819897755187059215917442304e-153Q, 6.6476058774188256202611396416535206e-156Q, 2.1907913883958482863705726011811944e-158Q, 6.5969704613629998580324088255164448e-161Q, 1.8125024222344232769814833021310009e-163Q, 4.5370781893964839845073953864812105e-166Q, 1.0332388835710739936372904447767308e-168Q, 2.1374954497695898284726118552680548e-171Q, 4.0108149042055622979938927508096981e-174Q, 6.8157812455297175262972900652817266e-177Q, 1.0473127652676199964496156413213892e-179Q, 1.4528685940321876156376494017441343e-182Q, 1.8166282837173462776489744689123018e-185Q, 2.0440202882824856548036164467448088e-188Q, 2.0661513859552458565266153108297534e-191Q, 1.8731127932057798663856916994067048e-194Q, 1.5203587637183862829799380406495058e-197Q, 1.1029412423875246289335781867943994e-200Q, 7.138626970990275795307217364262657e-204Q, 4.1148385080761107172311325770404465e-207Q, 2.1085028345530812052701929614749437e-210Q, 9.586804728597153811540457301738394e-214Q, 3.8604168930466380230648935566836905e-217Q, 1.3741198913182849308419643845423577e-220Q, 4.3152058575378643032664917818412533e-224Q, 1.19318553486394227968739928824324e-227Q, 2.8991695266404489121362655770787829e-231Q, 6.1775221006993094876500875992969792e-235Q, 1.1519457912295313262297054573241955e-238Q, 1.8759214343015253296548435854195451e-242Q, 2.6621687700905798726983482845704724e-246Q, 3.2851388833240439850794784627378447e-250Q, 3.5173302898760059862233242135090423e-254Q, 3.260189457452227113017033626415114e-258Q, 2.6100961489800200467379180863184362e-262Q, 1.8007454797962902444457099319194981e-266Q, 1.0681019906266894643271137718146545e-270Q, 5.4338051160125203325306044546291973e-275Q, 2.3652466547636417935201205492175566e-279Q, 8.7874613708003418754944028581674092e-284Q, 2.7795968403545195493312606588081939e-288Q, 7.4667445765219841782970695464816343e-293Q, 1.6990035121087781757668989612218036e-297Q, 3.2661456244114182842789617411036552e-302Q, 5.2905644824269341726292739407836284e-307Q, 7.2014912174357894815487914007866659e-312Q, 8.2149916381513794689686855840667286e-317Q, 7.8315488217791735530193073164613925e-322Q, 6.221807701348355377240172152359918e-327Q, 4.1074011155154758472047101692258134e-332Q, 2.2466366589127674529456245569217313e-337Q, 1.0151434061771573997492847262735324e-342Q, 3.7778453114026807637246195807729534e-348Q, 1.1543990703305213109241662519678786e-353Q, 2.8874514917596574178755044320075352e-359Q, 5.8931980361396154630354121875276487e-365Q, 9.7830460697139640980628824283457061e-371Q, 1.3166522887017193888073217487220663e-376Q, 1.4318812372702150835656599374620546e-382Q, 1.2540768871672304974301195995718396e-388Q, 8.8153996483879828169726259431129063e-395Q, 4.9562889772003524717252843516553902e-401Q, 2.2209583723340796264599763080008776e-407Q, 7.903905845967360394872219425003336e-414Q, 2.2257919152191142215565812315993462e-420Q, 4.9416038684875140142672214621735078e-427Q, 8.6171916788075114925145119819509171e-434Q, 1.1757806822258262957023704296248014e-440Q, 1.2504660464052680899003468814266606e-447Q, 1.0325197258632347378121850864959173e-454Q, 6.5928728293837187402797552969580767e-462Q, 3.2422215378060561710679179733872247e-469Q, 1.222971654709343975246423698805888e-476Q, 3.523560719191273512100160441884497e-484Q, 7.7214021325433144875052949047234787e-492Q, 1.2814096433117550022825846412075423e-499Q, 1.6034524983169066795932277083952198e-507Q, 1.506154257333325578480885384144555e-515Q, 1.0572229793982283970011093126796893e-523Q, 5.5202045762026741431740525809554222e-532Q, 2.1340837910128019442948018148493991e-540Q, 6.0796683172016911238300290124661526e-549Q, 1.2702010542787853060770224333562558e-557Q, 1.9367268433132755704840764854736682e-566Q, 2.1444373126935426310796432391730652e-575Q, 1.7156127051237753338771752429597998e-584Q, 9.866507362005302302229219896627392e-594Q, 4.0577781777778825723169578502780851e-603Q, 1.1871364801794013747840938511563031e-612Q, 2.4573736732127578624297116105185871e-622Q, 3.5795957466771145363085369419550411e-632Q, 3.6491000343716609306595204093204503e-642Q, 2.5887224173643746039322073618863653e-652Q, 1.2707309714711704379079743917253552e-662Q, 4.2911292837382087644451178350840055e-673Q, 9.9101724991114880676267115929463864e-684Q, 1.5559081312551687762049592042215559e-694Q, 1.6505944447381619620675148844917786e-705Q, 1.1758976044388560589646808736426135e-716Q, 5.5904673599123524828590221558073227e-728Q, 1.762422841281411916279811438897522e-739Q, 3.660545736359787919552147533680784e-751Q, 4.9762407942794836638678732794521407e-763Q, 4.3982297935392846258826361101417004e-775Q, 2.5103306493196863847807186768995234e-787Q, 9.1890276778950746130428977933070467e-800Q, 2.1421794336828190981917187030902949e-812Q, 3.1579407773552118084939940851249037e-825Q, 2.9226685587591509131252404660323457e-838Q, 1.6857720383594173922437511994184956e-851Q, 6.0148932059792413237874599630717323e-865Q, 1.3175950977896871810836083428540193e-878Q, 1.7584274071402706626129462062711265e-892Q, 1.4186205574627811155197950438077455e-906Q, 6.863804756553040536363703712029114e-921Q, 1.9757126782016829801994589969078639e-935Q, 3.3557616466388148224311943077895109e-950Q, 3.3354866661158784873247273739595471e-965Q, 1.9238163515428741014100444007200552e-980Q, 6.3838419214869081664291315367530963e-996Q, 1.208186393746817780221157077221556e-1011Q, 1.2926433460770675227136395965601267e-1027Q, 7.7484641126890628613399212918871834e-1044Q, 2.578590762872741885363873428172601e-1060Q, 4.720135411440959292309368252688105e-1077Q, 4.7080786123051904219070581932647786e-1094Q, 2.5345319096404707885383043943244978e-1111Q, 7.2928761242789730396354678181188802e-1129Q, 1.1106128952895418090598971812669904e-1146Q, 8.8621216538366976598099979452808551e-1165Q, 3.6677828388640988980975786646419682e-1183Q, 7.7923888084439739305704880307980387e-1202Q, 8.4096550976573708334084140027496576e-1221Q, 4.5613561814429013831962003215267279e-1240Q, 1.2300215778004431684442502009102409e-1259Q, 1.6310040159866857782581696492106591e-1279Q, 1.0516379174444742948762886500817157e-1299Q, 3.2599823473651125257811218258666689e-1320Q, 4.8027868480449172060158102541122388e-1341Q, 3.3236309884819155458562664594667437e-1362Q, 1.0675935976034168796912624171598076e-1383Q, 1.5726195400977448490722891999643084e-1405Q, 1.0493832555753684651126599489805473e-1427Q, 3.1327201084154872489458088843708842e-1450Q, 4.1312837255709912970140480142041816e-1473Q, 2.3759469769680296617336666937339053e-1496Q, 5.8816760470052203616229940275916193e-1520Q, 6.1846204357986408200352274197037853e-1544Q, 2.7253154006156158167192213817170292e-1568Q, 4.964370850871644112480158952518382e-1593Q, 3.6864952720610418491857518517405997e-1618Q, 1.1003435724966953469136035841615193e-1643Q, 1.3012915572536198178305157209959287e-1669Q, 6.0092590718277568469858434192698668e-1696Q, 1.0676671777328477051443719591612721e-1722Q, 7.1893041788265042697820383343649581e-1750Q, 1.8069174401475778125395048319028868e-1777Q, 1.6689765331128672749329764129278041e-1805Q, 5.5766895369980043818737558535999006e-1834Q, 6.6338104205654511592967377535571654e-1863Q, 2.7640539994999072399732281044814252e-1892Q, 3.9678218215367472586686997493459426e-1922Q, 1.9297110274588854079208153981267479e-1952Q, 3.125823255660491143824024380405163e-1983Q, 1.6574847870654916983076674690989236e-2014Q, 2.8268986732520512350429266473306993e-2046Q, 1.5233117185863507338781156113800939e-2078Q, 2.546861334196453858326476740489303e-2111Q, 1.2970473455790653045919178951673388e-2144Q, 1.9747419969447016216735762205746422e-2178Q, 8.8188278044353709778558661887540083e-2213Q, 1.1331026308914886857015956789021835e-2247Q, 4.1073843396377054383734821718609159e-2283Q, 4.1176061068991316842526396776090883e-2319Q, 1.1187086154165438557157295454514512e-2355Q, 8.0696152044407520449588862080186105e-2393Q, 1.5135007846133660639825213215103939e-2430Q, 7.2259333243684066847653432848351411e-2469Q, 8.5946687461833096509693248289938412e-2508Q, 2.4916284852956646502671815296350685e-2547Q, 1.7218755528601187283427831366854425e-2587Q, 2.7731789802471774097405514299103397e-2628Q, 1.0173036737175759305843452255817661e-2669Q, 8.3042791798168477802920353914502218e-2712Q, 1.473175854535708068279125062330391e-2754Q, 5.5445898944436653916624336507572418e-2798Q, 4.320588676830861227044616106347197e-2842Q, 6.7999319106199079525777026656783353e-2887Q, 2.1077263780365503485840282493709679e-2932Q, 1.2541789874677469018547003272238725e-2978Q, 1.3958959110384407791740617210399902e-3025Q, 2.8302814609077924874798718558506843e-3073Q, 1.0177558252358910503169620579616733e-3121Q, 6.316345161489586703263200702377878e-3171Q, 6.5808353794152592529153513818570413e-3221Q, 1.1191402820754794725611968922105955e-3271Q, 3.0191144446114914489317417615052391e-3323Q, 1.2550879768384736567252096901362895e-3375Q, 7.8068891083719869927416696059040226e-3429Q, 7.0517902304991510532607166162881123e-3483Q, 8.9730892510839231589218006993975962e-3538Q, 1.5595586152851619317721078977043233e-3593Q, 3.5880900047081973177436521469002167e-3650Q, 1.0585155878906962124317498469363852e-3707Q, 3.8766455756851727310799307162918377e-3766Q, 1.7055766393620807246392140051588691e-3825Q, 8.7186526945824113614692955827617228e-3886Q, 5.0057478847913665022916271652366648e-3947Q, 3.118721903551705673676508466953291e-4009Q, 2.0360271187838855169643637345546437e-4072Q, 1.344193072571113944443469925533764e-4136Q, 8.6564521926545774914724471102499854e-4202Q, 5.2420435234912004640647252129478902e-4268Q, 2.8759098307799421718470860096954611e-4335Q, 1.3763877452472741048491095385711433e-4403Q, 5.5298776937738818735087266649244396e-4473Q, 1.7937216962986389293716315095996859e-4543Q, 4.5149004338871753808860898565339903e-4615Q, 8.4705695199542943533046216376760939e-4688Q, 1.1370794062105632021349671352107651e-4761Q, 1.0477206804639390072354388690482908e-4836Q, 6.3526587059143165049479765478742544e-4913Q, 2.4283486680552345908529800038916585e-4990Q, 5.6028531999416699789095738832933157e-5069Q, 7.4653403674710397422097751397913229e-5149Q, 5.4919841992020489039553213694177019e-5230Q, 2.1312688707736268785590779947753119e-5312Q, 4.1653791598980828217930742787672032e-5396Q, 3.9114639992058990826656399856975019e-5481Q, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_MATH_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +#endif // BOOST_HAS_FLOAT128 + +template +void tanh_sinh_detail::prune_to_min_complement(const Real& m) +{ + // + // If our tables were constructed from pre-computed data, then they will have more values stored than we can ever use, + // and although the table size at this stage won't be too large, if we calculate down to m_max_levels then they will + // grow by a huge amount - doubling in size at each step - so lets prune them down, removing values which will never + // be used: + // + if (m > tools::min_value() * 4) + { + for (unsigned row = 0; (row < m_abscissas.size()) && m_abscissas[row].size(); ++row) + { + typename std::vector::iterator pos = std::lower_bound(m_abscissas[row].begin(), m_abscissas[row].end(), m, [](const Real& a, const Real& b) { using std::fabs; return fabs(a) > fabs(b); }); + if (pos != m_abscissas[row].end()) + { + m_abscissas[row].erase(pos, m_abscissas[row].end()); + m_weights[row].erase(m_weights[row].begin() + m_abscissas[row].size(), m_weights[row].end()); + } + } + } +} + +}}}} // namespaces + +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/exp_sinh.hpp b/third-party/boost-math/include/boost/math/quadrature/exp_sinh.hpp new file mode 100644 index 0000000000000..d3148e0c0a721 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/exp_sinh.hpp @@ -0,0 +1,180 @@ +// Copyright Nick Thompson, 2017 +// 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) + +/* + * This class performs exp-sinh quadrature on half infinite intervals. + * + * References: + * + * 1) Tanaka, Ken'ichiro, et al. "Function classes for double exponential integration formulas." Numerische Mathematik 111.4 (2009): 631-655. + */ + +#ifndef BOOST_MATH_QUADRATURE_EXP_SINH_HPP +#define BOOST_MATH_QUADRATURE_EXP_SINH_HPP + +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class exp_sinh +{ +public: + exp_sinh(size_t max_refinements = 9) + : m_imp(std::make_shared>(max_refinements)) {} + + template + auto integrate(const F& f, Real a, Real b, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval())); + template + auto integrate(const F& f, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval())); + +private: + std::shared_ptr> m_imp; +}; + +template +template +auto exp_sinh::integrate(const F& f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + using std::abs; + using boost::math::constants::half; + using boost::math::quadrature::detail::exp_sinh_detail; + + static const char* function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + + // Neither limit may be a NaN: + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + { + return static_cast(policies::raise_domain_error(function, "NaN supplied as one limit of integration - sorry I don't know what to do", a, Policy())); + } + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= boost::math::tools::max_value())) + { + // If a = 0, don't use an additional level of indirection: + if (a == static_cast(0)) + { + return m_imp->integrate(f, error, L1, function, tolerance, levels); + } + const auto u = [&](Real t)->K { return f(t + a); }; + return m_imp->integrate(u, error, L1, function, tolerance, levels); + } + + if ((boost::math::isfinite)(b) && a <= -boost::math::tools::max_value()) + { + const auto u = [&](Real t)->K { return f(b-t);}; + return m_imp->integrate(u, error, L1, function, tolerance, levels); + } + + // Infinite limits: + if ((a <= -boost::math::tools::max_value()) && (b >= boost::math::tools::max_value())) + { + return static_cast(policies::raise_domain_error(function, "Use sinh_sinh quadrature for integration over the whole real line; exp_sinh is for half infinite integrals.", a, Policy())); + } + // If we get to here then both ends must necessarily be finite: + return static_cast(policies::raise_domain_error(function, "Use tanh_sinh quadrature for integration over finite domains; exp_sinh is for half infinite integrals.", a, Policy())); +} + +template +template +auto exp_sinh::integrate(const F& f, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + static const char* function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + using std::abs; + if (abs(tolerance) > 1) { + return policies::raise_domain_error(function, "The tolerance provided (%1%) is unusually large; did you confuse it with a domain bound?", tolerance, Policy()); + } + return m_imp->integrate(f, error, L1, function, tolerance, levels); +} + + +}}} + +#endif // BOOST_MATH_HAS_NVRTC + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace quadrature { + +template > +__device__ auto exp_sinh_integrate(const F& f, Real a, Real b, Real tolerance, Real* error, Real* L1, boost::math::size_t* levels) +{ + BOOST_MATH_STD_USING + + using K = decltype(f(a)); + static_assert(!boost::math::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + + constexpr auto function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + + // Neither limit may be a NaN: + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + { + return static_cast(policies::raise_domain_error(function, "NaN supplied as one limit of integration - sorry I don't know what to do", a, Policy())); + } + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= boost::math::tools::max_value())) + { + // If a = 0, don't use an additional level of indirection: + if (a == static_cast(0)) + { + return detail::exp_sinh_integrate_impl(f, tolerance, error, L1, levels); + } + const auto u = [&](Real t)->K { return f(t + a); }; + return detail::exp_sinh_integrate_impl(u, tolerance, error, L1, levels); + } + + if ((boost::math::isfinite)(b) && a <= -boost::math::tools::max_value()) + { + const auto u = [&](Real t)->K { return f(b-t);}; + return detail::exp_sinh_integrate_impl(u, tolerance, error, L1, levels); + } + + // Infinite limits: + if ((a <= -boost::math::tools::max_value()) && (b >= boost::math::tools::max_value())) + { + return static_cast(policies::raise_domain_error(function, "Use sinh_sinh quadrature for integration over the whole real line; exp_sinh is for half infinite integrals.", a, Policy())); + } + // If we get to here then both ends must necessarily be finite: + return static_cast(policies::raise_domain_error(function, "Use tanh_sinh quadrature for integration over finite domains; exp_sinh is for half infinite integrals.", a, Policy())); +} + +template > +__device__ auto exp_sinh_integrate(const F& f, Real tolerance, Real* error, Real* L1, boost::math::size_t* levels) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + if (abs(tolerance) > 1) { + return policies::raise_domain_error(function, "The tolerance provided (%1%) is unusually large; did you confuse it with a domain bound?", tolerance, Policy()); + } + return detail::exp_sinh_integrate_impl(f, tolerance, error, L1, levels); +} + +} // namespace quadrature +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif // BOOST_MATH_QUADRATURE_EXP_SINH_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/gauss.hpp b/third-party/boost-math/include/boost/math/quadrature/gauss.hpp new file mode 100644 index 0000000000000..91ffcf0bcd616 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/gauss.hpp @@ -0,0 +1,904 @@ +// Copyright John Maddock 2015. +// 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) + +#ifndef BOOST_MATH_QUADRATURE_GAUSS_HPP +#define BOOST_MATH_QUADRATURE_GAUSS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +namespace boost { namespace math{ namespace quadrature{ namespace detail{ + +template +struct gauss_constant_category +{ + static const unsigned value = + (std::numeric_limits::is_specialized == 0) ? 999 : + (std::numeric_limits::radix == 2) ? + ( +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && std::is_constructible::value ? 0 : +#else + (std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_constructible::value ? 0 : +#endif + (std::numeric_limits::digits10 <= 110) && std::is_constructible::value ? 4 : 999 + ) : (std::numeric_limits::digits10 <= 110) && std::is_constructible::value ? 4 : 999; + + using storage_type = + std::conditional_t<(std::numeric_limits::is_specialized == 0), T, + std::conditional_t<(std::numeric_limits::radix == 2), + std::conditional_t< ((std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_constructible::value), + float, + std::conditional_t<((std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_constructible::value), + double, + std::conditional_t<((std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_constructible::value), + long double, +#ifdef BOOST_HAS_FLOAT128 + std::conditional_t<((std::numeric_limits::digits <= 113) && std::is_constructible::value), + __float128, + T + > + > +#else + T + > +#endif + > + >, T + > + >; +}; + +#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND + +template +class gauss_detail +{ + static std::vector calculate_weights() + { + std::vector result(abscissa().size(), 0); + for (unsigned i = 0; i < abscissa().size(); ++i) + { + Real x = abscissa()[i]; + Real p = boost::math::legendre_p_prime(N, x); + result[i] = 2 / ((1 - x * x) * p * p); + } + return result; + } +public: + static const std::vector& abscissa() + { + static std::vector data = boost::math::legendre_p_zeros(N); + return data; + } + static const std::vector& weights() + { + static std::vector data = calculate_weights(); + return data; + } +}; + +#else + +template +class gauss_detail; + +#endif +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(4.05845151377397166906606412076961463e-01L), + static_cast(7.41531185599394439863864773280788407e-01L), + static_cast(9.49107912342758524526189684047851262e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(4.17959183673469387755102040816326531e-01L), + static_cast(3.81830050505118944950369775488975134e-01L), + static_cast(2.79705391489276667901467771423779582e-01L), + static_cast(1.29484966168869693270611432679082018e-01L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(4.05845151377397166906606412076961463e-01Q), + static_cast(7.41531185599394439863864773280788407e-01Q), + static_cast(9.49107912342758524526189684047851262e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(4.17959183673469387755102040816326531e-01Q), + static_cast(3.81830050505118944950369775488975134e-01Q), + static_cast(2.79705391489276667901467771423779582e-01Q), + static_cast(1.29484966168869693270611432679082018e-01Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1795918367346938775510204081632653061224489795918367346938775510204081632653061224489795918367346938775510204081633e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8183005050511894495036977548897513387836508353386273475108345103070554643412970834868465934404480145031467176458536e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7970539148927666790146777142377958248692506522659876453701403269361881043056267681324094290119761876632337521337205e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2948496616886969327061143267908201832858740225994666397720863872465523497204230871562541816292084508948440200163443e-01), + }; // LCOV_EXCL_STOP + return data; + } +}; +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(1.48874338981631210884826001129719985e-01L), + static_cast(4.33395394129247190799265943165784162e-01L), + static_cast(6.79409568299024406234327365114873576e-01L), + static_cast(8.65063366688984510732096688423493049e-01L), + static_cast(9.73906528517171720077964012084452053e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(2.95524224714752870173892994651338329e-01L), + static_cast(2.69266719309996355091226921569469353e-01L), + static_cast(2.19086362515982043995534934228163192e-01L), + static_cast(1.49451349150580593145776339657697332e-01L), + static_cast(6.66713443086881375935688098933317929e-02L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(1.48874338981631210884826001129719985e-01Q), + static_cast(4.33395394129247190799265943165784162e-01Q), + static_cast(6.79409568299024406234327365114873576e-01Q), + static_cast(8.65063366688984510732096688423493049e-01Q), + static_cast(9.73906528517171720077964012084452053e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(2.95524224714752870173892994651338329e-01Q), + static_cast(2.69266719309996355091226921569469353e-01Q), + static_cast(2.19086362515982043995534934228163192e-01Q), + static_cast(1.49451349150580593145776339657697332e-01Q), + static_cast(6.66713443086881375935688098933317929e-02Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9552422471475287017389299465133832942104671702685360135430802975599593821715232927035659579375421672271716440125256e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6926671930999635509122692156946935285975993846088379580056327624215343231917927676422663670925276075559581145036870e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1908636251598204399553493422816319245877187052267708988095654363519991065295128124268399317720219278659121687281289e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4945134915058059314577633965769733240255663966942736783547726875323865472663001094594726463473195191400575256104544e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6671344308688137593568809893331792857864834320158145128694881613412064084087101776785509685058877821090054714520419e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(2.01194093997434522300628303394596208e-01L), + static_cast(3.94151347077563369897207370981045468e-01L), + static_cast(5.70972172608538847537226737253910641e-01L), + static_cast(7.24417731360170047416186054613938010e-01L), + static_cast(8.48206583410427216200648320774216851e-01L), + static_cast(9.37273392400705904307758947710209471e-01L), + static_cast(9.87992518020485428489565718586612581e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(2.02578241925561272880620199967519315e-01L), + static_cast(1.98431485327111576456118326443839325e-01L), + static_cast(1.86161000015562211026800561866422825e-01L), + static_cast(1.66269205816993933553200860481208811e-01L), + static_cast(1.39570677926154314447804794511028323e-01L), + static_cast(1.07159220467171935011869546685869303e-01L), + static_cast(7.03660474881081247092674164506673385e-02L), + static_cast(3.07532419961172683546283935772044177e-02L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(2.01194093997434522300628303394596208e-01Q), + static_cast(3.94151347077563369897207370981045468e-01Q), + static_cast(5.70972172608538847537226737253910641e-01Q), + static_cast(7.24417731360170047416186054613938010e-01Q), + static_cast(8.48206583410427216200648320774216851e-01Q), + static_cast(9.37273392400705904307758947710209471e-01Q), + static_cast(9.87992518020485428489565718586612581e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(2.02578241925561272880620199967519315e-01Q), + static_cast(1.98431485327111576456118326443839325e-01Q), + static_cast(1.86161000015562211026800561866422825e-01Q), + static_cast(1.66269205816993933553200860481208811e-01Q), + static_cast(1.39570677926154314447804794511028323e-01Q), + static_cast(1.07159220467171935011869546685869303e-01Q), + static_cast(7.03660474881081247092674164506673385e-02Q), + static_cast(3.07532419961172683546283935772044177e-02Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0257824192556127288062019996751931483866215800947735679670411605143539875474607409339344071278803213535148267082999e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9843148532711157645611832644383932481869255995754199348473792792912479753343426813331499916481782320766020854889310e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8616100001556221102680056186642282450622601227792840281549572731001325550269916061894976888609932360539977709001384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6626920581699393355320086048120881113090018009841290732186519056355356321227851771070517429241553621484461540657185e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3957067792615431444780479451102832252085027531551124320239112863108844454190781168076825736357133363814908889327664e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0715922046717193501186954668586930341554371575810198068702238912187799485231579972568585713760862404439808767837506e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.0366047488108124709267416450667338466708032754330719825907292914387055512874237044840452066693939219355489858595041e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0753241996117268354628393577204417721748144833434074264228285504237189467117168039038770732399404002516991188859473e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(7.65265211334973337546404093988382110e-02L), + static_cast(2.27785851141645078080496195368574625e-01L), + static_cast(3.73706088715419560672548177024927237e-01L), + static_cast(5.10867001950827098004364050955250998e-01L), + static_cast(6.36053680726515025452836696226285937e-01L), + static_cast(7.46331906460150792614305070355641590e-01L), + static_cast(8.39116971822218823394529061701520685e-01L), + static_cast(9.12234428251325905867752441203298113e-01L), + static_cast(9.63971927277913791267666131197277222e-01L), + static_cast(9.93128599185094924786122388471320278e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(1.52753387130725850698084331955097593e-01L), + static_cast(1.49172986472603746787828737001969437e-01L), + static_cast(1.42096109318382051329298325067164933e-01L), + static_cast(1.31688638449176626898494499748163135e-01L), + static_cast(1.18194531961518417312377377711382287e-01L), + static_cast(1.01930119817240435036750135480349876e-01L), + static_cast(8.32767415767047487247581432220462061e-02L), + static_cast(6.26720483341090635695065351870416064e-02L), + static_cast(4.06014298003869413310399522749321099e-02L), + static_cast(1.76140071391521183118619623518528164e-02L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(7.65265211334973337546404093988382110e-02Q), + static_cast(2.27785851141645078080496195368574625e-01Q), + static_cast(3.73706088715419560672548177024927237e-01Q), + static_cast(5.10867001950827098004364050955250998e-01Q), + static_cast(6.36053680726515025452836696226285937e-01Q), + static_cast(7.46331906460150792614305070355641590e-01Q), + static_cast(8.39116971822218823394529061701520685e-01Q), + static_cast(9.12234428251325905867752441203298113e-01Q), + static_cast(9.63971927277913791267666131197277222e-01Q), + static_cast(9.93128599185094924786122388471320278e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(1.52753387130725850698084331955097593e-01Q), + static_cast(1.49172986472603746787828737001969437e-01Q), + static_cast(1.42096109318382051329298325067164933e-01Q), + static_cast(1.31688638449176626898494499748163135e-01Q), + static_cast(1.18194531961518417312377377711382287e-01Q), + static_cast(1.01930119817240435036750135480349876e-01Q), + static_cast(8.32767415767047487247581432220462061e-02Q), + static_cast(6.26720483341090635695065351870416064e-02Q), + static_cast(4.06014298003869413310399522749321099e-02Q), + static_cast(1.76140071391521183118619623518528164e-02Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5275338713072585069808433195509759349194864511237859727470104981759745316273778153557248783650390593544001842813788e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4917298647260374678782873700196943669267990408136831649621121780984442259558678069396132603521048105170913854567338e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4209610931838205132929832506716493303451541339202030333736708298382808749793436761694922428320058260133068573666201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3168863844917662689849449974816313491611051114698352699643649370885435642948093314355797518397262924510598005463625e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1819453196151841731237737771138228700504121954896877544688995202017474835051151630572868782581901744606267543092317e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0193011981724043503675013548034987616669165602339255626197161619685232202539434647534931576947985821375859035525483e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3276741576704748724758143222046206100177828583163290744882060785693082894079419471375190843790839349096116111932764e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2672048334109063569506535187041606351601076578436364099584345437974811033665678644563766056832203512603253399592073e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0601429800386941331039952274932109879090639989951536817606854561832296750987328295538920623044384976189825709675075e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.7614007139152118311861962351852816362143105543336732524349326677348419259621847817403105542146097668703716227512570e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(1.22864692610710396387359818808036806e-01L), + static_cast(2.43866883720988432045190362797451586e-01L), + static_cast(3.61172305809387837735821730127640667e-01L), + static_cast(4.73002731445714960522182115009192041e-01L), + static_cast(5.77662930241222967723689841612654067e-01L), + static_cast(6.73566368473468364485120633247622176e-01L), + static_cast(7.59259263037357630577282865204360976e-01L), + static_cast(8.33442628760834001421021108693569569e-01L), + static_cast(8.94991997878275368851042006782804954e-01L), + static_cast(9.42974571228974339414011169658470532e-01L), + static_cast(9.76663921459517511498315386479594068e-01L), + static_cast(9.95556969790498097908784946893901617e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(1.23176053726715451203902873079050142e-01L), + static_cast(1.22242442990310041688959518945851506e-01L), + static_cast(1.19455763535784772228178126512901047e-01L), + static_cast(1.14858259145711648339325545869555809e-01L), + static_cast(1.08519624474263653116093957050116619e-01L), + static_cast(1.00535949067050644202206890392685827e-01L), + static_cast(9.10282619829636498114972207028916534e-02L), + static_cast(8.01407003350010180132349596691113023e-02L), + static_cast(6.80383338123569172071871856567079686e-02L), + static_cast(5.49046959758351919259368915404733242e-02L), + static_cast(4.09391567013063126556234877116459537e-02L), + static_cast(2.63549866150321372619018152952991449e-02L), + static_cast(1.13937985010262879479029641132347736e-02L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(1.22864692610710396387359818808036806e-01Q), + static_cast(2.43866883720988432045190362797451586e-01Q), + static_cast(3.61172305809387837735821730127640667e-01Q), + static_cast(4.73002731445714960522182115009192041e-01Q), + static_cast(5.77662930241222967723689841612654067e-01Q), + static_cast(6.73566368473468364485120633247622176e-01Q), + static_cast(7.59259263037357630577282865204360976e-01Q), + static_cast(8.33442628760834001421021108693569569e-01Q), + static_cast(8.94991997878275368851042006782804954e-01Q), + static_cast(9.42974571228974339414011169658470532e-01Q), + static_cast(9.76663921459517511498315386479594068e-01Q), + static_cast(9.95556969790498097908784946893901617e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(1.23176053726715451203902873079050142e-01Q), + static_cast(1.22242442990310041688959518945851506e-01Q), + static_cast(1.19455763535784772228178126512901047e-01Q), + static_cast(1.14858259145711648339325545869555809e-01Q), + static_cast(1.08519624474263653116093957050116619e-01Q), + static_cast(1.00535949067050644202206890392685827e-01Q), + static_cast(9.10282619829636498114972207028916534e-02Q), + static_cast(8.01407003350010180132349596691113023e-02Q), + static_cast(6.80383338123569172071871856567079686e-02Q), + static_cast(5.49046959758351919259368915404733242e-02Q), + static_cast(4.09391567013063126556234877116459537e-02Q), + static_cast(2.63549866150321372619018152952991449e-02Q), + static_cast(1.13937985010262879479029641132347736e-02Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2317605372671545120390287307905014243823362751815166539135219731691200794926142128460112517504958377310054583945994e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2224244299031004168895951894585150583505924756305904090758008223203896721918010243033540891078906637115620156845304e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1945576353578477222817812651290104739017670141372642551958788133518409022018773502442869720975271321374348568426235e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1485825914571164833932554586955580864093619166818014959151499003148279667112542256534429898558156273250513652351744e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0851962447426365311609395705011661934007758798672201615649430734883929279360844269339768350029654172135832773427565e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0053594906705064420220689039268582698846609452814190706986904199941294815904602968195565620373258211755226681206658e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1028261982963649811497220702891653380992558959334310970483768967017384678410526902484398142953718885872521590850372e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0140700335001018013234959669111302290225732853675893716201462973612828934801289559457377714225318048243957479325813e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8038333812356917207187185656707968554709494354636562615071226410003654051711473106651522969481873733098761760660898e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4904695975835191925936891540473324160109985553111349048508498244593774678436511895711924079433444763756746828817613e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0939156701306312655623487711645953660845783364104346504698414899297432880215512770478971055110424130123527015425511e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6354986615032137261901815295299144935963281703322468755366165783870934008879499371529821528172928890350362464605104e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1393798501026287947902964113234773603320526292909696448948061116189891729766743355923677112945033505688431618009664e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(5.14718425553176958330252131667225737e-02L), + static_cast(1.53869913608583546963794672743255920e-01L), + static_cast(2.54636926167889846439805129817805108e-01L), + static_cast(3.52704725530878113471037207089373861e-01L), + static_cast(4.47033769538089176780609900322854000e-01L), + static_cast(5.36624148142019899264169793311072794e-01L), + static_cast(6.20526182989242861140477556431189299e-01L), + static_cast(6.97850494793315796932292388026640068e-01L), + static_cast(7.67777432104826194917977340974503132e-01L), + static_cast(8.29565762382768397442898119732501916e-01L), + static_cast(8.82560535792052681543116462530225590e-01L), + static_cast(9.26200047429274325879324277080474004e-01L), + static_cast(9.60021864968307512216871025581797663e-01L), + static_cast(9.83668123279747209970032581605662802e-01L), + static_cast(9.96893484074649540271630050918695283e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(1.02852652893558840341285636705415044e-01L), + static_cast(1.01762389748405504596428952168554045e-01L), + static_cast(9.95934205867952670627802821035694765e-02L), + static_cast(9.63687371746442596394686263518098651e-02L), + static_cast(9.21225222377861287176327070876187672e-02L), + static_cast(8.68997872010829798023875307151257026e-02L), + static_cast(8.07558952294202153546949384605297309e-02L), + static_cast(7.37559747377052062682438500221907342e-02L), + static_cast(6.59742298821804951281285151159623612e-02L), + static_cast(5.74931562176190664817216894020561288e-02L), + static_cast(4.84026728305940529029381404228075178e-02L), + static_cast(3.87991925696270495968019364463476920e-02L), + static_cast(2.87847078833233693497191796112920436e-02L), + static_cast(1.84664683110909591423021319120472691e-02L), + static_cast(7.96819249616660561546588347467362245e-03L), + }; + return data; + } +}; +#else +template +class gauss_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(5.14718425553176958330252131667225737e-02Q), + static_cast(1.53869913608583546963794672743255920e-01Q), + static_cast(2.54636926167889846439805129817805108e-01Q), + static_cast(3.52704725530878113471037207089373861e-01Q), + static_cast(4.47033769538089176780609900322854000e-01Q), + static_cast(5.36624148142019899264169793311072794e-01Q), + static_cast(6.20526182989242861140477556431189299e-01Q), + static_cast(6.97850494793315796932292388026640068e-01Q), + static_cast(7.67777432104826194917977340974503132e-01Q), + static_cast(8.29565762382768397442898119732501916e-01Q), + static_cast(8.82560535792052681543116462530225590e-01Q), + static_cast(9.26200047429274325879324277080474004e-01Q), + static_cast(9.60021864968307512216871025581797663e-01Q), + static_cast(9.83668123279747209970032581605662802e-01Q), + static_cast(9.96893484074649540271630050918695283e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(1.02852652893558840341285636705415044e-01Q), + static_cast(1.01762389748405504596428952168554045e-01Q), + static_cast(9.95934205867952670627802821035694765e-02Q), + static_cast(9.63687371746442596394686263518098651e-02Q), + static_cast(9.21225222377861287176327070876187672e-02Q), + static_cast(8.68997872010829798023875307151257026e-02Q), + static_cast(8.07558952294202153546949384605297309e-02Q), + static_cast(7.37559747377052062682438500221907342e-02Q), + static_cast(6.59742298821804951281285151159623612e-02Q), + static_cast(5.74931562176190664817216894020561288e-02Q), + static_cast(4.84026728305940529029381404228075178e-02Q), + static_cast(3.87991925696270495968019364463476920e-02Q), + static_cast(2.87847078833233693497191796112920436e-02Q), + static_cast(1.84664683110909591423021319120472691e-02Q), + static_cast(7.96819249616660561546588347467362245e-03Q), + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0285265289355884034128563670541504386837555706492822258631898667601623865660942939262884632188870916503815852709086e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0176238974840550459642895216855404463270628948712684086426094541964251360531767494547599781978391198881693385887696e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9593420586795267062780282103569476529869263666704277221365146183946660389908809018092299289324184705373523229592037e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6368737174644259639468626351809865096406461430160245912994275732837534742003123724951247818104195363343093583583429e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2122522237786128717632707087618767196913234418234107527675047001973047070094168298464052916811907158954949394100501e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6899787201082979802387530715125702576753328743545344012222129882153582254261494247955033509639105330215477601953921e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0755895229420215354694938460529730875892803708439299890258593706051180567026345604212402769217808080749416147400962e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3755974737705206268243850022190734153770526037049438941269182374599399314635211710401352716638183270192254236882630e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5974229882180495128128515115962361237442953656660378967031516042143672466094179365819913911598737439478205808271237e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7493156217619066481721689402056128797120670721763134548715799003232147409954376925211999650950125355559974348279846e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8402672830594052902938140422807517815271809197372736345191936791805425677102152797767439563562263454374645955072007e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8799192569627049596801936446347692033200976766395352107732789705946970952769793919055026279035105656340228558382274e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8784707883323369349719179611292043639588894546287496474180122608145988940013933101730206711484171554940392262251283e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8466468311090959142302131912047269096206533968181403371298365514585599521307973654080519029675417955638095832046164e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9681924961666056154658834746736224504806965871517212294851633569200384329013332941536616922861735209846506562158817e-03), + }; // LCOV_EXCL_STOP + return data; + } +}; + +} + +template > +class gauss : public detail::gauss_detail::value> +{ + typedef detail::gauss_detail::value> base; +public: + + template + static auto integrate(F f, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + // In many math texts, K represents the field of real or complex numbers. + // Too bad we can't put blackboard bold into C++ source! + typedef decltype(f(Real(0))) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + using std::abs; + unsigned non_zero_start = 1; + K result = Real(0); + if (N & 1) { + result = f(Real(0)) * static_cast(base::weights()[0]); + } + else { + result = 0; + non_zero_start = 0; + } + Real L1 = abs(result); + for (unsigned i = non_zero_start; i < base::abscissa().size(); ++i) + { + K fp = f(static_cast(base::abscissa()[i])); + K fm = f(static_cast(-base::abscissa()[i])); + result += (fp + fm) * static_cast(base::weights()[i]); + L1 += (abs(fp) + abs(fm)) * static_cast(base::weights()[i]); + } + if (pL1) + *pL1 = L1; + return result; + } + template + static auto integrate(F f, Real a, Real b, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(a)) K; + static const char* function = "boost::math::quadrature::gauss<%1%>::integrate(f, %1%, %1%)"; + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + // Infinite limits: + Real min_inf = -tools::max_value(); + if ((a <= min_inf) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real t_sq = t*t; + Real inv = 1 / (1 - t_sq); + K res = f(t*inv)*(1 + t_sq)*inv*inv; + return res; + }; + return integrate(u, pL1); + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z + a - 1; + K res = f(arg)*z*z; + return res; + }; + K Q = Real(2) * integrate(u, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z - 1; + K res = f(b - arg) * z * z; + return res; + }; + K Q = Real(2) * integrate(v, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a == b) + { + return K(0); + } + if (b < a) + { + return -integrate(f, b, a, pL1); + } + Real avg = (a + b)*constants::half(); + Real scale = (b - a)*constants::half(); + + auto u = [&](Real z)->K + { + return f(avg + scale*z); + }; + K Q = scale*integrate(u, pL1); + + if (pL1) + { + *pL1 *= scale; + } + return Q; + } + } + return static_cast(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy())); + } +}; + +} // namespace quadrature +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_QUADRATURE_GAUSS_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/gauss_kronrod.hpp b/third-party/boost-math/include/boost/math/quadrature/gauss_kronrod.hpp new file mode 100644 index 0000000000000..a81cb43c4f55e --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/gauss_kronrod.hpp @@ -0,0 +1,1317 @@ +// Copyright John Maddock 2017. +// Copyright Nick Thompson 2017. +// 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) + +#ifndef BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP +#define BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable: 4127) +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math{ namespace quadrature{ namespace detail{ + +#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND + +template +class gauss_kronrod_detail +{ + static legendre_stieltjes const& get_legendre_stieltjes() + { + static const legendre_stieltjes data((N - 1) / 2 + 1); + return data; + } + static std::vector calculate_abscissa() + { + static std::vector result = boost::math::legendre_p_zeros((N - 1) / 2); + const legendre_stieltjes E = get_legendre_stieltjes(); + std::vector ls_zeros = E.zeros(); + result.insert(result.end(), ls_zeros.begin(), ls_zeros.end()); + std::sort(result.begin(), result.end()); + return result; + } + static std::vector calculate_weights() + { + std::vector result(abscissa().size(), 0); + unsigned gauss_order = (N - 1) / 2; + unsigned gauss_start = gauss_order & 1 ? 0 : 1; + const legendre_stieltjes& E = get_legendre_stieltjes(); + + for (unsigned i = gauss_start; i < abscissa().size(); i += 2) + { + Real x = abscissa()[i]; + Real p = boost::math::legendre_p_prime(gauss_order, x); + Real gauss_weight = 2 / ((1 - x * x) * p * p); + result[i] = gauss_weight + static_cast(2) / (static_cast(gauss_order + 1) * legendre_p_prime(gauss_order, x) * E(x)); + } + for (unsigned i = gauss_start ? 0 : 1; i < abscissa().size(); i += 2) + { + Real x = abscissa()[i]; + result[i] = static_cast(2) / (static_cast(gauss_order + 1) * legendre_p(gauss_order, x) * E.prime(x)); + } + return result; + } +public: + static const std::vector& abscissa() + { + static std::vector data = calculate_abscissa(); + return data; + } + static const std::vector& weights() + { + static std::vector data = calculate_weights(); + return data; + } +}; + +#else + +template +class gauss_kronrod_detail; + +#endif + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(2.07784955007898467600689403773244913e-01L), + static_cast(4.05845151377397166906606412076961463e-01L), + static_cast(5.86087235467691130294144838258729598e-01L), + static_cast(7.41531185599394439863864773280788407e-01L), + static_cast(8.64864423359769072789712788640926201e-01L), + static_cast(9.49107912342758524526189684047851262e-01L), + static_cast(9.91455371120812639206854697526328517e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(2.09482141084727828012999174891714264e-01L), + static_cast(2.04432940075298892414161999234649085e-01L), + static_cast(1.90350578064785409913256402421013683e-01L), + static_cast(1.69004726639267902826583426598550284e-01L), + static_cast(1.40653259715525918745189590510237920e-01L), + static_cast(1.04790010322250183839876322541518017e-01L), + static_cast(6.30920926299785532907006631892042867e-02L), + static_cast(2.29353220105292249637320080589695920e-02L), + }; + return data; + } +}; + +#else +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(2.07784955007898467600689403773244913e-01Q), + static_cast(4.05845151377397166906606412076961463e-01Q), + static_cast(5.86087235467691130294144838258729598e-01Q), + static_cast(7.41531185599394439863864773280788407e-01Q), + static_cast(8.64864423359769072789712788640926201e-01Q), + static_cast(9.49107912342758524526189684047851262e-01Q), + static_cast(9.91455371120812639206854697526328517e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(2.09482141084727828012999174891714264e-01Q), + static_cast(2.04432940075298892414161999234649085e-01Q), + static_cast(1.90350578064785409913256402421013683e-01Q), + static_cast(1.69004726639267902826583426598550284e-01Q), + static_cast(1.40653259715525918745189590510237920e-01Q), + static_cast(1.04790010322250183839876322541518017e-01Q), + static_cast(6.30920926299785532907006631892042867e-02Q), + static_cast(2.29353220105292249637320080589695920e-02Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0778495500789846760068940377324491347978440714517064971384573461986693844943520226910343227183698530560857645062738e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8608723546769113029414483825872959843678075060436095130499289319880373607444407464511674498935942098956811555121368e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6486442335976907278971278864092620121097230707408814860145771276706770813259572103585847859604590541475281326027862e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9145537112081263920685469752632851664204433837033470129108741357244173934653407235924503509626841760744349505339308e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0948214108472782801299917489171426369776208022370431671299800656137515132325648616816908211675949102392971459688215e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0443294007529889241416199923464908471651760418071835742447095312045467698546598879348374292009347554167803659293064e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9035057806478540991325640242101368282607807545535835588544088036744058072410212679605964605106377593834568683551139e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6900472663926790282658342659855028410624490030294424149734006755695680921619029112936702403855359908156070095656537e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4065325971552591874518959051023792039988975724799857556174546893312708093090950408097379122415555910759700350860143e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0479001032225018383987632254151801744375665421383061189339065133963746321576289524167571627509311333949422518201492e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3092092629978553290700663189204286665071157211550707113605545146983997477964874928199170264504441995865872491871943e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2935322010529224963732008058969591993560811275746992267507430254711815787976075946156368168156289483493617134063245e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(1.48874338981631210884826001129719985e-01L), + static_cast(2.94392862701460198131126603103865566e-01L), + static_cast(4.33395394129247190799265943165784162e-01L), + static_cast(5.62757134668604683339000099272694141e-01L), + static_cast(6.79409568299024406234327365114873576e-01L), + static_cast(7.80817726586416897063717578345042377e-01L), + static_cast(8.65063366688984510732096688423493049e-01L), + static_cast(9.30157491355708226001207180059508346e-01L), + static_cast(9.73906528517171720077964012084452053e-01L), + static_cast(9.95657163025808080735527280689002848e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(1.49445554002916905664936468389821204e-01L), + static_cast(1.47739104901338491374841515972068046e-01L), + static_cast(1.42775938577060080797094273138717061e-01L), + static_cast(1.34709217311473325928054001771706833e-01L), + static_cast(1.23491976262065851077958109831074160e-01L), + static_cast(1.09387158802297641899210590325804960e-01L), + static_cast(9.31254545836976055350654650833663444e-02L), + static_cast(7.50396748109199527670431409161900094e-02L), + static_cast(5.47558965743519960313813002445801764e-02L), + static_cast(3.25581623079647274788189724593897606e-02L), + static_cast(1.16946388673718742780643960621920484e-02L), + }; + return data; + } +}; + +#else +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(1.48874338981631210884826001129719985e-01Q), + static_cast(2.94392862701460198131126603103865566e-01Q), + static_cast(4.33395394129247190799265943165784162e-01Q), + static_cast(5.62757134668604683339000099272694141e-01Q), + static_cast(6.79409568299024406234327365114873576e-01Q), + static_cast(7.80817726586416897063717578345042377e-01Q), + static_cast(8.65063366688984510732096688423493049e-01Q), + static_cast(9.30157491355708226001207180059508346e-01Q), + static_cast(9.73906528517171720077964012084452053e-01Q), + static_cast(9.95657163025808080735527280689002848e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(1.49445554002916905664936468389821204e-01Q), + static_cast(1.47739104901338491374841515972068046e-01Q), + static_cast(1.42775938577060080797094273138717061e-01Q), + static_cast(1.34709217311473325928054001771706833e-01Q), + static_cast(1.23491976262065851077958109831074160e-01Q), + static_cast(1.09387158802297641899210590325804960e-01Q), + static_cast(9.31254545836976055350654650833663444e-02Q), + static_cast(7.50396748109199527670431409161900094e-02Q), + static_cast(5.47558965743519960313813002445801764e-02Q), + static_cast(3.25581623079647274788189724593897606e-02Q), + static_cast(1.16946388673718742780643960621920484e-02Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9439286270146019813112660310386556616268662515695791864888229172724611166332737888445523178268237359119185139299872e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.6275713466860468333900009927269414084301388194196695886034621458779266353216327549712087854169992422106448211158815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.8081772658641689706371757834504237716340752029815717974694859999505607982761420654526977234238996241110129779403362e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3015749135570822600120718005950834622516790998193924230349406866828415983091673055011194572851007884702013619684320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9565716302580808073552728068900284792126058721947892436337916111757023046774867357152325996912076724298149077812671e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4944555400291690566493646838982120374523631668747280383560851873698964478511841925721030705689540264726493367634340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4773910490133849137484151597206804552373162548520660451819195439885993016735696405732703959182882254268727823258502e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4277593857706008079709427313871706088597905653190555560741004743970770449909340027811131706283756428281146832304737e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3470921731147332592805400177170683276099191300855971406636668491320291400121282036676953159488271772384389604997640e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2349197626206585107795810983107415951230034952864832764467994120974054238975454689681538622363738230836484113389878e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0938715880229764189921059032580496027181329983434522007819675829826550372891432168683899432674553842507906611591517e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3125454583697605535065465083366344390018828880760031970085038760177735672200775237414123061615827474831165614953012e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5039674810919952767043140916190009395219382000910088173697048048430404342858495178813808730646554086856929327903059e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4755896574351996031381300244580176373721114058333557524432615804784098927818975325116301569003298086458722055550981e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2558162307964727478818972459389760617388939845662609571537504232714121820165498692381607605384626494546068817765276e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1694638867371874278064396062192048396217332481931888927598147525622222058064992651806736704969967250888097490233242e-02), + }; // LCOV_EXCL_STOP + return data; + } +}; + + +#ifndef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(1.01142066918717499027074231447392339e-01L), + static_cast(2.01194093997434522300628303394596208e-01L), + static_cast(2.99180007153168812166780024266388963e-01L), + static_cast(3.94151347077563369897207370981045468e-01L), + static_cast(4.85081863640239680693655740232350613e-01L), + static_cast(5.70972172608538847537226737253910641e-01L), + static_cast(6.50996741297416970533735895313274693e-01L), + static_cast(7.24417731360170047416186054613938010e-01L), + static_cast(7.90418501442465932967649294817947347e-01L), + static_cast(8.48206583410427216200648320774216851e-01L), + static_cast(8.97264532344081900882509656454495883e-01L), + static_cast(9.37273392400705904307758947710209471e-01L), + static_cast(9.67739075679139134257347978784337225e-01L), + static_cast(9.87992518020485428489565718586612581e-01L), + static_cast(9.98002298693397060285172840152271209e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(1.01330007014791549017374792767492547e-01L), + static_cast(1.00769845523875595044946662617569722e-01L), + static_cast(9.91735987217919593323931734846031311e-02L), + static_cast(9.66427269836236785051799076275893351e-02L), + static_cast(9.31265981708253212254868727473457186e-02L), + static_cast(8.85644430562117706472754436937743032e-02L), + static_cast(8.30805028231330210382892472861037896e-02L), + static_cast(7.68496807577203788944327774826590067e-02L), + static_cast(6.98541213187282587095200770991474758e-02L), + static_cast(6.20095678006706402851392309608029322e-02L), + static_cast(5.34815246909280872653431472394302968e-02L), + static_cast(4.45897513247648766082272993732796902e-02L), + static_cast(3.53463607913758462220379484783600481e-02L), + static_cast(2.54608473267153201868740010196533594e-02L), + static_cast(1.50079473293161225383747630758072681e-02L), + static_cast(5.37747987292334898779205143012764982e-03L), + }; + return data; + } +}; + +#else + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(1.01142066918717499027074231447392339e-01Q), + static_cast(2.01194093997434522300628303394596208e-01Q), + static_cast(2.99180007153168812166780024266388963e-01Q), + static_cast(3.94151347077563369897207370981045468e-01Q), + static_cast(4.85081863640239680693655740232350613e-01Q), + static_cast(5.70972172608538847537226737253910641e-01Q), + static_cast(6.50996741297416970533735895313274693e-01Q), + static_cast(7.24417731360170047416186054613938010e-01Q), + static_cast(7.90418501442465932967649294817947347e-01Q), + static_cast(8.48206583410427216200648320774216851e-01Q), + static_cast(8.97264532344081900882509656454495883e-01Q), + static_cast(9.37273392400705904307758947710209471e-01Q), + static_cast(9.67739075679139134257347978784337225e-01Q), + static_cast(9.87992518020485428489565718586612581e-01Q), + static_cast(9.98002298693397060285172840152271209e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(1.01330007014791549017374792767492547e-01Q), + static_cast(1.00769845523875595044946662617569722e-01Q), + static_cast(9.91735987217919593323931734846031311e-02Q), + static_cast(9.66427269836236785051799076275893351e-02Q), + static_cast(9.31265981708253212254868727473457186e-02Q), + static_cast(8.85644430562117706472754436937743032e-02Q), + static_cast(8.30805028231330210382892472861037896e-02Q), + static_cast(7.68496807577203788944327774826590067e-02Q), + static_cast(6.98541213187282587095200770991474758e-02Q), + static_cast(6.20095678006706402851392309608029322e-02Q), + static_cast(5.34815246909280872653431472394302968e-02Q), + static_cast(4.45897513247648766082272993732796902e-02Q), + static_cast(3.53463607913758462220379484783600481e-02Q), + static_cast(2.54608473267153201868740010196533594e-02Q), + static_cast(1.50079473293161225383747630758072681e-02Q), + static_cast(5.37747987292334898779205143012764982e-03Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0114206691871749902707423144739233878745105740164180495800189504151097862454083050931321451540380998341273193681967e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9918000715316881216678002426638896266160338274382080184125545738918081102513884467602322020157243563662094470221235e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8508186364023968069365574023235061286633893089407312129367943604080239955167155974371848690848595275551258416303565e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5099674129741697053373589531327469254694822609259966708966160576093305841043840794460394747228060367236079289132544e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9041850144246593296764929481794734686214051995697617332365280643308302974631807059994738664225445530963711137343440e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9726453234408190088250965645449588283177871149442786763972687601078537721473771221195399661919716123038835639691946e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6773907567913913425734797878433722528335733730013163797468062226335804249452174804319385048203118506304424717089291e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9800229869339706028517284015227120907340644231555723034839427970683348682837134566648979907760125278631896777136104e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0133000701479154901737479276749254677092627259659629246734858372174107615774696665932418050683956749891773195816338e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0076984552387559504494666261756972191634838013536373069278929029488122760822761077475060185965408326901925180106227e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9173598721791959332393173484603131059567260816713281734860095693651563064308745717056680128223790739026832596087552e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6642726983623678505179907627589335136656568630495198973407668882934392359962841826511402504664592185391687490319950e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3126598170825321225486872747345718561927881321317330560285879189052002874531855060114908990458716740695847509343865e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8564443056211770647275443693774303212266732690655967817996052574877144544749814260718837576325109922207832119243346e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3080502823133021038289247286103789601554188253368717607281604875233630643885056057630789228337088859687986285569521e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6849680757720378894432777482659006722109101167947000584089097112470821092034084418224731527690291913686588446455555e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9854121318728258709520077099147475786045435140671549698798093177992675624987998849748628778570667518643649536771245e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2009567800670640285139230960802932190400004210329723569147829395618376206272317333030584268303808639229575334680414e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3481524690928087265343147239430296771554760947116739813222888752727413616259625439714812475198987513183153639571249e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4589751324764876608227299373279690223256649667921096570980823211805450700059906366455036418897149593261561551176267e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5346360791375846222037948478360048122630678992420820868148023340902501837247680978434662724296810081131106317333086e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5460847326715320186874001019653359397271745046864640508377984982400903447009185267605205778819712848080691366407461e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5007947329316122538374763075807268094639436437387634979291759700896494746154334398961710227490402528151677469993935e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3774798729233489877920514301276498183080402431284197876486169536848635554354599213793172596490038991436925569025913e-03), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(7.65265211334973337546404093988382110e-02L), + static_cast(1.52605465240922675505220241022677528e-01L), + static_cast(2.27785851141645078080496195368574625e-01L), + static_cast(3.01627868114913004320555356858592261e-01L), + static_cast(3.73706088715419560672548177024927237e-01L), + static_cast(4.43593175238725103199992213492640108e-01L), + static_cast(5.10867001950827098004364050955250998e-01L), + static_cast(5.75140446819710315342946036586425133e-01L), + static_cast(6.36053680726515025452836696226285937e-01L), + static_cast(6.93237656334751384805490711845931533e-01L), + static_cast(7.46331906460150792614305070355641590e-01L), + static_cast(7.95041428837551198350638833272787943e-01L), + static_cast(8.39116971822218823394529061701520685e-01L), + static_cast(8.78276811252281976077442995113078467e-01L), + static_cast(9.12234428251325905867752441203298113e-01L), + static_cast(9.40822633831754753519982722212443380e-01L), + static_cast(9.63971927277913791267666131197277222e-01L), + static_cast(9.81507877450250259193342994720216945e-01L), + static_cast(9.93128599185094924786122388471320278e-01L), + static_cast(9.98859031588277663838315576545863010e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(7.66007119179996564450499015301017408e-02L), + static_cast(7.63778676720807367055028350380610018e-02L), + static_cast(7.57044976845566746595427753766165583e-02L), + static_cast(7.45828754004991889865814183624875286e-02L), + static_cast(7.30306903327866674951894176589131128e-02L), + static_cast(7.10544235534440683057903617232101674e-02L), + static_cast(6.86486729285216193456234118853678017e-02L), + static_cast(6.58345971336184221115635569693979431e-02L), + static_cast(6.26532375547811680258701221742549806e-02L), + static_cast(5.91114008806395723749672206485942171e-02L), + static_cast(5.51951053482859947448323724197773292e-02L), + static_cast(5.09445739237286919327076700503449487e-02L), + static_cast(4.64348218674976747202318809261075168e-02L), + static_cast(4.16688733279736862637883059368947380e-02L), + static_cast(3.66001697582007980305572407072110085e-02L), + static_cast(3.12873067770327989585431193238007379e-02L), + static_cast(2.58821336049511588345050670961531430e-02L), + static_cast(2.03883734612665235980102314327547051e-02L), + static_cast(1.46261692569712529837879603088683562e-02L), + static_cast(8.60026985564294219866178795010234725e-03L), + static_cast(3.07358371852053150121829324603098749e-03L), + }; + return data; + } +}; + +#else + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(7.65265211334973337546404093988382110e-02Q), + static_cast(1.52605465240922675505220241022677528e-01Q), + static_cast(2.27785851141645078080496195368574625e-01Q), + static_cast(3.01627868114913004320555356858592261e-01Q), + static_cast(3.73706088715419560672548177024927237e-01Q), + static_cast(4.43593175238725103199992213492640108e-01Q), + static_cast(5.10867001950827098004364050955250998e-01Q), + static_cast(5.75140446819710315342946036586425133e-01Q), + static_cast(6.36053680726515025452836696226285937e-01Q), + static_cast(6.93237656334751384805490711845931533e-01Q), + static_cast(7.46331906460150792614305070355641590e-01Q), + static_cast(7.95041428837551198350638833272787943e-01Q), + static_cast(8.39116971822218823394529061701520685e-01Q), + static_cast(8.78276811252281976077442995113078467e-01Q), + static_cast(9.12234428251325905867752441203298113e-01Q), + static_cast(9.40822633831754753519982722212443380e-01Q), + static_cast(9.63971927277913791267666131197277222e-01Q), + static_cast(9.81507877450250259193342994720216945e-01Q), + static_cast(9.93128599185094924786122388471320278e-01Q), + static_cast(9.98859031588277663838315576545863010e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(7.66007119179996564450499015301017408e-02Q), + static_cast(7.63778676720807367055028350380610018e-02Q), + static_cast(7.57044976845566746595427753766165583e-02Q), + static_cast(7.45828754004991889865814183624875286e-02Q), + static_cast(7.30306903327866674951894176589131128e-02Q), + static_cast(7.10544235534440683057903617232101674e-02Q), + static_cast(6.86486729285216193456234118853678017e-02Q), + static_cast(6.58345971336184221115635569693979431e-02Q), + static_cast(6.26532375547811680258701221742549806e-02Q), + static_cast(5.91114008806395723749672206485942171e-02Q), + static_cast(5.51951053482859947448323724197773292e-02Q), + static_cast(5.09445739237286919327076700503449487e-02Q), + static_cast(4.64348218674976747202318809261075168e-02Q), + static_cast(4.16688733279736862637883059368947380e-02Q), + static_cast(3.66001697582007980305572407072110085e-02Q), + static_cast(3.12873067770327989585431193238007379e-02Q), + static_cast(2.58821336049511588345050670961531430e-02Q), + static_cast(2.03883734612665235980102314327547051e-02Q), + static_cast(1.46261692569712529837879603088683562e-02Q), + static_cast(8.60026985564294219866178795010234725e-03Q), + static_cast(3.07358371852053150121829324603098749e-03Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5260546524092267550522024102267752791167622481841730660174156703809133685751696356987995886397049724808931527012542e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0162786811491300432055535685859226061539650501373092456926374427956957435978384116066498234762220215751079886015902e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4359317523872510319999221349264010784010101082300309613315028346299543059315258601993479156987847429893626854030516e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7514044681971031534294603658642513281381264014771682537415885495717468074720062012357788489049470208285175093670561e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9323765633475138480549071184593153338642585141021417904687378454301191710739219011546672416325022748282227809465165e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9504142883755119835063883327278794295938959911578029703855163894322697871710382866701777890251824617748545658564370e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.7827681125228197607744299511307846671124526828251164853898086998248145904743220740840261624245683876748360309079747e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4082263383175475351998272221244338027429557377965291059536839973186796006557571220888218676776618448841584569497535e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8150787745025025919334299472021694456725093981023759869077533318793098857465723460898060491887511355706497739384103e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9885903158827766383831557654586300999957020432629666866666860339324411793311982967839129772854179884971700274369367e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6600711917999656445049901530101740827932500628670118055485349620314721456712029449597396569857880493210849110825276e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6377867672080736705502835038061001800801036764945996714946431116936745542061941050008345047482501253320401746334511e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5704497684556674659542775376616558263363155900414326194855223272348838596099414841886740468379707283366777797425290e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4582875400499188986581418362487528616116493572092273080047040726969899567887364227664202642942357104526915332274625e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3030690332786667495189417658913112760626845234552742380174250771849743831660040966804802312464527721645765620253776e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1054423553444068305790361723210167412912159322210143921628270586407381879789525901086146473278095159807542174985045e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8648672928521619345623411885367801715489704958239860400434264173923806029589970941711224257967651039544669425313433e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5834597133618422111563556969397943147223506343381443709751749639944420314384296347503523810096842402960802728781816e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2653237554781168025870122174254980585819744698897886186553324157100424088919284503451596742588386343548162830898103e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9111400880639572374967220648594217136419365977042191748388047204015262840407696611508732839851952697839735487615776e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5195105348285994744832372419777329194753456228153116909812131213177827707884692917845453999535518818940813085110223e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0944573923728691932707670050344948664836365809262579747517140086119113476866735641054822574173198900379392130050979e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6434821867497674720231880926107516842127071007077929289994127933243222585938804392953931185146446072587020288747981e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1668873327973686263788305936894738043960843153010324860966353235271889596379726462208702081068715463576895020003842e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6600169758200798030557240707211008487453496747498001651070009441973280061489266074044986901436324295513243878212345e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.1287306777032798958543119323800737887769280362813337359554598005322423266047996771926031069705049476071896145456496e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5882133604951158834505067096153142999479118048674944526997797755374306421629440393392427198869345793286369198147609e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0388373461266523598010231432754705122838627940185929365371868214433006532030353671253640300679157504987977281782909e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4626169256971252983787960308868356163881050162249770342103474631076960029748751959380482484308382288261238476948520e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6002698556429421986617879501023472521289227667077976622450602031426535362696437838448828009554532025301579670206091e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0735837185205315012182932460309874880335046882543449198461628212114333665590378156706265241414469306987988292234740e-03), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(6.15444830056850788865463923667966313e-02L), + static_cast(1.22864692610710396387359818808036806e-01L), + static_cast(1.83718939421048892015969888759528416e-01L), + static_cast(2.43866883720988432045190362797451586e-01L), + static_cast(3.03089538931107830167478909980339329e-01L), + static_cast(3.61172305809387837735821730127640667e-01L), + static_cast(4.17885382193037748851814394594572487e-01L), + static_cast(4.73002731445714960522182115009192041e-01L), + static_cast(5.26325284334719182599623778158010178e-01L), + static_cast(5.77662930241222967723689841612654067e-01L), + static_cast(6.26810099010317412788122681624517881e-01L), + static_cast(6.73566368473468364485120633247622176e-01L), + static_cast(7.17766406813084388186654079773297781e-01L), + static_cast(7.59259263037357630577282865204360976e-01L), + static_cast(7.97873797998500059410410904994306569e-01L), + static_cast(8.33442628760834001421021108693569569e-01L), + static_cast(8.65847065293275595448996969588340088e-01L), + static_cast(8.94991997878275368851042006782804954e-01L), + static_cast(9.20747115281701561746346084546330632e-01L), + static_cast(9.42974571228974339414011169658470532e-01L), + static_cast(9.61614986425842512418130033660167242e-01L), + static_cast(9.76663921459517511498315386479594068e-01L), + static_cast(9.88035794534077247637331014577406227e-01L), + static_cast(9.95556969790498097908784946893901617e-01L), + static_cast(9.99262104992609834193457486540340594e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(6.15808180678329350787598242400645532e-02L), + static_cast(6.14711898714253166615441319652641776e-02L), + static_cast(6.11285097170530483058590304162927119e-02L), + static_cast(6.05394553760458629453602675175654272e-02L), + static_cast(5.97203403241740599790992919325618538e-02L), + static_cast(5.86896800223942079619741758567877641e-02L), + static_cast(5.74371163615678328535826939395064720e-02L), + static_cast(5.59508112204123173082406863827473468e-02L), + static_cast(5.42511298885454901445433704598756068e-02L), + static_cast(5.23628858064074758643667121378727149e-02L), + static_cast(5.02776790807156719633252594334400844e-02L), + static_cast(4.79825371388367139063922557569147550e-02L), + static_cast(4.55029130499217889098705847526603930e-02L), + static_cast(4.28728450201700494768957924394951611e-02L), + static_cast(4.00838255040323820748392844670756464e-02L), + static_cast(3.71162714834155435603306253676198760e-02L), + static_cast(3.40021302743293378367487952295512032e-02L), + static_cast(3.07923001673874888911090202152285856e-02L), + static_cast(2.74753175878517378029484555178110786e-02L), + static_cast(2.40099456069532162200924891648810814e-02L), + static_cast(2.04353711458828354565682922359389737e-02L), + static_cast(1.68478177091282982315166675363363158e-02L), + static_cast(1.32362291955716748136564058469762381e-02L), + static_cast(9.47397338617415160720771052365532387e-03L), + static_cast(5.56193213535671375804023690106552207e-03L), + static_cast(1.98738389233031592650785188284340989e-03L), + }; + return data; + } +}; + +#else + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(6.15444830056850788865463923667966313e-02Q), + static_cast(1.22864692610710396387359818808036806e-01Q), + static_cast(1.83718939421048892015969888759528416e-01Q), + static_cast(2.43866883720988432045190362797451586e-01Q), + static_cast(3.03089538931107830167478909980339329e-01Q), + static_cast(3.61172305809387837735821730127640667e-01Q), + static_cast(4.17885382193037748851814394594572487e-01Q), + static_cast(4.73002731445714960522182115009192041e-01Q), + static_cast(5.26325284334719182599623778158010178e-01Q), + static_cast(5.77662930241222967723689841612654067e-01Q), + static_cast(6.26810099010317412788122681624517881e-01Q), + static_cast(6.73566368473468364485120633247622176e-01Q), + static_cast(7.17766406813084388186654079773297781e-01Q), + static_cast(7.59259263037357630577282865204360976e-01Q), + static_cast(7.97873797998500059410410904994306569e-01Q), + static_cast(8.33442628760834001421021108693569569e-01Q), + static_cast(8.65847065293275595448996969588340088e-01Q), + static_cast(8.94991997878275368851042006782804954e-01Q), + static_cast(9.20747115281701561746346084546330632e-01Q), + static_cast(9.42974571228974339414011169658470532e-01Q), + static_cast(9.61614986425842512418130033660167242e-01Q), + static_cast(9.76663921459517511498315386479594068e-01Q), + static_cast(9.88035794534077247637331014577406227e-01Q), + static_cast(9.95556969790498097908784946893901617e-01Q), + static_cast(9.99262104992609834193457486540340594e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(6.15808180678329350787598242400645532e-02Q), + static_cast(6.14711898714253166615441319652641776e-02Q), + static_cast(6.11285097170530483058590304162927119e-02Q), + static_cast(6.05394553760458629453602675175654272e-02Q), + static_cast(5.97203403241740599790992919325618538e-02Q), + static_cast(5.86896800223942079619741758567877641e-02Q), + static_cast(5.74371163615678328535826939395064720e-02Q), + static_cast(5.59508112204123173082406863827473468e-02Q), + static_cast(5.42511298885454901445433704598756068e-02Q), + static_cast(5.23628858064074758643667121378727149e-02Q), + static_cast(5.02776790807156719633252594334400844e-02Q), + static_cast(4.79825371388367139063922557569147550e-02Q), + static_cast(4.55029130499217889098705847526603930e-02Q), + static_cast(4.28728450201700494768957924394951611e-02Q), + static_cast(4.00838255040323820748392844670756464e-02Q), + static_cast(3.71162714834155435603306253676198760e-02Q), + static_cast(3.40021302743293378367487952295512032e-02Q), + static_cast(3.07923001673874888911090202152285856e-02Q), + static_cast(2.74753175878517378029484555178110786e-02Q), + static_cast(2.40099456069532162200924891648810814e-02Q), + static_cast(2.04353711458828354565682922359389737e-02Q), + static_cast(1.68478177091282982315166675363363158e-02Q), + static_cast(1.32362291955716748136564058469762381e-02Q), + static_cast(9.47397338617415160720771052365532387e-03Q), + static_cast(5.56193213535671375804023690106552207e-03Q), + static_cast(1.98738389233031592650785188284340989e-03Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1544483005685078886546392366796631281724348039823545274305431751687279361558658545141048781022691067898008423227288e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8371893942104889201596988875952841578528447834990555215034512653236752851109815617651867160645591242103823539931527e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0308953893110783016747890998033932920041937876655194685731578452573120372337209717349617882111662416355753711853559e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1788538219303774885181439459457248709336998140069528034955785068796932076966599548717224205109797297615032607570119e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2632528433471918259962377815801017803683252320191114313002425180471455022502695302371008520604638341970901082293650e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2681009901031741278812268162451788101954628995068510806525222008437260184181183053045236423845198752346149030569920e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1776640681308438818665407977329778059771167555515582423493486823991612820974965089522905953765860328116692570706602e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9787379799850005941041090499430656940863230009338267661706934499488650817643824077118950314443984031474353711531825e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6584706529327559544899696958834008820284409402823690293965213246691432948180280120756708738064779055576005302835351e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2074711528170156174634608454633063157457035996277199700642836501131385042631212407808952281702820179915510491592339e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6161498642584251241813003366016724169212642963709676666624520141292893281185666917636407790823210892689040877316178e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8803579453407724763733101457740622707248415209160748131449972199405186821347293686245404742032360498210710718706868e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9926210499260983419345748654034059370452496042279618586228697762904524428167719073818746102238075978747461480736921e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1580818067832935078759824240064553190436936903140808056908996403358367244202623293256774502185186717703954810463664e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1471189871425316661544131965264177586537962876885022711111683500151700796198726558483367566537422877227096643444043e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1128509717053048305859030416292711922678552321960938357322028070390133769952032831204895569347757809858568165047769e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.0539455376045862945360267517565427162312365710457079923487043144554747810689514408013582515489930908693681447570811e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9720340324174059979099291932561853835363045476189975483372207816149988460708299020779612375010639778624011960832019e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8689680022394207961974175856787764139795646254828315293243700305012569486054157617049685031506591863121580010947248e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7437116361567832853582693939506471994832856823896682976509412313367495727224381199978598247737089593472710899482737e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5950811220412317308240686382747346820271035112771802428932791066115158268338607019365831655460314732208940609352540e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4251129888545490144543370459875606826076838441263383072163293312936923476650934130242315028422047795830492882862973e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2362885806407475864366712137872714887351550723707596350905793656046659248541276597504566497990926306481919129870507e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0277679080715671963325259433440084440587630604775975142050968279743014641141402310302584542633557037153607386127936e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7982537138836713906392255756914754983592207423271169651235865196757913880334117810235517477328110033499422471098658e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.5502913049921788909870584752660393043707768935695327316724254392794299567957035458208970599641697203261236226745020e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.2872845020170049476895792439495161101999504199883328877919242515738957655253932048951366960802592343905647433925806e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0083825504032382074839284467075646401410549266591308713115878386835777315058451955614116158949614066927183232852042e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7116271483415543560330625367619875995997802688047764805628702762773009669395760582294525748583875707140577080663373e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4002130274329337836748795229551203225670528250050443083264193121524339063344855010257660547708022429300203676502386e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0792300167387488891109020215228585600877162393292487644544830559965388047996492709248618249084851477787538356572832e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7475317587851737802948455517811078614796013288710603199613621069727810352835469926107822047433566792405123805901196e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4009945606953216220092489164881081392931528209659330290734972342536012282191913069778658241972047765300060007037359e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0435371145882835456568292235938973678758006097668937220074531550163622566841885855957623103354443247806459277197725e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6847817709128298231516667536336315840402654624706139411175769276842182270078960078544597372646532637619276509222462e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3236229195571674813656405846976238077578084997863654732213860488560614587634395544002156258192582265590155862296710e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4739733861741516072077105236553238716453268483726334971394029603529306140359023187904705754719643032594360138998941e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5619321353567137580402369010655220701769295496290984052961210793810038857581724171021610100708799763006942755331129e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9873838923303159265078518828434098894299804282505973837653346298985629336820118753523093675303476883723992297810124e-03), + }; // LCOV_EXCL_STOP + return data; + } +}; + +#ifndef BOOST_HAS_FLOAT128 + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + static_cast(0.00000000000000000000000000000000000e+00L), + static_cast(5.14718425553176958330252131667225737e-02L), + static_cast(1.02806937966737030147096751318000592e-01L), + static_cast(1.53869913608583546963794672743255920e-01L), + static_cast(2.04525116682309891438957671002024710e-01L), + static_cast(2.54636926167889846439805129817805108e-01L), + static_cast(3.04073202273625077372677107199256554e-01L), + static_cast(3.52704725530878113471037207089373861e-01L), + static_cast(4.00401254830394392535476211542660634e-01L), + static_cast(4.47033769538089176780609900322854000e-01L), + static_cast(4.92480467861778574993693061207708796e-01L), + static_cast(5.36624148142019899264169793311072794e-01L), + static_cast(5.79345235826361691756024932172540496e-01L), + static_cast(6.20526182989242861140477556431189299e-01L), + static_cast(6.60061064126626961370053668149270753e-01L), + static_cast(6.97850494793315796932292388026640068e-01L), + static_cast(7.33790062453226804726171131369527646e-01L), + static_cast(7.67777432104826194917977340974503132e-01L), + static_cast(7.99727835821839083013668942322683241e-01L), + static_cast(8.29565762382768397442898119732501916e-01L), + static_cast(8.57205233546061098958658510658943857e-01L), + static_cast(8.82560535792052681543116462530225590e-01L), + static_cast(9.05573307699907798546522558925958320e-01L), + static_cast(9.26200047429274325879324277080474004e-01L), + static_cast(9.44374444748559979415831324037439122e-01L), + static_cast(9.60021864968307512216871025581797663e-01L), + static_cast(9.73116322501126268374693868423706885e-01L), + static_cast(9.83668123279747209970032581605662802e-01L), + static_cast(9.91630996870404594858628366109485725e-01L), + static_cast(9.96893484074649540271630050918695283e-01L), + static_cast(9.99484410050490637571325895705810819e-01L), + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + static_cast(5.14947294294515675583404336470993075e-02L), + static_cast(5.14261285374590259338628792157812598e-02L), + static_cast(5.12215478492587721706562826049442083e-02L), + static_cast(5.08817958987496064922974730498046919e-02L), + static_cast(5.04059214027823468408930856535850289e-02L), + static_cast(4.97956834270742063578115693799423285e-02L), + static_cast(4.90554345550297788875281653672381736e-02L), + static_cast(4.81858617570871291407794922983045926e-02L), + static_cast(4.71855465692991539452614781810994865e-02L), + static_cast(4.60592382710069881162717355593735806e-02L), + static_cast(4.48148001331626631923555516167232438e-02L), + static_cast(4.34525397013560693168317281170732581e-02L), + static_cast(4.19698102151642461471475412859697578e-02L), + static_cast(4.03745389515359591119952797524681142e-02L), + static_cast(3.86789456247275929503486515322810503e-02L), + static_cast(3.68823646518212292239110656171359677e-02L), + static_cast(3.49793380280600241374996707314678751e-02L), + static_cast(3.29814470574837260318141910168539275e-02L), + static_cast(3.09072575623877624728842529430922726e-02L), + static_cast(2.87540487650412928439787853543342111e-02L), + static_cast(2.65099548823331016106017093350754144e-02L), + static_cast(2.41911620780806013656863707252320268e-02L), + static_cast(2.18280358216091922971674857383389934e-02L), + static_cast(1.94141411939423811734089510501284559e-02L), + static_cast(1.69208891890532726275722894203220924e-02L), + static_cast(1.43697295070458048124514324435800102e-02L), + static_cast(1.18230152534963417422328988532505929e-02L), + static_cast(9.27327965951776342844114689202436042e-03L), + static_cast(6.63070391593129217331982636975016813e-03L), + static_cast(3.89046112709988405126720184451550328e-03L), + static_cast(1.38901369867700762455159122675969968e-03L), + }; + return data; + } +}; + +#else + +template +class gauss_kronrod_detail +{ + using storage_type = typename gauss_constant_category::storage_type; +public: + static std::array const & abscissa() + { + static const std::array data = { + static_cast(0.00000000000000000000000000000000000e+00Q), + static_cast(5.14718425553176958330252131667225737e-02Q), + static_cast(1.02806937966737030147096751318000592e-01Q), + static_cast(1.53869913608583546963794672743255920e-01Q), + static_cast(2.04525116682309891438957671002024710e-01Q), + static_cast(2.54636926167889846439805129817805108e-01Q), + static_cast(3.04073202273625077372677107199256554e-01Q), + static_cast(3.52704725530878113471037207089373861e-01Q), + static_cast(4.00401254830394392535476211542660634e-01Q), + static_cast(4.47033769538089176780609900322854000e-01Q), + static_cast(4.92480467861778574993693061207708796e-01Q), + static_cast(5.36624148142019899264169793311072794e-01Q), + static_cast(5.79345235826361691756024932172540496e-01Q), + static_cast(6.20526182989242861140477556431189299e-01Q), + static_cast(6.60061064126626961370053668149270753e-01Q), + static_cast(6.97850494793315796932292388026640068e-01Q), + static_cast(7.33790062453226804726171131369527646e-01Q), + static_cast(7.67777432104826194917977340974503132e-01Q), + static_cast(7.99727835821839083013668942322683241e-01Q), + static_cast(8.29565762382768397442898119732501916e-01Q), + static_cast(8.57205233546061098958658510658943857e-01Q), + static_cast(8.82560535792052681543116462530225590e-01Q), + static_cast(9.05573307699907798546522558925958320e-01Q), + static_cast(9.26200047429274325879324277080474004e-01Q), + static_cast(9.44374444748559979415831324037439122e-01Q), + static_cast(9.60021864968307512216871025581797663e-01Q), + static_cast(9.73116322501126268374693868423706885e-01Q), + static_cast(9.83668123279747209970032581605662802e-01Q), + static_cast(9.91630996870404594858628366109485725e-01Q), + static_cast(9.96893484074649540271630050918695283e-01Q), + static_cast(9.99484410050490637571325895705810819e-01Q), + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + static_cast(5.14947294294515675583404336470993075e-02Q), + static_cast(5.14261285374590259338628792157812598e-02Q), + static_cast(5.12215478492587721706562826049442083e-02Q), + static_cast(5.08817958987496064922974730498046919e-02Q), + static_cast(5.04059214027823468408930856535850289e-02Q), + static_cast(4.97956834270742063578115693799423285e-02Q), + static_cast(4.90554345550297788875281653672381736e-02Q), + static_cast(4.81858617570871291407794922983045926e-02Q), + static_cast(4.71855465692991539452614781810994865e-02Q), + static_cast(4.60592382710069881162717355593735806e-02Q), + static_cast(4.48148001331626631923555516167232438e-02Q), + static_cast(4.34525397013560693168317281170732581e-02Q), + static_cast(4.19698102151642461471475412859697578e-02Q), + static_cast(4.03745389515359591119952797524681142e-02Q), + static_cast(3.86789456247275929503486515322810503e-02Q), + static_cast(3.68823646518212292239110656171359677e-02Q), + static_cast(3.49793380280600241374996707314678751e-02Q), + static_cast(3.29814470574837260318141910168539275e-02Q), + static_cast(3.09072575623877624728842529430922726e-02Q), + static_cast(2.87540487650412928439787853543342111e-02Q), + static_cast(2.65099548823331016106017093350754144e-02Q), + static_cast(2.41911620780806013656863707252320268e-02Q), + static_cast(2.18280358216091922971674857383389934e-02Q), + static_cast(1.94141411939423811734089510501284559e-02Q), + static_cast(1.69208891890532726275722894203220924e-02Q), + static_cast(1.43697295070458048124514324435800102e-02Q), + static_cast(1.18230152534963417422328988532505929e-02Q), + static_cast(9.27327965951776342844114689202436042e-03Q), + static_cast(6.63070391593129217331982636975016813e-03Q), + static_cast(3.89046112709988405126720184451550328e-03Q), + static_cast(1.38901369867700762455159122675969968e-03Q), + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0280693796673703014709675131800059247190133296515840552101946914632788253917872738234797140786490207720254922664913e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0452511668230989143895767100202470952410426459556377447604465028350321894663245495592565235317147819577892124850607e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0407320227362507737267710719925655353115778980946272844421536998312150442387767304001423699909778588529370119457430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0040125483039439253547621154266063361104593297078395983186610656429170689311759061175527015710247383961903284673474e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9248046786177857499369306120770879564426564096318697026073340982988422546396352776837047452262025983265531109327026e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7934523582636169175602493217254049590705158881215289208126016612312833567812241903809970751783808208940322061083509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6006106412662696137005366814927075303835037480883390955067197339904937499734522076788020517029688190998858739703079e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3379006245322680472617113136952764566938172775468549208701399518300016463613325382024664531597318795933262446521430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9972783582183908301366894232268324073569842937778450923647349548686662567326007229195202524185356472023967927713548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.5720523354606109895865851065894385682080017062359612850504551739119887225712932688031120704657195642614071367390794e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.0557330769990779854652255892595831956897536366222841356404766397803760239449631913585074426842574155323901785046522e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4437444474855997941583132403743912158564371496498093181748940139520917000657342753448871376849848523800667868447591e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7311632250112626837469386842370688488763796428343933853755850185624118958166838288308561708261486365954975485787212e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9163099687040459485862836610948572485050033374616325510019923349807489603260796605556191495843575227494654783755353e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9948441005049063757132589570581081946887394701850801923632642830748016674843587830656468823145435723317885056396548e-01), + }; // LCOV_EXCL_STOP + return data; + } + static std::array const & weights() + { + static std::array data = { // LCOV_EXCL_START + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1494729429451567558340433647099307532736880396464168074637323362474083844397567724480716864880173808112573901197920e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1426128537459025933862879215781259829552034862395987263855824172761589259406892072066110681184224608133314131500422e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1221547849258772170656282604944208251146952425246327553509056805511015401279553971190412722969308620984161625812560e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0881795898749606492297473049804691853384914260919239920771942080972542646780575571132056254070929858650733836163479e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0405921402782346840893085653585028902197018251622233664243959211066713308635283713447747907973700791599900911248852e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9795683427074206357811569379942328539209602813696108951047392842948482646220377655098341924089250200477846596263918e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9055434555029778887528165367238173605887405295296569579490717901328215644590555247522873065246297467067324397612445e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8185861757087129140779492298304592605799236108429800057373350872433793583969368428942672063270298939865425225579922e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7185546569299153945261478181099486482884807300628457194141861551725533289490897029020276525603515502104799540544222e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6059238271006988116271735559373580594692875571824924004732379492293604006446052672252973438978639166425766841417488e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4814800133162663192355551616723243757431392796373009889680201194063503947907899189061064792111919040540351834527742e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3452539701356069316831728117073258074603308631703168064888805495738640839573863333942084117196541456054957383622173e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1969810215164246147147541285969757790088656718992374820388720323852655511200365790379948462006156953358103259681948e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0374538951535959111995279752468114216126062126030255633998289613810846761059740961836828802959573901107306640876603e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8678945624727592950348651532281050250923629821553846790376130679337402056620700554139109487533759557982632153728099e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6882364651821229223911065617135967736955164781030337670005198584196134970154169862584193360751243227989492571664973e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4979338028060024137499670731467875097226912794818719972208457232177786702008744219498470603846784465175225933802357e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2981447057483726031814191016853927510599291213858385714519347641452316582381008804994515341969205985818543200837577e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0907257562387762472884252943092272635270458523807153426840486964022086189874056947717446328187131273807982629114591e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8754048765041292843978785354334211144679160542074930035102280759132174815469834227854660515366003136772757344886331e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6509954882333101610601709335075414366517579522748565770867438338472138903658077617652522759934474895733739329287706e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4191162078080601365686370725232026760391377828182462432228943562944885267501070688006470962871743661192935455117297e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1828035821609192297167485738338993401507296056834912773630422358720439403382559079356058602393879803560534375378340e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9414141193942381173408951050128455851421014191431525770276066536497179079025540486072726114628763606440143557769099e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6920889189053272627572289420322092368566703783835191139883410840546679978551861043620089451681146020853650713611444e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4369729507045804812451432443580010195841899895001505873565899403000198662495821906144274682894222591414503342336172e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1823015253496341742232898853250592896264406250607818326302431548265365155855182739401700032519141448997853772603766e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2732796595177634284411468920243604212700249381931076964956469143626665557434385492325784596343112153704094886248672e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6307039159312921733198263697501681336283882177812585973955597357837568277731921327731815844512598157843672104469554e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8904611270998840512672018445155032785151429848864649214200101281144733676455451061226273655941038347210163533085954e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3890136986770076245515912267596996810488412919632724534411055332301367130989865366956251556423820479579333920310978e-03), + }; // LCOV_EXCL_STOP + return data; + } +}; + +} + +template > +class gauss_kronrod : public detail::gauss_kronrod_detail::value> +{ + typedef detail::gauss_kronrod_detail::value> base; +public: + typedef Real value_type; +private: + template + static auto integrate_non_adaptive_m1_1(F f, Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(Real(0))) K; + using std::abs; + unsigned gauss_start = 2; + unsigned kronrod_start = 1; + unsigned gauss_order = (N - 1) / 2; + K kronrod_result = 0; + K gauss_result = 0; + K fp, fm; + if (gauss_order & 1) + { + fp = f(value_type(0)); + kronrod_result = fp * static_cast(base::weights()[0]); + gauss_result += fp * static_cast(gauss::weights()[0]); + } + else + { + fp = f(value_type(0)); + kronrod_result = fp * static_cast(base::weights()[0]); + gauss_start = 1; + kronrod_start = 2; + } + Real L1 = abs(kronrod_result); + for (unsigned i = gauss_start; i < base::abscissa().size(); i += 2) + { + fp = f(static_cast(base::abscissa()[i])); + fm = f(static_cast(-base::abscissa()[i])); + kronrod_result += (fp + fm) * static_cast(base::weights()[i]); + L1 += (abs(fp) + abs(fm)) * static_cast(base::weights()[i]); + gauss_result += (fp + fm) * static_cast(gauss::weights()[i / 2]); + } + for (unsigned i = kronrod_start; i < base::abscissa().size(); i += 2) + { + fp = f(static_cast(base::abscissa()[i])); + fm = f(static_cast(-base::abscissa()[i])); + kronrod_result += (fp + fm) * static_cast(base::weights()[i]); + L1 += (abs(fp) + abs(fm)) * static_cast(base::weights()[i]); + } + if (pL1) + *pL1 = L1; + if (error) + *error = (std::max)(static_cast(abs(kronrod_result - gauss_result)), static_cast(abs(kronrod_result * tools::epsilon() * Real(2)))); + return kronrod_result; + } + + template + struct recursive_info + { + F f; + Real tol; + }; + + template + static auto recursive_adaptive_integrate(const recursive_info* info, Real a, Real b, unsigned max_levels, Real abs_tol, Real* error, Real* L1)->decltype(std::declval()(std::declval())) + { + typedef decltype(info->f(Real(a))) K; + using std::abs; + Real error_local; + Real mean = (b + a) / 2; + Real scale = (b - a) / 2; + auto ff = [&](const Real& x)->K + { + return info->f(scale * x + mean); + }; + K r1 = integrate_non_adaptive_m1_1(ff, &error_local, L1); + K estimate = scale * r1; + + K tmp = estimate * info->tol; + Real abs_tol1 = abs(tmp); + if (abs_tol == 0) + abs_tol = abs_tol1; + + if (max_levels && (abs_tol1 < error_local) && (abs_tol < error_local)) + { + Real mid = (a + b) / 2; + Real L1_local; + estimate = recursive_adaptive_integrate(info, a, mid, max_levels - 1, abs_tol / 2, error, L1); + estimate += recursive_adaptive_integrate(info, mid, b, max_levels - 1, abs_tol / 2, &error_local, &L1_local); + if (error) + *error += error_local; + if (L1) + *L1 += L1_local; + return estimate; + } + if(L1) + *L1 *= scale; + if (error) + *error = error_local; + return estimate; + } + +public: + template + static auto integrate(F f, Real a, Real b, unsigned max_depth = 15, Real tol = tools::root_epsilon(), Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + static const char* function = "boost::math::quadrature::gauss_kronrod<%1%>::integrate(f, %1%, %1%)"; + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + // Infinite limits: + if ((a <= -tools::max_value()) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real t_sq = t*t; + Real inv = 1 / (1 - t_sq); + Real w = (1 + t_sq)*inv*inv; + Real arg = t*inv; + K res = f(arg)*w; + return res; + }; + recursive_info info = { u, tol }; + K res = recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + return res; + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z + a - 1; + K res = f(arg)*z*z; + return res; + }; + recursive_info info = { u, tol }; + K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z - 1; + return f(b - arg) * z * z; + }; + recursive_info info = { v, tol }; + K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a==b) + { + return K(0); + } + recursive_info info = { f, tol }; + if (b < a) + { + return -recursive_adaptive_integrate(&info, b, a, max_depth, Real(0), error, pL1); + } + return recursive_adaptive_integrate(&info, a, b, max_depth, Real(0), error, pL1); + } + } + return static_cast(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy())); + } +}; + +} // namespace quadrature +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/naive_monte_carlo.hpp b/third-party/boost-math/include/boost/math/quadrature/naive_monte_carlo.hpp new file mode 100644 index 0000000000000..4ad95ad832370 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/naive_monte_carlo.hpp @@ -0,0 +1,468 @@ +/* + * Copyright Nick Thompson, 2018 + * 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) + */ +#ifndef BOOST_MATH_QUADRATURE_NAIVE_MONTE_CARLO_HPP +#define BOOST_MATH_QUADRATURE_NAIVE_MONTE_CARLO_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES +# include +#endif + +namespace boost { namespace math { namespace quadrature { + +namespace detail { + enum class limit_classification {FINITE, + LOWER_BOUND_INFINITE, + UPPER_BOUND_INFINITE, + DOUBLE_INFINITE}; +} + +template, + typename std::enable_if::value, bool>::type = true> +class naive_monte_carlo +{ +public: + naive_monte_carlo(const F& integrand, + std::vector> const & bounds, + Real error_goal, + bool singular = true, + uint64_t threads = std::thread::hardware_concurrency(), + uint64_t seed = 0) noexcept : m_num_threads{threads}, m_seed{seed}, m_volume(1) + { + using std::numeric_limits; + using std::sqrt; + using boost::math::isinf; + + uint64_t n = bounds.size(); + m_lbs.resize(n); + m_dxs.resize(n); + m_limit_types.resize(n); + + static const char* function = "boost::math::quadrature::naive_monte_carlo<%1%>"; + for (uint64_t i = 0; i < n; ++i) + { + if (bounds[i].second <= bounds[i].first) + { + boost::math::policies::raise_domain_error(function, "The upper bound is <= the lower bound.\n", bounds[i].second, Policy()); + return; + } + if (isinf(bounds[i].first)) + { + if (isinf(bounds[i].second)) + { + m_limit_types[i] = detail::limit_classification::DOUBLE_INFINITE; + } + else + { + m_limit_types[i] = detail::limit_classification::LOWER_BOUND_INFINITE; + // Ok ok this is bad to use the second bound as the lower limit and then reflect. + m_lbs[i] = bounds[i].second; + m_dxs[i] = numeric_limits::quiet_NaN(); + } + } + else if (isinf(bounds[i].second)) + { + m_limit_types[i] = detail::limit_classification::UPPER_BOUND_INFINITE; + if (singular) + { + // I've found that it's easier to sample on a closed set and perturb the boundary + // than to try to sample very close to the boundary. + m_lbs[i] = std::nextafter(bounds[i].first, (std::numeric_limits::max)()); + } + else + { + m_lbs[i] = bounds[i].first; + } + m_dxs[i] = numeric_limits::quiet_NaN(); + } + else + { + m_limit_types[i] = detail::limit_classification::FINITE; + if (singular) + { + if (bounds[i].first == 0) + { + m_lbs[i] = std::numeric_limits::epsilon(); + } + else + { + m_lbs[i] = std::nextafter(bounds[i].first, (std::numeric_limits::max)()); + } + + m_dxs[i] = std::nextafter(bounds[i].second, std::numeric_limits::lowest()) - m_lbs[i]; + } + else + { + m_lbs[i] = bounds[i].first; + m_dxs[i] = bounds[i].second - bounds[i].first; + } + m_volume *= m_dxs[i]; + } + } + + m_integrand = [this, &integrand](std::vector & x)->Real + { + Real coeff = m_volume; + for (uint64_t i = 0; i < x.size(); ++i) + { + // Variable transformation are listed at: + // https://en.wikipedia.org/wiki/Numerical_integration + // However, we've made some changes to these so that we can evaluate on a compact domain. + if (m_limit_types[i] == detail::limit_classification::FINITE) + { + x[i] = m_lbs[i] + x[i]*m_dxs[i]; + } + else if (m_limit_types[i] == detail::limit_classification::UPPER_BOUND_INFINITE) + { + Real t = x[i]; + Real z = 1/(1 + numeric_limits::epsilon() - t); + coeff *= (z*z)*(1 + numeric_limits::epsilon()); + x[i] = m_lbs[i] + t*z; + } + else if (m_limit_types[i] == detail::limit_classification::LOWER_BOUND_INFINITE) + { + Real t = x[i]; + Real z = 1/(t+sqrt((numeric_limits::min)())); + coeff *= (z*z); + x[i] = m_lbs[i] + (t-1)*z; + } + else + { + Real t1 = 1/(1+numeric_limits::epsilon() - x[i]); + Real t2 = 1/(x[i]+numeric_limits::epsilon()); + x[i] = (2*x[i]-1)*t1*t2/4; + coeff *= (t1*t1+t2*t2)/4; + } + } + return coeff*integrand(x); + }; + + // If we don't do a single function call in the constructor, + // we can't do a restart. + std::vector x(m_lbs.size()); + + // If the seed is zero, that tells us to choose a random seed for the user: + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + + RandomNumberGenerator gen(seed); + Real inv_denom = 1/static_cast(((gen.max)()-(gen.min)())); + + m_num_threads = (std::max)(m_num_threads, static_cast(1)); + m_thread_calls.reset(new std::atomic[threads]); + m_thread_Ss.reset(new std::atomic[threads]); + m_thread_averages.reset(new std::atomic[threads]); + + Real avg = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + for (uint64_t j = 0; j < m_lbs.size(); ++j) + { + x[j] = (gen()-(gen.min)())*inv_denom; + } + Real y = m_integrand(x); + m_thread_averages[i] = y; // relaxed store + m_thread_calls[i] = 1; + m_thread_Ss[i] = 0; + avg += y; + } + avg /= m_num_threads; + m_avg = avg; // relaxed store + + m_error_goal = error_goal; // relaxed store + m_start = std::chrono::system_clock::now(); + m_done = false; // relaxed store + m_total_calls = m_num_threads; // relaxed store + m_variance = (numeric_limits::max)(); + } + + std::future integrate() + { + // Set done to false in case we wish to restart: + m_done.store(false); // relaxed store, no worker threads yet + m_start = std::chrono::system_clock::now(); + return std::async(std::launch::async, + &naive_monte_carlo::m_integrate, this); + } + + void cancel() + { + // If seed = 0 (meaning have the routine pick the seed), this leaves the seed the same. + // If seed != 0, then the seed is changed, so a restart doesn't do the exact same thing. + m_seed = m_seed*m_seed; + m_done = true; // relaxed store, worker threads will get the message eventually + // Make sure the error goal is infinite, because otherwise we'll loop when we do the final error goal check: + m_error_goal = (std::numeric_limits::max)(); + } + + Real variance() const + { + return m_variance.load(); + } + + Real current_error_estimate() const + { + using std::sqrt; + // + // There is a bug here: m_variance and m_total_calls get updated asynchronously + // and may be out of synch when we compute the error estimate, not sure if it matters though... + // + return sqrt(m_variance.load()/m_total_calls.load()); + } + + std::chrono::duration estimated_time_to_completion() const + { + auto now = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = now - m_start; + Real r = this->current_error_estimate()/m_error_goal.load(); // relaxed load + if (r*r <= 1) { + return 0*elapsed_seconds; + } + return (r*r - 1)*elapsed_seconds; + } + + void update_target_error(Real new_target_error) + { + m_error_goal = new_target_error; // relaxed store + } + + Real progress() const + { + Real r = m_error_goal.load()/this->current_error_estimate(); // relaxed load + if (r*r >= 1) + { + return 1; + } + return r*r; + } + + Real current_estimate() const + { + return m_avg.load(); + } + + uint64_t calls() const + { + return m_total_calls.load(); // relaxed load + } + +private: + + Real m_integrate() + { + uint64_t seed; + // If the user tells us to pick a seed, pick a seed: + if (m_seed == 0) + { + std::random_device rd; + seed = rd(); + } + else // use the seed we are given: + { + seed = m_seed; + } + RandomNumberGenerator gen(seed); + int max_repeat_tries = 5; + do{ + + if (max_repeat_tries < 5) + { + m_done = false; + +#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES + std::cerr << "Failed to achieve required tolerance first time through..\n"; + std::cerr << " variance = " << m_variance << std::endl; + std::cerr << " average = " << m_avg << std::endl; + std::cerr << " total calls = " << m_total_calls << std::endl; + + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cerr << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl; + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cerr << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl; + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cerr << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl; +#endif + } + + std::vector threads(m_num_threads); + for (uint64_t i = 0; i < threads.size(); ++i) + { + threads[i] = std::thread(&naive_monte_carlo::m_thread_monte, this, i, gen()); + } + do { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + uint64_t total_calls = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + total_calls += t_calls; + } + Real variance = 0; + Real avg = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + // Will this overflow? Not hard to remove . . . + avg += m_thread_averages[i].load(std::memory_order_relaxed)*(static_cast(t_calls) / static_cast(total_calls)); + variance += m_thread_Ss[i].load(std::memory_order_relaxed); + } + m_avg.store(avg, std::memory_order_release); + m_variance.store(variance / (total_calls - 1), std::memory_order_release); + m_total_calls = total_calls; // relaxed store, it's just for user feedback + // Allow cancellation: + if (m_done) // relaxed load + { + break; + } + } while (m_total_calls < 2048 || this->current_error_estimate() > m_error_goal.load(std::memory_order_consume)); + // Error bound met; signal the threads: + m_done = true; // relaxed store, threads will get the message in the end + std::for_each(threads.begin(), threads.end(), + std::mem_fn(&std::thread::join)); + if (m_exception) + { + std::rethrow_exception(m_exception); + } + // Incorporate their work into the final estimate: + uint64_t total_calls = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + total_calls += t_calls; + } + Real variance = 0; + Real avg = 0; + + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + // Averages weighted by the number of calls the thread made: + avg += m_thread_averages[i].load(std::memory_order_relaxed)*(static_cast(t_calls) / static_cast(total_calls)); + variance += m_thread_Ss[i].load(std::memory_order_relaxed); + } + m_avg.store(avg, std::memory_order_release); + m_variance.store(variance / (total_calls - 1), std::memory_order_release); + m_total_calls = total_calls; // relaxed store, this is just user feedback + + // Sometimes, the master will observe the variance at a very "good" (or bad?) moment, + // Then the threads proceed to find the variance is much greater by the time they hear the message to stop. + // This *WOULD* make sure that the final error estimate is within the error bounds. + } + while ((--max_repeat_tries >= 0) && (this->current_error_estimate() > m_error_goal)); + + return m_avg.load(std::memory_order_consume); + } + + void m_thread_monte(uint64_t thread_index, uint64_t seed) + { + using std::numeric_limits; + try + { + std::vector x(m_lbs.size()); + RandomNumberGenerator gen(seed); + Real inv_denom = static_cast(1) / static_cast(( (gen.max)() - (gen.min)() )); + Real M1 = m_thread_averages[thread_index].load(std::memory_order_consume); + Real S = m_thread_Ss[thread_index].load(std::memory_order_consume); + // Kahan summation is required or the value of the integrand will go on a random walk during long computations. + // See the implementation discussion. + // The idea is that the unstabilized additions have error sigma(f)/sqrt(N) + epsilon*N, which diverges faster than it converges! + // Kahan summation turns this to sigma(f)/sqrt(N) + epsilon^2*N, and the random walk occurs on a timescale of 10^14 years (on current hardware) + Real compensator = 0; + uint64_t k = m_thread_calls[thread_index].load(std::memory_order_consume); + while (!m_done) // relaxed load + { + int j = 0; + // If we don't have a certain number of calls before an update, we can easily terminate prematurely + // because the variance estimate is way too low. This magic number is a reasonable compromise, as 1/sqrt(2048) = 0.02, + // so it should recover 2 digits if the integrand isn't poorly behaved, and if it is, it should discover that before premature termination. + // Of course if the user has 64 threads, then this number is probably excessive. + int magic_calls_before_update = 2048; + while (j++ < magic_calls_before_update) + { + for (uint64_t i = 0; i < m_lbs.size(); ++i) + { + x[i] = (gen() - (gen.min)())*inv_denom; + } + Real f = m_integrand(x); + using std::isfinite; + if (!isfinite(f)) + { + // The call to m_integrand transform x, so this error message states the correct node. + std::stringstream os; + os << "Your integrand was evaluated at {"; + for (uint64_t i = 0; i < x.size() -1; ++i) + { + os << x[i] << ", "; + } + os << x[x.size() -1] << "}, and returned " << f << std::endl; + static const char* function = "boost::math::quadrature::naive_monte_carlo<%1%>"; + boost::math::policies::raise_domain_error(function, os.str().c_str(), /*this is a dummy arg to make it compile*/ 7.2, Policy()); + } + ++k; + Real term = (f - M1)/k; + Real y1 = term - compensator; + Real M2 = M1 + y1; + compensator = (M2 - M1) - y1; + S += (f - M1)*(f - M2); + M1 = M2; + } + m_thread_averages[thread_index].store(M1, std::memory_order_release); + m_thread_Ss[thread_index].store(S, std::memory_order_release); + m_thread_calls[thread_index].store(k, std::memory_order_release); + } + } + catch (...) + { + // Signal the other threads that the computation is ruined: + m_done = true; // relaxed store + std::lock_guard lock(m_exception_mutex); // Scoped lock to prevent race writing to m_exception + m_exception = std::current_exception(); + } + } + + std::function &)> m_integrand; + uint64_t m_num_threads; + std::atomic m_seed; + std::atomic m_error_goal; + std::atomic m_done{}; + std::vector m_lbs; + std::vector m_dxs; + std::vector m_limit_types; + Real m_volume; + std::atomic m_total_calls{}; + // I wanted these to be vectors rather than maps, + // but you can't resize a vector of atomics. + std::unique_ptr[]> m_thread_calls; + std::atomic m_variance; + std::unique_ptr[]> m_thread_Ss; + std::atomic m_avg; + std::unique_ptr[]> m_thread_averages; + std::chrono::time_point m_start; + std::exception_ptr m_exception; + std::mutex m_exception_mutex; +}; + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/ooura_fourier_integrals.hpp b/third-party/boost-math/include/boost/math/quadrature/ooura_fourier_integrals.hpp new file mode 100644 index 0000000000000..b31996c2bccb9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/ooura_fourier_integrals.hpp @@ -0,0 +1,68 @@ +// Copyright Nick Thompson, 2019 +// 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) + +/* + * References: + * Ooura, Takuya, and Masatake Mori. "A robust double exponential formula for Fourier-type integrals." Journal of computational and applied mathematics 112.1-2 (1999): 229-241. + * http://www.kurims.kyoto-u.ac.jp/~ooura/intde.html + */ +#ifndef BOOST_MATH_QUADRATURE_OOURA_FOURIER_INTEGRALS_HPP +#define BOOST_MATH_QUADRATURE_OOURA_FOURIER_INTEGRALS_HPP +#include +#include + +namespace boost { namespace math { namespace quadrature { + +template +class ooura_fourier_sin { +public: + ooura_fourier_sin(const Real relative_error_tolerance = tools::root_epsilon(), size_t levels = sizeof(Real)) : impl_(std::make_shared>(relative_error_tolerance, levels)) + {} + + template + std::pair integrate(F const & f, Real omega) { + return impl_->integrate(f, omega); + } + + // These are just for debugging/unit tests: + std::vector> const & big_nodes() const { + return impl_->big_nodes(); + } + + std::vector> const & weights_for_big_nodes() const { + return impl_->weights_for_big_nodes(); + } + + std::vector> const & little_nodes() const { + return impl_->little_nodes(); + } + + std::vector> const & weights_for_little_nodes() const { + return impl_->weights_for_little_nodes(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class ooura_fourier_cos { +public: + ooura_fourier_cos(const Real relative_error_tolerance = tools::root_epsilon(), size_t levels = sizeof(Real)) : impl_(std::make_shared>(relative_error_tolerance, levels)) + {} + + template + std::pair integrate(F const & f, Real omega) { + return impl_->integrate(f, omega); + } +private: + std::shared_ptr> impl_; +}; + + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/sinh_sinh.hpp b/third-party/boost-math/include/boost/math/quadrature/sinh_sinh.hpp new file mode 100644 index 0000000000000..7aabcb43765b2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/sinh_sinh.hpp @@ -0,0 +1,72 @@ +// Copyright Nick Thompson, 2017 +// Copyright Matt Borland, 2024 +// 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) + +/* + * This class performs sinh-sinh quadrature over the entire real line. + * + * References: + * + * 1) Tanaka, Ken'ichiro, et al. "Function classes for double exponential integration formulas." Numerische Mathematik 111.4 (2009): 631-655. + */ + +#ifndef BOOST_MATH_QUADRATURE_SINH_SINH_HPP +#define BOOST_MATH_QUADRATURE_SINH_SINH_HPP + +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class sinh_sinh +{ +public: + sinh_sinh(size_t max_refinements = 9) + : m_imp(std::make_shared >(max_refinements)) {} + + template + auto integrate(const F f, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval())) + { + return m_imp->integrate(f, tol, error, L1, levels); + } + +private: + std::shared_ptr> m_imp; +}; + +}}} + +#endif // BOOST_MATH_HAS_NVRTC + +#ifdef BOOST_MATH_ENABLE_CUDA + +namespace boost { +namespace math { +namespace quadrature { + +template > +__device__ auto sinh_sinh_integrate(const F& f, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, boost::math::size_t* levels = nullptr) +{ + return detail::sinh_sinh_integrate_impl(f, tol, error, L1, levels); +} + +} // namespace quadrature +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif // BOOST_MATH_QUADRATURE_SINH_SINH_HPP diff --git a/third-party/boost-math/include/boost/math/quadrature/tanh_sinh.hpp b/third-party/boost-math/include/boost/math/quadrature/tanh_sinh.hpp new file mode 100644 index 0000000000000..d5fbe82525242 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/tanh_sinh.hpp @@ -0,0 +1,289 @@ +// Copyright Nick Thompson, 2017 +// 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) + +/* + * This class performs tanh-sinh quadrature on the real line. + * Tanh-sinh quadrature is exponentially convergent for integrands in Hardy spaces, + * (see https://en.wikipedia.org/wiki/Hardy_space for a formal definition), and is optimal for a random function from that class. + * + * The tanh-sinh quadrature is one of a class of so called "double exponential quadratures"-there is a large family of them, + * but this one seems to be the most commonly used. + * + * As always, there are caveats: For instance, if the function you want to integrate is not holomorphic on the unit disk, + * then the rapid convergence will be spoiled. In this case, a more appropriate quadrature is (say) Romberg, which does not + * require the function to be holomorphic, only differentiable up to some order. + * + * In addition, if you are integrating a periodic function over a period, the trapezoidal rule is better. + * + * References: + * + * 1) Mori, Masatake. "Quadrature formulas obtained by variable transformation and the DE-rule." Journal of Computational and Applied Mathematics 12 (1985): 119-130. + * 2) Bailey, David H., Karthik Jeyabalan, and Xiaoye S. Li. "A comparison of three high-precision quadrature schemes." Experimental Mathematics 14.3 (2005): 317-329. + * 3) Press, William H., et al. "Numerical recipes third edition: the art of scientific computing." Cambridge University Press 32 (2007): 10013-2473. + * + */ + +#ifndef BOOST_MATH_QUADRATURE_TANH_SINH_HPP +#define BOOST_MATH_QUADRATURE_TANH_SINH_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class tanh_sinh +{ +public: + tanh_sinh(size_t max_refinements = 15, const Real& min_complement = tools::min_value() * 4) + : m_imp(std::make_shared>(max_refinements, min_complement)) {} + + template + auto integrate(const F f, Real a, Real b, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval())); + template + auto integrate(const F f, Real a, Real b, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval(), std::declval())); + + template + auto integrate(const F f, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval())); + template + auto integrate(const F f, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) const ->decltype(std::declval()(std::declval(), std::declval())); + +private: + std::shared_ptr> m_imp; +}; + +template +template +auto tanh_sinh::integrate(const F f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + BOOST_MATH_STD_USING + using boost::math::constants::half; + using boost::math::quadrature::detail::tanh_sinh_detail; + + static const char* function = "tanh_sinh<%1%>::integrate"; + + typedef decltype(std::declval()(std::declval())) result_type; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + + // Infinite limits: + if ((a <= -tools::max_value()) && (b >= tools::max_value())) + { + auto u = [&](const Real& t, const Real& tc)->result_type + { + Real t_sq = t*t; + Real inv; + if (t > 0.5f) + inv = 1 / ((2 - tc) * tc); + else if(t < -0.5) + inv = 1 / ((2 + tc) * -tc); + else + inv = 1 / (1 - t_sq); + return f(t*inv)*(1 + t_sq)*inv*inv; + }; + Real limit = sqrt(tools::min_value()) * 4; + return m_imp->integrate(u, error, L1, function, limit, limit, tolerance, levels); + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t, const Real& tc)->result_type + { + Real z, arg; + if (t > -0.5f) + z = 1 / (t + 1); + else + z = -1 / tc; + if (t < 0.5) + arg = 2 * z + a - 1; + else + arg = a + tc / (2 - tc); + return f(arg)*z*z; + }; + Real left_limit = sqrt(tools::min_value()) * 4; + result_type Q = Real(2) * m_imp->integrate(u, error, L1, function, left_limit, tools::min_value(), tolerance, levels); + if (L1) + { + *L1 *= 2; + } + if (error) + { + *error *= 2; + } + + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t, const Real& tc)->result_type + { + Real z; + if (t > -0.5) + z = 1 / (t + 1); + else + z = -1 / tc; + Real arg; + if (t < 0.5) + arg = 2 * z - 1; + else + arg = tc / (2 - tc); + return f(b - arg) * z * z; + }; + + Real left_limit = sqrt(tools::min_value()) * 4; + result_type Q = Real(2) * m_imp->integrate(v, error, L1, function, left_limit, tools::min_value(), tolerance, levels); + if (L1) + { + *L1 *= 2; + } + if (error) + { + *error *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a == b) + { + return result_type(0); + } + if (b < a) + { + return -this->integrate(f, b, a, tolerance, error, L1, levels); + } + Real avg = (a + b)*half(); + Real diff = (b - a)*half(); + Real avg_over_diff_m1 = a / diff; + Real avg_over_diff_p1 = b / diff; + bool have_small_left = fabs(a) < 0.5f; + bool have_small_right = fabs(b) < 0.5f; + Real left_min_complement = float_next(avg_over_diff_m1) - avg_over_diff_m1; + Real min_complement_limit = (std::max)(tools::min_value(), float_next(Real(tools::min_value() / diff))); + if (left_min_complement < min_complement_limit) + left_min_complement = min_complement_limit; + Real right_min_complement = avg_over_diff_p1 - float_prior(avg_over_diff_p1); + if (right_min_complement < min_complement_limit) + right_min_complement = min_complement_limit; + // + // These asserts will fail only if rounding errors on + // type Real have accumulated so much error that it's + // broken our internal logic. Should that prove to be + // a persistent issue, we might need to add a bit of fudge + // factor to move left_min_complement and right_min_complement + // further from the end points of the range. + // + BOOST_MATH_ASSERT((left_min_complement * diff + a) > a); + BOOST_MATH_ASSERT((b - right_min_complement * diff) < b); + auto u = [&](Real z, Real zc)->result_type + { + Real position; + if (z < -0.5) + { + if(have_small_left) + return f(diff * (avg_over_diff_m1 - zc)); + position = a - diff * zc; + } + else if (z > 0.5) + { + if(have_small_right) + return f(diff * (avg_over_diff_p1 - zc)); + position = b - diff * zc; + } + else + position = avg + diff*z; + BOOST_MATH_ASSERT(position != a); + BOOST_MATH_ASSERT(position != b); + return f(position); + }; + result_type Q = diff*m_imp->integrate(u, error, L1, function, left_min_complement, right_min_complement, tolerance, levels); + + if (L1) + { + *L1 *= diff; + } + if (error) + { + *error *= diff; + } + return Q; + } + } + return policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()); +} + +template +template +auto tanh_sinh::integrate(const F f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval(), std::declval())) +{ + BOOST_MATH_STD_USING + using boost::math::constants::half; + using boost::math::quadrature::detail::tanh_sinh_detail; + + static const char* function = "tanh_sinh<%1%>::integrate"; + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (b <= a) + { + return policies::raise_domain_error(function, "Arguments to integrate are in wrong order; integration over [a,b] must have b > a.", a, Policy()); + } + auto u = [&](Real z, Real zc)->Real + { + if (z < 0) + return f((a - b) * zc / 2 + a, (b - a) * zc / 2); + else + return f((a - b) * zc / 2 + b, (b - a) * zc / 2); + }; + Real diff = (b - a)*half(); + Real left_min_complement = tools::min_value() * 4; + Real right_min_complement = tools::min_value() * 4; + Real Q = diff*m_imp->integrate(u, error, L1, function, left_min_complement, right_min_complement, tolerance, levels); + + if (L1) + { + *L1 *= diff; + } + if (error) + { + *error *= diff; + } + return Q; + } + return policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()); +} + +template +template +auto tanh_sinh::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval())) +{ + using boost::math::quadrature::detail::tanh_sinh_detail; + static const char* function = "tanh_sinh<%1%>::integrate"; + Real min_complement = tools::epsilon(); + return m_imp->integrate([&](const Real& arg, const Real&) { return f(arg); }, error, L1, function, min_complement, min_complement, tolerance, levels); +} + +template +template +auto tanh_sinh::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) const ->decltype(std::declval()(std::declval(), std::declval())) +{ + using boost::math::quadrature::detail::tanh_sinh_detail; + static const char* function = "tanh_sinh<%1%>::integrate"; + Real min_complement = tools::min_value() * 4; + return m_imp->integrate(f, error, L1, function, min_complement, min_complement, tolerance, levels); +} + +} +} +} +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/trapezoidal.hpp b/third-party/boost-math/include/boost/math/quadrature/trapezoidal.hpp new file mode 100644 index 0000000000000..8190fb66ae1fa --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/trapezoidal.hpp @@ -0,0 +1,125 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + * + * Use the adaptive trapezoidal rule to estimate the integral of periodic functions over a period, + * or to integrate a function whose derivative vanishes at the endpoints. + * + * If your function does not satisfy these conditions, and instead is simply continuous and bounded + * over the whole interval, then this routine will still converge, albeit slowly. However, there + * are much more efficient methods in this case, including Romberg, Simpson, and double exponential quadrature. + */ + +#ifndef BOOST_MATH_QUADRATURE_TRAPEZOIDAL_HPP +#define BOOST_MATH_QUADRATURE_TRAPEZOIDAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template +auto trapezoidal(F f, Real a, Real b, Real tol, std::size_t max_refinements, Real* error_estimate, Real* L1, const Policy& pol)->decltype(std::declval()(std::declval())) +{ + static const char* function = "boost::math::quadrature::trapezoidal<%1%>(F, %1%, %1%, %1%)"; + using std::abs; + using boost::math::constants::half; + // In many math texts, K represents the field of real or complex numbers. + // Too bad we can't put blackboard bold into C++ source! + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + if (!(boost::math::isfinite)(a)) + { + return static_cast(boost::math::policies::raise_domain_error(function, "Left endpoint of integration must be finite for adaptive trapezoidal integration but got a = %1%.\n", a, pol)); + } + if (!(boost::math::isfinite)(b)) + { + return static_cast(boost::math::policies::raise_domain_error(function, "Right endpoint of integration must be finite for adaptive trapezoidal integration but got b = %1%.\n", b, pol)); + } + + if (a == b) + { + return static_cast(0); + } + if(a > b) + { + return -trapezoidal(f, b, a, tol, max_refinements, error_estimate, L1, pol); + } + + + K ya = f(a); + K yb = f(b); + Real h = (b - a)*half(); + K I0 = (ya + yb)*h; + Real IL0 = (abs(ya) + abs(yb))*h; + + K yh = f(a + h); + K I1; + I1 = I0*half() + yh*h; + Real IL1 = IL0*half() + abs(yh)*h; + + // The recursion is: + // I_k = 1/2 I_{k-1} + 1/2^k \sum_{j=1; j odd, j < 2^k} f(a + j(b-a)/2^k) + std::size_t k = 2; + // We want to go through at least 5 levels so we have sampled the function at least 20 times. + // Otherwise, we could terminate prematurely and miss essential features. + // This is of course possible anyway, but 20 samples seems to be a reasonable compromise. + Real error = abs(I0 - I1); + // I take k < 5, rather than k < 4, or some other smaller minimum number, + // because I hit a truly exceptional bug where the k = 2 and k =3 refinement were bitwise equal, + // but the quadrature had not yet converged. + while (k < 5 || (k < max_refinements && error > tol*IL1) ) + { + I0 = I1; + IL0 = IL1; + + I1 = I0*half(); + IL1 = IL0*half(); + std::size_t p = static_cast(1u) << k; + h *= half(); + K sum = 0; + Real absum = 0; + + for(std::size_t j = 1; j < p; j += 2) + { + K y = f(a + j*h); + sum += y; + absum += abs(y); + } + + I1 += sum*h; + IL1 += absum*h; + ++k; + error = abs(I0 - I1); + } + + if (error_estimate) + { + *error_estimate = error; + } + + if (L1) + { + *L1 = IL1; + } + + return static_cast(I1); +} + +template +auto trapezoidal(F f, Real a, Real b, Real tol = boost::math::tools::root_epsilon(), std::size_t max_refinements = 12, Real* error_estimate = nullptr, Real* L1 = nullptr)->decltype(std::declval()(std::declval())) +{ + return trapezoidal(f, a, b, tol, max_refinements, error_estimate, L1, boost::math::policies::policy<>()); +} + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/quadrature/wavelet_transforms.hpp b/third-party/boost-math/include/boost/math/quadrature/wavelet_transforms.hpp new file mode 100644 index 0000000000000..7c811d5cafc83 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quadrature/wavelet_transforms.hpp @@ -0,0 +1,47 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ +#ifndef BOOST_MATH_QUADRATURE_WAVELET_TRANSFORMS_HPP +#define BOOST_MATH_QUADRATURE_WAVELET_TRANSFORMS_HPP +#include +#include + +namespace boost::math::quadrature { + +template +class daubechies_wavelet_transform +{ +public: + daubechies_wavelet_transform(F f, int grid_refinements = -1, Real tol = 100*std::numeric_limits::epsilon(), + int max_refinements = 12) : f_{f}, psi_(grid_refinements), tol_{tol}, max_refinements_{max_refinements} + {} + + daubechies_wavelet_transform(F f, boost::math::daubechies_wavelet wavelet, Real tol = 100*std::numeric_limits::epsilon(), + int max_refinements = 12) : f_{f}, psi_{wavelet}, tol_{tol}, max_refinements_{max_refinements} + {} + + auto operator()(Real s, Real t) const ->decltype(std::declval()(std::declval())) + { + using std::sqrt; + using std::abs; + using boost::math::quadrature::trapezoidal; + auto g = [&] (Real u) { + return f_(s*u+t)*psi_(u); + }; + auto [a,b] = psi_.support(); + return sqrt(abs(s))*trapezoidal(g, a, b, tol_, max_refinements_); + } + +private: + F f_; + boost::math::daubechies_wavelet psi_; + Real tol_; + int max_refinements_; +}; + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/quaternion.hpp b/third-party/boost-math/include/boost/math/quaternion.hpp new file mode 100644 index 0000000000000..831dd92bef1f9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/quaternion.hpp @@ -0,0 +1,1190 @@ +// boost quaternion.hpp header file + +// (C) Copyright Hubert Holin 2001. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_QUATERNION_HPP +#define BOOST_QUATERNION_HPP + +#include +#include +#include // for the "<<" operator + +#include +#include // for the "<<" and ">>" operators +#include // for the "<<" operator + +#include // for the Sinus cardinal +#include // for the Hyperbolic Sinus cardinal +#include + +#include + +namespace boost +{ + namespace math + { + + namespace detail { + + template + struct is_trivial_arithmetic_type_imp + { + typedef std::integral_constant() += std::declval()) + && noexcept(std::declval() -= std::declval()) + && noexcept(std::declval() *= std::declval()) + && noexcept(std::declval() /= std::declval()) + > type; + }; + + template + struct is_trivial_arithmetic_type : public is_trivial_arithmetic_type_imp::type {}; + } + +#ifndef BOOST_MATH_NO_CXX14_CONSTEXPR + namespace constexpr_detail + { + template + constexpr void swap(T& a, T& b) + { + T t(a); + a = b; + b = t; + } + } +#endif + + template + class quaternion + { + public: + + typedef T value_type; + + + // constructor for H seen as R^4 + // (also default constructor) + + constexpr explicit quaternion( T const & requested_a = T(), + T const & requested_b = T(), + T const & requested_c = T(), + T const & requested_d = T()) + : a(requested_a), + b(requested_b), + c(requested_c), + d(requested_d) + { + // nothing to do! + } + + + // constructor for H seen as C^2 + + constexpr explicit quaternion( ::std::complex const & z0, + ::std::complex const & z1 = ::std::complex()) + : a(z0.real()), + b(z0.imag()), + c(z1.real()), + d(z1.imag()) + { + // nothing to do! + } + + + // UNtemplated copy constructor + constexpr quaternion(quaternion const & a_recopier) + : a(a_recopier.R_component_1()), + b(a_recopier.R_component_2()), + c(a_recopier.R_component_3()), + d(a_recopier.R_component_4()) {} + + constexpr quaternion(quaternion && a_recopier) + : a(std::move(a_recopier.R_component_1())), + b(std::move(a_recopier.R_component_2())), + c(std::move(a_recopier.R_component_3())), + d(std::move(a_recopier.R_component_4())) {} + + // templated copy constructor + + template + constexpr explicit quaternion(quaternion const & a_recopier) + : a(static_cast(a_recopier.R_component_1())), + b(static_cast(a_recopier.R_component_2())), + c(static_cast(a_recopier.R_component_3())), + d(static_cast(a_recopier.R_component_4())) + { + // nothing to do! + } + + + // destructor + // (this is taken care of by the compiler itself) + + + // accessors + // + // Note: Like complex number, quaternions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is a quaternion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + constexpr T real() const + { + return(a); + } + + constexpr quaternion unreal() const + { + return(quaternion(static_cast(0), b, c, d)); + } + + constexpr T R_component_1() const + { + return(a); + } + + constexpr T R_component_2() const + { + return(b); + } + + constexpr T R_component_3() const + { + return(c); + } + + constexpr T R_component_4() const + { + return(d); + } + + constexpr ::std::complex C_component_1() const + { + return(::std::complex(a, b)); + } + + constexpr ::std::complex C_component_2() const + { + return(::std::complex(c, d)); + } + + BOOST_MATH_CXX14_CONSTEXPR void swap(quaternion& o) + { +#ifndef BOOST_MATH_NO_CXX14_CONSTEXPR + using constexpr_detail::swap; +#else + using std::swap; +#endif + swap(a, o.a); + swap(b, o.b); + swap(c, o.c); + swap(d, o.d); + } + + // assignment operators + + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator = (quaternion const & a_affecter) + { + a = static_cast(a_affecter.R_component_1()); + b = static_cast(a_affecter.R_component_2()); + c = static_cast(a_affecter.R_component_3()); + d = static_cast(a_affecter.R_component_4()); + + return(*this); + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator = (quaternion const & a_affecter) + { + a = a_affecter.a; + b = a_affecter.b; + c = a_affecter.c; + d = a_affecter.d; + + return(*this); + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator = (quaternion && a_affecter) + { + a = std::move(a_affecter.a); + b = std::move(a_affecter.b); + c = std::move(a_affecter.c); + d = std::move(a_affecter.d); + + return(*this); + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator = (T const & a_affecter) + { + a = a_affecter; + + b = c = d = static_cast(0); + + return(*this); + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator = (::std::complex const & a_affecter) + { + a = a_affecter.real(); + b = a_affecter.imag(); + + c = d = static_cast(0); + + return(*this); + } + + // other assignment-related operators + // + // NOTE: Quaternion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);" + // + // Note2: Each operator comes in 2 forms - one for the simple case where + // type T throws no exceptions, and one exception-safe version + // for the case where it might. + private: + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(T const & rhs, const std::true_type&) + { + a += rhs; + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(T const & rhs, const std::false_type&) + { + quaternion result(a + rhs, b, c, d); // exception guard + swap(result); + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(std::complex const & rhs, const std::true_type&) + { + a += std::real(rhs); + b += std::imag(rhs); + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(std::complex const & rhs, const std::false_type&) + { + quaternion result(a + std::real(rhs), b + std::imag(rhs), c, d); // exception guard + swap(result); + return *this; + } + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(quaternion const & rhs, const std::true_type&) + { + a += rhs.R_component_1(); + b += rhs.R_component_2(); + c += rhs.R_component_3(); + d += rhs.R_component_4(); + return *this; + } + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_add(quaternion const & rhs, const std::false_type&) + { + quaternion result(a + rhs.R_component_1(), b + rhs.R_component_2(), c + rhs.R_component_3(), d + rhs.R_component_4()); // exception guard + swap(result); + return *this; + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(T const & rhs, const std::true_type&) + { + a -= rhs; + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(T const & rhs, const std::false_type&) + { + quaternion result(a - rhs, b, c, d); // exception guard + swap(result); + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(std::complex const & rhs, const std::true_type&) + { + a -= std::real(rhs); + b -= std::imag(rhs); + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(std::complex const & rhs, const std::false_type&) + { + quaternion result(a - std::real(rhs), b - std::imag(rhs), c, d); // exception guard + swap(result); + return *this; + } + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(quaternion const & rhs, const std::true_type&) + { + a -= rhs.R_component_1(); + b -= rhs.R_component_2(); + c -= rhs.R_component_3(); + d -= rhs.R_component_4(); + return *this; + } + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_subtract(quaternion const & rhs, const std::false_type&) + { + quaternion result(a - rhs.R_component_1(), b - rhs.R_component_2(), c - rhs.R_component_3(), d - rhs.R_component_4()); // exception guard + swap(result); + return *this; + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_multiply(T const & rhs, const std::true_type&) + { + a *= rhs; + b *= rhs; + c *= rhs; + d *= rhs; + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_multiply(T const & rhs, const std::false_type&) + { + quaternion result(a * rhs, b * rhs, c * rhs, d * rhs); // exception guard + swap(result); + return *this; + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_divide(T const & rhs, const std::true_type&) + { + a /= rhs; + b /= rhs; + c /= rhs; + d /= rhs; + return *this; + } + BOOST_MATH_CXX14_CONSTEXPR quaternion & do_divide(T const & rhs, const std::false_type&) + { + quaternion result(a / rhs, b / rhs, c / rhs, d / rhs); // exception guard + swap(result); + return *this; + } + public: + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator += (T const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator += (::std::complex const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + template BOOST_MATH_CXX14_CONSTEXPR quaternion & operator += (quaternion const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator -= (T const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator -= (::std::complex const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + template BOOST_MATH_CXX14_CONSTEXPR quaternion & operator -= (quaternion const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator *= (T const & rhs) { return do_multiply(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator *= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + quaternion result(a*ar - b*br, a*br + b*ar, c*ar + d*br, -c*br+d*ar); + swap(result); + return(*this); + } + + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator *= (quaternion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + + quaternion result(a*ar - b*br - c*cr - d*dr, a*br + b*ar + c*dr - d*cr, a*cr - b*dr + c*ar + d*br, a*dr + b*cr - c*br + d*ar); + swap(result); + return(*this); + } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator /= (T const & rhs) { return do_divide(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator /= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + T denominator = ar*ar+br*br; + quaternion result((+a*ar + b*br) / denominator, (-a*br + b*ar) / denominator, (+c*ar - d*br) / denominator, (+c*br + d*ar) / denominator); + swap(result); + return(*this); + } + + template + BOOST_MATH_CXX14_CONSTEXPR quaternion & operator /= (quaternion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + + T denominator = ar*ar+br*br+cr*cr+dr*dr; + quaternion result((+a*ar+b*br+c*cr+d*dr)/denominator, (-a*br+b*ar-c*dr+d*cr)/denominator, (-a*cr+b*dr+c*ar-d*br)/denominator, (-a*dr-b*cr+c*br+d*ar)/denominator); + swap(result); + return(*this); + } + private: + T a, b, c, d; + + }; + +// swap: +template +BOOST_MATH_CXX14_CONSTEXPR void swap(quaternion& a, quaternion& b) { a.swap(b); } + +// operator+ +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator + (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() + b), a.R_component_2(), a.R_component_3(), a.R_component_4()); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator + (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(b.R_component_1() + a), b.R_component_2(), b.R_component_3(), b.R_component_4()); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator + (const quaternion& a, const std::complex& b) +{ + return quaternion(a.R_component_1() + std::real(b), a.R_component_2() + std::imag(b), a.R_component_3(), a.R_component_4()); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator + (const std::complex& a, const quaternion& b) +{ + return quaternion(b.R_component_1() + std::real(a), b.R_component_2() + std::imag(a), b.R_component_3(), b.R_component_4()); +} +template +inline constexpr quaternion operator + (const quaternion& a, const quaternion& b) +{ + return quaternion(a.R_component_1() + b.R_component_1(), a.R_component_2() + b.R_component_2(), a.R_component_3() + b.R_component_3(), a.R_component_4() + b.R_component_4()); +} +// operator- +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator - (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() - b), a.R_component_2(), a.R_component_3(), a.R_component_4()); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator - (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(a - b.R_component_1()), -b.R_component_2(), -b.R_component_3(), -b.R_component_4()); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator - (const quaternion& a, const std::complex& b) +{ + return quaternion(a.R_component_1() - std::real(b), a.R_component_2() - std::imag(b), a.R_component_3(), a.R_component_4()); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator - (const std::complex& a, const quaternion& b) +{ + return quaternion(std::real(a) - b.R_component_1(), std::imag(a) - b.R_component_2(), -b.R_component_3(), -b.R_component_4()); +} +template +inline constexpr quaternion operator - (const quaternion& a, const quaternion& b) +{ + return quaternion(a.R_component_1() - b.R_component_1(), a.R_component_2() - b.R_component_2(), a.R_component_3() - b.R_component_3(), a.R_component_4() - b.R_component_4()); +} + +// operator* +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator * (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() * b), a.R_component_2() * b, a.R_component_3() * b, a.R_component_4() * b); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator * (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(a * b.R_component_1()), a * b.R_component_2(), a * b.R_component_3(), a * b.R_component_4()); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator * (const quaternion& a, const std::complex& b) +{ + quaternion result(a); + result *= b; + return result; +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator * (const std::complex& a, const quaternion& b) +{ + quaternion result(a); + result *= b; + return result; +} +template +inline BOOST_MATH_CXX14_CONSTEXPR quaternion operator * (const quaternion& a, const quaternion& b) +{ + quaternion result(a); + result *= b; + return result; +} + +// operator/ +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator / (const quaternion& a, const T2& b) +{ + return quaternion(a.R_component_1() / b, a.R_component_2() / b, a.R_component_3() / b, a.R_component_4() / b); +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const T1& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const quaternion& a, const std::complex& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_MATH_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const std::complex& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_MATH_CXX14_CONSTEXPR quaternion operator / (const quaternion& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} + + + template + inline constexpr const quaternion& operator + (quaternion const & q) + { + return q; + } + + + template + inline constexpr quaternion operator - (quaternion const & q) + { + return(quaternion(-q.R_component_1(),-q.R_component_2(),-q.R_component_3(),-q.R_component_4())); + } + + + template + inline constexpr typename std::enable_if::value, bool>::type operator == (R const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs)&& + (rhs.R_component_2() == static_cast(0))&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0)) + ); + } + + + template + inline constexpr typename std::enable_if::value, bool>::type operator == (quaternion const & lhs, R const & rhs) + { + return rhs == lhs; + } + + + template + inline constexpr bool operator == (::std::complex const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs.real())&& + (rhs.R_component_2() == lhs.imag())&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0)) + ); + } + + + template + inline constexpr bool operator == (quaternion const & lhs, ::std::complex const & rhs) + { + return rhs == lhs; + } + + + template + inline constexpr bool operator == (quaternion const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4()) + ); + } + + template inline constexpr bool operator != (R const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, R const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (::std::complex const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, ::std::complex const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + + + // Note: we allow the following formats, with a, b, c, and d reals + // a + // (a), (a,b), (a,b,c), (a,b,c,d) + // (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d)) + template + ::std::basic_istream & operator >> ( ::std::basic_istream & is, + quaternion & q) + { + const ::std::ctype & ct = ::std::use_facet< ::std::ctype >(is.getloc()); + + T a = T(); + T b = T(); + T c = T(); + T d = T(); + + ::std::complex u = ::std::complex(); + ::std::complex v = ::std::complex(); + + charT ch = charT(); + char cc; + + is >> ch; // get the first lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "(", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is >> ch; // get the second lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "((", possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is.putback(ch); + + is >> u; // we extract the first and second components + a = u.real(); + b = u.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: ((a)) or ((a,b)) + { + q = quaternion(a,b); + } + else if (cc == ',') // read "((a)," or "((a,b),", possible: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is >> v; // we extract the third and fourth components + c = v.real(); + d = v.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the last lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,)) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the third lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a) + { + q = quaternion(a); + } + else if (cc == ',') // read "(a,", possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) + { + is >> ch; // get the fourth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "(a,(", possible: (a,(c)), (a,(c,d)) + { + is.putback(ch); + + is >> v; // we extract the third and fourth component + + c = v.real(); + d = v.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the ninth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,(c)) or (a,(c,d)) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b", possible: (a,b), (a,b,c), (a,b,c,d) + { + is.putback(ch); + + is >> b; // we extract the second component + + if (!is.good()) goto finish; + + is >> ch; // get the fifth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b) + { + q = quaternion(a,b); + } + else if (cc == ',') // read "(a,b,", possible: (a,b,c), (a,b,c,d) + { + is >> c; // we extract the third component + + if (!is.good()) goto finish; + + is >> ch; // get the seventh lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b,c) + { + q = quaternion(a,b,c); + } + else if (cc == ',') // read "(a,b,c,", possible: (a,b,c,d) + { + is >> d; // we extract the fourth component + + if (!is.good()) goto finish; + + is >> ch; // get the ninth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b,c,d) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // format: a + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + q = quaternion(a); + } + + finish: + return(is); + } + + + template + ::std::basic_ostream & operator << ( ::std::basic_ostream & os, + quaternion const & q) + { + ::std::basic_ostringstream s; + + s.flags(os.flags()); + s.imbue(os.getloc()); + s.precision(os.precision()); + + s << '(' << q.R_component_1() << ',' + << q.R_component_2() << ',' + << q.R_component_3() << ',' + << q.R_component_4() << ')'; + + return os << s.str(); + } + + + // values + + template + inline constexpr T real(quaternion const & q) + { + return(q.real()); + } + + + template + inline constexpr quaternion unreal(quaternion const & q) + { + return(q.unreal()); + } + + template + inline T sup(quaternion const & q) + { + using ::std::abs; + return (std::max)((std::max)(abs(q.R_component_1()), abs(q.R_component_2())), (std::max)(abs(q.R_component_3()), abs(q.R_component_4()))); + } + + + template + inline T l1(quaternion const & q) + { + using ::std::abs; + return abs(q.R_component_1()) + abs(q.R_component_2()) + abs(q.R_component_3()) + abs(q.R_component_4()); + } + + + template + inline T abs(quaternion const & q) + { + using ::std::abs; + using ::std::sqrt; + + T maxim = sup(q); // overflow protection + + if (maxim == static_cast(0)) + { + return(maxim); + } + else + { + T mixam = static_cast(1)/maxim; // prefer multiplications over divisions + + T a = q.R_component_1() * mixam; + T b = q.R_component_2() * mixam; + T c = q.R_component_3() * mixam; + T d = q.R_component_4() * mixam; + + a *= a; + b *= b; + c *= c; + d *= d; + + return(maxim * sqrt(a + b + c + d)); + } + + //return(sqrt(norm(q))); + } + + + // Note: This is the Cayley norm, not the Euclidean norm... + + template + inline BOOST_MATH_CXX14_CONSTEXPR T norm(quaternionconst & q) + { + return(real(q*conj(q))); + } + + + template + inline constexpr quaternion conj(quaternion const & q) + { + return(quaternion( +q.R_component_1(), + -q.R_component_2(), + -q.R_component_3(), + -q.R_component_4())); + } + + + template + inline quaternion spherical( T const & rho, + T const & theta, + T const & phi1, + T const & phi2) + { + using ::std::cos; + using ::std::sin; + + //T a = cos(theta)*cos(phi1)*cos(phi2); + //T b = sin(theta)*cos(phi1)*cos(phi2); + //T c = sin(phi1)*cos(phi2); + //T d = sin(phi2); + + T courrant = static_cast(1); + + T d = sin(phi2); + + courrant *= cos(phi2); + + T c = sin(phi1)*courrant; + + courrant *= cos(phi1); + + T b = sin(theta)*courrant; + T a = cos(theta)*courrant; + + return(rho*quaternion(a,b,c,d)); + } + + + template + inline quaternion semipolar( T const & rho, + T const & alpha, + T const & theta1, + T const & theta2) + { + using ::std::cos; + using ::std::sin; + + T a = cos(alpha)*cos(theta1); + T b = cos(alpha)*sin(theta1); + T c = sin(alpha)*cos(theta2); + T d = sin(alpha)*sin(theta2); + + return(rho*quaternion(a,b,c,d)); + } + + + template + inline quaternion multipolar( T const & rho1, + T const & theta1, + T const & rho2, + T const & theta2) + { + using ::std::cos; + using ::std::sin; + + T a = rho1*cos(theta1); + T b = rho1*sin(theta1); + T c = rho2*cos(theta2); + T d = rho2*sin(theta2); + + return(quaternion(a,b,c,d)); + } + + + template + inline quaternion cylindrospherical( T const & t, + T const & radius, + T const & longitude, + T const & latitude) + { + using ::std::cos; + using ::std::sin; + + + + T b = radius*cos(longitude)*cos(latitude); + T c = radius*sin(longitude)*cos(latitude); + T d = radius*sin(latitude); + + return(quaternion(t,b,c,d)); + } + + + template + inline quaternion cylindrical(T const & r, + T const & angle, + T const & h1, + T const & h2) + { + using ::std::cos; + using ::std::sin; + + T a = r*cos(angle); + T b = r*sin(angle); + + return(quaternion(a,b,h1,h2)); + } + + + // transcendentals + // (please see the documentation) + + + template + inline quaternion exp(quaternion const & q) + { + using ::std::exp; + using ::std::cos; + + using ::boost::math::sinc_pi; + + T u = exp(real(q)); + + T z = abs(unreal(q)); + + T w = sinc_pi(z); + + return(u*quaternion(cos(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion cos(quaternion const & q) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(q)); + + T w = -sin(q.real())*sinhc_pi(z); + + return(quaternion(cos(q.real())*cosh(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion sin(quaternion const & q) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(q)); + + T w = +cos(q.real())*sinhc_pi(z); + + return(quaternion(sin(q.real())*cosh(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion tan(quaternion const & q) + { + return(sin(q)/cos(q)); + } + + + template + inline quaternion cosh(quaternion const & q) + { + return((exp(+q)+exp(-q))/static_cast(2)); + } + + + template + inline quaternion sinh(quaternion const & q) + { + return((exp(+q)-exp(-q))/static_cast(2)); + } + + + template + inline quaternion tanh(quaternion const & q) + { + return(sinh(q)/cosh(q)); + } + + + template + quaternion pow(quaternion const & q, + int n) + { + if (n > 1) + { + int m = n>>1; + + quaternion result = pow(q, m); + + result *= result; + + if (n != (m<<1)) + { + result *= q; // n odd + } + + return(result); + } + else if (n == 1) + { + return(q); + } + else if (n == 0) + { + return(quaternion(static_cast(1))); + } + else /* n < 0 */ + { + return(pow(quaternion(static_cast(1))/q,-n)); + } + } + } +} + +#endif /* BOOST_QUATERNION_HPP */ diff --git a/third-party/boost-math/include/boost/math/special_functions.hpp b/third-party/boost-math/include/boost/math/special_functions.hpp new file mode 100644 index 0000000000000..d3aa95c5c1d47 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions.hpp @@ -0,0 +1,86 @@ +// Copyright John Maddock 2006, 2007, 2012, 2014. +// Copyright Paul A. Bristow 2006, 2007, 2012 + +// 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) + +// This file includes *all* the special functions. +// this may be useful if many are used +// - to avoid including each function individually. + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_MATH_NO_EXCEPTIONS +#include +#endif + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/acosh.hpp b/third-party/boost-math/include/boost/math/special_functions/acosh.hpp new file mode 100644 index 0000000000000..63e8e2dff05e9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/acosh.hpp @@ -0,0 +1,102 @@ +// boost asinh.hpp header file + +// (C) Copyright Eric Ford 2001 & Hubert Holin. +// (C) Copyright John Maddock 2008. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ACOSH_HPP +#define BOOST_ACOSH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic cosine function. + +namespace boost +{ + namespace math + { + namespace detail + { + template + inline T acosh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + + if((x < 1) || (boost::math::isnan)(x)) + { + return policies::raise_domain_error("boost::math::acosh<%1%>(%1%)", "acosh requires x >= 1, but got x = %1%.", x, pol); + } + else if ((x - 1) >= tools::root_epsilon()) + { + if (x > 1 / tools::root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/ + // approximation by laurent series in 1/x at 0+ order from -1 to 0 + return log(x) + constants::ln_two(); + } + else if(x < 1.5f) + { + // This is just a rearrangement of the standard form below + // devised to minimise loss of precision when x ~ 1: + T y = x - 1; + return boost::math::log1p(y + sqrt(y * y + 2 * y), pol); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ + return( log( x + sqrt(x * x - 1) ) ); + } + } + else + { + // see http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/04/01/0001/ + T y = x - 1; + + // approximation by taylor series in y at 0 up to order 2 + T result = sqrt(2 * y) * (1 - y /12 + 3 * y * y / 160); + return result; + } + } + } + + template + inline typename tools::promote_args::type acosh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::acosh_imp(static_cast(x), forwarding_policy()), + "boost::math::acosh<%1%>(%1%)"); + } + template + inline typename tools::promote_args::type acosh(T x) + { + return boost::math::acosh(x, policies::policy<>()); + } + + } +} + +#endif /* BOOST_ACOSH_HPP */ + + diff --git a/third-party/boost-math/include/boost/math/special_functions/airy.hpp b/third-party/boost-math/include/boost/math/special_functions/airy.hpp new file mode 100644 index 0000000000000..4219e5286e9f8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/airy.hpp @@ -0,0 +1,475 @@ +// Copyright John Maddock 2012. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_AIRY_HPP +#define BOOST_MATH_AIRY_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T airy_ai_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T ai = sqrt(-x) * (j1 + j2) / 3; + //T bi = sqrt(-x / 3) * (j2 - j1); + return ai; + } + else if(fabs(x * x * x) / 6 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::twothirds(), pol); + T ai = 1 / (pow(T(3), constants::twothirds()) * tg); + //T bi = 1 / (sqrt(boost::math::cbrt(T(3))) * tg); + return ai; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(1) / 3; + //T j1 = boost::math::cyl_bessel_i(-v, p, pol); + //T j2 = boost::math::cyl_bessel_i(v, p, pol); + // + // Note that although we can calculate ai from j1 and j2, the accuracy is horrible + // as we're subtracting two very large values, so use the Bessel K relation instead: + // + T ai = cyl_bessel_k(v, p, pol) * sqrt(x / 3) / boost::math::constants::pi(); //sqrt(x) * (j1 - j2) / 3; + //T bi = sqrt(x / 3) * (j1 + j2); + return ai; + } +} + +template +BOOST_MATH_GPU_ENABLED T airy_bi_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + //T ai = sqrt(-x) * (j1 + j2) / 3; + T bi = sqrt(-x / 3) * (j2 - j1); + return bi; + } + else if(fabs(x * x * x) / 6 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::twothirds(), pol); + //T ai = 1 / (pow(T(3), constants::twothirds()) * tg); + T bi = 1 / (sqrt(boost::math::cbrt(T(3), pol)) * tg); + return bi; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_i(-v, p, pol); + T j2 = boost::math::cyl_bessel_i(v, p, pol); + T bi = sqrt(x / 3) * (j1 + j2); + return bi; + } +} + +template +BOOST_MATH_GPU_ENABLED T airy_ai_prime_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T aip = -x * (j1 - j2) / 3; + return aip; + } + else if(fabs(x * x) / 2 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::third(), pol); + T aip = 1 / (boost::math::cbrt(T(3), pol) * tg); + return -aip; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(2) / 3; + //T j1 = boost::math::cyl_bessel_i(-v, p, pol); + //T j2 = boost::math::cyl_bessel_i(v, p, pol); + // + // Note that although we can calculate ai from j1 and j2, the accuracy is horrible + // as we're subtracting two very large values, so use the Bessel K relation instead: + // + T aip = -cyl_bessel_k(v, p, pol) * x / (boost::math::constants::root_three() * boost::math::constants::pi()); + return aip; + } +} + +template +BOOST_MATH_GPU_ENABLED T airy_bi_prime_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T aip = -x * (j1 + j2) / constants::root_three(); + return aip; + } + else if(fabs(x * x) / 2 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::third(), pol); + T bip = sqrt(boost::math::cbrt(T(3), pol)) / tg; + return bip; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_i(-v, p, pol); + T j2 = boost::math::cyl_bessel_i(v, p, pol); + T aip = x * (j1 + j2) / boost::math::constants::root_three(); + return aip; + } +} + +template +BOOST_MATH_GPU_ENABLED T airy_ai_zero_imp(int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error("boost::math::airy_ai_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must be 1 or more !", static_cast(m), pol); + } + + // Handle case when the zero'th zero is requested. + if(m == 0U) + { + return policies::raise_domain_error("boost::math::airy_ai_zero<%1%>(%1%,%1%)", + "The requested rank of the zero is %1%, but must be 1 or more !", static_cast(m), pol); + } + + // Set up the initial guess for the upcoming root-finding. + const T guess_root = boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess(m, pol); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast(static_cast(policies::digits() * 0.301F)); + + const std::uintmax_t iterations_allowed = static_cast(BOOST_MATH_GPU_SAFE_MAX(12, my_digits10 * 2)); + + std::uintmax_t iterations_used = iterations_allowed; + + // Use a dynamic tolerance because the roots get closer the higher m gets. + T tolerance; // LCOV_EXCL_LINE + + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T am = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::airy_zero::airy_ai_zero_detail::function_object_ai_and_ai_prime(pol), + guess_root, + T(guess_root - tolerance), + T(guess_root + tolerance), + policies::digits(), + iterations_used); + + static_cast(iterations_used); + + return am; +} + +template +BOOST_MATH_GPU_ENABLED T airy_bi_zero_imp(int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error("boost::math::airy_bi_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must 1 or more !", static_cast(m), pol); + } + + // Handle case when the zero'th zero is requested. + if(m == 0U) + { + return policies::raise_domain_error("boost::math::airy_bi_zero<%1%>(%1%,%1%)", + "The requested rank of the zero is %1%, but must be 1 or more !", static_cast(m), pol); + } + // Set up the initial guess for the upcoming root-finding. + const T guess_root = boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess(m, pol); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast(static_cast(policies::digits() * 0.301F)); + + const std::uintmax_t iterations_allowed = static_cast(BOOST_MATH_GPU_SAFE_MAX(12, my_digits10 * 2)); + + std::uintmax_t iterations_used = iterations_allowed; + + // Use a dynamic tolerance because the roots get closer the higher m gets. + T tolerance; // LCOV_EXCL_LINE + + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T bm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::airy_zero::airy_bi_zero_detail::function_object_bi_and_bi_prime(pol), + guess_root, + T(guess_root - tolerance), + T(guess_root + tolerance), + policies::digits(), + iterations_used); + + static_cast(iterations_used); + + return bm; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_ai(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_ai_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_ai(T x) +{ + return airy_ai(x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_bi(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_bi_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_bi(T x) +{ + return airy_bi(x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_ai_prime(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_ai_prime_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_ai_prime(T x) +{ + return airy_ai_prime(x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_bi_prime(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_bi_prime_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type airy_bi_prime(T x) +{ + return airy_bi_prime(x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T airy_ai_zero(int m, const Policy& /*pol*/) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::airy_ai_zero_imp(m, forwarding_policy()), "boost::math::airy_ai_zero<%1%>(unsigned)"); +} + +template +BOOST_MATH_GPU_ENABLED inline T airy_ai_zero(int m) +{ + return airy_ai_zero(m, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + typedef T result_type; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + for(unsigned i = 0; i < number_of_zeros; ++i) + { + *out_it = boost::math::airy_ai_zero(start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return airy_ai_zero(start_index, number_of_zeros, out_it, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T airy_bi_zero(int m, const Policy& /*pol*/) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::airy_bi_zero_imp(m, forwarding_policy()), "boost::math::airy_bi_zero<%1%>(unsigned)"); +} + +template +BOOST_MATH_GPU_ENABLED inline T airy_bi_zero(int m) +{ + return airy_bi_zero(m, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + typedef T result_type; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + for(unsigned i = 0; i < number_of_zeros; ++i) + { + *out_it = boost::math::airy_bi_zero(start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return airy_bi_zero(start_index, number_of_zeros, out_it, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_AIRY_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/asinh.hpp b/third-party/boost-math/include/boost/math/special_functions/asinh.hpp new file mode 100644 index 0000000000000..52362dd2942b2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/asinh.hpp @@ -0,0 +1,110 @@ +// boost asinh.hpp header file + +// (C) Copyright Eric Ford & Hubert Holin 2001. +// (C) Copyright John Maddock 2008. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ASINH_HPP +#define BOOST_ASINH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + + +#include +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic sine function. + +namespace boost +{ + namespace math + { + namespace detail{ + template + inline T asinh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + + if((boost::math::isnan)(x)) + { + return policies::raise_domain_error("boost::math::asinh<%1%>(%1%)", "asinh requires a finite argument, but got x = %1%.", x, pol); + } + if (x >= tools::forth_root_epsilon()) + { + if (x > 1 / tools::root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/06/01/0001/ + // approximation by laurent series in 1/x at 0+ order from -1 to 1 + return constants::ln_two() + log(x) + 1/ (4 * x * x); + } + else if(x < 0.5f) + { + // As below, but rearranged to preserve digits: + return boost::math::log1p(x + boost::math::sqrt1pm1(x * x, pol), pol); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ + return( log( x + sqrt(x*x+1) ) ); + } + } + else if (x <= -tools::forth_root_epsilon()) + { + return(-asinh(-x, pol)); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/03/01/0001/ + // approximation by taylor series in x at 0 up to order 2 + T result = x; + + if (abs(x) >= tools::root_epsilon()) + { + T x3 = x*x*x; + + // approximation by taylor series in x at 0 up to order 4 + result -= x3/static_cast(6); + } + + return(result); + } + } + } + + template + inline typename tools::promote_args::type asinh(T x) + { + return boost::math::asinh(x, policies::policy<>()); + } + template + inline typename tools::promote_args::type asinh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::asinh_imp(static_cast(x), forwarding_policy()), + "boost::math::asinh<%1%>(%1%)"); + } + + } +} + +#endif /* BOOST_ASINH_HPP */ + diff --git a/third-party/boost-math/include/boost/math/special_functions/atanh.hpp b/third-party/boost-math/include/boost/math/special_functions/atanh.hpp new file mode 100644 index 0000000000000..9d73e568c0abd --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/atanh.hpp @@ -0,0 +1,116 @@ +// boost atanh.hpp header file + +// (C) Copyright Hubert Holin 2001. +// (C) Copyright John Maddock 2008. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ATANH_HPP +#define BOOST_ATANH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic tangent function. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the main fare + + template + BOOST_MATH_GPU_ENABLED inline T atanh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::atanh<%1%>(%1%)"; + + if(x < -1) + { + return policies::raise_domain_error(function, "atanh requires x >= -1, but got x = %1%.", x, pol); + } + else if(x > 1) + { + return policies::raise_domain_error(function, "atanh requires x <= 1, but got x = %1%.", x, pol); + } + else if((boost::math::isnan)(x)) + { + return policies::raise_domain_error(function, "atanh requires -1 <= x <= 1, but got x = %1%.", x, pol); + } + else if(x < -1 + tools::epsilon()) + { + // -Infinity: + return -policies::raise_overflow_error(function, nullptr, pol); + } + else if(x > 1 - tools::epsilon()) + { + // Infinity: + return policies::raise_overflow_error(function, nullptr, pol); + } + else if(abs(x) >= tools::forth_root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ + if(abs(x) < 0.5f) + return (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2; + return(log( (1 + x) / (1 - x) ) / 2); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/06/01/03/01/ + // approximation by taylor series in x at 0 up to order 2 + T result = x; + + if (abs(x) >= tools::root_epsilon()) + { + T x3 = x*x*x; + + // approximation by taylor series in x at 0 up to order 4 + result += x3/static_cast(3); + } + + return(result); + } + } + } + + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type atanh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::atanh_imp(static_cast(x), forwarding_policy()), + "boost::math::atanh<%1%>(%1%)"); + } + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type atanh(T x) + { + return boost::math::atanh(x, policies::policy<>()); + } + + } +} + +#endif /* BOOST_ATANH_HPP */ + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/bernoulli.hpp b/third-party/boost-math/include/boost/math/special_functions/bernoulli.hpp new file mode 100644 index 0000000000000..102b49399e898 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/bernoulli.hpp @@ -0,0 +1,149 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2013 John Maddock +// Copyright 2013 Paul Bristow +// 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) + +#ifndef _BOOST_BERNOULLI_B2N_2013_05_30_HPP_ +#define _BOOST_BERNOULLI_B2N_2013_05_30_HPP_ + +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + +template +OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const std::integral_constant& tag) +{ + for(std::size_t i = start; (i <= max_bernoulli_b2n::value) && (i < start + n); ++i) + { + *out = unchecked_bernoulli_imp(i, tag); + ++out; + } + + for(std::size_t i = (std::max)(static_cast(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + // We must overflow: + *out = (i & 1 ? 1 : -1) * policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(n)", nullptr, T(i), pol); + ++out; + } + return out; +} + +template +OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const std::integral_constant& tag) +{ + for(std::size_t i = start; (i <= max_bernoulli_b2n::value) && (i < start + n); ++i) + { + *out = unchecked_bernoulli_imp(i, tag); + ++out; + } + // + // Short circuit return so we don't grab the mutex below unless we have to: + // + if(start + n <= max_bernoulli_b2n::value) + { + return out; + } + + return get_bernoulli_numbers_cache().copy_bernoulli_numbers(out, start, n, pol); +} + +} // namespace detail + +template +inline T bernoulli_b2n(const int i, const Policy &pol) +{ + using tag_type = std::integral_constant::value>; + if(i < 0) + { + return policies::raise_domain_error("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol); + } + + T result {}; + boost::math::detail::bernoulli_number_imp(&result, static_cast(i), 1u, pol, tag_type()); + return result; +} + +template +inline T bernoulli_b2n(const int i) +{ + return boost::math::bernoulli_b2n(i, policies::policy<>()); +} + +template +inline OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol) +{ + using tag_type = std::integral_constant::value>; + if(start_index < 0) + { + *out_it = policies::raise_domain_error("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol); + return ++out_it; // LCOV_EXCL_LINE we don't reach here, previous line throws. + } + + return boost::math::detail::bernoulli_number_imp(out_it, start_index, number_of_bernoullis_b2n, pol, tag_type()); +} + +template +inline OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it) +{ + return boost::math::bernoulli_b2n(start_index, number_of_bernoullis_b2n, out_it, policies::policy<>()); +} + +template +inline T tangent_t2n(const int i, const Policy &pol) +{ + if(i < 0) + { + return policies::raise_domain_error("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol); + } + + T result {}; + boost::math::detail::get_bernoulli_numbers_cache().copy_tangent_numbers(&result, i, 1, pol); + return result; +} + +template +inline T tangent_t2n(const int i) +{ + return boost::math::tangent_t2n(i, policies::policy<>()); +} + +template +inline OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_tangent_t2n, + OutputIterator out_it, + const Policy& pol) +{ + if(start_index < 0) + { + *out_it = policies::raise_domain_error("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol); + return ++out_it; // LCOV_EXCL_LINE we don't reach here, previous line throws. + } + + return boost::math::detail::get_bernoulli_numbers_cache().copy_tangent_numbers(out_it, start_index, number_of_tangent_t2n, pol); +} + +template +inline OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_tangent_t2n, + OutputIterator out_it) +{ + return boost::math::tangent_t2n(start_index, number_of_tangent_t2n, out_it, policies::policy<>()); +} + +} } // namespace boost::math + +#endif // _BOOST_BERNOULLI_B2N_2013_05_30_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/bessel.hpp b/third-party/boost-math/include/boost/math/special_functions/bessel.hpp new file mode 100644 index 0000000000000..0cf9b63764039 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/bessel.hpp @@ -0,0 +1,795 @@ +// Copyright (c) 2007, 2013 John Maddock +// Copyright Christopher Kormanyos 2013. +// 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) +// +// This header just defines the function entry points, and adds dispatch +// to the right implementation method. Most of the implementation details +// are in separate headers and copyright Xiaogang Zhang. +// +#ifndef BOOST_MATH_BESSEL_HPP +#define BOOST_MATH_BESSEL_HPP + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 6326) // potential comparison of a constant with another constant +#endif + +namespace boost{ namespace math{ + +namespace detail{ + +template +struct sph_bessel_j_small_z_series_term +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED sph_bessel_j_small_z_series_term(unsigned v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + if(v + 3 > max_factorial::value) + { + term = v * log(mult) - boost::math::lgamma(v+1+T(0.5f), Policy()); + term = exp(term); + } + else + term = pow(mult, T(v)) / boost::math::tgamma(v+1+T(0.5f), Policy()); + mult *= -mult; + } + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = term; + ++N; + term *= mult / (N * T(N + v + 0.5f)); + return r; + } +private: + unsigned N; + unsigned v; + T mult; + T term; +}; + +template +BOOST_MATH_GPU_ENABLED inline T sph_bessel_j_small_z_series(unsigned v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + sph_bessel_j_small_z_series_term s(v, x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::sph_bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return result * sqrt(constants::pi() / 4); +} + +template +BOOST_MATH_GPU_ENABLED T cyl_bessel_j_imp_final(T v, T x, const bessel_no_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T result_J, y; // LCOV_EXCL_LINE + bessel_jy(v, x, &result_J, &y, need_j, pol); + return result_J; +} + +// Dispatch funtion to avoid recursion +template +BOOST_MATH_GPU_ENABLED T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + // better have integer v: + if (floor(v) == v) + { + // LCOV_EXCL_START + // This branch is hit by multiprecision types only, and is + // tested by our real_concept tests, but thee are excluded from coverage + // due to time constraints. + T r = cyl_bessel_j_imp_final(T(v), T(-x), t, pol); + if (iround(v, pol) & 1) + { + r = -r; + } + + return r; + // LCOV_EXCL_STOP + } + else + { + constexpr auto function = "boost::math::bessel_j<%1%>(%1%,%1%)"; + return policies::raise_domain_error(function, "Got x = %1%, but we need x >= 0", x, pol); + } + } + + return cyl_bessel_j_imp_final(T(v), T(x), t, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_j_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names. + int ival = detail::iconv(v, pol); + // If v is an integer, use the integer recursion + // method, both that and Steeds method are O(v): + if((0 == v - ival)) + { + return bessel_jn(ival, x, pol); + } + return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_j_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + return bessel_jn(v, x, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T sph_bessel_j_imp(unsigned n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + if(x < 0) + return policies::raise_domain_error("boost::math::sph_bessel_j<%1%>(%1%,%1%)", "Got x = %1%, but function requires x > 0.", x, pol); + // + // Special case, n == 0 resolves down to the sinus cardinal of x: + // + if(n == 0) + return (boost::math::isinf)(x) ? T(0) : boost::math::sinc_pi(x, pol); + // + // Special case for x == 0: + // + if(x == 0) + return 0; + // + // When x is small we may end up with 0/0, use series evaluation + // instead, especially as it converges rapidly: + // + if(x < 1) + return sph_bessel_j_small_z_series(n, x, pol); + // + // Default case is just a naive evaluation of the definition: + // + return sqrt(constants::pi() / (2 * x)) + * cyl_bessel_j_imp(T(T(n)+T(0.5f)), x, bessel_no_int_tag(), pol); +} + +template +BOOST_MATH_GPU_ENABLED T cyl_bessel_i_imp_final(T v, T x, const Policy& pol) +{ + // + // This handles all the bessel I functions, note that we don't optimise + // for integer v, other than the v = 0 or 1 special cases, as Millers + // algorithm is at least as inefficient as the general case (the general + // case has better error handling too). + // + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::cyl_bessel_i<%1%>(%1%,%1%)"; + if(x == 0) + { + if(v < 0) + return floor(v) == v ? static_cast(0) : policies::raise_overflow_error(function, nullptr, pol); + return (v == 0) ? static_cast(1) : static_cast(0); + } + if(v == 0.5f) + { + // common special case, note try and avoid overflow in exp(x): + if(x >= tools::log_max_value()) + { + T e = exp(x / 2); + return e * (e / sqrt(2 * x * constants::pi())); + } + return sqrt(2 / (x * constants::pi())) * sinh(x); + } + if((policies::digits() <= 113) && (boost::math::numeric_limits::digits <= 113) && (boost::math::numeric_limits::radix == 2)) + { + if(v == 0) + { + return bessel_i0(x); + } + if(v == 1) + { + return bessel_i1(x); + } + } + if((v > 0) && (x / v < 0.25)) + return bessel_i_small_z_series(v, x, pol); + T result_I, result_K; // LCOV_EXCL_LINE + bessel_ik(v, x, &result_I, &result_K, need_i, pol); + return result_I; +} + +// Additional dispatch function to get the GPU impls happy +template +BOOST_MATH_GPU_ENABLED T cyl_bessel_i_imp(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::cyl_bessel_i<%1%>(%1%,%1%)"; + + if(x < 0) + { + // better have integer v: + if(floor(v) == v) + { + T r = cyl_bessel_i_imp_final(T(v), T(-x), pol); + if(iround(v, pol) & 1) + { + r = -r; + } + + return r; + } + else + { + return policies::raise_domain_error(function, "Got x = %1%, but we need x >= 0", x, pol); + } + } + + return cyl_bessel_i_imp_final(T(v), T(x), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_k_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol) +{ + constexpr auto function = "boost::math::cyl_bessel_k<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + if(x < 0) + { + return policies::raise_domain_error(function, "Got x = %1%, but we need x > 0", x, pol); + } + if(x == 0) + { + return (v == 0) ? policies::raise_overflow_error(function, nullptr, pol) + : policies::raise_domain_error(function, "Got x = %1%, but we need x > 0", x, pol); + } + T result_I, result_K; // LCOV_EXCL_LINE + bessel_ik(v, x, &result_I, &result_K, need_k, pol); + return result_K; +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_k_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + if((floor(v) == v)) + { + return bessel_kn(itrunc(v), x, pol); + } + return cyl_bessel_k_imp(v, x, bessel_no_int_tag(), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_k_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + return bessel_kn(v, x, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_neumann_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol) +{ + constexpr auto function = "boost::math::cyl_neumann<%1%>(%1%,%1%)"; + + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + if(x <= 0) + { + return (v == 0) && (x == 0) ? + -policies::raise_overflow_error(function, nullptr, pol) // LCOV_EXCL_LINE MP case only here, not tested in code coverage as it takes too long. + : policies::raise_domain_error(function, "Got x = %1%, but result is complex for x <= 0", x, pol); + } + T result_J, y; // LCOV_EXCL_LINE + bessel_jy(v, x, &result_J, &y, need_y, pol); + // + // Post evaluation check for internal overflow during evaluation, + // can occur when x is small and v is large, in which case the result + // is -INF: + // + if(!(boost::math::isfinite)(y)) + return -policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE defensive programming? Might be dead code now... + return y; +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_neumann_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + if(floor(v) == v) + { + T r = bessel_yn(itrunc(v, pol), x, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + return r; + } + T r = cyl_neumann_imp(v, x, bessel_no_int_tag(), pol); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + return r; +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_neumann_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + return bessel_yn(v, x, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T sph_neumann_imp(unsigned v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + constexpr auto function = "boost::math::sph_neumann<%1%>(%1%,%1%)"; + // + // Nothing much to do here but check for errors, and + // evaluate the function's definition directly: + // + if(x < 0) + return policies::raise_domain_error(function, "Got x = %1%, but function requires x > 0.", x, pol); + + if(x < 2 * tools::min_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result = cyl_neumann_imp(T(T(v)+0.5f), x, bessel_no_int_tag(), pol); + T tx = sqrt(constants::pi() / (2 * x)); + + if((tx > 1) && (tools::max_value() / tx < fabs(result))) + return -policies::raise_overflow_error(function, nullptr, pol); + + return result * tx; +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_bessel_j_zero_imp(T v, int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + constexpr auto function = "boost::math::cyl_bessel_j_zero<%1%>(%1%, int)"; + + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + // Handle non-finite order. + if (!(boost::math::isfinite)(v) ) + { + return policies::raise_domain_error(function, "Order argument is %1%, but must be finite >= 0 !", v, pol); + } + + // Handle negative rank. + if(m < 0) + { + // Zeros of Jv(x) with negative rank are not defined and requesting one raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast(m), pol); + } + + // Get the absolute value of the order. + const bool order_is_negative = (v < 0); + const T vv((!order_is_negative) ? v : T(-v)); + + // Check if the order is very close to zero or very close to an integer. + const bool order_is_zero = (vv < half_epsilon); + const bool order_is_integer = ((vv - floor(vv)) < half_epsilon); + + if(m == 0) + { + if(order_is_zero) + { + // The zero'th zero of J0(x) is not defined and requesting it raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of J0, but the rank must be > 0 !", static_cast(m), pol); + } + + // The zero'th zero of Jv(x) for v < 0 is not defined + // unless the order is a negative integer. + if(order_is_negative && (!order_is_integer)) + { + // For non-integer, negative order, requesting the zero'th zero raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of Jv for negative, non-integer order, but the rank must be > 0 !", static_cast(m), pol); + } + + // The zero'th zero does exist and its value is zero. + return T(0); + } + + // Set up the initial guess for the upcoming root-finding. + // If the order is a negative integer, then use the corresponding + // positive integer for the order. + const T guess_root = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess((order_is_integer ? vv : v), m, pol); + + // Select the maximum allowed iterations from the policy. + boost::math::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T jvm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv_and_jv_prime((order_is_integer ? vv : v), order_is_zero, pol), + guess_root, + T(guess_root - delta_lo), + T(guess_root + 0.2F), + policies::digits(), + number_of_iterations); + + if(number_of_iterations >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate root in a reasonable time: Current best guess is %1%", jvm, Policy()); // LCOV_EXCL_LINE + } + + return jvm; +} + +template +BOOST_MATH_GPU_ENABLED inline T cyl_neumann_zero_imp(T v, int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + constexpr auto function = "boost::math::cyl_neumann_zero<%1%>(%1%, int)"; + + // Handle non-finite order. + if (!(boost::math::isfinite)(v) ) + { + return policies::raise_domain_error(function, "Order argument is %1%, but must be finite >= 0 !", v, pol); + } + + // Handle negative rank. + if(m < 0) + { + return policies::raise_domain_error(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast(m), pol); + } + + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + // Get the absolute value of the order. + const bool order_is_negative = (v < 0); + const T vv((!order_is_negative) ? v : T(-v)); + + const bool order_is_integer = ((vv - floor(vv)) < half_epsilon); + + // For negative integers, use reflection to positive integer order. + if(order_is_negative && order_is_integer) + return boost::math::detail::cyl_neumann_zero_imp(vv, m, pol); + + // Check if the order is very close to a negative half-integer. + const T delta_half_integer(vv - (floor(vv) + 0.5F)); + + const bool order_is_negative_half_integer = + (order_is_negative && ((delta_half_integer > -half_epsilon) && (delta_half_integer < +half_epsilon))); + + // The zero'th zero of Yv(x) for v < 0 is not defined + // unless the order is a negative integer. + if((m == 0) && (!order_is_negative_half_integer)) + { + // For non-integer, negative order, requesting the zero'th zero raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of Yv for negative, non-half-integer order, but the rank must be > 0 !", static_cast(m), pol); + } + + // For negative half-integers, use the corresponding + // spherical Bessel function of positive half-integer order. + if(order_is_negative_half_integer) + return boost::math::detail::cyl_bessel_j_zero_imp(vv, m, pol); + + // Set up the initial guess for the upcoming root-finding. + // If the order is a negative integer, then use the corresponding + // positive integer for the order. + const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(v, m, pol); + + // Select the maximum allowed iterations from the policy. + boost::math::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T yvm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime(v, pol), + guess_root, + T(guess_root - delta_lo), + T(guess_root + 0.2F), + policies::digits(), + number_of_iterations); + + if(number_of_iterations >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate root in a reasonable time: Current best guess is %1%", yvm, Policy()); // LCOV_EXCL_LINE + } + + return yvm; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_j_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_j<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_bessel_j(T1 v, T2 x) +{ + return cyl_bessel_j(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type sph_bessel(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_bessel_j_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_bessel<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type sph_bessel(unsigned v, T x) +{ + return sph_bessel(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_bessel_i(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_i_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_i<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_bessel_i(T1 v, T2 x) +{ + return cyl_bessel_i(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_bessel_k(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag128 tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_k_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_k<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_bessel_k(T1 v, T2 x) +{ + return cyl_bessel_k(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_neumann(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_neumann_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_neumann<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_neumann(T1 v, T2 x) +{ + return cyl_neumann(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type sph_neumann(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_neumann_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_neumann<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type sph_neumann(unsigned v, T x) +{ + return sph_neumann(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::cyl_bessel_j_zero_imp(v, m, forwarding_policy()), "boost::math::cyl_bessel_j_zero<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_bessel_j_zero(T v, int m) +{ + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return cyl_bessel_j_zero >(v, m, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + for(int i = 0; i < static_cast(number_of_zeros); ++i) + { + *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits::result_type cyl_neumann_zero(T v, int m, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::cyl_neumann_zero_imp(v, m, forwarding_policy()), "boost::math::cyl_neumann_zero<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::bessel_traits >::result_type cyl_neumann_zero(T v, int m) +{ + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return cyl_neumann_zero >(v, m, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + static_assert( false == boost::math::numeric_limits::is_specialized + || ( true == boost::math::numeric_limits::is_specialized + && false == boost::math::numeric_limits::is_integer), + "Order must be a floating-point type."); + + for(int i = 0; i < static_cast(number_of_zeros); ++i) + { + *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +BOOST_MATH_GPU_ENABLED inline OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return cyl_neumann_zero(v, start_index, number_of_zeros, out_it, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_HPP + + diff --git a/third-party/boost-math/include/boost/math/special_functions/bessel_iterators.hpp b/third-party/boost-math/include/boost/math/special_functions/bessel_iterators.hpp new file mode 100644 index 0000000000000..7e0de2f865bc1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/bessel_iterators.hpp @@ -0,0 +1,187 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) + +#ifndef BOOST_MATH_BESSEL_ITERATORS_HPP +#define BOOST_MATH_BESSEL_ITERATORS_HPP + +#include +#include + +namespace boost { + namespace math { + namespace detail { + + template + struct bessel_jy_recurrence + { + bessel_jy_recurrence(T v, T z) : v(v), z(z) {} + boost::math::tuple operator()(int k) + { + return boost::math::tuple(1, -2 * (v + k) / z, 1); + } + + T v, z; + }; + template + struct bessel_ik_recurrence + { + bessel_ik_recurrence(T v, T z) : v(v), z(z) {} + boost::math::tuple operator()(int k) + { + return boost::math::tuple(1, -2 * (v + k) / z, -1); + } + + T v, z; + }; + } // namespace detail + + template > + struct bessel_j_backwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_j_backwards_iterator(const T& v, const T& x) + : it(detail::bessel_jy_recurrence(v, x), boost::math::cyl_bessel_j(v, x, Policy())) + { + if(v < 0) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v) + : it(detail::bessel_jy_recurrence(v, x), J_v) + { + if(v < 0) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v_plus_1, const T& J_v) + : it(detail::bessel_jy_recurrence(v, x), J_v_plus_1, J_v) + { + if (v < -1) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_j_backwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_j_backwards_iterator operator++(int) + { + bessel_j_backwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::backward_recurrence_iterator< detail::bessel_jy_recurrence > it; + }; + + template > + struct bessel_i_backwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_i_backwards_iterator(const T& v, const T& x) + : it(detail::bessel_ik_recurrence(v, x), boost::math::cyl_bessel_i(v, x, Policy())) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v_plus_1, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v_plus_1, I_v) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_i_backwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_i_backwards_iterator operator++(int) + { + bessel_i_backwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::backward_recurrence_iterator< detail::bessel_ik_recurrence > it; + }; + + template > + struct bessel_i_forwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_i_forwards_iterator(const T& v, const T& x) + : it(detail::bessel_ik_recurrence(v, x), boost::math::cyl_bessel_i(v, x, Policy())) + { + if(v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v) + { + if (v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v_minus_1, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v_minus_1, I_v) + { + if (v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + + bessel_i_forwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_i_forwards_iterator operator++(int) + { + bessel_i_forwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::forward_recurrence_iterator< detail::bessel_ik_recurrence > it; + }; + + } +} // namespaces + +#endif // BOOST_MATH_BESSEL_ITERATORS_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/bessel_prime.hpp b/third-party/boost-math/include/boost/math/special_functions/bessel_prime.hpp new file mode 100644 index 0000000000000..ba71562885f73 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/bessel_prime.hpp @@ -0,0 +1,343 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) +// +#ifndef BOOST_MATH_BESSEL_DERIVATIVES_HPP +#define BOOST_MATH_BESSEL_DERIVATIVES_HPP + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +inline T cyl_bessel_j_prime_imp(T v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::cyl_bessel_j_prime<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + // + // Prevent complex result: + // + if ((x < 0) && (floor(v) != v)) + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function requires x >= 0", x, pol); + // + // Special cases for x == 0: + // + if (x == 0) + { + if (v == 1) + return static_cast(0.5); + else if (v == -1) + return static_cast(-0.5); + else if (floor(v) == v || v > 1) + return 0; + else + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function is indeterminate for this order", x, pol); + } + // + // Special case for large x: use asymptotic expansion: + // + if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x)) + return boost::math::detail::asymptotic_bessel_j_derivative_large_x_2(v, x, pol); + // + // Special case for small x: use Taylor series: + // + if ((abs(x) < 5) || (abs(v) > x * x / 4)) + { + bool inversed = false; + if (floor(v) == v && v < 0) + { + v = -v; + if (itrunc(v, pol) & 1) + inversed = true; + } + T r = boost::math::detail::bessel_j_derivative_small_z_series(v, x, pol); + return inversed ? T(-r) : r; + } + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_bessel_j_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_j_derivative_linear(v, x, Tag(), pol); +} + +template +inline T sph_bessel_j_prime_imp(unsigned v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::sph_bessel_prime<%1%>(%1%,%1%)"; + // + // Prevent complex result: + // + if (x < 0) + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function requires x >= 0.", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return (x == 0) ? boost::math::policies::raise_overflow_error(function, nullptr, pol) + : static_cast(-boost::math::detail::sph_bessel_j_imp(1, x, pol)); + // + // Special case for x == 0 and v > 0: + // + if (x == 0) + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function is indeterminate for this order", x, pol); + // + // Default case: + // + return boost::math::detail::sph_bessel_j_derivative_linear(v, x, pol); +} + +template +inline T cyl_bessel_i_prime_imp(T v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + // + // Prevent complex result: + // + if (x < 0 && floor(v) != v) + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function requires x >= 0", x, pol); + // + // Special cases for x == 0: + // + if (x == 0) + { + if (v == 1 || v == -1) + return static_cast(0.5); + else if (floor(v) == v || v > 1) + return 0; + else + return boost::math::policies::raise_domain_error(function, "Got x = %1%, but function is indeterminate for this order", x, pol); + } + // + // Special case for v == 0: + // + if (v == 0) + return boost::math::detail::cyl_bessel_i_imp(1, x, pol); + // + // Default case: + // + return boost::math::detail::bessel_i_derivative_linear(v, x, pol); +} + +template +inline T cyl_bessel_k_prime_imp(T v, T x, const Policy& pol) +{ + // + // Prevent complex and indeterminate results: + // + if (x <= 0) + return boost::math::policies::raise_domain_error("boost::math::cyl_bessel_k_prime<%1%>(%1%,%1%)", "Got x = %1%, but function requires x > 0", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_bessel_k_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_k_derivative_linear(v, x, Tag(), pol); +} + +template +inline T cyl_neumann_prime_imp(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Prevent complex and indeterminate results: + // + if (x <= 0) + return boost::math::policies::raise_domain_error("boost::math::cyl_neumann_prime<%1%>(%1%,%1%)", "Got x = %1%, but function requires x > 0", x, pol); + // + // Special case for large x: use asymptotic expansion: + // + if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x)) + return boost::math::detail::asymptotic_bessel_y_derivative_large_x_2(v, x, pol); + // + // Special case for small x: use Taylor series: + // + if (v > 0 && floor(v) != v) + { + const T eps = boost::math::policies::get_epsilon(); + if (log(eps / 2) > v * log((x * x) / (v * 4))) + return boost::math::detail::bessel_y_derivative_small_z_series(v, x, pol); + } + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_neumann_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_y_derivative_linear(v, x, Tag(), pol); +} + +template +inline T sph_neumann_prime_imp(unsigned v, T x, const Policy& pol) +{ + // + // Prevent complex and indeterminate result: + // + if (x <= 0) + return boost::math::policies::raise_domain_error("boost::math::sph_neumann_prime<%1%>(%1%,%1%)", "Got x = %1%, but function requires x > 0.", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::sph_neumann_imp(1, x, pol); + // + // Default case: + // + return boost::math::detail::sph_neumann_derivative_linear(v, x, pol); +} + +} // namespace detail + +template +inline typename detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_j_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_j_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_j_prime(T1 v, T2 x) +{ + return cyl_bessel_j_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_bessel_j_prime_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_bessel_j_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_bessel_prime(unsigned v, T x) +{ + return sph_bessel_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_i_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_i_prime(T1 v, T2 x) +{ + return cyl_bessel_i_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_k_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_k_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_k_prime(T1 v, T2 x) +{ + return cyl_bessel_k_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_neumann_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_neumann_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_neumann_prime(T1 v, T2 x) +{ + return cyl_neumann_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_neumann_prime(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_neumann_prime_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_neumann_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_neumann_prime(unsigned v, T x) +{ + return sph_neumann_prime(v, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_BESSEL_DERIVATIVES_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/beta.hpp b/third-party/boost-math/include/boost/math/special_functions/beta.hpp new file mode 100644 index 0000000000000..f6327fa220f80 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/beta.hpp @@ -0,0 +1,1849 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_BETA_HPP +#define BOOST_MATH_SPECIAL_BETA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +// +// Implementation of Beta(a,b) using the Lanczos approximation: +// +template +BOOST_MATH_GPU_ENABLED T beta_imp(T a, T b, const Lanczos&, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std names + + if(a <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol); + + T result; // LCOV_EXCL_LINE + + T prefix = 1; + T c = a + b; + + // Special cases: + if((c == a) && (b < tools::epsilon())) + return 1 / b; + else if((c == b) && (a < tools::epsilon())) + return 1 / a; + if(b == 1) + return 1/a; + else if(a == 1) + return 1/b; + else if(c < tools::epsilon()) + { + result = c / a; + result /= b; + return result; + } + + /* + // + // This code appears to be no longer necessary: it was + // used to offset errors introduced from the Lanczos + // approximation, but the current Lanczos approximations + // are sufficiently accurate for all z that we can ditch + // this. It remains in the file for future reference... + // + // If a or b are less than 1, shift to greater than 1: + if(a < 1) + { + prefix *= c / a; + c += 1; + a += 1; + } + if(b < 1) + { + prefix *= c / b; + c += 1; + b += 1; + } + */ + + if(a < b) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + } + + // Lanczos calculation: + T agh = static_cast(a + Lanczos::g() - 0.5f); + T bgh = static_cast(b + Lanczos::g() - 0.5f); + T cgh = static_cast(c + Lanczos::g() - 0.5f); + result = Lanczos::lanczos_sum_expG_scaled(a) * (Lanczos::lanczos_sum_expG_scaled(b) / Lanczos::lanczos_sum_expG_scaled(c)); + T ambh = a - 0.5f - b; + if((fabs(b * ambh) < (cgh * 100)) && (a > 100)) + { + // Special case where the base of the power term is close to 1 + // compute (1+x)^y instead: + result *= exp(ambh * boost::math::log1p(-b / cgh, pol)); + } + else + { + result *= pow(agh / cgh, a - T(0.5) - b); + } + if(cgh > 1e10f) + // this avoids possible overflow, but appears to be marginally less accurate: + result *= pow((agh / cgh) * (bgh / cgh), b); + else + result *= pow((agh * bgh) / (cgh * cgh), b); + result *= sqrt(boost::math::constants::e() / bgh); + + // If a and b were originally less than 1 we need to scale the result: + result *= prefix; + + return result; +} // template beta_imp(T a, T b, const Lanczos&) + +// +// Generic implementation of Beta(a,b) without Lanczos approximation support +// (Caution this is slow!!!): +// +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +template +BOOST_MATH_GPU_ENABLED T beta_imp(T a, T b, const lanczos::undefined_lanczos& l, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(a <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol); + + const T c = a + b; + + // Special cases: + if ((c == a) && (b < tools::epsilon())) + return 1 / b; + else if ((c == b) && (a < tools::epsilon())) + return 1 / a; + if (b == 1) + return 1 / a; + else if (a == 1) + return 1 / b; + else if (c < tools::epsilon()) + { + T result = c / a; + result /= b; + return result; + } + + // Regular cases start here: + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if(a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if(b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + long shift_c = shift_a + shift_b; + + if ((shift_a == 0) && (shift_b == 0)) + { + return pow(a / c, a) * pow(b / c, b) * scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol) / scaled_tgamma_no_lanczos(c, pol); + } + else if ((a < 1) && (b < 1)) + { + return boost::math::tgamma(a, pol) * (boost::math::tgamma(b, pol) / boost::math::tgamma(c)); + } + else if(a < 1) + return boost::math::tgamma(a, pol) * boost::math::tgamma_delta_ratio(b, a, pol); + else if(b < 1) + return boost::math::tgamma(b, pol) * boost::math::tgamma_delta_ratio(a, b, pol); + else + { + T result = beta_imp(T(a + shift_a), T(b + shift_b), l, pol); + // + // Recursion: + // + for (long i = 0; i < shift_c; ++i) + { + result *= c + i; + if (i < shift_a) + result /= a + i; + if (i < shift_b) + result /= b + i; + } + return result; + } + +} // template T beta_imp(T a, T b, const lanczos::undefined_lanczos& l) +#endif + +// +// Compute the leading power terms in the incomplete Beta: +// +// (x^a)(y^b)/Beta(a,b) when normalised, and +// (x^a)(y^b) otherwise. +// +// Almost all of the error in the incomplete beta comes from this +// function: particularly when a and b are large. Computing large +// powers are *hard* though, and using logarithms just leads to +// horrendous cancellation errors. +// +template +BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a, + T b, + T x, + T y, + const Lanczos&, + bool normalised, + const Policy& pol, + T prefix = 1, + const char* function = "boost::math::ibeta<%1%>(%1%, %1%, %1%)") +{ + BOOST_MATH_STD_USING + + if(!normalised) + { + // can we do better here? + return pow(x, a) * pow(y, b); + } + + T result; // LCOV_EXCL_LINE + + T c = a + b; + + // combine power terms with Lanczos approximation: + T gh = Lanczos::g() - 0.5f; + T agh = static_cast(a + gh); + T bgh = static_cast(b + gh); + T cgh = static_cast(c + gh); + if ((a < tools::min_value()) || (b < tools::min_value())) + result = 0; // denominator overflows in this case + else + result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result *= prefix; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + // combine with the leftover terms from the Lanczos approximation: + result *= sqrt(bgh / boost::math::constants::e()); + result *= sqrt(agh / cgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + + // l1 and l2 are the base of the exponents minus one: + T l1 = ((x * b - y * a) - y * gh) / agh; + T l2 = ((y * a - x * b) - x * gh) / bgh; + if((BOOST_MATH_GPU_SAFE_MIN(fabs(l1), fabs(l2)) < 0.2)) + { + // when the base of the exponent is very near 1 we get really + // gross errors unless extra care is taken: + if((l1 * l2 > 0) || (BOOST_MATH_GPU_SAFE_MIN(a, b) < 1)) + { + // + // This first branch handles the simple cases where either: + // + // * The two power terms both go in the same direction + // (towards zero or towards infinity). In this case if either + // term overflows or underflows, then the product of the two must + // do so also. + // *Alternatively if one exponent is less than one, then we + // can't productively use it to eliminate overflow or underflow + // from the other term. Problems with spurious overflow/underflow + // can't be ruled out in this case, but it is *very* unlikely + // since one of the power terms will evaluate to a number close to 1. + // + if(fabs(l1) < 0.1) + { + result *= exp(a * boost::math::log1p(l1, pol)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + result *= pow((x * cgh) / agh, a); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + if(fabs(l2) < 0.1) + { + result *= exp(b * boost::math::log1p(l2, pol)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + result *= pow((y * cgh) / bgh, b); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else if(BOOST_MATH_GPU_SAFE_MAX(fabs(l1), fabs(l2)) < 0.5) + { + // + // Both exponents are near one and both the exponents are + // greater than one and further these two + // power terms tend in opposite directions (one towards zero, + // the other towards infinity), so we have to combine the terms + // to avoid any risk of overflow or underflow. + // + // We do this by moving one power term inside the other, we have: + // + // (1 + l1)^a * (1 + l2)^b + // = ((1 + l1)*(1 + l2)^(b/a))^a + // = (1 + l1 + l3 + l1*l3)^a ; l3 = (1 + l2)^(b/a) - 1 + // = exp((b/a) * log(1 + l2)) - 1 + // + // The tricky bit is deciding which term to move inside :-) + // By preference we move the larger term inside, so that the + // size of the largest exponent is reduced. However, that can + // only be done as long as l3 (see above) is also small. + // + bool small_a = a < b; + T ratio = b / a; + if((small_a && (ratio * l2 < 0.1)) || (!small_a && (l1 / ratio > 0.1))) + { + T l3 = boost::math::expm1(ratio * boost::math::log1p(l2, pol), pol); + l3 = l1 + l3 + l3 * l1; + l3 = a * boost::math::log1p(l3, pol); + result *= exp(l3); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + T l3 = boost::math::expm1(boost::math::log1p(l1, pol) / ratio, pol); + l3 = l2 + l3 + l3 * l2; + l3 = b * boost::math::log1p(l3, pol); + result *= exp(l3); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else if(fabs(l1) < fabs(l2)) + { + // First base near 1 only: + T l = a * boost::math::log1p(l1, pol) + + b * log((y * cgh) / bgh); + if((l <= tools::log_min_value()) || (l >= tools::log_max_value())) + { + l += log(result); + if(l >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE we can probably never get here, probably! + result = exp(l); + } + else + result *= exp(l); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // Second base near 1 only: + T l = b * boost::math::log1p(l2, pol) + + a * log((x * cgh) / agh); + if((l <= tools::log_min_value()) || (l >= tools::log_max_value())) + { + l += log(result); + if(l >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE we can probably never get here, probably! + result = exp(l); + } + else + result *= exp(l); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else + { + // general case: + T b1 = (x * cgh) / agh; + T b2 = (y * cgh) / bgh; + l1 = a * log(b1); + l2 = b * log(b2); + BOOST_MATH_INSTRUMENT_VARIABLE(b1); + BOOST_MATH_INSTRUMENT_VARIABLE(b2); + BOOST_MATH_INSTRUMENT_VARIABLE(l1); + BOOST_MATH_INSTRUMENT_VARIABLE(l2); + if((l1 >= tools::log_max_value()) + || (l1 <= tools::log_min_value()) + || (l2 >= tools::log_max_value()) + || (l2 <= tools::log_min_value()) + ) + { + // Oops, under/overflow, sidestep if we can: + if(a < b) + { + T p1 = pow(b2, b / a); + T l3 = (b1 != 0) && (p1 != 0) ? (a * (log(b1) + log(p1))) : tools::max_value(); // arbitrary large value if the logs would fail! + if((l3 < tools::log_max_value()) + && (l3 > tools::log_min_value())) + { + result *= pow(p1 * b1, a); + } + else + { + l2 += l1 + log(result); + if(l2 >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE we can probably never get here, probably! + result = exp(l2); + } + } + else + { + // This protects against spurious overflow in a/b: + T p1 = (b1 < 1) && (b < 1) && (tools::max_value() * b < a) ? static_cast(0) : static_cast(pow(b1, a / b)); + T l3 = (p1 != 0) && (b2 != 0) ? (log(p1) + log(b2)) * b : tools::max_value(); // arbitrary large value if the logs would fail! + if((l3 < tools::log_max_value()) + && (l3 > tools::log_min_value())) + { + result *= pow(p1 * b2, b); + } + else if(result != 0) // we can elude the calculation below if we're already going to be zero + { + l2 += l1 + log(result); + if(l2 >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE we can probably never get here, probably! + result = exp(l2); + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // finally the normal case: + result *= pow(b1, a) * pow(b2, b); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + + if (0 == result) + { + if ((a > 1) && (x == 0)) + return result; // true zero LCOV_EXCL_LINE we can probably never get here + if ((b > 1) && (y == 0)) + return result; // true zero LCOV_EXCL_LINE we can probably never get here + return boost::math::policies::raise_underflow_error(function, nullptr, pol); + } + + return result; +} +// +// Compute the leading power terms in the incomplete Beta: +// +// (x^a)(y^b)/Beta(a,b) when normalised, and +// (x^a)(y^b) otherwise. +// +// Almost all of the error in the incomplete beta comes from this +// function: particularly when a and b are large. Computing large +// powers are *hard* though, and using logarithms just leads to +// horrendous cancellation errors. +// +// This version is generic, slow, and does not use the Lanczos approximation. +// +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +template +BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a, + T b, + T x, + T y, + const boost::math::lanczos::undefined_lanczos& l, + bool normalised, + const Policy& pol, + T prefix = 1, + const char* = "boost::math::ibeta<%1%>(%1%, %1%, %1%)") +{ + BOOST_MATH_STD_USING + + if(!normalised) + { + return prefix * pow(x, a) * pow(y, b); + } + + T c = a + b; + + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if (a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if (b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + + if ((shift_a == 0) && (shift_b == 0)) + { + T power1, power2; + bool need_logs = false; + if (a < b) + { + BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits::has_infinity) + { + power1 = pow((x * y * c * c) / (a * b), a); + power2 = pow((y * c) / b, b - a); + } + else + { + // We calculate these logs purely so we can check for overflow in the power functions + T l1 = log((x * y * c * c) / (a * b)); + T l2 = log((y * c) / b); + if ((l1 * a > tools::log_min_value()) && (l1 * a < tools::log_max_value()) && (l2 * (b - a) < tools::log_max_value()) && (l2 * (b - a) > tools::log_min_value())) + { + power1 = pow((x * y * c * c) / (a * b), a); + power2 = pow((y * c) / b, b - a); + } + else + { + need_logs = true; + } + } + } + else + { + BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits::has_infinity) + { + power1 = pow((x * y * c * c) / (a * b), b); + power2 = pow((x * c) / a, a - b); + } + else + { + // We calculate these logs purely so we can check for overflow in the power functions + T l1 = log((x * y * c * c) / (a * b)) * b; + T l2 = log((x * c) / a) * (a - b); + if ((l1 * a > tools::log_min_value()) && (l1 * a < tools::log_max_value()) && (l2 * (b - a) < tools::log_max_value()) && (l2 * (b - a) > tools::log_min_value())) + { + power1 = pow((x * y * c * c) / (a * b), b); + power2 = pow((x * c) / a, a - b); + } + else + need_logs = true; + } + } + BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits::has_infinity) + { + if (!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2)) + { + need_logs = true; + } + } + if (need_logs) + { + // + // We want: + // + // (xc / a)^a (yc / b)^b + // + // But we know that one or other term will over / underflow and combining the logs will be next to useless as that will cause significant cancellation. + // If we assume b > a and express z ^ b as(z ^ b / a) ^ a with z = (yc / b) then we can move one power term inside the other : + // + // ((xc / a) * (yc / b)^(b / a))^a + // + // However, we're not quite there yet, as the term being exponentiated is quite likely to be close to unity, so let: + // + // xc / a = 1 + (xb - ya) / a + // + // analogously let : + // + // 1 + p = (yc / b) ^ (b / a) = 1 + expm1((b / a) * log1p((ya - xb) / b)) + // + // so putting the two together we have : + // + // exp(a * log1p((xb - ya) / a + p + p(xb - ya) / a)) + // + // Analogously, when a > b we can just swap all the terms around. + // + // Finally, there are a few cases (x or y is unity) when the above logic can't be used + // or where there is no logarithmic cancellation and accuracy is better just using + // the regular formula: + // + T xc_a = x * c / a; + T yc_b = y * c / b; + if ((x == 1) || (y == 1) || (fabs(xc_a - 1) > 0.25) || (fabs(yc_b - 1) > 0.25)) + { + // The above logic fails, the result is almost certainly zero: + power1 = exp(log(xc_a) * a + log(yc_b) * b); + power2 = 1; + } + else if (b > a) + { + T p = boost::math::expm1((b / a) * boost::math::log1p((y * a - x * b) / b)); + power1 = exp(a * boost::math::log1p((x * b - y * a) / a + p * (x * c / a))); + power2 = 1; + } + else + { + T p = boost::math::expm1((a / b) * boost::math::log1p((x * b - y * a) / a)); + power1 = exp(b * boost::math::log1p((y * a - x * b) / b + p * (y * c / b))); + power2 = 1; + } + } + return prefix * power1 * power2 * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol)); + } + + T power1 = pow(x, a); + T power2 = pow(y, b); + T bet = beta_imp(a, b, l, pol); + + if(!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2) || !(boost::math::isnormal)(bet)) + { + int shift_c = shift_a + shift_b; + T result = ibeta_power_terms(T(a + shift_a), T(b + shift_b), x, y, l, normalised, pol, prefix); + if ((boost::math::isnormal)(result)) + { + for (int i = 0; i < shift_c; ++i) + { + result /= c + i; + if (i < shift_a) + { + result *= a + i; + result /= x; + } + if (i < shift_b) + { + result *= b + i; + result /= y; + } + } + return prefix * result; + } + else + { + T log_result = log(x) * a + log(y) * b + log(prefix); + if ((boost::math::isnormal)(bet)) + log_result -= log(bet); + else + log_result += boost::math::lgamma(c, pol) - boost::math::lgamma(a, pol) - boost::math::lgamma(b, pol); + return exp(log_result); + } + } + return prefix * power1 * (power2 / bet); +} + +#endif +// +// Series approximation to the incomplete beta: +// +template +struct ibeta_series_t +{ + typedef T result_type; + BOOST_MATH_GPU_ENABLED ibeta_series_t(T a_, T b_, T x_, T mult) : result(mult), x(x_), apn(a_), poch(1-b_), n(1) {} + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = result / apn; + apn += 1; + result *= poch * x / n; + ++n; + poch += 1; + return r; + } +private: + T result, x, apn, poch; + int n; +}; + +template +BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool normalised, T* p_derivative, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T result; + + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(normalised) + { + T c = a + b; + + // incomplete beta power term, combined with the Lanczos approximation: + T agh = static_cast(a + Lanczos::g() - 0.5f); + T bgh = static_cast(b + Lanczos::g() - 0.5f); + T cgh = static_cast(c + Lanczos::g() - 0.5f); + if ((a < tools::min_value()) || (b < tools::min_value())) + result = 0; // denorms cause overflow in the Lanzos series, result will be zero anyway + else + { + T l1 = Lanczos::lanczos_sum_expG_scaled(c); + T l2 = Lanczos::lanczos_sum_expG_scaled(a); + T l3 = Lanczos::lanczos_sum_expG_scaled(b); + if ((l2 > 1) && (l3 > 1) && (tools::max_value() / l2 < l3)) + result = (l1 / l2) / l3; + else + result = l1 / (l2 * l3); + } + + if (!(boost::math::isfinite)(result)) + result = 0; // LCOV_EXCL_LINE we can probably never get here, covered already above? + + T l1 = log(cgh / bgh) * (b - 0.5f); + T l2 = log(x * cgh / agh) * a; + // + // Check for over/underflow in the power terms: + // + if((l1 > tools::log_min_value()) + && (l1 < tools::log_max_value()) + && (l2 > tools::log_min_value()) + && (l2 < tools::log_max_value())) + { + if(a * b < bgh * 10) + result *= exp((b - 0.5f) * boost::math::log1p(a / bgh, pol)); + else + result *= pow(cgh / bgh, T(b - T(0.5))); + result *= pow(x * cgh / agh, a); + result *= sqrt(agh / boost::math::constants::e()); + + if(p_derivative) + { + *p_derivative = result * pow(y, b); + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + } + else + { + // + // Oh dear, we need logs, and this *will* cancel: + // + if (result != 0) // elude calculation when result will be zero. + { + result = log(result) + l1 + l2 + (log(agh) - 1) / 2; + if (p_derivative) + *p_derivative = exp(result + b * log(y)); + result = exp(result); + } + } + } + else + { + // Non-normalised, just compute the power: + result = pow(x, a); + } + if(result < tools::min_value()) + return s0; // Safeguard: series can't cope with denorms. + ibeta_series_t s(a, b, x, result); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, s0); + policies::check_series_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (with lanczos)", max_iter, pol); + return result; +} +// +// Incomplete Beta series again, this time without Lanczos support: +// +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +template +BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const boost::math::lanczos::undefined_lanczos& l, bool normalised, T* p_derivative, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T result; + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(normalised) + { + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if (a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if (b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + + T c = a + b; + + if ((shift_a == 0) && (shift_b == 0)) + { + result = pow(x * c / a, a) * pow(c / b, b) * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol)); + } + else if ((a < 1) && (b > 1)) + result = pow(x, a) / (boost::math::tgamma(a, pol) * boost::math::tgamma_delta_ratio(b, a, pol)); + else + { + T power = pow(x, a); + T bet = beta_imp(a, b, l, pol); + if (!(boost::math::isnormal)(power) || !(boost::math::isnormal)(bet)) + { + result = exp(a * log(x) + boost::math::lgamma(c, pol) - boost::math::lgamma(a, pol) - boost::math::lgamma(b, pol)); + } + else + result = power / bet; + } + if(p_derivative) + { + *p_derivative = result * pow(y, b); + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + } + else + { + // Non-normalised, just compute the power: + result = pow(x, a); + } + if(result < tools::min_value()) + return s0; // Safeguard: series can't cope with denorms. + ibeta_series_t s(a, b, x, result); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, s0); + policies::check_series_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (without lanczos)", max_iter, pol); + return result; +} +#endif +// +// Continued fraction for the incomplete beta: +// +template +struct ibeta_fraction2_t +{ + typedef boost::math::pair result_type; + + BOOST_MATH_GPU_ENABLED ibeta_fraction2_t(T a_, T b_, T x_, T y_) : a(a_), b(b_), x(x_), y(y_), m(0) {} + + BOOST_MATH_GPU_ENABLED result_type operator()() + { + T denom = (a + 2 * m - 1); + T aN = (m * (a + m - 1) / denom) * ((a + b + m - 1) / denom) * (b - m) * x * x; + + T bN = static_cast(m); + bN += (m * (b - m) * x) / (a + 2*m - 1); + bN += ((a + m) * (a * y - b * x + 1 + m *(2 - x))) / (a + 2*m + 1); + + ++m; + + return boost::math::make_pair(aN, bN); + } + +private: + T a, b, x, y; + int m; +}; +// +// Evaluate the incomplete beta via the continued fraction representation: +// +template +BOOST_MATH_GPU_ENABLED inline T ibeta_fraction2(T a, T b, T x, T y, const Policy& pol, bool normalised, T* p_derivative) +{ + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING + T result = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol); + if(p_derivative) + { + *p_derivative = result; + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + if(result == 0) + return result; + + ibeta_fraction2_t f(a, b, x, y); + boost::math::uintmax_t max_terms = boost::math::policies::get_max_series_iterations(); + T fract = boost::math::tools::continued_fraction_b(f, boost::math::policies::get_epsilon(), max_terms); + boost::math::policies::check_series_iterations("boost::math::ibeta", max_terms, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result / fract; +} +// +// Computes the difference between ibeta(a,b,x) and ibeta(a+k,b,x): +// +template +BOOST_MATH_GPU_ENABLED T ibeta_a_step(T a, T b, T x, T y, int k, const Policy& pol, bool normalised, T* p_derivative) +{ + typedef typename lanczos::lanczos::type lanczos_type; + + BOOST_MATH_INSTRUMENT_VARIABLE(k); + + T prefix = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol); + if(p_derivative) + { + *p_derivative = prefix; + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + prefix /= a; + if(prefix == 0) + return prefix; + T sum = 1; + T term = 1; + // series summation from 0 to k-1: + for(int i = 0; i < k-1; ++i) + { + term *= (a+b+i) * x / (a+i+1); + sum += term; + } + prefix *= sum; + + return prefix; +} + +// +// This function is only needed for the non-regular incomplete beta, +// it computes the delta in: +// beta(a,b,x) = prefix + delta * beta(a+k,b,x) +// it is currently only called for small k. +// +template +BOOST_MATH_GPU_ENABLED inline T rising_factorial_ratio(T a, T b, int k) +{ + // calculate: + // (a)(a+1)(a+2)...(a+k-1) + // _______________________ + // (b)(b+1)(b+2)...(b+k-1) + + // This is only called with small k, for large k + // it is grossly inefficient, do not use outside it's + // intended purpose!!! + BOOST_MATH_INSTRUMENT_VARIABLE(k); + BOOST_MATH_ASSERT(k > 0); + + T result = 1; + for(int i = 0; i < k; ++i) + result *= (a+i) / (b+i); + return result; +} +// +// Routine for a > 15, b < 1 +// +// Begin by figuring out how large our table of Pn's should be, +// quoted accuracies are "guesstimates" based on empirical observation. +// Note that the table size should never exceed the size of our +// tables of factorials. +// +template +struct Pn_size +{ + // This is likely to be enough for ~35-50 digit accuracy + // but it's hard to quantify exactly: + #ifndef BOOST_MATH_HAS_NVRTC + static constexpr unsigned value = + ::boost::math::max_factorial::value >= 100 ? 50 + : ::boost::math::max_factorial::value >= ::boost::math::max_factorial::value ? 30 + : ::boost::math::max_factorial::value >= ::boost::math::max_factorial::value ? 15 : 1; + static_assert(::boost::math::max_factorial::value >= ::boost::math::max_factorial::value, "Type does not provide for 35-50 digits of accuracy."); + #else + static constexpr unsigned value = 0; // Will never be called + #endif +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 15; // ~8-15 digit accuracy +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + static_assert(::boost::math::max_factorial::value >= 30, "Type does not provide for 8-15 digits of accuracy."); +#endif +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 30; // 16-20 digit accuracy +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + static_assert(::boost::math::max_factorial::value >= 60, "Type does not provide for 16-20 digits of accuracy."); +#endif +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 50; // ~35-50 digit accuracy +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + static_assert(::boost::math::max_factorial::value >= 100, "Type does not provide for ~35-50 digits of accuracy"); +#endif +}; + +template +BOOST_MATH_GPU_ENABLED T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Policy& pol, bool normalised) +{ + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING + // + // This is DiDonato and Morris's BGRAT routine, see Eq's 9 through 9.6. + // + // Some values we'll need later, these are Eq 9.1: + // + T bm1 = b - 1; + T t = a + bm1 / 2; + T lx, u; // LCOV_EXCL_LINE + if(y < 0.35) + lx = boost::math::log1p(-y, pol); + else + lx = log(x); + u = -t * lx; + // and from from 9.2: + T prefix; // LCOV_EXCL_LINE + T h = regularised_gamma_prefix(b, u, pol, lanczos_type()); + if(h <= tools::min_value()) + return s0; + if(normalised) + { + prefix = h / boost::math::tgamma_delta_ratio(a, b, pol); + prefix /= pow(t, b); + } + else + { + prefix = full_igamma_prefix(b, u, pol) / pow(t, b); + } + prefix *= mult; + // + // now we need the quantity Pn, unfortunately this is computed + // recursively, and requires a full history of all the previous values + // so no choice but to declare a big table and hope it's big enough... + // + T p[ ::boost::math::detail::Pn_size::value ] = { 1 }; // see 9.3. + // + // Now an initial value for J, see 9.6: + // + T j = boost::math::gamma_q(b, u, pol) / h; + // + // Now we can start to pull things together and evaluate the sum in Eq 9: + // + T sum = s0 + prefix * j; // Value at N = 0 + // some variables we'll need: + unsigned tnp1 = 1; // 2*N+1 + T lx2 = lx / 2; + lx2 *= lx2; + T lxp = 1; + T t4 = 4 * t * t; + T b2n = b; + + for(unsigned n = 1; n < sizeof(p)/sizeof(p[0]); ++n) + { + /* + // debugging code, enable this if you want to determine whether + // the table of Pn's is large enough... + // + static int max_count = 2; + if(n > max_count) + { + max_count = n; + std::cerr << "Max iterations in BGRAT was " << n << std::endl; + } + */ + // + // begin by evaluating the next Pn from Eq 9.4: + // + tnp1 += 2; + p[n] = 0; + T mbn = b - n; + unsigned tmp1 = 3; + for(unsigned m = 1; m < n; ++m) + { + mbn = m * b - n; + p[n] += mbn * p[n-m] / boost::math::unchecked_factorial(tmp1); + tmp1 += 2; + } + p[n] /= n; + p[n] += bm1 / boost::math::unchecked_factorial(tnp1); + // + // Now we want Jn from Jn-1 using Eq 9.6: + // + j = (b2n * (b2n + 1) * j + (u + b2n + 1) * lxp) / t4; + lxp *= lx2; + b2n += 2; + // + // pull it together with Eq 9: + // + T r = prefix * p[n] * j; + sum += r; + // r is always small: + BOOST_MATH_ASSERT(tools::max_value() * tools::epsilon() > fabs(r)); + if(fabs(r / tools::epsilon()) < fabs(sum)) + break; + } + return sum; +} // template T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Lanczos& l, bool normalised) + +// +// For integer arguments we can relate the incomplete beta to the +// complement of the binomial distribution cdf and use this finite sum. +// +template +BOOST_MATH_GPU_ENABLED T binomial_ccdf(T n, T k, T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + T result = pow(x, n); + + if(result > tools::min_value()) + { + T term = result; + for(unsigned i = itrunc(T(n - 1)); i > k; --i) + { + term *= ((i + 1) * y) / ((n - i) * x); + result += term; + } + } + else + { + // First term underflows so we need to start at the mode of the + // distribution and work outwards: + int start = itrunc(n * x); + if(start <= k + 1) + start = itrunc(k + 2); + result = static_cast(pow(x, T(start)) * pow(y, n - T(start)) * boost::math::binomial_coefficient(itrunc(n), itrunc(start), pol)); + if(result == 0) + { + // OK, starting slightly above the mode didn't work, + // we'll have to sum the terms the old fashioned way. + // Very hard to get here, possibly only when exponent + // range is very limited (as with type float): + // LCOV_EXCL_START + for(unsigned i = start - 1; i > k; --i) + { + result += static_cast(pow(x, static_cast(i)) * pow(y, n - i) * boost::math::binomial_coefficient(itrunc(n), itrunc(i), pol)); + } + // LCOV_EXCL_STOP + } + else + { + T term = result; + T start_term = result; + for(unsigned i = start - 1; i > k; --i) + { + term *= ((i + 1) * y) / ((n - i) * x); + result += term; + } + term = start_term; + for(unsigned i = start + 1; i <= n; ++i) + { + term *= (n - i + 1) * x / (i * y); + result += term; + } + } + } + + return result; +} + +template +BOOST_MATH_GPU_ENABLED T ibeta_large_ab(T a, T b, T x, T y, bool invert, bool normalised, const Policy& pol) +{ + // + // Large arguments, symetric case, see https://dlmf.nist.gov/8.18 + // + BOOST_MATH_STD_USING + + T x0 = a / (a + b); + T y0 = b / (a + b); + T nu = x0 * log(x / x0) + y0 * log(y / y0); + // + // Above compution is unstable, force nu to zero if + // something went wrong: + // + if ((nu > 0) || (x == x0) || (y == y0)) + nu = 0; + nu = sqrt(-2 * nu); + // + // As per https://dlmf.nist.gov/8.18#E10 we need to make sure we have the correct root: + // + if ((nu != 0) && (nu / (x - x0) < 0)) + nu = -nu; + // + // The correction term in https://dlmf.nist.gov/8.18#E9 is badly unstable, and often + // makes the compution worse not better, we exclude it for now: + /* + T c0 = 0; + + if (nu != 0) + { + c0 = 1 / nu; + T lim = fabs(10 * tools::epsilon() * c0); + c0 -= sqrt(x0 * y0) / (x - x0); + if(fabs(c0) < lim) + c0 = (1 - 2 * x0) / (3 * sqrt(x0 * y0)); + else + c0 *= exp(a * log(x / x0) + b * log(y / y0)); + c0 /= sqrt(constants::two_pi() * (a + b)); + } + else + { + c0 = (1 - 2 * x0) / (3 * sqrt(x0 * y0)); + c0 /= sqrt(constants::two_pi() * (a + b)); + } + */ + T mul = 1; + if (!normalised) + mul = boost::math::beta(a, b, pol); + + return mul * ((invert ? (1 + boost::math::erf(-nu * sqrt((a + b) / 2), pol)) / 2 : boost::math::erfc(-nu * sqrt((a + b) / 2), pol) / 2)); +} + + + +// +// The incomplete beta function implementation: +// This is just a big bunch of spaghetti code to divide up the +// input range and select the right implementation method for +// each domain: +// + +template +BOOST_MATH_GPU_ENABLED T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised, T* p_derivative) +{ + constexpr auto function = "boost::math::ibeta<%1%>(%1%, %1%, %1%)"; + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING // for ADL of std math functions. + + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(inv); + BOOST_MATH_INSTRUMENT_VARIABLE(normalised); + + bool invert = inv; + T fract; + T y = 1 - x; + + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(!(boost::math::isfinite)(a)) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be finite (got a=%1%).", a, pol); + if(!(boost::math::isfinite)(b)) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be finite (got b=%1%).", b, pol); + if (!(0 <= x && x <= 1)) + return policies::raise_domain_error(function, "The argument x to the incomplete beta function must be in [0,1] (got x=%1%).", x, pol); + + if(p_derivative) + *p_derivative = -1; // value not set. + + if(normalised) + { + if(a < 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be >= zero (got a=%1%).", a, pol); + if(b < 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be >= zero (got b=%1%).", b, pol); + // extend to a few very special cases: + if(a == 0) + { + if(b == 0) + return policies::raise_domain_error(function, "The arguments a and b to the incomplete beta function cannot both be zero, with x=%1%.", x, pol); + if(b > 0) + return static_cast(inv ? 0 : 1); + } + else if(b == 0) + { + if(a > 0) + return static_cast(inv ? 1 : 0); + } + } + else + { + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol); + } + + if(x == 0) + { + if(p_derivative) + { + *p_derivative = (a == 1) ? (T)1 : (a < 1) ? T(tools::max_value() / 2) : T(tools::min_value() * 2); + } + return (invert ? (normalised ? T(1) : boost::math::beta(a, b, pol)) : T(0)); + } + if(x == 1) + { + if(p_derivative) + { + *p_derivative = (b == 1) ? T(1) : (b < 1) ? T(tools::max_value() / 2) : T(tools::min_value() * 2); + } + return (invert == 0 ? (normalised ? 1 : boost::math::beta(a, b, pol)) : 0); + } + if((a == 0.5f) && (b == 0.5f)) + { + // We have an arcsine distribution: + if(p_derivative) + { + *p_derivative = 1 / (constants::pi() * sqrt(y * x)); + } + T p = invert ? asin(sqrt(y)) / constants::half_pi() : asin(sqrt(x)) / constants::half_pi(); + if(!normalised) + p *= constants::pi(); + return p; + } + if(a == 1) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + } + if(b == 1) + { + // + // Special case see: http://functions.wolfram.com/GammaBetaErf/BetaRegularized/03/01/01/ + // + if(a == 1) + { + if(p_derivative) + *p_derivative = 1; + return invert ? y : x; + } + + if(p_derivative) + { + *p_derivative = a * pow(x, a - 1); + } + T p; // LCOV_EXCL_LINE + if(y < 0.5) + p = invert ? T(-boost::math::expm1(a * boost::math::log1p(-y, pol), pol)) : T(exp(a * boost::math::log1p(-y, pol))); + else + p = invert ? T(-boost::math::powm1(x, a, pol)) : T(pow(x, a)); + if(!normalised) + p /= a; + return p; + } + + if(BOOST_MATH_GPU_SAFE_MIN(a, b) <= 1) + { + if(x > 0.5) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + BOOST_MATH_INSTRUMENT_VARIABLE(invert); + } + if(BOOST_MATH_GPU_SAFE_MAX(a, b) <= 1) + { + // Both a,b < 1: + if((a >= BOOST_MATH_GPU_SAFE_MIN(T(0.2), b)) || (pow(x, a) <= 0.9)) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + if(y >= 0.3) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + // Sidestep on a, and then use the series representation: + T prefix; // LCOV_EXCL_LINE + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+b), a, 20); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative); + if(!invert) + { + fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract -= (normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + } + } + else + { + // One of a, b < 1 only: + if((b <= 1) || ((x < 0.1) && (pow(b * x, a) <= 0.7))) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + + if(y >= 0.3) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else if(a >= 15) + { + if(!invert) + { + fract = beta_small_b_large_a_series(a, b, x, y, T(0), T(1), pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(a, b, x, y, fract, T(1), pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + // Sidestep to improve errors: + T prefix; // LCOV_EXCL_LINE + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+b), a, 20); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + if(!invert) + { + fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract -= (normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + } + } + } + else + { + // Both a,b >= 1: + T lambda; // LCOV_EXCL_LINE + if(a < b) + { + lambda = a - (a + b) * x; + } + else + { + lambda = (a + b) * y - b; + } + if(lambda < 0) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + BOOST_MATH_INSTRUMENT_VARIABLE(invert); + } + + if(b < 40) + { + if((floor(a) == a) && (floor(b) == b) && (a < static_cast((boost::math::numeric_limits::max)() - 100)) && (y != 1)) + { + // relate to the binomial distribution and use a finite sum: + T k = a - 1; + T n = b + k; + fract = binomial_ccdf(n, k, x, y, pol); + if(!normalised) + fract *= boost::math::beta(a, b, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else if(b * x <= 0.7) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else if(a > 15) + { + // sidestep so we can use the series representation: + int n = itrunc(T(floor(b)), pol); + if(n == b) + --n; + T bbar = b - n; + T prefix; // LCOV_EXCL_LINE + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+bbar), bbar, n); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast(nullptr)); + fract = beta_small_b_large_a_series(a, bbar, x, y, fract, T(1), pol, normalised); + fract /= prefix; + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else if(normalised) + { + // The formula here for the non-normalised case is tricky to figure + // out (for me!!), and requires two pochhammer calculations rather + // than one, so leave it for now and only use this in the normalized case.... + int n = itrunc(T(floor(b)), pol); + T bbar = b - n; + if(bbar <= 0) + { + --n; + bbar += 1; + } + fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast(nullptr)); + fract += ibeta_a_step(a, bbar, x, y, 20, pol, normalised, static_cast(nullptr)); + if(invert) + fract -= 1; // Note this line would need changing if we ever enable this branch in non-normalized case + fract = beta_small_b_large_a_series(T(a+20), bbar, x, y, fract, T(1), pol, normalised); + if(invert) + { + fract = -fract; + invert = false; + } + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + // a and b both large: + bool use_asym = false; + T ma = BOOST_MATH_GPU_SAFE_MAX(a, b); + T xa = ma == a ? x : y; + T saddle = ma / (a + b); + T powers = 0; + if ((ma > 1e-5f / tools::epsilon()) && (ma / BOOST_MATH_GPU_SAFE_MIN(a, b) < (xa < saddle ? 2 : 15))) + { + if (a == b) + use_asym = true; + else + { + powers = exp(log(x / (a / (a + b))) * a + log(y / (b / (a + b))) * b); + if (powers < tools::epsilon()) + use_asym = true; + } + } + if(use_asym) + { + fract = ibeta_large_ab(a, b, x, y, invert, normalised, pol); + if (fract * tools::epsilon() < powers) + { + // Erf approximation failed, correction term is too large, fall back: + fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative); + } + else + invert = false; + } + else + fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative); + + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + if(p_derivative) + { + if(*p_derivative < 0) + { + *p_derivative = ibeta_power_terms(a, b, x, y, lanczos_type(), true, pol); + } + T div = y * x; + + if(*p_derivative != 0) + { + if((tools::max_value() * div < *p_derivative)) + { + // overflow, return an arbitrarily large value: + *p_derivative = tools::max_value() / 2; // LCOV_EXCL_LINE Probably can only get here with denormalized x. + } + else + { + *p_derivative /= div; + } + } + } + return invert ? (normalised ? 1 : boost::math::beta(a, b, pol)) - fract : fract; +} // template T ibeta_imp(T a, T b, T x, const Lanczos& l, bool inv, bool normalised) + +template +BOOST_MATH_GPU_ENABLED inline T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised) +{ + return ibeta_imp(a, b, x, pol, inv, normalised, static_cast(nullptr)); +} + +template +BOOST_MATH_GPU_ENABLED T ibeta_derivative_imp(T a, T b, T x, const Policy& pol) +{ + constexpr auto function = "ibeta_derivative<%1%>(%1%,%1%,%1%)"; + // + // start with the usual error checks: + // + if (!(boost::math::isfinite)(a)) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be finite (got a=%1%).", a, pol); + if (!(boost::math::isfinite)(b)) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be finite (got b=%1%).", b, pol); + if (!(0 <= x && x <= 1)) + return policies::raise_domain_error(function, "The argument x to the incomplete beta function must be in [0,1] (got x=%1%).", x, pol); + + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol); + // + // Now the corner cases: + // + if(x == 0) + { + return (a > 1) ? 0 : + (a == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error(function, nullptr, pol); + } + else if(x == 1) + { + return (b > 1) ? 0 : + (b == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error(function, nullptr, pol); + } + // + // Now the regular cases: + // + typedef typename lanczos::lanczos::type lanczos_type; + T y = (1 - x) * x; + T f1; + if (!(boost::math::isinf)(1 / y)) + { + f1 = ibeta_power_terms(a, b, x, 1 - x, lanczos_type(), true, pol, 1 / y, function); + } + else + { + return (a > 1) ? 0 : (a == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error(function, nullptr, pol); + } + + return f1; +} +// +// Some forwarding functions that disambiguate the third argument type: +// +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + beta(RT1 a, RT2 b, const Policy&, const boost::math::true_type*) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::beta_imp(static_cast(a), static_cast(b), evaluation_type(), forwarding_policy()), "boost::math::beta<%1%>(%1%,%1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + beta(RT1 a, RT2 b, RT3 x, const boost::math::false_type*) +{ + return boost::math::beta(a, b, x, policies::policy<>()); +} +} // namespace detail + +// +// The actual function entry-points now follow, these just figure out +// which Lanczos approximation to use +// and forward to the implementation functions: +// +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + beta(RT1 a, RT2 b, A arg) +{ + using tag = typename policies::is_policy::type; + using ReturnType = tools::promote_args_t; + return static_cast(boost::math::detail::beta(a, b, arg, static_cast(nullptr))); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + beta(RT1 a, RT2 b) +{ + return boost::math::beta(a, b, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + beta(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), false, false), "boost::math::beta<%1%>(%1%,%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), true, false), "boost::math::betac<%1%>(%1%,%1%,%1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x) +{ + return boost::math::betac(a, b, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), false, true), "boost::math::ibeta<%1%>(%1%,%1%,%1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibeta(a, b, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), true, true), "boost::math::ibetac<%1%>(%1%,%1%,%1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibetac(a, b, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_derivative_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy()), "boost::math::ibeta_derivative<%1%>(%1%,%1%,%1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibeta_derivative(a, b, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#include +#include + +#endif // BOOST_MATH_SPECIAL_BETA_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/binomial.hpp b/third-party/boost-math/include/boost/math/special_functions/binomial.hpp new file mode 100644 index 0000000000000..3c49ff30d542c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/binomial.hpp @@ -0,0 +1,87 @@ +// Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SF_BINOMIAL_HPP +#define BOOST_MATH_SF_BINOMIAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +template +BOOST_MATH_GPU_ENABLED T binomial_coefficient(unsigned n, unsigned k, const Policy& pol) +{ + static_assert(!boost::math::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::binomial_coefficient<%1%>(unsigned, unsigned)"; + if(k > n) + return policies::raise_domain_error(function, "The binomial coefficient is undefined for k > n, but got k = %1%.", static_cast(k), pol); + T result; // LCOV_EXCL_LINE + if((k == 0) || (k == n)) + return static_cast(1); + if((k == 1) || (k == n-1)) + return static_cast(n); + + if(n <= max_factorial::value) + { + // Use fast table lookup: + result = unchecked_factorial(n); + result /= unchecked_factorial(n-k); + result /= unchecked_factorial(k); + } + else + { + // Use the beta function: + if(k < n - k) + result = static_cast(k * boost::math::beta(static_cast(k), static_cast(n-k+1), pol)); + else + result = static_cast((n - k) * boost::math::beta(static_cast(k+1), static_cast(n-k), pol)); + if(result == 0) + return policies::raise_overflow_error(function, nullptr, pol); + result = 1 / result; + } + // convert to nearest integer: + return ceil(result - 0.5f); +} +// +// Type float can only store the first 35 factorials, in order to +// increase the chance that we can use a table driven implementation +// we'll promote to double: +// +template <> +BOOST_MATH_GPU_ENABLED inline float binomial_coefficient >(unsigned n, unsigned k, const policies::policy<>&) +{ + typedef policies::normalise< + policies::policy<>, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(binomial_coefficient(n, k, forwarding_policy()), "boost::math::binomial_coefficient<%1%>(unsigned,unsigned)"); +} + +template +BOOST_MATH_GPU_ENABLED inline T binomial_coefficient(unsigned n, unsigned k) +{ + return binomial_coefficient(n, k, policies::policy<>()); +} + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_SF_BINOMIAL_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/cardinal_b_spline.hpp b/third-party/boost-math/include/boost/math/special_functions/cardinal_b_spline.hpp new file mode 100644 index 0000000000000..dfb4cf835d608 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/cardinal_b_spline.hpp @@ -0,0 +1,218 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_SPECIAL_CARDINAL_B_SPLINE_HPP +#define BOOST_MATH_SPECIAL_CARDINAL_B_SPLINE_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + + template + inline Real B1(Real x) + { + if (x < 0) + { + return B1(-x); + } + if (x < Real(1)) + { + return 1 - x; + } + return Real(0); + } +} + +template +Real cardinal_b_spline(Real x) { + static_assert(!std::is_integral::value, "Does not work with integral types."); + + if (x < 0) { + // All B-splines are even functions: + return cardinal_b_spline(-x); + } + + if (n==0) + { + if (x < Real(1)/Real(2)) { + return Real(1); + } + else if (x == Real(1)/Real(2)) { + return Real(1)/Real(2); + } + else { + return Real(0); + } + } + + if (n==1) + { + return detail::B1(x); + } + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Fill v with values of B1: + // At most two of these terms are nonzero, and at least 1. + // There is only one non-zero term when n is odd and x = 0. + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[0]; +} + + +template +Real cardinal_b_spline_prime(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integer types."); + + if (x < 0) + { + // All B-splines are even functions, so derivatives are odd: + return -cardinal_b_spline_prime(-x); + } + + + if (n==0) + { + // Kinda crazy but you get what you ask for! + if (x == Real(1)/Real(2)) + { + return std::numeric_limits::infinity(); + } + else + { + return Real(0); + } + } + + if (n==1) + { + if (x==0) + { + return Real(0); + } + if (x==1) + { + return -Real(1)/Real(2); + } + return Real(-1); + } + + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Now we want to evaluate B_{n}(x), but stop at the second to last step and collect B_{n-1}(x+1/2) and B_{n-1}(x-1/2): + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n - 1; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[1] - v[0]; +} + + +template +Real cardinal_b_spline_double_prime(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integer types."); + static_assert(n >= 3, "n>=3 for second derivatives of cardinal B-splines is required."); + + if (x < 0) + { + // All B-splines are even functions, so second derivatives are even: + return cardinal_b_spline_double_prime(-x); + } + + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Now we want to evaluate B_{n}(x), but stop at the second to last step and collect B_{n-1}(x+1/2) and B_{n-1}(x-1/2): + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n - 2; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[2] - 2*v[1] + v[0]; +} + + +template +Real forward_cardinal_b_spline(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integral types."); + return cardinal_b_spline(x - (n+1)/Real(2)); +} + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/cbrt.hpp b/third-party/boost-math/include/boost/math/special_functions/cbrt.hpp new file mode 100644 index 0000000000000..7fdf78d0147bf --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/cbrt.hpp @@ -0,0 +1,215 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SF_CBRT_HPP +#define BOOST_MATH_SF_CBRT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail +{ + +struct big_int_type +{ + operator std::uintmax_t() const; +}; + +template +struct largest_cbrt_int_type +{ + using type = typename std::conditional< + std::is_convertible::value, + std::uintmax_t, + unsigned int + >::type; +}; + +template +BOOST_MATH_GPU_ENABLED T cbrt_imp(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // cbrt approximation for z in the range [0.5,1] + // It's hard to say what number of terms gives the optimum + // trade off between precision and performance, this seems + // to be about the best for double precision. + // + // Maximum Deviation Found: 1.231e-006 + // Expected Error Term: -1.231e-006 + // Maximum Relative Change in Control Points: 5.982e-004 + // + BOOST_MATH_STATIC const T P[] = { + static_cast(0.37568269008611818), + static_cast(1.3304968705558024), + static_cast(-1.4897101632445036), + static_cast(1.2875573098219835), + static_cast(-0.6398703759826468), + static_cast(0.13584489959258635), + }; + BOOST_MATH_STATIC const T correction[] = { + static_cast(0.62996052494743658238360530363911), // 2^-2/3 + static_cast(0.79370052598409973737585281963615), // 2^-1/3 + static_cast(1), + static_cast(1.2599210498948731647672106072782), // 2^1/3 + static_cast(1.5874010519681994747517056392723), // 2^2/3 + }; + if((boost::math::isinf)(z) || (z == 0)) + return z; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error("boost::math::cbrt<%1%>(%1%)", "Argument to function must be finite but got %1%.", z, pol); + } + + int i_exp, sign(1); + if(z < 0) + { + z = -z; + sign = -sign; + } + + T guess = frexp(z, &i_exp); + int original_i_exp = i_exp; // save for later + guess = tools::evaluate_polynomial(P, guess); + int i_exp3 = i_exp / 3; + + using shift_type = typename largest_cbrt_int_type::type; + + static_assert( ::std::numeric_limits::radix == 2, "The radix of the type to shift to must be 2."); + + if(abs(i_exp3) < std::numeric_limits::digits) + { + if(i_exp3 > 0) + guess *= shift_type(1u) << i_exp3; + else + guess /= shift_type(1u) << -i_exp3; + } + else + { + guess = ldexp(guess, i_exp3); + } + i_exp %= 3; + guess *= correction[i_exp + 2]; + // + // Now inline Halley iteration. + // We do this here rather than calling tools::halley_iterate since we can + // simplify the expressions algebraically, and don't need most of the error + // checking of the boilerplate version as we know in advance that the function + // is well behaved... + // + using prec = typename policies::precision::type; + constexpr auto prec3 = prec::value / 3; + constexpr auto new_prec = prec3 + 3; + using new_policy = typename policies::normalise>::type; + // + // Epsilon calculation uses compile time arithmetic when it's available for type T, + // otherwise uses ldexp to calculate at runtime: + // + T eps = (new_prec > 3) ? policies::get_epsilon() : ldexp(T(1), -2 - tools::digits() / 3); + T diff; + + if(original_i_exp < std::numeric_limits::max_exponent - 3) + { + // + // Safe from overflow, use the fast method: + // + do + { + T g3 = guess * guess * guess; + diff = (g3 + z + z) / (g3 + g3 + z); + guess *= diff; + } + while(fabs(1 - diff) > eps); + } + else + { + // + // Either we're ready to overflow, or we can't tell because numeric_limits isn't + // available for type T: + // + do + { + T g2 = guess * guess; + diff = (g2 - z / guess) / (2 * guess + z / g2); + guess -= diff; + } + while((guess * eps) < fabs(diff)); + } + + return sign * guess; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type cbrt(T z, const Policy& pol) +{ + using result_type = typename tools::promote_args::type; + using value_type = typename policies::evaluation::type; + return static_cast(detail::cbrt_imp(value_type(z), pol)); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type cbrt(T z) +{ + return cbrt(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#else // Special NVRTC handling + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED double cbrt(T x) +{ + return ::cbrt(x); +} + +BOOST_MATH_GPU_ENABLED inline float cbrt(float x) +{ + return ::cbrtf(x); +} + +template +BOOST_MATH_GPU_ENABLED double cbrt(T x, const Policy&) +{ + return ::cbrt(x); +} + +template +BOOST_MATH_GPU_ENABLED float cbrt(float x, const Policy&) +{ + return ::cbrtf(x); +} + +} // namespace math +} // namespace boost + +#endif // NVRTC + +#endif // BOOST_MATH_SF_CBRT_HPP + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/chebyshev.hpp b/third-party/boost-math/include/boost/math/special_functions/chebyshev.hpp new file mode 100644 index 0000000000000..df8570821f4c3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/chebyshev.hpp @@ -0,0 +1,314 @@ +// (C) Copyright Nick Thompson 2017. +// 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) + +#ifndef BOOST_MATH_SPECIAL_CHEBYSHEV_HPP +#define BOOST_MATH_SPECIAL_CHEBYSHEV_HPP +#include +#include +#include +#include +#include +#include +#include + +#if (__cplusplus > 201103) || (defined(_CPPLIB_VER) && (_CPPLIB_VER >= 610)) +# define BOOST_MATH_CHEB_USE_STD_ACOSH +#endif + +#ifndef BOOST_MATH_CHEB_USE_STD_ACOSH +# include +#endif + +namespace boost { namespace math { + +template +inline tools::promote_args_t chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1) +{ + return 2*x*Tn - Tn_1; +} + +namespace detail { + +// https://stackoverflow.com/questions/5625431/efficient-way-to-compute-pq-exponentiation-where-q-is-an-integer +template ::value, bool>::type = true> +T expt(T p, unsigned q) +{ + T r = 1; + + while (q != 0) { + if (q % 2 == 1) { // q is odd + r *= p; + q--; + } + p *= p; + q /= 2; + } + + return r; +} + +template ::value, bool>::type = true> +T expt(T p, unsigned q) +{ + using std::pow; + return pow(p, static_cast(q)); +} + +template +inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) +{ +#ifdef BOOST_MATH_CHEB_USE_STD_ACOSH + using std::acosh; +#define BOOST_MATH_ACOSH_POLICY +#else + using boost::math::acosh; +#define BOOST_MATH_ACOSH_POLICY , Policy() +#endif + using std::cosh; + using std::pow; + using std::sqrt; + Real T0 = 1; + Real T1; + + BOOST_MATH_IF_CONSTEXPR (second) + { + if (x > 1 || x < -1) + { + Real t = sqrt(x*x -1); + return static_cast((expt(static_cast(x+t), n+1) - expt(static_cast(x-t), n+1))/(2*t)); + } + T1 = 2*x; + } + else + { + if (x > 1) + { + return cosh(n*acosh(x BOOST_MATH_ACOSH_POLICY)); + } + if (x < -1) + { + if (n & 1) + { + return -cosh(n*acosh(-x BOOST_MATH_ACOSH_POLICY)); + } + else + { + return cosh(n*acosh(-x BOOST_MATH_ACOSH_POLICY)); + } + } + T1 = x; + } + + if (n == 0) + { + return T0; + } + + unsigned l = 1; + while(l < n) + { + std::swap(T0, T1); + T1 = static_cast(boost::math::chebyshev_next(x, T0, T1)); + ++l; + } + return T1; +} +} // namespace detail + +template +inline tools::promote_args_t chebyshev_t(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + return policies::checked_narrowing_cast(detail::chebyshev_imp(n, static_cast(x), forwarding_policy()), "boost::math::chebyshev_t<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_t(unsigned n, Real const & x) +{ + return chebyshev_t(n, x, policies::policy<>()); +} + +template +inline tools::promote_args_t chebyshev_u(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + return policies::checked_narrowing_cast(detail::chebyshev_imp(n, static_cast(x), forwarding_policy()), "boost::math::chebyshev_u<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_u(unsigned n, Real const & x) +{ + return chebyshev_u(n, x, policies::policy<>()); +} + +template +inline tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + if (n == 0) + { + return result_type(0); + } + return policies::checked_narrowing_cast(n * detail::chebyshev_imp(n - 1, static_cast(x), forwarding_policy()), "boost::math::chebyshev_t_prime<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x) +{ + return chebyshev_t_prime(n, x, policies::policy<>()); +} + +/* + * This is Algorithm 3.1 of + * Gil, Amparo, Javier Segura, and Nico M. Temme. + * Numerical methods for special functions. + * Society for Industrial and Applied Mathematics, 2007. + * https://www.siam.org/books/ot99/OT99SampleChapter.pdf + * However, our definition of c0 differs by a factor of 1/2, as stated in the docs. . . + */ +template +inline Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const T2& x) +{ + using boost::math::constants::half; + if (length < 2) + { + if (length == 0) + { + return 0; + } + return c[0]/2; + } + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*x*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return x*b1 - b2 + half()*c[0]; +} + + + +namespace detail { +template +inline Real unchecked_chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const Real & a, const Real & b, const Real& x) +{ + Real t; + Real u; + // This cutoff is not super well defined, but it's a good estimate. + // See "An Error Analysis of the Modified Clenshaw Method for Evaluating Chebyshev and Fourier Series" + // J. OLIVER, IMA Journal of Applied Mathematics, Volume 20, Issue 3, November 1977, Pages 379-391 + // https://doi.org/10.1093/imamat/20.3.379 + const auto cutoff = static_cast(0.6L); + if (x - a < b - x) + { + u = 2*(x-a)/(b-a); + t = u - 1; + if (t > -cutoff) + { + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*t*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return t*b1 - b2 + c[0]/2; + } + else + { + Real b1 = c[length - 1]; + Real d = b1; + Real b2 = 0; + for (size_t r = length - 2; r >= 1; --r) + { + d = 2*u*b1 - d + c[r]; + b2 = b1; + b1 = d - b1; + } + return t*b1 - b2 + c[0]/2; + } + } + else + { + u = -2*(b-x)/(b-a); + t = u + 1; + if (t < cutoff) + { + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*t*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return t*b1 - b2 + c[0]/2; + } + else + { + Real b1 = c[length - 1]; + Real d = b1; + Real b2 = 0; + for (size_t r = length - 2; r >= 1; --r) + { + d = 2*u*b1 + d + c[r]; + b2 = b1; + b1 = d + b1; + } + return t*b1 - b2 + c[0]/2; + } + } +} + +} // namespace detail + +template +inline Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const Real & a, const Real & b, const Real& x) +{ + if (x < a || x > b) + { + BOOST_MATH_THROW_EXCEPTION(std::domain_error("x in [a, b] is required.")); + } + if (length < 2) + { + if (length == 0) + { + return 0; + } + return c[0]/2; + } + return detail::unchecked_chebyshev_clenshaw_recurrence(c, length, a, b, x); +} + +}} // Namespace boost::math + +#endif // BOOST_MATH_SPECIAL_CHEBYSHEV_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/chebyshev_transform.hpp b/third-party/boost-math/include/boost/math/special_functions/chebyshev_transform.hpp new file mode 100644 index 0000000000000..20390be6e0873 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/chebyshev_transform.hpp @@ -0,0 +1,237 @@ +// (C) Copyright Nick Thompson 2017. +// 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) + +#ifndef BOOST_MATH_SPECIAL_CHEBYSHEV_TRANSFORM_HPP +#define BOOST_MATH_SPECIAL_CHEBYSHEV_TRANSFORM_HPP +#include +#include +#include +#include + +#ifdef BOOST_HAS_FLOAT128 +#include +#endif + +#ifdef __has_include +# if __has_include() +# include +# else +# error "This feature is unavailable without fftw3 installed" +#endif +#endif + +namespace boost { namespace math { + +namespace detail{ + +template +struct fftw_cos_transform; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, double* data1, double* data2) + { + plan = fftw_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftw_destroy_plan(plan); + } + void execute(double* data1, double* data2) + { + fftw_execute_r2r(plan, data1, data2); + } + static double cos(double x) { return std::cos(x); } + static double fabs(double x) { return std::fabs(x); } +private: + fftw_plan plan; +}; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, float* data1, float* data2) + { + plan = fftwf_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwf_destroy_plan(plan); + } + void execute(float* data1, float* data2) + { + fftwf_execute_r2r(plan, data1, data2); + } + static float cos(float x) { return std::cos(x); } + static float fabs(float x) { return std::fabs(x); } +private: + fftwf_plan plan; +}; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, long double* data1, long double* data2) + { + plan = fftwl_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwl_destroy_plan(plan); + } + void execute(long double* data1, long double* data2) + { + fftwl_execute_r2r(plan, data1, data2); + } + static long double cos(long double x) { return std::cos(x); } + static long double fabs(long double x) { return std::fabs(x); } +private: + fftwl_plan plan; +}; +#ifdef BOOST_HAS_FLOAT128 +template<> +struct fftw_cos_transform<__float128> +{ + fftw_cos_transform(int n, __float128* data1, __float128* data2) + { + plan = fftwq_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwq_destroy_plan(plan); + } + void execute(__float128* data1, __float128* data2) + { + fftwq_execute_r2r(plan, data1, data2); + } + static __float128 cos(__float128 x) { return cosq(x); } + static __float128 fabs(__float128 x) { return fabsq(x); } +private: + fftwq_plan plan; +}; + +#endif +} + +template +class chebyshev_transform +{ +public: + template + chebyshev_transform(const F& f, Real a, Real b, + Real tol = 500 * std::numeric_limits::epsilon(), + size_t max_refinements = 16) : m_a(a), m_b(b) + { + if (a >= b) + { + throw std::domain_error("a < b is required.\n"); + } + using boost::math::constants::half; + using boost::math::constants::pi; + using std::cos; + using std::abs; + Real bma = (b-a)*half(); + Real bpa = (b+a)*half(); + size_t n = 256; + std::vector vf; + + size_t refinements = 0; + while(refinements < max_refinements) + { + vf.resize(n); + m_coeffs.resize(n); + + detail::fftw_cos_transform plan(static_cast(n), vf.data(), m_coeffs.data()); + Real inv_n = 1/static_cast(n); + for(size_t j = 0; j < n/2; ++j) + { + // Use symmetry cos((j+1/2)pi/n) = - cos((n-1-j+1/2)pi/n) + Real y = detail::fftw_cos_transform::cos(pi()*(j+half())*inv_n); + vf[j] = f(y*bma + bpa)*inv_n; + vf[n-1-j]= f(bpa-y*bma)*inv_n; + } + + plan.execute(vf.data(), m_coeffs.data()); + Real max_coeff = 0; + for (auto const & coeff : m_coeffs) + { + if (detail::fftw_cos_transform::fabs(coeff) > max_coeff) + { + max_coeff = detail::fftw_cos_transform::fabs(coeff); + } + } + size_t j = m_coeffs.size() - 1; + while (abs(m_coeffs[j])/max_coeff < tol) + { + --j; + } + // If ten coefficients are eliminated, the we say we've done all + // we need to do: + if (n - j > 10) + { + m_coeffs.resize(j+1); + return; + } + + n *= 2; + ++refinements; + } + } + + inline Real operator()(Real x) const + { + return chebyshev_clenshaw_recurrence(m_coeffs.data(), m_coeffs.size(), m_a, m_b, x); + } + + // Integral over entire domain [a, b] + Real integrate() const + { + Real Q = m_coeffs[0]/2; + for(size_t j = 2; j < m_coeffs.size(); j += 2) + { + Q += -m_coeffs[j]/((j+1)*(j-1)); + } + return (m_b - m_a)*Q; + } + + const std::vector& coefficients() const + { + return m_coeffs; + } + + Real prime(Real x) const + { + Real z = (2*x - m_a - m_b)/(m_b - m_a); + Real dzdx = 2/(m_b - m_a); + if (m_coeffs.size() < 2) + { + return 0; + } + Real b2 = 0; + Real d2 = 0; + Real b1 = m_coeffs[m_coeffs.size() -1]; + Real d1 = 0; + for(size_t j = m_coeffs.size() - 2; j >= 1; --j) + { + Real tmp1 = 2*z*b1 - b2 + m_coeffs[j]; + Real tmp2 = 2*z*d1 - d2 + 2*b1; + b2 = b1; + b1 = tmp1; + + d2 = d1; + d1 = tmp2; + } + return dzdx*(z*d1 - d2 + b1); + } + +private: + std::vector m_coeffs; + Real m_a; + Real m_b; +}; + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/cos_pi.hpp b/third-party/boost-math/include/boost/math/special_functions/cos_pi.hpp new file mode 100644 index 0000000000000..7c33614de7cd2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/cos_pi.hpp @@ -0,0 +1,128 @@ +// Copyright (c) 2007 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_COS_PI_HPP +#define BOOST_MATH_COS_PI_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T cos_pi_imp(T x, const Policy&) +{ + BOOST_MATH_STD_USING // ADL of std names + // cos of pi*x: + bool invert = false; + if(fabs(x) < T(0.25)) + return cos(constants::pi() * x); + + if(x < 0) + { + x = -x; + } + T rem = floor(x); + if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits::epsilon()) + { + invert = !invert; + } + rem = x - rem; + if(rem > 0.5f) + { + rem = 1 - rem; + invert = !invert; + } + if(rem == 0.5f) + return 0; + + if(rem > 0.25f) + { + rem = 0.5f - rem; + rem = sin(constants::pi() * rem); + } + else + rem = cos(constants::pi() * rem); + return invert ? T(-rem) : rem; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type cos_pi(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<>, + // We want to ignore overflows since the result is in [-1,1] and the + // check slows the code down considerably. + policies::overflow_error >::type forwarding_policy; + return policies::checked_narrowing_cast(boost::math::detail::cos_pi_imp(x, forwarding_policy()), "cos_pi"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type cos_pi(T x) +{ + return boost::math::cos_pi(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#else // Special handling for NVRTC + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED auto cos_pi(T x) +{ + return ::cospi(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto cos_pi(float x) +{ + return ::cospif(x); +} + +template +BOOST_MATH_GPU_ENABLED auto cos_pi(T x, const Policy&) +{ + return ::cospi(x); +} + +template +BOOST_MATH_GPU_ENABLED auto cos_pi(float x, const Policy&) +{ + return ::cospif(x); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif + diff --git a/third-party/boost-math/include/boost/math/special_functions/daubechies_scaling.hpp b/third-party/boost-math/include/boost/math/special_functions/daubechies_scaling.hpp new file mode 100644 index 0000000000000..fe9d7b16d13d1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/daubechies_scaling.hpp @@ -0,0 +1,491 @@ +/* + * Copyright Nick Thompson, John Maddock 2020 + * 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) + */ + +#ifndef BOOST_MATH_SPECIAL_DAUBECHIES_SCALING_HPP +#define BOOST_MATH_SPECIAL_DAUBECHIES_SCALING_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +# include +# ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +# error "The header can only be used in C++17 and later." +# endif +#endif + +namespace boost::math { + +template +std::vector daubechies_scaling_dyadic_grid(int64_t j_max) +{ + using std::isnan; + using std::sqrt; + auto c = boost::math::filters::daubechies_scaling_filter(); + Real scale = sqrt(static_cast(2))*(1 << order); + for (auto & x : c) + { + x *= scale; + } + + auto phik = detail::daubechies_scaling_integer_grid(); + + // Maximum sensible j for 32 bit floats is j_max = 22: + if constexpr (std::is_same_v) + { + if (j_max > 23) + { + throw std::logic_error("Requested dyadic grid more dense than number of representables on the interval."); + } + } + std::vector v(2*p + (2*p-1)*((1<::quiet_NaN()); + v[0] = 0; + v[v.size()-1] = 0; + for (int64_t i = 0; i < static_cast(phik.size()); ++i) { + v[i*(1uLL<= static_cast(v.size())) { + // std::cerr << "Delivery index out of range!\n"; + // continue; + //} + Real term = 0; + for (int64_t l = 0; l < static_cast(c.size()); ++l) + { + int64_t idx = k*(int64_t(1) << (j_max - j + 1)) - l*(int64_t(1) << j_max); + if (idx < 0) + { + break; + } + if (idx < static_cast(v.size())) + { + term += c[l]*v[idx]; + } + } + // Again, another nice check: + //if (!isnan(v[delivery_idx])) { + // std::cerr << "Delivery index already populated!, = " << v[delivery_idx] << "\n"; + // std::cerr << "would overwrite with " << term << "\n"; + //} + v[delivery_idx] = term; + } + } + return v; +} + +namespace detail { + +template +class matched_holder { +public: + using Real = typename RandomAccessContainer::value_type; + + matched_holder(RandomAccessContainer && y, RandomAccessContainer && dydx, int grid_refinements, Real x0) : x0_{x0}, y_{std::move(y)}, dy_{std::move(dydx)} + { + inv_h_ = (1 << grid_refinements); + Real h = 1/inv_h_; + for (auto & dy : dy_) + { + dy *= h; + } + } + + inline Real operator()(Real x) const + { + using std::floor; + using std::sqrt; + // This is the exact Holder exponent, but it's pessimistic almost everywhere! + // It's only exactly right at dyadic rationals. + //Real const alpha = 2 - log(1+sqrt(Real(3)))/log(Real(2)); + // We're gonna use alpha = 1/2, rather than 0.5500... + Real s = (x-x0_)*inv_h_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real dphi = dy_[i+1]; + Real diff = y_[i+1] - y_[i]; + return y_[i] + (2*dphi - diff)*t + 2*sqrt(t)*(diff-dphi); + } + + int64_t bytes() const + { + return 2*y_.size()*sizeof(Real) + sizeof(*this); + } + +private: + Real x0_; + Real inv_h_; + RandomAccessContainer y_; + RandomAccessContainer dy_; +}; + +template +class matched_holder_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + matched_holder_aos(RandomAccessContainer && data, int grid_refinements, Real x0) : x0_{x0}, data_{std::move(data)} + { + inv_h_ = Real(1uLL << grid_refinements); + Real h = 1/inv_h_; + for (auto & datum : data_) + { + datum[1] *= h; + } + } + + inline Real operator()(Real x) const + { + using std::floor; + using std::sqrt; + Real s = (x-x0_)*inv_h_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dphi = data_[i+1][1]; + Real diff = y1 - y0; + return y0 + (2*dphi - diff)*t + 2*sqrt(t)*(diff-dphi); + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + sizeof(*this); + } + +private: + Real x0_; + Real inv_h_; + RandomAccessContainer data_; +}; + + +template +class linear_interpolation { +public: + using Real = typename RandomAccessContainer::value_type; + + linear_interpolation(RandomAccessContainer && y, RandomAccessContainer && dydx, int grid_refinements) : y_{std::move(y)}, dydx_{std::move(dydx)} + { + s_ = (1 << grid_refinements); + } + + inline Real operator()(Real x) const + { + using std::floor; + Real y = x*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return (1-t)*y_[kk] + t*y_[kk+1]; + } + + inline Real prime(Real x) const + { + using std::floor; + + Real y = x*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return static_cast((Real(1)-t)*dydx_[kk] + t*dydx_[kk+1]); + } + + int64_t bytes() const + { + return (1 + y_.size() + dydx_.size())*sizeof(Real) + sizeof(y_) + sizeof(dydx_); + } + +private: + Real s_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; +}; + +template +class linear_interpolation_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + linear_interpolation_aos(RandomAccessContainer && data, int grid_refinements, Real x0) : x0_{x0}, data_{std::move(data)} + { + s_ = Real(1uLL << grid_refinements); + } + + inline Real operator()(Real x) const + { + using std::floor; + Real y = (x-x0_)*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return (t != 0) ? (1-t)*data_[kk][0] + t*data_[kk+1][0] : data_[kk][0]; + } + + inline Real prime(Real x) const + { + using std::floor; + Real y = (x-x0_)*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return t != 0 ? (1-t)*data_[kk][1] + t*data_[kk+1][1] : data_[kk][1]; + } + + int64_t bytes() const + { + return sizeof(*this) + data_.size()*data_[0].size()*sizeof(Real); + } + +private: + Real x0_; + Real s_; + RandomAccessContainer data_; +}; + + +template +struct daubechies_eval_type +{ + using type = T; + + static const std::vector& vector_cast(const std::vector& v) { return v; } + +}; +template <> +struct daubechies_eval_type +{ + using type = double; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } +}; +template <> +struct daubechies_eval_type +{ + using type = long double; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } +}; + +struct null_interpolator +{ + template + T operator()(const T&) + { + return 1; + } +}; + +} // namespace detail + +template +class daubechies_scaling { + // + // Some type manipulation so we know the type of the interpolator, and the vector type it requires: + // + using vector_type = std::vector>; + // + // List our interpolators: + // + using interpolator_list = std::tuple< + detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, + interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, + interpolators::detail::cardinal_septic_hermite_detail_aos >; + // + // Select the one we need: + // + using interpolator_type = std::tuple_element_t< + p == 1 ? 0 : + p == 2 ? 1 : + p == 3 ? 2 : + p <= 5 ? 3 : + p <= 9 ? 4 : 5, interpolator_list>; + +public: + daubechies_scaling(int grid_refinements = -1) + { + static_assert(p < 20, "Daubechies scaling functions are only implemented for p < 20."); + static_assert(p > 0, "Daubechies scaling functions must have at least 1 vanishing moment."); + if constexpr (p == 1) + { + return; + } + else { + if (grid_refinements < 0) + { + if constexpr (std::is_same_v) + { + if (grid_refinements == -2) + { + // Control absolute error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + constexpr std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; + grid_refinements = r[p]; + } + else + { + // Control relative error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + constexpr std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; + grid_refinements = r[p]; + } + } + else if constexpr (std::is_same_v) + { + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + constexpr std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; + } + else + { + grid_refinements = 21; + } + } + + // Compute the refined grid: + // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. + std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { + // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: + auto v = daubechies_scaling_dyadic_grid::type, p, 0>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + // Compute the derivative of the refined grid: + std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 1>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + // if necessary, compute the second and third derivative: + std::vector d2ydx2; + std::vector d3ydx3; + if constexpr (p >= 6) { + std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 2>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + if constexpr (p >= 10) { + std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 3>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + d3ydx3 = t4.get(); + } + d2ydx2 = t3.get(); + } + + + auto y = t0.get(); + auto dydx = t1.get(); + + if constexpr (p >= 2) + { + vector_type data(y.size()); + for (size_t i = 0; i < y.size(); ++i) + { + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; + } + if constexpr (p <= 3) + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); + else + m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); + } + else + m_interpolator = std::make_shared(); + } + } + + inline Real operator()(Real x) const + { + if (x <= 0 || x >= 2*p-1) + { + return 0; + } + return (*m_interpolator)(x); + } + + inline Real prime(Real x) const + { + static_assert(p > 2, "The 3-vanishing moment Daubechies scaling function is the first which is continuously differentiable."); + if (x <= Real(0) || x >= 2*p-1) + { + return 0; + } + return m_interpolator->prime(x); + } + + inline Real double_prime(Real x) const + { + static_assert(p >= 6, "Second derivatives require at least 6 vanishing moments."); + if (x <= 0 || x >= 2*p - 1) + { + return Real(0); + } + return m_interpolator->double_prime(x); + } + + std::pair support() const + { + return {Real(0), Real(2*p-1)}; + } + + int64_t bytes() const + { + return m_interpolator->bytes() + sizeof(m_interpolator); + } + +private: + std::shared_ptr m_interpolator; +}; + +} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/daubechies_wavelet.hpp b/third-party/boost-math/include/boost/math/special_functions/daubechies_wavelet.hpp new file mode 100644 index 0000000000000..d374c848700b5 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/daubechies_wavelet.hpp @@ -0,0 +1,266 @@ +/* + * Copyright Nick Thompson, 2020 + * 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) + */ + +#ifndef BOOST_MATH_SPECIAL_DAUBECHIES_WAVELET_HPP +#define BOOST_MATH_SPECIAL_DAUBECHIES_WAVELET_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math { + + template + std::vector daubechies_wavelet_dyadic_grid(int64_t j_max) + { + if (j_max == 0) + { + throw std::domain_error("The wavelet dyadic grid is refined from the scaling integer grid, so its minimum amount of data is half integer widths."); + } + auto phijk = daubechies_scaling_dyadic_grid(j_max - 1); + //psi_j[l] = psi(-p+1 + l/2^j) = \sum_{k=0}^{2p-1} (-1)^k c_k \phi(1-2p+k + l/2^{j-1}) + //For derivatives just map c_k -> 2^order c_k. + auto d = boost::math::filters::daubechies_scaling_filter(); + Real scale = boost::math::constants::root_two() * (1 << order); + for (size_t i = 0; i < d.size(); ++i) + { + d[i] *= scale; + if (!(i & 1)) + { + d[i] = -d[i]; + } + } + + std::vector v(2 * p + (2 * p - 1) * ((int64_t(1) << j_max) - 1), std::numeric_limits::quiet_NaN()); + v[0] = 0; + v[v.size() - 1] = 0; + + for (int64_t l = 1; l < static_cast(v.size() - 1); ++l) + { + Real term = 0; + for (int64_t k = 0; k < static_cast(d.size()); ++k) + { + int64_t idx = (int64_t(1) << (j_max - 1)) * (1 - 2 * p + k) + l; + if (idx < 0 || idx >= static_cast(phijk.size())) + { + continue; + } + term += d[k] * phijk[idx]; + } + v[l] = term; + } + + return v; + } + + + template + class daubechies_wavelet { + // + // Some type manipulation so we know the type of the interpolator, and the vector type it requires: + // + using vector_type = std::vector < std::array < Real, p < 6 ? 2 : p < 10 ? 3 : 4>>; + // + // List our interpolators: + // + using interpolator_list = std::tuple< + detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, + interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, + interpolators::detail::cardinal_septic_hermite_detail_aos > ; + // + // Select the one we need: + // + using interpolator_type = std::tuple_element_t< + p == 1 ? 0 : + p == 2 ? 1 : + p == 3 ? 2 : + p <= 5 ? 3 : + p <= 9 ? 4 : 5, interpolator_list>; + public: + explicit daubechies_wavelet(int grid_refinements = -1) + { + static_assert(p < 20, "Daubechies wavelets are only implemented for p < 20."); + static_assert(p > 0, "Daubechies wavelets must have at least 1 vanishing moment."); + if (grid_refinements == 0) + { + throw std::domain_error("The wavelet requires at least 1 grid refinement."); + } + if constexpr (p == 1) + { + return; + } + else + { + if (grid_refinements < 0) + { + if constexpr (std::is_same_v) + { + if (grid_refinements == -2) + { + // Control absolute error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; + grid_refinements = r[p]; + } + else + { + // Control relative error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; + grid_refinements = r[p]; + } + } + else if constexpr (std::is_same_v) + { + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 18, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; + } + else + { + grid_refinements = 21; + } + } + + // Compute the refined grid: + // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. + std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { + // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: + auto v = daubechies_wavelet_dyadic_grid::type, p, 0>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + // Compute the derivative of the refined grid: + std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 1>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + // if necessary, compute the second and third derivative: + std::vector d2ydx2; + std::vector d3ydx3; + if constexpr (p >= 6) { + std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 2>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + if constexpr (p >= 10) { + std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 3>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + d3ydx3 = t4.get(); + } + d2ydx2 = t3.get(); + } + + + auto y = t0.get(); + auto dydx = t1.get(); + + if constexpr (p >= 2) + { + vector_type data(y.size()); + for (size_t i = 0; i < y.size(); ++i) + { + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; + } + if constexpr (p <= 3) + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(-p + 1)); + else + m_interpolator = std::make_shared(std::move(data), Real(-p + 1), Real(1) / (1 << grid_refinements)); + } + else + m_interpolator = std::make_shared(); + } + } + + + inline Real operator()(Real x) const + { + if (x <= -p + 1 || x >= p) + { + return 0; + } + + if constexpr (p == 1) + { + if (x < Real(1) / Real(2)) + { + return 1; + } + else if (x == Real(1) / Real(2)) + { + return 0; + } + return -1; + } + else + { + return (*m_interpolator)(x); + } + } + + inline Real prime(Real x) const + { + static_assert(p > 2, "The 3-vanishing moment Daubechies wavelet is the first which is continuously differentiable."); + if (x <= -p + 1 || x >= p) + { + return 0; + } + return m_interpolator->prime(x); + } + + inline Real double_prime(Real x) const + { + static_assert(p >= 6, "Second derivatives of Daubechies wavelets require at least 6 vanishing moments."); + if (x <= -p + 1 || x >= p) + { + return Real(0); + } + return m_interpolator->double_prime(x); + } + + std::pair support() const + { + return std::make_pair(Real(-p + 1), Real(p)); + } + + int64_t bytes() const + { + return m_interpolator->bytes() + sizeof(*this); + } + + private: + std::shared_ptr m_interpolator; + }; + +} + +#endif // BOOST_MATH_SPECIAL_DAUBECHIES_WAVELET_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/airy_ai_bi_zero.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/airy_ai_bi_zero.hpp new file mode 100644 index 0000000000000..e518422f17a2b --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/airy_ai_bi_zero.hpp @@ -0,0 +1,222 @@ +// Copyright (c) 2013 Christopher Kormanyos +// 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) +// +// This work is based on an earlier work: +// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", +// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 +// +// This header contains implementation details for estimating the zeros +// of the Airy functions airy_ai and airy_bi on the negative real axis. +// +#ifndef BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ + #define BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ + + #include + #include + #include + #include + + namespace boost { namespace math { + namespace detail + { + // Forward declarations of the needed Airy function implementations. + template + BOOST_MATH_GPU_ENABLED T airy_ai_imp(T x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T airy_bi_imp(T x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T airy_ai_prime_imp(T x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T airy_bi_prime_imp(T x, const Policy& pol); + + namespace airy_zero + { + template + BOOST_MATH_GPU_ENABLED T equation_as_10_4_105(const T& z, const Policy& pol) + { + const T one_over_z (T(1) / z); + const T one_over_z_squared(one_over_z * one_over_z); + + const T z_pow_third (boost::math::cbrt(z, pol)); + const T z_pow_two_thirds(z_pow_third * z_pow_third); + + // Implement the top line of Eq. 10.4.105. + const T fz(z_pow_two_thirds * ((((( + (T(162375596875.0) / 334430208UL) + * one_over_z_squared - ( T(108056875.0) / 6967296UL)) + * one_over_z_squared + ( T(77125UL) / 82944UL)) + * one_over_z_squared - ( T(5U) / 36U)) + * one_over_z_squared + ( T(5U) / 48U)) + * one_over_z_squared + 1)); + + return fz; + } + + namespace airy_ai_zero_detail + { + template + BOOST_MATH_GPU_ENABLED T initial_guess(const int m, const Policy& pol) + { + T guess; + + switch(m) + { + case 0: + guess = T(0); + break; + case 1: + guess = T(-2.33810741045976703849); + break; + case 2: + guess = T(-4.08794944413097061664); + break; + case 3: + guess = T(-5.52055982809555105913); + break; + case 4: + guess = T(-6.78670809007175899878); + break; + case 5: + guess = T(-7.94413358712085312314); + break; + case 6: + guess = T(-9.02265085334098038016); + break; + case 7: + guess = T(-10.0401743415580859306); + break; + case 8: + guess = T(-11.0085243037332628932); + break; + case 9: + guess = T(-11.9360155632362625170); + break; + case 10: + guess = T(-12.8287767528657572004); + break; + default: + const T t(((boost::math::constants::pi() * 3) * ((T(m) * 4) - 1)) / 8); + guess = -boost::math::detail::airy_zero::equation_as_10_4_105(t, pol); + break; + } + + return guess; + } + + template + class function_object_ai_and_ai_prime + { + public: + BOOST_MATH_GPU_ENABLED explicit function_object_ai_and_ai_prime(const Policy& pol) : my_pol(pol) { } + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_suppress 20012 + #endif + + BOOST_MATH_GPU_ENABLED function_object_ai_and_ai_prime(const function_object_ai_and_ai_prime&) = default; + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_default 20012 + #endif + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& x) const + { + // Return a tuple containing both Ai(x) and Ai'(x). + return boost::math::make_tuple( + boost::math::detail::airy_ai_imp (x, my_pol), + boost::math::detail::airy_ai_prime_imp(x, my_pol)); + } + + private: + const Policy& my_pol; + const function_object_ai_and_ai_prime& operator=(const function_object_ai_and_ai_prime&) = delete; + }; + } // namespace airy_ai_zero_detail + + namespace airy_bi_zero_detail + { + template + BOOST_MATH_GPU_ENABLED T initial_guess(const int m, const Policy& pol) + { + T guess; + + switch(m) + { + case 0: + guess = T(0); + break; + case 1: + guess = T(-1.17371322270912792492); + break; + case 2: + guess = T(-3.27109330283635271568); + break; + case 3: + guess = T(-4.83073784166201593267); + break; + case 4: + guess = T(-6.16985212831025125983); + break; + case 5: + guess = T(-7.37676207936776371360); + break; + case 6: + guess = T(-8.49194884650938801345); + break; + case 7: + guess = T(-9.53819437934623888663); + break; + case 8: + guess = T(-10.5299135067053579244); + break; + case 9: + guess = T(-11.4769535512787794379); + break; + case 10: + guess = T(-12.3864171385827387456); + break; + default: + const T t(((boost::math::constants::pi() * 3) * ((T(m) * 4) - 3)) / 8); + guess = -boost::math::detail::airy_zero::equation_as_10_4_105(t, pol); + break; + } + + return guess; + } + + template + class function_object_bi_and_bi_prime + { + public: + BOOST_MATH_GPU_ENABLED explicit function_object_bi_and_bi_prime(const Policy& pol) : my_pol(pol) { } + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_suppress 20012 + #endif + + BOOST_MATH_GPU_ENABLED function_object_bi_and_bi_prime(const function_object_bi_and_bi_prime&) = default; + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_default 20012 + #endif + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& x) const + { + // Return a tuple containing both Bi(x) and Bi'(x). + return boost::math::make_tuple( + boost::math::detail::airy_bi_imp (x, my_pol), + boost::math::detail::airy_bi_prime_imp(x, my_pol)); + } + + private: + const Policy& my_pol; + const function_object_bi_and_bi_prime& operator=(const function_object_bi_and_bi_prime&) = delete; + }; + } // namespace airy_bi_zero_detail + } // namespace airy_zero + } // namespace detail + } // namespace math + } // namespaces boost + +#endif // BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bernoulli_details.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bernoulli_details.hpp new file mode 100644 index 0000000000000..3dbc9b575df72 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bernoulli_details.hpp @@ -0,0 +1,629 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 John Maddock +// 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) + +#ifndef BOOST_MATH_BERNOULLI_DETAIL_HPP +#define BOOST_MATH_BERNOULLI_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_MATH_HAS_THREADS) && !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_MATH_NO_ATOMIC_INT) +#include +#else +# define BOOST_MATH_BERNOULLI_NOTHREADS +#endif + +namespace boost{ namespace math{ namespace detail{ +// +// Asymptotic expansion for B2n due to +// Luschny LogB3 formula (http://www.luschny.de/math/primes/bernincl.html) +// +template +T b2n_asymptotic(int n) +{ + BOOST_MATH_STD_USING + const auto nx = static_cast(n); + const T nx2(nx * nx); + + const T approximate_log_of_bernoulli_bn = + ((boost::math::constants::half() + nx) * log(nx)) + + ((boost::math::constants::half() - nx) * log(boost::math::constants::pi())) + + (((T(3) / 2) - nx) * boost::math::constants::ln_two()) + + ((nx * (T(2) - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520)); + return ((n / 2) & 1 ? 1 : -1) * (approximate_log_of_bernoulli_bn > tools::log_max_value() + ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, nx, Policy()) + : static_cast(exp(approximate_log_of_bernoulli_bn))); +} + +template +T t2n_asymptotic(int n) +{ + BOOST_MATH_STD_USING + // Just get B2n and convert to a Tangent number: + T t2n = fabs(b2n_asymptotic(2 * n)) / (2 * n); + T p2 = ldexp(T(1), n); + if(tools::max_value() / p2 < t2n) + { + return policies::raise_overflow_error("boost::math::tangent_t2n<%1%>(std::size_t)", nullptr, T(n), Policy()); + } + t2n *= p2; + p2 -= 1; + if(tools::max_value() / p2 < t2n) + { + return policies::raise_overflow_error("boost::math::tangent_t2n<%1%>(std::size_t)", nullptr, Policy()); + } + t2n *= p2; + return t2n; +} +// +// We need to know the approximate value of /n/ which will +// cause bernoulli_b2n(n) to return infinity - this allows +// us to elude a great deal of runtime checking for values below +// n, and only perform the full overflow checks when we know that we're +// getting close to the point where our calculations will overflow. +// We use Luschny's LogB3 formula (http://www.luschny.de/math/primes/bernincl.html) +// to find the limit, and since we're dealing with the log of the Bernoulli numbers +// we need only perform the calculation at double precision and not with T +// (which may be a multiprecision type). The limit returned is within 1 of the true +// limit for all the types tested. Note that although the code below is basically +// the same as b2n_asymptotic above, it has been recast as a continuous real-valued +// function as this makes the root finding go smoother/faster. It also omits the +// sign of the Bernoulli number. +// +struct max_bernoulli_root_functor +{ + explicit max_bernoulli_root_functor(unsigned long long t) : target(static_cast(t)) {} + double operator()(double n) const + { + BOOST_MATH_STD_USING + + // Luschny LogB3(n) formula. + + const double nx2(n * n); + + const double approximate_log_of_bernoulli_bn + = ((boost::math::constants::half() + n) * log(n)) + + ((boost::math::constants::half() - n) * log(boost::math::constants::pi())) + + (((static_cast(3) / 2) - n) * boost::math::constants::ln_two()) + + ((n * (2 - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520)); + + return approximate_log_of_bernoulli_bn - target; + } +private: + double target; +}; + +template +inline std::size_t find_bernoulli_overflow_limit(const std::false_type&) +{ + // Set a limit on how large the result can ever be: + static const auto max_result = static_cast((std::numeric_limits::max)() - 1000u); + + unsigned long long t = static_cast(lltrunc(boost::math::tools::log_max_value())); + max_bernoulli_root_functor fun(t); + boost::math::tools::equal_floor tol; + std::uintmax_t max_iter = boost::math::policies::get_max_root_iterations(); + double result = boost::math::tools::toms748_solve(fun, sqrt(static_cast(t)), static_cast(t), tol, max_iter).first / 2; + if (result > max_result) + { + result = max_result; + } + + return static_cast(result); +} + +template +inline std::size_t find_bernoulli_overflow_limit(const std::true_type&) +{ + return max_bernoulli_index::value>::value; +} + +template +std::size_t b2n_overflow_limit() +{ + // This routine is called at program startup if it's called at all: + // that guarantees safe initialization of the static variable. + using tag_type = std::integral_constant::value >= 1) && (bernoulli_imp_variant::value <= 3)>; + static const std::size_t lim = find_bernoulli_overflow_limit(tag_type()); + return lim; +} + +// +// The tangent numbers grow larger much more rapidly than the Bernoulli numbers do.... +// so to compute the Bernoulli numbers from the tangent numbers, we need to avoid spurious +// overflow in the calculation, we can do this by scaling all the tangent number by some scale factor: +// +template ::is_specialized && (std::numeric_limits::radix == 2), bool>::type = true> +inline T tangent_scale_factor() +{ + BOOST_MATH_STD_USING + return ldexp(T(1), std::numeric_limits::min_exponent + 5); +} + +template ::is_specialized || !(std::numeric_limits::radix == 2), bool>::type = true> +inline T tangent_scale_factor() +{ + return tools::min_value() * 16; +} + +// +// We need something to act as a cache for our calculated Bernoulli numbers. In order to +// ensure both fast access and thread safety, we need a stable table which may be extended +// in size, but which never reallocates: that way values already calculated may be accessed +// concurrently with another thread extending the table with new values. +// +// Very very simple vector class that will never allocate more than once, we could use +// boost::container::static_vector here, but that allocates on the stack, which may well +// cause issues for the amount of memory we want in the extreme case... +// +template +struct fixed_vector : private std::allocator +{ + using size_type = unsigned; + using iterator = T*; + using const_iterator = const T*; + fixed_vector() : m_used(0) + { + std::size_t overflow_limit = 5 + b2n_overflow_limit >(); + m_capacity = static_cast((std::min)(overflow_limit, static_cast(100000u))); + m_data = this->allocate(m_capacity); + } + ~fixed_vector() + { + using allocator_type = std::allocator; + using allocator_traits = std::allocator_traits; + allocator_type& alloc = *this; + for(unsigned i = 0; i < m_used; ++i) + { + allocator_traits::destroy(alloc, &m_data[i]); + } + allocator_traits::deallocate(alloc, m_data, m_capacity); + } + T& operator[](unsigned n) { BOOST_MATH_ASSERT(n < m_used); return m_data[n]; } + const T& operator[](unsigned n)const { BOOST_MATH_ASSERT(n < m_used); return m_data[n]; } + unsigned size()const { return m_used; } + unsigned size() { return m_used; } + bool resize(unsigned n, const T& val) + { + if(n > m_capacity) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Exhausted storage for Bernoulli numbers.")); +#else + return false; +#endif + } + for(unsigned i = m_used; i < n; ++i) + new (m_data + i) T(val); + m_used = n; + return true; + } + bool resize(unsigned n) { return resize(n, T()); } + T* begin() { return m_data; } + T* end() { return m_data + m_used; } + T* begin()const { return m_data; } + T* end()const { return m_data + m_used; } + unsigned capacity()const { return m_capacity; } + void clear() { m_used = 0; } +private: + T* m_data; + unsigned m_used {}; + unsigned m_capacity; +}; + +template +class bernoulli_numbers_cache +{ +public: + bernoulli_numbers_cache() : m_overflow_limit((std::numeric_limits::max)()) + , m_counter(0) + , m_current_precision(boost::math::tools::digits()) + {} + + using container_type = fixed_vector; + + bool tangent(std::size_t m) + { + static const std::size_t min_overflow_index = b2n_overflow_limit() - 1; + + if (!tn.resize(static_cast(m), T(0U))) + { + return false; + } + + BOOST_MATH_INSTRUMENT_VARIABLE(min_overflow_index); + + std::size_t prev_size = m_intermediates.size(); + m_intermediates.resize(m, T(0U)); + + if(prev_size == 0) + { + m_intermediates[1] = tangent_scale_factor() /*T(1U)*/; + tn[0U] = T(0U); + tn[1U] = tangent_scale_factor()/* T(1U)*/; + BOOST_MATH_INSTRUMENT_VARIABLE(tn[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(tn[1]); + } + + for(std::size_t i = std::max(2, prev_size); i < m; i++) + { + bool overflow_check = false; + if(i >= min_overflow_index && (boost::math::tools::max_value() / (i-1) < m_intermediates[1]) ) + { + std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value()); + break; + } + m_intermediates[1] = m_intermediates[1] * (i-1); + for(std::size_t j = 2; j <= i; j++) + { + overflow_check = + (i >= min_overflow_index) && ( + (boost::math::tools::max_value() / (i - j) < m_intermediates[j]) + || (boost::math::tools::max_value() / (i - j + 2) < m_intermediates[j-1]) + || (boost::math::tools::max_value() - m_intermediates[j] * (i - j) < m_intermediates[j-1] * (i - j + 2)) + || ((boost::math::isinf)(m_intermediates[j])) + ); + + if(overflow_check) + { + std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value()); + break; + } + m_intermediates[j] = m_intermediates[j] * (i - j) + m_intermediates[j-1] * (i - j + 2); + } + if(overflow_check) + break; // already filled the tn... + tn[static_cast(i)] = m_intermediates[i]; + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(tn[static_cast(i)]); + } + return true; + } + + bool tangent_numbers_series(const std::size_t m) + { + BOOST_MATH_STD_USING + static const std::size_t min_overflow_index = b2n_overflow_limit() - 1; + + typename container_type::size_type old_size = bn.size(); + + if (!tangent(m)) + return false; + if (!bn.resize(static_cast(m))) + return false; + + if(!old_size) + { + bn[0] = 1; + old_size = 1; + } + + T power_two(ldexp(T(1), static_cast(2 * old_size))); + + for(std::size_t i = old_size; i < m; i++) + { + T b(static_cast(i * 2)); + // + // Not only do we need to take care to avoid spurious over/under flow in + // the calculation, but we also need to avoid overflow altogether in case + // we're calculating with a type where "bad things" happen in that case: + // + b = b / (power_two * tangent_scale_factor()); + b /= (power_two - 1); + bool overflow_check = (i >= min_overflow_index) && (tools::max_value() / tn[static_cast(i)] < b); + if(overflow_check) + { + m_overflow_limit = i; + while(i < m) + { + b = std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : tools::max_value(); + bn[static_cast(i)] = ((i % 2U) ? b : T(-b)); + ++i; + } + break; + } + else + { + b *= tn[static_cast(i)]; + } + + power_two = ldexp(power_two, 2); + + const bool b_neg = i % 2 == 0; + + bn[static_cast(i)] = ((!b_neg) ? b : T(-b)); + } + return true; + } + + template + OutputIterator copy_bernoulli_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol) + { + // + // There are basically 3 thread safety options: + // + // 1) There are no threads (BOOST_MATH_HAS_THREADS is not defined). + // 2) There are threads, but we do not have a true atomic integer type, + // in this case we just use a mutex to guard against race conditions. + // 3) There are threads, and we have an atomic integer: in this case we can + // use the double-checked locking pattern to avoid thread synchronisation + // when accessing values already in the cache. + // + // First off handle the common case for overflow and/or asymptotic expansion: + // + if(start + n > bn.capacity()) + { + if(start < bn.capacity()) + { + out = copy_bernoulli_numbers(out, start, bn.capacity() - start, pol); + n -= bn.capacity() - start; + start = static_cast(bn.capacity()); + } + if(start < b2n_overflow_limit() + 2u) + { + for(; n; ++start, --n) + { + *out = b2n_asymptotic(static_cast(start * 2U)); + ++out; + } + } + for(; n; ++start, --n) + { + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(start), pol); + ++out; + } + return out; + } + + #if defined(BOOST_MATH_HAS_THREADS) && defined(BOOST_MATH_BERNOULLI_NOTHREADS) && !defined(BOOST_MATH_BERNOULLI_UNTHREADED) + // Add a static_assert on instantiation if we have threads, but no C++11 threading support. + static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have either no atomic integers, or no std::mutex. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); + #elif defined(BOOST_MATH_BERNOULLI_NOTHREADS) + // + // Single threaded code, very simple: + // + if(m_current_precision < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + { + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + } + + for(std::size_t i = (std::max)(std::size_t(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + *out = (i >= m_overflow_limit) ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol) : bn[i]; + ++out; + } + #else + // + // Double-checked locking pattern, lets us access cached already cached values + // without locking: + // + // Get the counter and see if we need to calculate more constants: + // + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + std::lock_guard l(m_mutex); + + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + if(static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_counter.store(0, std::memory_order_release); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(new_size), pol)); + } + m_counter.store(static_cast(bn.size()), std::memory_order_release); + } + } + + for(std::size_t i = (std::max)(static_cast(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + *out = (i >= m_overflow_limit) ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol) : bn[static_cast(i)]; + ++out; + } + + #endif // BOOST_MATH_HAS_THREADS + return out; + } + + template + OutputIterator copy_tangent_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol) + { + // + // There are basically 3 thread safety options: + // + // 1) There are no threads (BOOST_MATH_HAS_THREADS is not defined). + // 2) There are threads, but we do not have a true atomic integer type, + // in this case we just use a mutex to guard against race conditions. + // 3) There are threads, and we have an atomic integer: in this case we can + // use the double-checked locking pattern to avoid thread synchronisation + // when accessing values already in the cache. + // + // + // First off handle the common case for overflow and/or asymptotic expansion: + // + if(start + n > bn.capacity()) + { + if(start < bn.capacity()) + { + out = copy_tangent_numbers(out, start, bn.capacity() - start, pol); + n -= bn.capacity() - start; + start = static_cast(bn.capacity()); + } + if(start < b2n_overflow_limit() + 2u) + { + for(; n; ++start, --n) + { + *out = t2n_asymptotic(static_cast(start)); + ++out; + } + } + for(; n; ++start, --n) + { + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol); + ++out; + } + return out; + } + + #if defined(BOOST_MATH_BERNOULLI_NOTHREADS) + // + // Single threaded code, very simple: + // + if(m_current_precision < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + + for(std::size_t i = start; i < start + n; ++i) + { + if(i >= m_overflow_limit) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + { + if(tools::max_value() * tangent_scale_factor() < tn[static_cast(i)]) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + *out = tn[static_cast(i)] / tangent_scale_factor(); + } + ++out; + } + #elif defined(BOOST_MATH_NO_ATOMIC_INT) + static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have no atomic integers. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); + #else + // + // Double-checked locking pattern, lets us access cached already cached values + // without locking: + // + // Get the counter and see if we need to calculate more constants: + // + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + std::lock_guard l(m_mutex); + + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + if(static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_counter.store(0, std::memory_order_release); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + m_counter.store(static_cast(bn.size()), std::memory_order_release); + } + } + + for(std::size_t i = start; i < start + n; ++i) + { + if(i >= m_overflow_limit) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + { + if(tools::max_value() * tangent_scale_factor() < tn[static_cast(i)]) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + *out = tn[static_cast(i)] / tangent_scale_factor(); + } + ++out; + } + + #endif // BOOST_MATH_HAS_THREADS + return out; + } + +private: + // + // The caches for Bernoulli and tangent numbers, once allocated, + // these must NEVER EVER reallocate as it breaks our thread + // safety guarantees: + // + fixed_vector bn, tn; + std::vector m_intermediates; + // The value at which we know overflow has already occurred for the Bn: + std::size_t m_overflow_limit; + + #if !defined(BOOST_MATH_BERNOULLI_NOTHREADS) + std::mutex m_mutex; + atomic_counter_type m_counter, m_current_precision; + #else + int m_counter; + int m_current_precision; + #endif // BOOST_MATH_HAS_THREADS +}; + +template +inline typename std::enable_if<(std::numeric_limits::digits == 0) || (std::numeric_limits::digits >= INT_MAX), bernoulli_numbers_cache&>::type get_bernoulli_numbers_cache() +{ + // + // When numeric_limits<>::digits is zero, the type has either not specialized numeric_limits at all + // or it's precision can vary at runtime. So make the cache thread_local so that each thread can + // have it's own precision if required: + // + static +#ifndef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES + BOOST_MATH_THREAD_LOCAL +#endif + bernoulli_numbers_cache data; + return data; +} +template +inline typename std::enable_if::digits && (std::numeric_limits::digits < INT_MAX), bernoulli_numbers_cache&>::type get_bernoulli_numbers_cache() +{ + // + // Note that we rely on C++11 thread-safe initialization here: + // + static bernoulli_numbers_cache data; + return data; +} + +}}} + +#endif // BOOST_MATH_BERNOULLI_DETAIL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_derivatives_linear.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_derivatives_linear.hpp new file mode 100644 index 0000000000000..ca62f38a5b1fa --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_derivatives_linear.hpp @@ -0,0 +1,107 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Linear combination for bessel derivatives are defined here +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP +#include +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +inline T bessel_j_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + return (boost::math::detail::cyl_bessel_j_imp(v-1, x, tag, pol) - boost::math::detail::cyl_bessel_j_imp(v+1, x, tag, pol)) / 2; +} + +template +inline T bessel_j_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + return (boost::math::detail::cyl_bessel_j_imp(itrunc(v-1), x, tag, pol) - boost::math::detail::cyl_bessel_j_imp(itrunc(v+1), x, tag, pol)) / 2; +} + +template +inline T sph_bessel_j_derivative_linear(unsigned v, T x, Policy pol) +{ + return (v / x) * boost::math::detail::sph_bessel_j_imp(v, x, pol) - boost::math::detail::sph_bessel_j_imp(v+1, x, pol); +} + +template +inline T bessel_i_derivative_linear(T v, T x, Policy pol) +{ + T result = boost::math::detail::cyl_bessel_i_imp(v - 1, x, pol); + if(result >= tools::max_value()) + return result; // result is infinite + // Both experimentally, and based on https://www.wolframalpha.com/input?i=BesselI%5Bv%2C+x%5D%2FBesselI%5Bv%2B2%2C+x%5D + // I[v + 1, x] < I[v-1, x], so this can't overflow: + T result2 = boost::math::detail::cyl_bessel_i_imp(v + 1, x, pol); + + return result / 2 + result2 / 2; +} + +template +inline T bessel_k_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + T result = boost::math::detail::cyl_bessel_k_imp(v - 1, x, tag, pol); + if(result >= tools::max_value()) + return -result; // result is infinite + T result2 = boost::math::detail::cyl_bessel_k_imp(v + 1, x, tag, pol); + if(result2 >= tools::max_value() + result) + return -boost::math::policies::raise_overflow_error("cyl_bessel_k_prime<%1>", 0, pol); // result is infinite + result /= -2; + result2 /= -2; + return result + result2; +} + +template +inline T bessel_k_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + T result = boost::math::detail::cyl_bessel_k_imp(itrunc(v - 1), x, tag, pol); + if (result >= tools::max_value()) + return -result; // result is infinite + T result2 = boost::math::detail::cyl_bessel_k_imp(itrunc(v + 1), x, tag, pol); + if (result2 >= tools::max_value() + result) + return -boost::math::policies::raise_overflow_error("cyl_bessel_k_prime<%1>", 0, pol); // result is infinite + result /= -2; + result2 /= -2; + return result + result2; +} + +template +inline T bessel_k_derivative_linear(T v, T x, const bessel_maybe_int_tag&, Policy pol) +{ + using std::floor; + if (floor(v) == v) + return bessel_k_derivative_linear(v, x, bessel_int_tag(), pol); + return bessel_k_derivative_linear(v, x, bessel_no_int_tag(), pol); +} + +template +inline T bessel_y_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + return (boost::math::detail::cyl_neumann_imp(v-1, x, tag, pol) - boost::math::detail::cyl_neumann_imp(v+1, x, tag, pol)) / 2; +} + +template +inline T bessel_y_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + return (boost::math::detail::cyl_neumann_imp(itrunc(v-1), x, tag, pol) - boost::math::detail::cyl_neumann_imp(itrunc(v+1), x, tag, pol)) / 2; +} + +template +inline T sph_neumann_derivative_linear(unsigned v, T x, Policy pol) +{ + return (v / x) * boost::math::detail::sph_neumann_imp(v, x, pol) - boost::math::detail::sph_neumann_imp(v+1, x, pol); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i0.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i0.hpp new file mode 100644 index 0000000000000..f2219cc940c6c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i0.hpp @@ -0,0 +1,550 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_BESSEL_I0_HPP +#define BOOST_MATH_BESSEL_I0_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the first kind of order zero +// we use the approximating forms derived in: +// "Rational Approximations for the Modified Bessel Function of the First Kind - I0(x) for Computations with Double Precision" +// by Pavel Holoborodko, +// see http://www.advanpix.com/2015/11/11/rational-approximations-for-the-modified-bessel-function-of-the-first-kind-i0-computations-double-precision +// The actual coefficients used are our own, and extend Pavel's work to precision's other than double. + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_i0(const T& x); + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T&, const boost::math::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Max error in interpolated form: 3.929e-08 + // Max Error found at float precision = Poly: 1.991226e-07 + BOOST_MATH_STATIC const float P[] = { + 1.00000003928615375e+00f, + 2.49999576572179639e-01f, + 2.77785268558399407e-02f, + 1.73560257755821695e-03f, + 6.96166518788906424e-05f, + 1.89645733877137904e-06f, + 4.29455004657565361e-08f, + 3.90565476357034480e-10f, + 1.48095934745267240e-11f + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 50) + { + // Max error in interpolated form: 5.195e-08 + // Max Error found at float precision = Poly: 8.502534e-08 + BOOST_MATH_STATIC const float P[] = { + 3.98942651588301770e-01f, + 4.98327234176892844e-02f, + 2.91866904423115499e-02f, + 1.35614940793742178e-02f, + 1.31409251787866793e-01f + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form: 1.782e-09 + // Max Error found at float precision = Poly: 6.473568e-08 + BOOST_MATH_STATIC const float P[] = { + 3.98942391532752700e-01f, + 4.98455950638200020e-02f, + 2.94835666900682535e-02f + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form : 3.042e-18 + // Max Error found at double precision = Poly : 5.106609e-16 Cheb : 5.239199e-16 + BOOST_MATH_STATIC const double P[] = { + 1.00000000000000000e+00, + 2.49999999999999909e-01, + 2.77777777777782257e-02, + 1.73611111111023792e-03, + 6.94444444453352521e-05, + 1.92901234513219920e-06, + 3.93675991102510739e-08, + 6.15118672704439289e-10, + 7.59407002058973446e-12, + 7.59389793369836367e-14, + 6.27767773636292611e-16, + 4.34709704153272287e-18, + 2.63417742690109154e-20, + 1.13943037744822825e-22, + 9.07926920085624812e-25 + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 500) + { + // Max error in interpolated form : 1.685e-16 + // Max Error found at double precision = Poly : 2.575063e-16 Cheb : 2.247615e+00 + BOOST_MATH_STATIC const double P[] = { + 3.98942280401425088e-01, + 4.98677850604961985e-02, + 2.80506233928312623e-02, + 2.92211225166047873e-02, + 4.44207299493659561e-02, + 1.30970574605856719e-01, + -3.35052280231727022e+00, + 2.33025711583514727e+02, + -1.13366350697172355e+04, + 4.24057674317867331e+05, + -1.23157028595698731e+07, + 2.80231938155267516e+08, + -5.01883999713777929e+09, + 7.08029243015109113e+10, + -7.84261082124811106e+11, + 6.76825737854096565e+12, + -4.49034849696138065e+13, + 2.24155239966958995e+14, + -8.13426467865659318e+14, + 2.02391097391687777e+15, + -3.08675715295370878e+15, + 2.17587543863819074e+15 + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form : 2.437e-18 + // Max Error found at double precision = Poly : 1.216719e-16 + BOOST_MATH_STATIC const double P[] = { + 3.98942280401432905e-01, + 4.98677850491434560e-02, + 2.80506308916506102e-02, + 2.92179096853915176e-02, + 4.53371208762579442e-02 + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form : 3.899e-20 + // Max Error found at float80 precision = Poly : 1.770840e-19 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 9.99999999999999999961011629e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.50000000000000001321873912e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.77777777777777703400424216e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.73611111111112764793802701e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94444444444251461247253525e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.92901234569262206386118739e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.93675988851131457141005209e-08), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.15118734688297476454205352e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59405797058091016449222685e-12), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59406599631719800679835140e-14), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.27598961062070013516660425e-16), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.35920318970387940278362992e-18), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.57372492687715452949437981e-20), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.33908663475949906992942204e-22), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.15976668870980234582896010e-25), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.46240478946376069211156548e-27) + }; + // LCOV_EXCL_STOP + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 10) + { + // Maximum Deviation Found: 6.906e-21 + // Expected Error Term : -6.903e-21 + // Maximum Relative Change in Control Points : 1.631e-04 + // Max Error found at float80 precision = Poly : 7.811948e-21 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T Y = 4.051098823547363281250e-01f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -6.158081780620616479492e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.883635969834048766148e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.892782002476195771920e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.478784996478070170327e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.988611837308006851257e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.140133766747436806179e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.117316447921276453271e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.942353667455141676001e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.493482682461387081534e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.228100538921466124653e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.195279248600467989454e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.601530760654337045917e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.504921137873298402679e+05) + }; + // LCOV_EXCL_STOP + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else if(x < 15) + { + // Maximum Deviation Found: 4.083e-21 + // Expected Error Term : -4.025e-21 + // Maximum Relative Change in Control Points : 1.304e-03 + // Max Error found at float80 precision = Poly : 2.303527e-20 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T Y = 4.033188819885253906250e-01f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -4.376373876116109401062e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.982899138682911273321e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.109477529533515397644e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.163760580110576407673e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.776501832837367371883e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.101478069227776656318e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.892071912448960299773e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.417739279982328117483e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.296963447724067390552e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.598589306710589358747e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.903662411851774878322e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.622677059040339516093e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.227776578828667629347e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.727797957441040896878e+07) + }; + // LCOV_EXCL_STOP + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else if(x < 50) + { + // Max error in interpolated form: 1.035e-21 + // Max Error found at float80 precision = Poly: 1.885872e-21 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T Y = 4.011702537536621093750e-01f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -2.227973351806078464328e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.986778486088017419036e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.805066823812285310011e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.921443721160964964623e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.517504941996594744052e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.316922639868793684401e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.535891099168810015433e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.706078229522448308087e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.351015763079160914632e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.948809013999277355098e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.967598958582595361757e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.346924657995383019558e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.998794574259956613472e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.016371355801690142095e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.768791455631826490838e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.441995678177349895640e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.482292669974971387738e+09) + }; + // LCOV_EXCL_STOP + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else + { + // Bessel I0 over[50, INF] + // Max error in interpolated form : 5.587e-20 + // Max Error found at float80 precision = Poly : 8.776852e-20 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401432677955074061e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.98677850501789875615574058e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.80506290908675604202206833e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.92194052159035901631494784e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.47422430732256364094681137e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.05971614435738691235525172e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.29180522595459823234266708e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.15122547776140254569073131e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.48491812136365376477357324e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.45569740166506688169730713e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.66857566379480730407063170e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.71924083955641197750323901e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.74276685704579268845870586e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -8.89753803265734681907148778e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.82590905134996782086242180e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.30623197145529889358596301e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.27310000726207055200805893e+10), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.64365417189215599168817064e+10) + }; + // LCOV_EXCL_STOP + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -34, 7.75] + // Max error in interpolated form : 1.274e-34 + // Max Error found at float128 precision = Poly : 3.096091e-34 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000001273856e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4999999999999999999999999999999107477496e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7777777777777777777777777777881795230918e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7361111111111111111111111106290091648808e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444444444444445629960334523101e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9290123456790123456790105563456483249753e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9367598891408415217940836339080514004844e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.1511873267825648777900014857992724731476e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266233066162999610732449709209e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266232783124723601470051895304e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2760813455591936763439337059117957836078e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3583898233049738471136482147779094353096e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5789288895299965395422423848480340736308e-20), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3157800456718804437960453545507623434606e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.8479113149412360748032684260932041506493e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2843403488398038539283241944594140493394e-27), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9042925594356556196790242908697582021825e-30), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4395919891312152120710245152115597111101e-32), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.7580986145276689333214547502373003196707e-35), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6886514018062348877723837017198859723889e-37), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.8540558465757554512570197585002702777999e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.4684706070226893763741850944911705726436e-43), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.0210715309399646335858150349406935414314e-45) + }; + // LCOV_EXCL_STOP + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 15) + { + // Bessel I0 over[7.75, 15] + // Max error in interpolated form : 7.534e-35 + // Max Error found at float128 precision = Poly : 6.123912e-34 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 9.9999999999999999992388573069504617493518e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5000000000000000007304739268173096975340e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7777777777777777744261405400543564492074e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7361111111111111209006987259719750726867e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444442399703186871329381908321e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9290123456790126709286741580242189785431e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9367598891408374246503061422528266924389e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.1511873267826068395343047827801353170966e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281262673459688011737168286944521e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281291583769928563167645746144508e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2760813455438840231126529638737436950274e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3583898233839583885132809584770578894948e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5789288891798658971960571838369339742994e-20), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3157800470129311623308216856009970266088e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.8479112701534604520063520412207286692581e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2843404822552330714586265081801727491890e-27), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9042888166225242675881424439818162458179e-30), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4396027771820721384198604723320045236973e-32), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.7577659910606076328136207973456511895030e-35), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6896548123724136624716224328803899914646e-37), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.8285850162160539150210466453921758781984e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9419071894227736216423562425429524883562e-43), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.4720374049498608905571855665134539425038e-45), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7763533278527958112907118930154738930378e-48), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.1213839473168678646697528580511702663617e-51), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0648035313124146852372607519737686740964e-53), + -BOOST_MATH_BIG_CONSTANT(T, 113, 5.1255595184052024349371058585102280860878e-57), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4652470895944157957727948355523715335882e-59) + }; + // LCOV_EXCL_STOP + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 30) + { + // Max error in interpolated form : 1.808e-34 + // Max Error found at float128 precision = Poly : 2.399403e-34 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040870793650581242239624530714032e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867780576714783790784348982178607842250e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8051948347934462928487999569249907599510e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8971143420388958551176254291160976367263e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.8197359701715582763961322341827341098897e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.3430484862908317377522273217643346601271e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7884507603213662610604413960838990199224e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.8304926482356755790062999202373909300514e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.8867173178574875515293357145875120137676e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.4261178812193528551544261731796888257644e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6453010340778116475788083817762403540097e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.0432401330113978669454035365747869477960e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2462165331309799059332310595587606836357e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.3299800389951335932792950236410844978273e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5748218240248714177527965706790413406639e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8330014378766930869945511450377736037385e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.8494610073827453236940544799030787866218e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.7244661371420647691301043350229977856476e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.2386378807889388140099109087465781254321e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.1104000573102013529518477353943384110982e+21), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.9426541092239879262282594572224300191016e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4061439136301913488512592402635688101020e+23), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.2836554760521986358980180942859101564671e+24), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6270285589905206294944214795661236766988e+25), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.7278631455211972017740134341610659484259e+26), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.1971734473772196124736986948034978906801e+26), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.8669270707172568763908838463689093500098e+27), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2368879358870281916900125550129211146626e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.8296235063297831758204519071113999839858e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.1253861666023020670144616019148954773662e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.8809536950051955163648980306847791014734e+28) + }; + // LCOV_EXCL_STOP + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Bessel I0 over[30, 100] + // Max error in interpolated form : 1.487e-34 + // Max Error found at float128 precision = Poly : 1.929924e-34 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793996798658172135362278e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867785050179084714910130342157246539820e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8050629090725751585266360464766768437048e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.9219405302833158254515212437025679637597e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.4742214371598631578107310396249912330627e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.0602983776478659136184969363625092585520e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2839507231977478205885469900971893734770e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8925739165733823730525449511456529001868e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4238082222874015159424842335385854632223e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.6759648427182491050716309699208988458050e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.7292246491169360014875196108746167872215e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.1001411442786230340015781205680362993575e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.8277628835804873490331739499978938078848e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.1208326312801432038715638596517882759639e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.4813611580683862051838126076298945680803e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.1278197693321821164135890132925119054391e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3190303792682886967459489059860595063574e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.1580767338646580750893606158043485767644e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.0256008808415702780816006134784995506549e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9044186472918017896554580836514681614475e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.2521078890073151875661384381880225635135e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3620352486836976842181057590770636605454e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.0375525734060401555856465179734887312420e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.6392664899881014534361728644608549445131e+16) + }; + // LCOV_EXCL_STOP + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form : 5.459e-35 + // Max Error found at float128 precision = Poly : 1.472240e-34 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793994605993438166526772e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867785050179084742493257495245185241487e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8050629090725735167652437695397756897920e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.9219405302839307466358297347675795965363e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.4742214369972689474366968442268908028204e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.0602984099194778006610058410222616383078e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2839502241666629677015839125593079416327e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8926354981801627920292655818232972385750e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4231921590621824187100989532173995000655e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.7264260959693775207585700654645245723497e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3890136225398811195878046856373030127018e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.1999720924619285464910452647408431234369e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2076909538525038580501368530598517194748e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5684635141332367730007149159063086133399e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.5178192543258299267923025833141286569141e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2966297919851965784482163987240461837728e+05) + }; + // LCOV_EXCL_STOP + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i0_imp(const T& x, const boost::math::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_i0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_i0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_i0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_i0_imp(x, boost::math::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline T bessel_i0(const T& x) +{ + typedef boost::math::integral_constant::digits == 0) || (boost::math::numeric_limits::radix != 2)) ? + 0 : + boost::math::numeric_limits::digits <= 24 ? + 24 : + boost::math::numeric_limits::digits <= 53 ? + 53 : + boost::math::numeric_limits::digits <= 64 ? + 64 : + boost::math::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + return bessel_i0_imp(x, tag_type()); +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_I0_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i1.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i1.hpp new file mode 100644 index 0000000000000..17e8389622b8e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_i1.hpp @@ -0,0 +1,556 @@ +// Copyright (c) 2017 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) + +// Modified Bessel function of the first kind of order zero +// we use the approximating forms derived in: +// "Rational Approximations for the Modified Bessel Function of the First Kind - I1(x) for Computations with Double Precision" +// by Pavel Holoborodko, +// see http://www.advanpix.com/2015/11/12/rational-approximations-for-the-modified-bessel-function-of-the-first-kind-i1-for-computations-with-double-precision/ +// The actual coefficients used are our own, and extend Pavel's work to precision's other than double. + +#ifndef BOOST_MATH_BESSEL_I1_HPP +#define BOOST_MATH_BESSEL_I1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the first kind of order one +// minimax rational approximations on intervals, see +// Blair and Edwards, Chalk River Report AECL-4928, 1974 + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_i1(const T& x); + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T&, const boost::math::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + //Max error in interpolated form : 1.348e-08 + // Max Error found at float precision = Poly : 1.469121e-07 + BOOST_MATH_STATIC const float P[] = { + 8.333333221e-02f, + 6.944453712e-03f, + 3.472097211e-04f, + 1.158047174e-05f, + 2.739745142e-07f, + 5.135884609e-09f, + 5.262251502e-11f, + 1.331933703e-12f + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else + { + // Max error in interpolated form: 9.000e-08 + // Max Error found at float precision = Poly: 1.044345e-07 + + BOOST_MATH_STATIC const float P[] = { + 3.98942115977513013e-01f, + -1.49581264836620262e-01f, + -4.76475741878486795e-02f, + -2.65157315524784407e-02f, + -1.47148600683672014e-01f + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form: 5.639e-17 + // Max Error found at double precision = Poly: 1.795559e-16 + + BOOST_MATH_STATIC const double P[] = { + 8.333333333333333803e-02, + 6.944444444444341983e-03, + 3.472222222225921045e-04, + 1.157407407354987232e-05, + 2.755731926254790268e-07, + 4.920949692800671435e-09, + 6.834657311305621830e-11, + 7.593969849687574339e-13, + 6.904822652741917551e-15, + 5.220157095351373194e-17, + 3.410720494727771276e-19, + 1.625212890947171108e-21, + 1.332898928162290861e-23 + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 500) + { + // Max error in interpolated form: 1.796e-16 + // Max Error found at double precision = Poly: 2.898731e-16 + + BOOST_MATH_STATIC const double P[] = { + 3.989422804014406054e-01, + -1.496033551613111533e-01, + -4.675104253598537322e-02, + -4.090895951581637791e-02, + -5.719036414430205390e-02, + -1.528189554374492735e-01, + 3.458284470977172076e+00, + -2.426181371595021021e+02, + 1.178785865993440669e+04, + -4.404655582443487334e+05, + 1.277677779341446497e+07, + -2.903390398236656519e+08, + 5.192386898222206474e+09, + -7.313784438967834057e+10, + 8.087824484994859552e+11, + -6.967602516005787001e+12, + 4.614040809616582764e+13, + -2.298849639457172489e+14, + 8.325554073334618015e+14, + -2.067285045778906105e+15, + 3.146401654361325073e+15, + -2.213318202179221945e+15 + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form: 1.320e-19 + // Max Error found at double precision = Poly: 7.065357e-17 + BOOST_MATH_STATIC const double P[] = { + 3.989422804014314820e-01, + -1.496033551467584157e-01, + -4.675105322571775911e-02, + -4.090421597376992892e-02, + -5.843630344778927582e-02 + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form: 8.086e-21 + // Max Error found at float80 precision = Poly: 7.225090e-20 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 8.33333333333333333340071817e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94444444444444442462728070e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.47222222222222318886683883e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.15740740740738880709555060e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.75573192240046222242685145e-07), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.92094986131253986838697503e-09), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.83465258979924922633502182e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59405830675154933645967137e-13), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.90369179710633344508897178e-15), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.23003610041709452814262671e-17), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.35291901027762552549170038e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.83991379419781823063672109e-21), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.87732714140192556332037815e-24), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.32120654663773147206454247e-26), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.95294659305369207813486871e-28) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 20) + { + // Max error in interpolated form: 4.258e-20 + // Max Error found at float80 precision = Poly: 2.851105e-19 + // Maximum Deviation Found : 3.887e-20 + // Expected Error Term : 3.887e-20 + // Maximum Relative Change in Control Points : 1.681e-04 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942260530218897338680e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49599542849073670179540e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.70492865454119188276875e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.12389893307392002405869e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.49696126385202602071197e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.84206507612717711565967e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.14748094784412558689584e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.70652726663596993005669e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.01659736164815617174439e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.04740659606466305607544e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.38383394696382837263656e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, -8.00779638649147623107378e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.02338237858684714480491e+10), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.41198553664947312995879e+11), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.05915186909564986897554e+12), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.00907636964168581116181e+13), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.60855263982359981275199e+13), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.12901817219239205393806e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.14861794397709807823575e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.02808138522587680348583e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.85505477056514919387171e+14) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Bessel I0 over [15, 50] + // Maximum Deviation Found: 2.444e-20 + // Expected Error Term : 2.438e-20 + // Maximum Relative Change in Control Points : 2.101e-03 + // Max Error found at float80 precision = Poly : 6.029974e-20 + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401431675205845e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49603355149968887210170e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.67510486284376330257260e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.09071458907089270559464e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.75278280327696940044714e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10591299500956620739254e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.77061766699949309115618e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.42683771801837596371638e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.17021412070404158464316e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.04154379346763380543310e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.43462345357478348323006e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.98109660274422449523837e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.74438822767781410362757e+04) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form: 2.456e-20 + // Max Error found at float80 precision = Poly: 5.446356e-20 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401432677958445e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49603355150537411254359e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.67510484842456251368526e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.09071676503922479645155e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.75256179814881566010606e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10754910257965227825040e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.67858639515616079840294e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.17266479586791298924367e-01) + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -34, 7.75] + // Max error in interpolated form: 1.835e-35 + // Max Error found at float128 precision = Poly: 1.645036e-34 + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.3333333333333333333333333333333331804098e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444444444444444444445418303082e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4722222222222222222222222222119082346591e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.1574074074074074074074074078415867655987e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7557319223985890652557318255143448192453e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9209498614260519022423916850415000626427e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8346525853139609753354247043900442393686e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266233060080535940234144302217e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9036894801151120925605467963949641957095e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.2300677879659941472662086395055636394839e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3526075563884539394691458717439115962233e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8420920639497841692288943167036233338434e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.7718669711748690065381181691546032291365e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.6549445715236427401845636880769861424730e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3437296196812697924703896979250126739676e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3912734588619073883015937023564978854893e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2839967682792395867255384448052781306897e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3790094235693528861015312806394354114982e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.0423861671932104308662362292359563970482e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7493858979396446292135661268130281652945e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.2786079392547776769387921361408303035537e-44), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.2335693685833531118863552173880047183822e-47) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 11) + { + // Max error in interpolated form: 8.574e-36 + // Maximum Deviation Found : 4.689e-36 + // Expected Error Term : 3.760e-36 + // Maximum Relative Change in Control Points : 5.204e-03 + // Max Error found at float128 precision = Poly : 2.882561e-34 + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.333333333333333326889717360850080939e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.944444444444444511272790848815114507e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.472222222222221892451965054394153443e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.157407407407408437378868534321538798e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.755731922398566216824909767320161880e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.920949861426434829568192525456800388e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.834652585308926245465686943255486934e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.594058428179852047689599244015979196e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.903689479655006062822949671528763738e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.230067791254403974475987777406992984e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.352607536815161679702105115200693346e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.842092161364672561828681848278567885e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.771862912600611801856514076709932773e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.654958704184380914803366733193713605e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.343688672071130980471207297730607625e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.392252844664709532905868749753463950e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.282086786672692641959912811902298600e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.408812012322547015191398229942864809e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.681220437734066258673404589233009892e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.072417451640733785626701738789290055e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.352218520142636864158849446833681038e-44), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.407918492276267527897751358794783640e-46) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 15) + { + //Max error in interpolated form: 7.599e-36 + // Maximum Deviation Found : 1.766e-35 + // Expected Error Term : 1.021e-35 + // Maximum Relative Change in Control Points : 6.228e-03 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.333333333333255774414858563409941233e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.944444444444897867884955912228700291e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.472222222220954970397343617150959467e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.157407407409660682751155024932538578e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.755731922369973706427272809014190998e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.920949861702265600960449699129258153e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.834652583208361401197752793379677147e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.594058441128280500819776168239988143e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.903689413939268702265479276217647209e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.230068069012898202890718644753625569e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.352606552027491657204243201021677257e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.842095100698532984651921750204843362e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.771789051329870174925649852681844169e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.655114381199979536997025497438385062e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.343415732516712339472538688374589373e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.396177019032432392793591204647901390e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.277563309255167951005939802771456315e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.449201419305514579791370198046544736e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.415430703400740634202379012388035255e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.195458831864936225409005027914934499e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.829726762743879793396637797534668039e-45), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.698302711685624490806751012380215488e-46), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.062520475425422618494185821587228317e-49), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.732372906742845717148185173723304360e-52) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 20) + { + // Max error in interpolated form: 8.864e-36 + // Max Error found at float128 precision = Poly: 8.522841e-35 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422793693152031514179994954750043e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496029423752889591425633234009799670e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.682975926820553021482820043377990241e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.138871171577224532369979905856458929e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.765350219426341341990447005798111212e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.321389275507714530941178258122955540e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.727748393898888756515271847678850411e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.123040820686242586086564998713862335e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.784112378374753535335272752884808068e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.054920416060932189433079126269416563e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.450129415468060676827180524327749553e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.758831882046487398739784498047935515e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.736936520262204842199620784338052937e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.051128683324042629513978256179115439e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.188008285959794869092624343537262342e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.108530004906954627420484180793165669e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.441516828490144766650287123765318484e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.158251664797753450664499268756393535e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.467314522709016832128790443932896401e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.896222045367960462945885220710294075e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.273382139594876997203657902425653079e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.669871448568623680543943144842394531e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.813923031370708069940575240509912588e+18) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 35) + { + // Max error in interpolated form: 6.028e-35 + // Max Error found at float128 precision = Poly: 1.368313e-34 + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422804012941975429616956496046931e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496033550576049830976679315420681402e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.675107835141866009896710750800622147e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.090104965125365961928716504473692957e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.842241652296980863361375208605487570e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.063604828033747303936724279018650633e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -9.113375972811586130949401996332817152e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.334748570425075872639817839399823709e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.759150758768733692594821032784124765e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.863672813448915255286274382558526321e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.798248643371718775489178767529282534e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.769963173932801026451013022000669267e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.381780137198278741566746511015220011e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.163891337116820832871382141011952931e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.764325864671438675151635117936912390e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.925668307403332887856809510525154955e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.416692606589060039334938090985713641e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.892398600219306424294729851605944429e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.107232903741874160308537145391245060e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.930223393531877588898224144054112045e+19), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.427759576167665663373350433236061007e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.306019279465532835530812122374386654e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.653753000392125229440044977239174472e+21), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.140760686989511568435076842569804906e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.249149337812510200795436107962504749e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.101619088427348382058085685849420866e+22) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Max error in interpolated form: 5.494e-35 + // Max Error found at float128 precision = Poly: 1.214651e-34 + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422804014326779399307367861631577e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496033551505372542086590873271571919e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.675104848454290286276466276677172664e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.090716742397105403027549796269213215e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.752570419098513588311026680089351230e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.107369803696534592906420980901195808e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.699214194000085622941721628134575121e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.953006169077813678478720427604462133e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.746618809476524091493444128605380593e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.084446249943196826652788161656973391e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.020325182518980633783194648285500554e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.510195971266257573425196228564489134e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.241661863814900938075696173192225056e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.323374362891993686413568398575539777e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.112838452096066633754042734723911040e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.369270194978310081563767560113534023e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.704295412488936504389347368131134993e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.320829576277038198439987439508754886e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.258818139077875493434420764260185306e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.396791306321498426110315039064592443e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.217617301585849875301440316301068439e+12) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form: 6.081e-35 + // Max Error found at float128 precision = Poly: 1.407151e-34 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793994605993438200208417e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4960335515053725422747977247811372936584e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.6751048484542891946087411826356811991039e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.0907167423975030452875828826630006305665e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.7525704189964886494791082898669060345483e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.1073698056568248642163476807108190176386e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.6992139012879749064623499618582631684228e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.9530409594026597988098934027440110587905e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.7462844478733532517044536719240098183686e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.0870711340681926669381449306654104739256e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.8510175413216969245241059608553222505228e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.4094682286011573747064907919522894740063e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.3128845936764406865199641778959502795443e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.1655901321962541203257516341266838487359e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.8019591025686295090160445920753823994556e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.7008089049178178697338128837158732831105e+05) + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_i1_imp(const T& x, const boost::math::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_i1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_i1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_i1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_i1_imp(x, boost::math::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline T bessel_i1(const T& x) +{ + typedef boost::math::integral_constant::digits == 0) || (boost::math::numeric_limits::radix != 2)) ? + 0 : + boost::math::numeric_limits::digits <= 24 ? + 24 : + boost::math::numeric_limits::digits <= 53 ? + 53 : + boost::math::numeric_limits::digits <= 64 ? + 64 : + boost::math::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + return bessel_i1_imp(x, tag_type()); +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_I1_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_ik.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_ik.hpp new file mode 100644 index 0000000000000..b0ae7cadb7c5c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_ik.hpp @@ -0,0 +1,447 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_BESSEL_IK_HPP +#define BOOST_MATH_BESSEL_IK_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Modified Bessel functions of the first and second kind of fractional order + +namespace boost { namespace math { + +namespace detail { + +template +struct cyl_bessel_i_small_z +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED cyl_bessel_i_small_z(T v_, T z_) : k(0), v(v_), mult(z_*z_/4) + { + BOOST_MATH_STD_USING + term = 1; + } + + BOOST_MATH_GPU_ENABLED T operator()() + { + T result = term; + ++k; + term *= mult / k; + term /= k + v; + return result; + } +private: + unsigned k; + T v; + T term; + T mult; +}; + +template +BOOST_MATH_GPU_ENABLED inline T bessel_i_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if(v < max_factorial::value) + { + prefix = pow(x / 2, v) / boost::math::tgamma(v + 1, pol); + } + else + { + prefix = v * log(x / 2) - boost::math::lgamma(v + 1, pol); + prefix = exp(prefix); + } + if(prefix == 0) + return prefix; + + cyl_bessel_i_small_z s(v, x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +// Calculate K(v, x) and K(v+1, x) by method analogous to +// Temme, Journal of Computational Physics, vol 21, 343 (1976) +template +BOOST_MATH_GPU_ENABLED int temme_ik(T v, T x, T* result_K, T* K1, const Policy& pol) +{ + T f, h, p, q, coef, sum, sum1, tolerance; + T a, b, c, d, sigma, gamma1, gamma2; + unsigned long k; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + + // |x| <= 2, Temme series converge rapidly + // |x| > 2, the larger the |x|, the slower the convergence + BOOST_MATH_ASSERT(abs(x) <= 2); + BOOST_MATH_ASSERT(abs(v) <= 0.5f); + + T gp = boost::math::tgamma1pm1(v, pol); + T gm = boost::math::tgamma1pm1(-v, pol); + + a = log(x / 2); + b = exp(v * a); + sigma = -a * v; + c = abs(v) < tools::epsilon() ? + T(1) : T(boost::math::sin_pi(v, pol) / (v * pi())); + d = abs(sigma) < tools::epsilon() ? + T(1) : T(sinh(sigma) / sigma); + gamma1 = abs(v) < tools::epsilon() ? + T(-euler()) : T((0.5f / v) * (gp - gm) * c); + gamma2 = (2 + gp + gm) * c / 2; + + // initial values + p = (gp + 1) / (2 * b); + q = (1 + gm) * b / 2; + f = (cosh(sigma) * gamma1 + d * (-a) * gamma2) / c; + h = p; + coef = 1; + sum = coef * f; + sum1 = coef * h; + + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(f); + BOOST_MATH_INSTRUMENT_VARIABLE(sigma); + BOOST_MATH_INSTRUMENT_CODE(sinh(sigma)); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma1); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma2); + BOOST_MATH_INSTRUMENT_VARIABLE(c); + BOOST_MATH_INSTRUMENT_VARIABLE(d); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + + // series summation + tolerance = tools::epsilon(); + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + f = (k * f + p + q) / (k*k - v*v); + p /= k - v; + q /= k + v; + h = p - k * f; + coef *= x * x / (4 * k); + sum += coef * f; + sum1 += coef * h; + if (abs(coef * f) < abs(sum) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in temme_ik", k, pol); + + *result_K = sum; + *K1 = 2 * sum1 / x; + + return 0; +} + +// Evaluate continued fraction fv = I_(v+1) / I_v, derived from +// Abramowitz and Stegun, Handbook of Mathematical Functions, 1972, 9.1.73 +template +BOOST_MATH_GPU_ENABLED int CF1_ik(T v, T x, T* fv, const Policy& pol) +{ + T C, D, f, a, b, delta, tiny, tolerance; + unsigned long k; + + BOOST_MATH_STD_USING + + // |x| <= |v|, CF1_ik converges rapidly + // |x| > |v|, CF1_ik needs O(|x|) iterations to converge + + // modified Lentz's method, see + // Lentz, Applied Optics, vol 15, 668 (1976) + tolerance = 2 * tools::epsilon(); + BOOST_MATH_INSTRUMENT_VARIABLE(tolerance); + tiny = sqrt(tools::min_value()); + BOOST_MATH_INSTRUMENT_VARIABLE(tiny); + C = f = tiny; // b0 = 0, replace with tiny + D = 0; + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + a = 1; + b = 2 * (v + k) / x; + C = b + a / C; + D = b + a * D; + if (C == 0) { C = tiny; } + if (D == 0) { D = tiny; } + D = 1 / D; + delta = C * D; + f *= delta; + BOOST_MATH_INSTRUMENT_VARIABLE(delta-1); + if (abs(delta - 1) <= tolerance) + { + break; + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(k); + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in CF1_ik", k, pol); + + *fv = f; + + return 0; +} + +// Calculate K(v, x) and K(v+1, x) by evaluating continued fraction +// z1 / z0 = U(v+1.5, 2v+1, 2x) / U(v+0.5, 2v+1, 2x), see +// Thompson and Barnett, Computer Physics Communications, vol 47, 245 (1987) +template +BOOST_MATH_GPU_ENABLED int CF2_ik(T v, T x, T* Kv, T* Kv1, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + T S, C, Q, D, f, a, b, q, delta, tolerance, current, prev; + unsigned long k; + + // |x| >= |v|, CF2_ik converges rapidly + // |x| -> 0, CF2_ik fails to converge + + BOOST_MATH_ASSERT(abs(x) > 1); + + // Steed's algorithm, see Thompson and Barnett, + // Journal of Computational Physics, vol 64, 490 (1986) + tolerance = tools::epsilon(); + a = v * v - 0.25f; + b = 2 * (x + 1); // b1 + D = 1 / b; // D1 = 1 / b1 + f = delta = D; // f1 = delta1 = D1, coincidence + prev = 0; // q0 + current = 1; // q1 + Q = C = -a; // Q1 = C1 because q1 = 1 + S = 1 + Q * delta; // S1 + BOOST_MATH_INSTRUMENT_VARIABLE(tolerance); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + BOOST_MATH_INSTRUMENT_VARIABLE(D); + BOOST_MATH_INSTRUMENT_VARIABLE(f); + + for (k = 2; k < policies::get_max_series_iterations(); k++) // starting from 2 + { + // continued fraction f = z1 / z0 + a -= 2 * (k - 1); + b += 2; + D = 1 / (b + a * D); + delta *= b * D - 1; + f += delta; + + // series summation S = 1 + \sum_{n=1}^{\infty} C_n * z_n / z_0 + q = (prev - (b - 2) * current) / a; + prev = current; + current = q; // forward recurrence for q + C *= -a / k; + Q += C * q; + S += Q * delta; + // + // Under some circumstances q can grow very small and C very + // large, leading to under/overflow. This is particularly an + // issue for types which have many digits precision but a narrow + // exponent range. A typical example being a "double double" type. + // To avoid this situation we can normalise q (and related prev/current) + // and C. All other variables remain unchanged in value. A typical + // test case occurs when x is close to 2, for example cyl_bessel_k(9.125, 2.125). + // + if(q < tools::epsilon()) + { + C *= q; + prev /= q; + current /= q; + q = 1; + } + + // S converges slower than f + BOOST_MATH_INSTRUMENT_VARIABLE(Q * delta); + BOOST_MATH_INSTRUMENT_VARIABLE(abs(S) * tolerance); + BOOST_MATH_INSTRUMENT_VARIABLE(S); + if (abs(Q * delta) < abs(S) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in CF2_ik", k, pol); + + if(-x < tools::log_min_value()) + *Kv = exp(0.5f * log(pi() / (2 * x)) - x - log(S)); + else + *Kv = sqrt(pi() / (2 * x)) * exp(-x) / S; + *Kv1 = *Kv * (0.5f + v + x + (v * v - 0.25f) * f) / x; + BOOST_MATH_INSTRUMENT_VARIABLE(*Kv); + BOOST_MATH_INSTRUMENT_VARIABLE(*Kv1); + + return 0; +} + +enum{ + need_i = 1, + need_k = 2 +}; + +// Compute I(v, x) and K(v, x) simultaneously by Temme's method, see +// Temme, Journal of Computational Physics, vol 19, 324 (1975) +template +BOOST_MATH_GPU_ENABLED int bessel_ik(T v, T x, T* result_I, T* result_K, int kind, const Policy& pol) +{ + // Kv1 = K_(v+1), fv = I_(v+1) / I_v + // Ku1 = K_(u+1), fu = I_(u+1) / I_u + T u, Iv, Kv, Kv1, Ku, Ku1, fv; + T W, current, prev, next; + bool reflect = false; + unsigned n, k; + int org_kind = kind; + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(kind); + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + constexpr auto function = "boost::math::bessel_ik<%1%>(%1%,%1%)"; + + if (v < 0) + { + reflect = true; + v = -v; // v is non-negative from here + kind |= need_k; + } + + T scale = 1; + T scale_sign = 1; + + n = iround(v, pol); + u = v - n; // -1/2 <= u < 1/2 + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + + if (((kind & need_i) == 0) && (fabs(4 * v * v - 25) / (8 * x) < tools::forth_root_epsilon())) + { + // A&S 9.7.2 + Iv = boost::math::numeric_limits::quiet_NaN(); // any value will do + T mu = 4 * v * v; + T eight_z = 8 * x; + Kv = 1 + (mu - 1) / eight_z + (mu - 1) * (mu - 9) / (2 * eight_z * eight_z) + (mu - 1) * (mu - 9) * (mu - 25) / (6 * eight_z * eight_z * eight_z); + Kv *= exp(-x) * constants::root_pi() / sqrt(2 * x); + } + else + { + BOOST_MATH_ASSERT(x > 0); // Error handling for x <= 0 handled in cyl_bessel_i and cyl_bessel_k + + // x is positive until reflection + W = 1 / x; // Wronskian + if (x <= 2) // x in (0, 2] + { + temme_ik(u, x, &Ku, &Ku1, pol); // Temme series + } + else // x in (2, \infty) + { + CF2_ik(u, x, &Ku, &Ku1, pol); // continued fraction CF2_ik + } + BOOST_MATH_INSTRUMENT_VARIABLE(Ku); + BOOST_MATH_INSTRUMENT_VARIABLE(Ku1); + prev = Ku; + current = Ku1; + for (k = 1; k <= n; k++) // forward recurrence for K + { + T fact = 2 * (u + k) / x; + // Check for overflow: if (max - |prev|) / fact > max, then overflow + // (max - |prev|) / fact > max + // max * (1 - fact) > |prev| + // if fact < 1: safe to compute overflow check + // if fact >= 1: won't overflow + const bool will_overflow = (fact < 1) + ? tools::max_value() * (1 - fact) > fabs(prev) + : false; + if (!will_overflow && ((tools::max_value() - fabs(prev)) / fact < fabs(current))) + { + prev /= current; + scale /= current; + scale_sign *= ((boost::math::signbit)(current) ? -1 : 1); + current = 1; + } + next = fact * current + prev; + prev = current; + current = next; + } + Kv = prev; + Kv1 = current; + BOOST_MATH_INSTRUMENT_VARIABLE(Kv); + BOOST_MATH_INSTRUMENT_VARIABLE(Kv1); + if (kind & need_i) + { + T lim = (4 * v * v + 10) / (8 * x); + lim *= lim; + lim *= lim; + lim /= 24; + if ((lim < tools::epsilon() * 10) && (x > 100)) + { + // x is huge compared to v, CF1 may be very slow + // to converge so use asymptotic expansion for large + // x case instead. Note that the asymptotic expansion + // isn't very accurate - so it's deliberately very hard + // to get here - probably we're going to overflow: + Iv = asymptotic_bessel_i_large_x(v, x, pol); + } + else if ((v > 0) && (x / v < 0.25)) + { + Iv = bessel_i_small_z_series(v, x, pol); + } + else + { + CF1_ik(v, x, &fv, pol); // continued fraction CF1_ik + Iv = scale * W / (Kv * fv + Kv1); // Wronskian relation + } + } + else + Iv = boost::math::numeric_limits::quiet_NaN(); // any value will do + } + if (reflect && (kind & need_i)) + { + BOOST_MATH_ASSERT(fabs(v - n - u) < tools::forth_root_epsilon()); + T z = (u + n % 2); + T fact = (2 / pi()) * (boost::math::sin_pi(z, pol) * Kv); + if(fact == 0) + *result_I = Iv; + else if(tools::max_value() * scale < fact) + *result_I = (org_kind & need_i) ? T(sign(fact) * scale_sign * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *result_I = Iv + fact / scale; // reflection formula + } + else + { + *result_I = Iv; + } + if(tools::max_value() * scale < Kv) + *result_K = (org_kind & need_k) ? T(sign(Kv) * scale_sign * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *result_K = Kv / scale; + BOOST_MATH_INSTRUMENT_VARIABLE(*result_I); + BOOST_MATH_INSTRUMENT_VARIABLE(*result_K); + return 0; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_IK_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j0.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j0.hpp new file mode 100644 index 0000000000000..2df027b21d705 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j0.hpp @@ -0,0 +1,192 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_J0_HPP +#define BOOST_MATH_BESSEL_J0_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the first kind of order zero +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_j0(T x); + +template +BOOST_MATH_GPU_ENABLED T bessel_j0(T x) +{ +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if (!b) + { + std::cout << "bessel_j0 called with " << typeid(x).name() << std::endl; + std::cout << "double = " << typeid(double).name() << std::endl; + std::cout << "long double = " << typeid(long double).name() << std::endl; + b = true; + } +#endif + + BOOST_MATH_STATIC const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.1298668500990866786e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7282507878605942706e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.2140700423540120665e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6302997904833794242e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.6629814655107086448e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0344222815443188943e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2117036164593528341e-01)) + }; + BOOST_MATH_STATIC const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.3883787996332290397e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.6328198300859648632e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3985097372263433271e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.5612696224219938200e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.3614022392337710626e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + BOOST_MATH_STATIC const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8319397969392084011e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2254078161378989535e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -7.2879702464464618998e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0341910641583726701e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1725046279757103576e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.4176707025325087628e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.4321196680624245801e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.8591703355916499363e+01)) + }; + BOOST_MATH_STATIC const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.5783478026152301072e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4599102262586308984e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.4055062591169562211e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8680990008359188352e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.9458766545509337327e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3307310774649071172e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.5258076240801555057e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + BOOST_MATH_STATIC const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684302e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1345386639580765797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1170523380864944322e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4806486443249270347e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5376201909008354296e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.8961548424210455236e-01)) + }; + BOOST_MATH_STATIC const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684318e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1370412495510416640e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1215350561880115730e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5028735138235608207e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5711159858080893649e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + BOOST_MATH_STATIC const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.9226600200800094098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8591953644342993800e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1183429920482737611e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2300261666214198472e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2441026745835638459e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.8033303048680751817e-03)) + }; + BOOST_MATH_STATIC const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.7105024128512061905e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1951131543434613647e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2642780169211018836e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4887231232283756582e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.0593769594993125859e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + + BOOST_MATH_STATIC const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4048255576957727686e+00)); + BOOST_MATH_STATIC const T x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.5200781102863106496e+00)); + BOOST_MATH_STATIC const T x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.160e+02)); + BOOST_MATH_STATIC const T x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.42444230422723137837e-03)); + BOOST_MATH_STATIC const T x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4130e+03)); + BOOST_MATH_STATIC const T x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.46860286310649596604e-04)); + + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + BOOST_MATH_ASSERT(x >= 0); // reflection handled elsewhere. + + if (x == 0) + { + return static_cast(1); + } + if (x <= 4) // x in (0, 4] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P1) == sizeof(Q1)); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12); + value = factor * r; + } + else if (x <= 8.0) // x in (4, 8] + { + T y = 1 - (x * x)/64; + BOOST_MATH_ASSERT(sizeof(P2) == sizeof(Q2)); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22); + value = factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + BOOST_MATH_ASSERT(sizeof(PC) == sizeof(QC)); + BOOST_MATH_ASSERT(sizeof(PS) == sizeof(QS)); + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = constants::one_div_root_pi() / sqrt(x); + // + // What follows is really just: + // + // T z = x - pi/4; + // value = factor * (rc * cos(z) - y * rs * sin(z)); + // + // But using the addition formulae for sin and cos, plus + // the special values for sin/cos of pi/4. + // + T sx = sin(x); + T cx = cos(x); + BOOST_MATH_INSTRUMENT_VARIABLE(rc); + BOOST_MATH_INSTRUMENT_VARIABLE(rs); + BOOST_MATH_INSTRUMENT_VARIABLE(factor); + BOOST_MATH_INSTRUMENT_VARIABLE(sx); + BOOST_MATH_INSTRUMENT_VARIABLE(cx); + value = factor * (rc * (cx + sx) - y * rs * (sx - cx)); + } + + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_J0_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j1.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j1.hpp new file mode 100644 index 0000000000000..fdb977952c79a --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_j1.hpp @@ -0,0 +1,179 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_J1_HPP +#define BOOST_MATH_BESSEL_J1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the first kind of order one +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_j1(T x) +{ + BOOST_MATH_STATIC const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4258509801366645672e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6781041261492395835e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1548696764841276794e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.8062904098958257677e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4615792982775076130e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0650724020080236441e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0767857011487300348e-02)) + }; + BOOST_MATH_STATIC const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1868604460820175290e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.2091902282580133541e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.0228375140097033958e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.9117614494174794095e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0742272239517380498e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + BOOST_MATH_STATIC const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.7527881995806511112e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.6608531731299018674e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.6658018905416665164e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5580665670910619166e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8113931269860667829e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.0793266148011179143e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -7.5023342220781607561e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.6179191852758252278e+00)) + }; + BOOST_MATH_STATIC const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7253905888447681194e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7128800897135812012e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.4899346165481429307e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7622777286244082666e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.4872502899596389593e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1267125065029138050e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3886978985861357615e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + BOOST_MATH_STATIC const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278571e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9422465050776411957e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.6033732483649391093e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5235293511811373833e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0982405543459346727e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.6116166443246101165e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + BOOST_MATH_STATIC const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278568e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9341243899345856590e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.5853394797230870728e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5118095066341608816e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0726385991103820119e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4550094401904961825e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + BOOST_MATH_STATIC const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3220913409857223519e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.5145160675335701966e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6178836581270835179e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8494262873223866797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7063754290207680021e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5265133846636032186e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + BOOST_MATH_STATIC const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0871281941028743574e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8194580422439972989e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4194606696037208929e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0029443582266975117e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7890229745772202641e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6383677696049909675e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + + BOOST_MATH_STATIC const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.8317059702075123156e+00)); + BOOST_MATH_STATIC const T x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0155866698156187535e+00)); + BOOST_MATH_STATIC const T x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.810e+02)); + BOOST_MATH_STATIC const T x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.2527979248768438556e-04)); + BOOST_MATH_STATIC const T x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7960e+03)); + BOOST_MATH_STATIC const T x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.8330184381246462950e-05)); + + T value, factor, r, rc, rs, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 4) // w in (0, 4] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P1) == sizeof(Q1)); + r = evaluate_rational(P1, Q1, y); + factor = w * (w + x1) * ((w - x11/256) - x12); + value = factor * r; + } + else if (w <= 8) // w in (4, 8] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P2) == sizeof(Q2)); + r = evaluate_rational(P2, Q2, y); + factor = w * (w + x2) * ((w - x21/256) - x22); + value = factor * r; + } + else // w in (8, \infty) + { + T y = 8 / w; + T y2 = y * y; + BOOST_MATH_ASSERT(sizeof(PC) == sizeof(QC)); + BOOST_MATH_ASSERT(sizeof(PS) == sizeof(QS)); + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = 1 / (sqrt(w) * constants::root_pi()); + // + // What follows is really just: + // + // T z = w - 0.75f * pi(); + // value = factor * (rc * cos(z) - y * rs * sin(z)); + // + // but using the sin/cos addition rules plus constants + // for the values of sin/cos of 3PI/4 which then cancel + // out with corresponding terms in "factor". + // + T sx = sin(x); + T cx = cos(x); + value = factor * (rc * (sx - cx) + y * rs * (sx + cx)); + } + + BOOST_MATH_ASSERT(x >= 0); // Negative values handled by the caller. + + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_J1_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jn.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jn.hpp new file mode 100644 index 0000000000000..6da09fbc4e18e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jn.hpp @@ -0,0 +1,127 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_JN_HPP +#define BOOST_MATH_BESSEL_JN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Bessel function of the first kind of integer order +// J_n(z) is the minimal solution +// n < abs(z), forward recurrence stable and usable +// n >= abs(z), forward recurrence unstable, use Miller's algorithm + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_jn(int n, T x, const Policy& pol) +{ + T value(0), factor, current, prev, next; + + BOOST_MATH_STD_USING + + // + // Reflection has to come first: + // + if (n < 0) + { + factor = static_cast((n & 0x1) ? -1 : 1); // J_{-n}(z) = (-1)^n J_n(z) + n = -n; + } + else + { + factor = 1; + } + if(x < 0) + { + factor *= (n & 0x1) ? -1 : 1; // J_{n}(-z) = (-1)^n J_n(z) + x = -x; + } + // + // Special cases: + // + if(asymptotic_bessel_large_x_limit(T(n), x)) + return factor * asymptotic_bessel_j_large_x_2(T(n), x, pol); + if (n == 0) + { + return factor * bessel_j0(x); + } + if (n == 1) + { + return factor * bessel_j1(x); + } + + if (x == 0) // n >= 2 + { + return static_cast(0); + } + + BOOST_MATH_ASSERT(n > 1); + T scale = 1; + if (n < abs(x)) // forward recurrence + { + prev = bessel_j0(x); + current = bessel_j1(x); + policies::check_series_iterations("boost::math::bessel_j_n<%1%>(%1%,%1%)", static_cast(n), pol); + for (int k = 1; k < n; k++) + { + value = (2 * k * current / x) - prev; + prev = current; + current = value; + } + } + else if((x < 1) || (n > x * x / 4) || (x < 5)) + { + return factor * bessel_j_small_z_series(T(n), x, pol); + } + else // backward recurrence + { + T fn; int s; // fn = J_(n+1) / J_n + // |x| <= n, fast convergence for continued fraction CF1 + boost::math::detail::CF1_jy(static_cast(n), x, &fn, &s, pol); + prev = fn; + current = 1; + // Check recursion won't go on too far: + policies::check_series_iterations("boost::math::bessel_j_n<%1%>(%1%,%1%)", static_cast(n), pol); + for (int k = n; k > 0; k--) + { + T fact = 2 * k / x; + if((fabs(fact) > 1) && ((tools::max_value() - fabs(prev)) / fabs(fact) < fabs(current))) + { + prev /= current; + scale /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + value = bessel_j0(x) / current; // normalization + scale = 1 / scale; + } + value *= factor; + + if(tools::max_value() * scale < fabs(value)) + return policies::raise_overflow_error("boost::math::bessel_jn<%1%>(%1%,%1%)", nullptr, pol); // LCOV_EXCL_LINE we should never get here! + + return value / scale; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JN_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy.hpp new file mode 100644 index 0000000000000..fb1b5830b587f --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy.hpp @@ -0,0 +1,600 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_JY_HPP +#define BOOST_MATH_BESSEL_JY_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Bessel functions of the first and second kind of fractional order + +namespace boost { namespace math { + + namespace detail { + + // + // Simultaneous calculation of A&S 9.2.9 and 9.2.10 + // for use in A&S 9.2.5 and 9.2.6. + // This series is quick to evaluate, but divergent unless + // x is very large, in fact it's pretty hard to figure out + // with any degree of precision when this series actually + // *will* converge!! Consequently, we may just have to + // try it and see... + // + template + BOOST_MATH_GPU_ENABLED bool hankel_PQ(T v, T x, T* p, T* q, const Policy& ) + { + BOOST_MATH_STD_USING + T tolerance = 2 * policies::get_epsilon(); + *p = 1; + *q = 0; + T k = 1; + T z8 = 8 * x; + T sq = 1; + T mu = 4 * v * v; + T term = 1; + bool ok = true; + do + { + term *= (mu - sq * sq) / (k * z8); + *q += term; + k += 1; + sq += 2; + T mult = (sq * sq - mu) / (k * z8); + ok = fabs(mult) < 0.5f; + term *= mult; + *p += term; + k += 1; + sq += 2; + } + while((fabs(term) > tolerance * *p) && ok); + return ok; + } + + // Calculate Y(v, x) and Y(v+1, x) by Temme's method, see + // Temme, Journal of Computational Physics, vol 21, 343 (1976) + template + BOOST_MATH_GPU_ENABLED int temme_jy(T v, T x, T* Y, T* Y1, const Policy& pol) + { + T g, h, p, q, f, coef, sum, sum1, tolerance; + T a, d, e, sigma; + unsigned long k; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + BOOST_MATH_ASSERT(fabs(v) <= 0.5f); // precondition for using this routine + + T gp = boost::math::tgamma1pm1(v, pol); + T gm = boost::math::tgamma1pm1(-v, pol); + T spv = boost::math::sin_pi(v, pol); + T spv2 = boost::math::sin_pi(v/2, pol); + T xp = pow(x/2, v); + + a = log(x / 2); + sigma = -a * v; + d = abs(sigma) < tools::epsilon() ? + T(1) : sinh(sigma) / sigma; + e = abs(v) < tools::epsilon() ? T(v*pi()*pi() / 2) + : T(2 * spv2 * spv2 / v); + + T g1 = (v == 0) ? T(-euler()) : T((gp - gm) / ((1 + gp) * (1 + gm) * 2 * v)); + T g2 = (2 + gp + gm) / ((1 + gp) * (1 + gm) * 2); + T vspv = (fabs(v) < tools::epsilon()) ? T(1/constants::pi()) : T(v / spv); + f = (g1 * cosh(sigma) - g2 * a * d) * 2 * vspv; + + p = vspv / (xp * (1 + gm)); + q = vspv * xp / (1 + gp); + + g = f + e * q; + h = p; + coef = 1; + sum = coef * g; + sum1 = coef * h; + + T v2 = v * v; + T coef_mult = -x * x / 4; + + // series summation + tolerance = policies::get_epsilon(); + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + f = (k * f + p + q) / (k*k - v2); + p /= k - v; + q /= k + v; + g = f + e * q; + h = p - k * g; + coef *= coef_mult / k; + sum += coef * g; + sum1 += coef * h; + if (abs(coef * g) < abs(sum) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in temme_jy", k, pol); + *Y = -sum; + *Y1 = -2 * sum1 / x; + + return 0; + } + + // Evaluate continued fraction fv = J_(v+1) / J_v, see + // Abramowitz and Stegun, Handbook of Mathematical Functions, 1972, 9.1.73 + template + BOOST_MATH_GPU_ENABLED int CF1_jy(T v, T x, T* fv, int* sign, const Policy& pol) + { + T C, D, f, a, b, delta, tiny, tolerance; + unsigned long k; + int s = 1; + + BOOST_MATH_STD_USING + + // |x| <= |v|, CF1_jy converges rapidly + // |x| > |v|, CF1_jy needs O(|x|) iterations to converge + + // modified Lentz's method, see + // Lentz, Applied Optics, vol 15, 668 (1976) + tolerance = 2 * policies::get_epsilon(); + tiny = sqrt(tools::min_value()); + C = f = tiny; // b0 = 0, replace with tiny + D = 0; + for (k = 1; k < policies::get_max_series_iterations() * 100; k++) + { + a = -1; + b = 2 * (v + k) / x; + C = b + a / C; + D = b + a * D; + if (C == 0) { C = tiny; } + if (D == 0) { D = tiny; } + D = 1 / D; + delta = C * D; + f *= delta; + if (D < 0) { s = -s; } + if (abs(delta - 1) < tolerance) + { break; } + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in CF1_jy", k / 100, pol); + *fv = -f; + *sign = s; // sign of denominator + + return 0; + } + // + // This algorithm was originally written by Xiaogang Zhang + // using std::complex to perform the complex arithmetic. + // However, that turns out to 10x or more slower than using + // all real-valued arithmetic, so it's been rewritten using + // real values only. + // + template + BOOST_MATH_GPU_ENABLED int CF2_jy(T v, T x, T* p, T* q, const Policy& pol) + { + BOOST_MATH_STD_USING + + T Cr, Ci, Dr, Di, fr, fi, a, br, bi, delta_r, delta_i, temp; + T tiny; + unsigned long k; + + // |x| >= |v|, CF2_jy converges rapidly + // |x| -> 0, CF2_jy fails to converge + BOOST_MATH_ASSERT(fabs(x) > 1); + + // modified Lentz's method, complex numbers involved, see + // Lentz, Applied Optics, vol 15, 668 (1976) + T tolerance = 2 * policies::get_epsilon(); + tiny = sqrt(tools::min_value()); + Cr = fr = -0.5f / x; + Ci = fi = 1; + //Dr = Di = 0; + T v2 = v * v; + a = (0.25f - v2) / x; // Note complex this one time only! + br = 2 * x; + bi = 2; + temp = Cr * Cr + 1; + Ci = bi + a * Cr / temp; + Cr = br + a / temp; + Dr = br; + Di = bi; + if (fabs(Cr) + fabs(Ci) < tiny) { Cr = tiny; } + if (fabs(Dr) + fabs(Di) < tiny) { Dr = tiny; } + temp = Dr * Dr + Di * Di; + Dr = Dr / temp; + Di = -Di / temp; + delta_r = Cr * Dr - Ci * Di; + delta_i = Ci * Dr + Cr * Di; + temp = fr; + fr = temp * delta_r - fi * delta_i; + fi = temp * delta_i + fi * delta_r; + for (k = 2; k < policies::get_max_series_iterations(); k++) + { + a = static_cast(k) - 0.5f; + a *= a; + a -= v2; + bi += 2; + temp = Cr * Cr + Ci * Ci; + Cr = br + a * Cr / temp; + Ci = bi - a * Ci / temp; + Dr = br + a * Dr; + Di = bi + a * Di; + if (fabs(Cr) + fabs(Ci) < tiny) { Cr = tiny; } + if (fabs(Dr) + fabs(Di) < tiny) { Dr = tiny; } + temp = Dr * Dr + Di * Di; + Dr = Dr / temp; + Di = -Di / temp; + delta_r = Cr * Dr - Ci * Di; + delta_i = Ci * Dr + Cr * Di; + temp = fr; + fr = temp * delta_r - fi * delta_i; + fi = temp * delta_i + fi * delta_r; + if (fabs(delta_r - 1) + fabs(delta_i) < tolerance) + break; + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in CF2_jy", k, pol); + *p = fr; + *q = fi; + + return 0; + } + + BOOST_MATH_STATIC const int need_j = 1; + BOOST_MATH_STATIC const int need_y = 2; + + // Compute J(v, x) and Y(v, x) simultaneously by Steed's method, see + // Barnett et al, Computer Physics Communications, vol 8, 377 (1974) + template + BOOST_MATH_GPU_ENABLED int bessel_jy(T v, T x, T* J, T* Y, int kind, const Policy& pol) + { + BOOST_MATH_ASSERT(x >= 0); + + T u, Jv, Ju, Yv, Yv1, Yu, Yu1(0), fv, fu; + T W, p, q, gamma, current, prev, next; + bool reflect = false; + unsigned n, k; + int s; + int org_kind = kind; + T cp = 0; + T sp = 0; + + constexpr auto function = "boost::math::bessel_jy<%1%>(%1%,%1%)"; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + if (v < 0) + { + reflect = true; + v = -v; // v is non-negative from here + } + if (v > static_cast((boost::math::numeric_limits::max)())) + { + *J = *Y = policies::raise_evaluation_error(function, "Order of Bessel function is too large to evaluate: got %1%", v, pol); + return 1; // LCOV_EXCL_LINE previous line will throw. + } + n = static_cast(iround(v, pol)); + u = v - n; // -1/2 <= u < 1/2 + + if(reflect) + { + T z = (u + n % 2); + cp = boost::math::cos_pi(z, pol); + sp = boost::math::sin_pi(z, pol); + if(u != 0) + kind = need_j|need_y; // need both for reflection formula + } + + if(x == 0) + { + if (v == 0) + *J = 1; // LCOV_EXCL_LINE multiprecision case only + else if ((u == 0) || !reflect) + *J = 0; + else if(kind & need_j) + *J = policies::raise_domain_error(function, "Value of Bessel J_v(x) is complex-infinity at %1%", x, pol); // complex infinity + else + *J = boost::math::numeric_limits::quiet_NaN(); // LCOV_EXCL_LINE, we should never get here, any value will do, not using J. + + if((kind & need_y) == 0) + *Y = boost::math::numeric_limits::quiet_NaN(); // any value will do, not using Y. + else + { + // We shoud never get here: + BOOST_MATH_ASSERT(x != 0); // LCOV_EXCL_LINE + } + return 1; + } + + // x is positive until reflection + W = T(2) / (x * pi()); // Wronskian + T Yv_scale = 1; + if(((kind & need_y) == 0) && ((x < 1) || (v > x * x / 4) || (x < 5))) + { + // + // This series will actually converge rapidly for all small + // x - say up to x < 20 - but the first few terms are large + // and divergent which leads to large errors :-( + // + Jv = bessel_j_small_z_series(v, x, pol); + Yv = boost::math::numeric_limits::quiet_NaN(); + } + else if((x < 1) && (u != 0) && (log(policies::get_epsilon() / 2) > v * log((x/2) * (x/2) / v))) + { + // Evaluate using series representations. + // This is particularly important for x << v as in this + // area temme_jy may be slow to converge, if it converges at all. + // Requires x is not an integer. + if(kind&need_j) + Jv = bessel_j_small_z_series(v, x, pol); + else + Jv = boost::math::numeric_limits::quiet_NaN(); + if((org_kind&need_y && (!reflect || (cp != 0))) + || (org_kind & need_j && (reflect && (sp != 0)))) + { + // Only calculate if we need it, and if the reflection formula will actually use it: + Yv = bessel_y_small_z_series(v, x, &Yv_scale, pol); + } + else + Yv = boost::math::numeric_limits::quiet_NaN(); + } + else if((u == 0) && (x < policies::get_epsilon())) + { + // Truncated series evaluation for small x and v an integer, + // much quicker in this area than temme_jy below. + // This code is only used in the multiprecision case, otherwise + // we go via bessel_jn. + // LCOV_EXCL_START + if(kind&need_j) + Jv = bessel_j_small_z_series(v, x, pol); + else + Jv = boost::math::numeric_limits::quiet_NaN(); + if((org_kind&need_y && (!reflect || (cp != 0))) + || (org_kind & need_j && (reflect && (sp != 0)))) + { + // Only calculate if we need it, and if the reflection formula will actually use it: + Yv = bessel_yn_small_z(static_cast(n), x, &Yv_scale, pol); + } + else + Yv = boost::math::numeric_limits::quiet_NaN(); + // LCOV_EXCL_STOP + } + else if(asymptotic_bessel_large_x_limit(v, x)) + { + if(kind&need_y) + { + Yv = asymptotic_bessel_y_large_x_2(v, x, pol); + } + else + Yv = boost::math::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + if(kind&need_j) + { + Jv = asymptotic_bessel_j_large_x_2(v, x, pol); + } + else + Jv = boost::math::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + } + else if((x > 8) && hankel_PQ(v, x, &p, &q, pol)) + { + // + // Hankel approximation: note that this method works best when x + // is large, but in that case we end up calculating sines and cosines + // of large values, with horrendous resulting accuracy. It is fast though + // when it works.... + // + // Normally we calculate sin/cos(chi) where: + // + // chi = x - fmod(T(v / 2 + 0.25f), T(2)) * boost::math::constants::pi(); + // + // But this introduces large errors, so use sin/cos addition formulae to + // improve accuracy: + // + T mod_v = fmod(T(v / 2 + 0.25f), T(2)); + T sx = sin(x); + T cx = cos(x); + T sv = boost::math::sin_pi(mod_v, pol); + T cv = boost::math::cos_pi(mod_v, pol); + + T sc = sx * cv - sv * cx; // == sin(chi); + T cc = cx * cv + sx * sv; // == cos(chi); + T chi = boost::math::constants::root_two() / (boost::math::constants::root_pi() * sqrt(x)); //sqrt(2 / (boost::math::constants::pi() * x)); + Yv = chi * (p * sc + q * cc); + Jv = chi * (p * cc - q * sc); + } + else if (x <= 2) // x in (0, 2] + { + if(temme_jy(u, x, &Yu, &Yu1, pol)) // Temme series + { + // domain error, this should really have already been handled. + *J = *Y = Yu; // LCOV_EXCL_LINE + return 1; // LCOV_EXCL_LINE + } + prev = Yu; + current = Yu1; + T scale = 1; + policies::check_series_iterations(function, n, pol); + for (k = 1; k <= n; k++) // forward recurrence for Y + { + T fact = 2 * (u + k) / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + scale /= current; + prev /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + Yv = prev; + Yv1 = current; + if(kind&need_j) + { + CF1_jy(v, x, &fv, &s, pol); // continued fraction CF1_jy + Jv = scale * W / (Yv * fv - Yv1); // Wronskian relation + } + else + Jv = boost::math::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + Yv_scale = scale; + } + else // x in (2, \infty) + { + // Get Y(u, x): + + T ratio; + CF1_jy(v, x, &fv, &s, pol); + // tiny initial value to prevent overflow + T init = sqrt(tools::min_value()); + BOOST_MATH_INSTRUMENT_VARIABLE(init); + prev = fv * s * init; + current = s * init; + if(v < max_factorial::value) + { + policies::check_series_iterations(function, n, pol); + for (k = n; k > 0; k--) // backward recurrence for J + { + next = 2 * (u + k) * current / x - prev; + // + // We can't allow next to completely cancel out or the subsequent logic breaks. + // Pretend that one bit did not cancel: + if (next == 0) + { + next = prev * tools::epsilon() / 2; // LCOV_EXCL_LINE requires specific hardware and rounding to trigger, does get tested on msvc + } + prev = current; + current = next; + } + ratio = (s * init) / current; // scaling ratio + // can also call CF1_jy() to get fu, not much difference in precision + fu = prev / current; + } + else + { + // + // When v is large we may get overflow in this calculation + // leading to NaN's and other nasty surprises: + // + policies::check_series_iterations(function, n, pol); + bool over = false; + for (k = n; k > 0; k--) // backward recurrence for J + { + T t = 2 * (u + k) / x; + if((t > 1) && (tools::max_value() / t < current)) + { + over = true; + break; + } + next = t * current - prev; + prev = current; + current = next; + } + if(!over) + { + ratio = (s * init) / current; // scaling ratio + // can also call CF1_jy() to get fu, not much difference in precision + fu = prev / current; + } + else + { + ratio = 0; + fu = 1; + } + } + CF2_jy(u, x, &p, &q, pol); // continued fraction CF2_jy + T t = u / x - fu; // t = J'/J + gamma = (p - t) / q; + // + // We can't allow gamma to cancel out to zero completely as it messes up + // the subsequent logic. So pretend that one bit didn't cancel out + // and set to a suitably small value. The only test case we've been able to + // find for this, is when v = 8.5 and x = 4*PI. + // + if(gamma == 0) + { + gamma = u * tools::epsilon() / x; // LCOV_EXCL_LINE requires specific hardware and rounding to trigger, does get tested on msvc + } + BOOST_MATH_INSTRUMENT_VARIABLE(current); + BOOST_MATH_INSTRUMENT_VARIABLE(W); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma); + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(t); + Ju = sign(current) * sqrt(W / (q + gamma * (p - t))); + BOOST_MATH_INSTRUMENT_VARIABLE(Ju); + + Jv = Ju * ratio; // normalization + + Yu = gamma * Ju; + Yu1 = Yu * (u/x - p - q/gamma); + + if(kind&need_y) + { + // compute Y: + prev = Yu; + current = Yu1; + policies::check_series_iterations(function, n, pol); + for (k = 1; k <= n; k++) // forward recurrence for Y + { + T fact = 2 * (u + k) / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + prev /= current; + Yv_scale /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + Yv = prev; + } + else + Yv = boost::math::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + } + + if (reflect) + { + if((sp != 0) && (tools::max_value() * fabs(Yv_scale) < fabs(sp * Yv))) + *J = org_kind & need_j ? T(-sign(sp) * sign(Yv) * (Yv_scale != 0 ? sign(Yv_scale) : 1) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *J = cp * Jv - (sp == 0 ? T(0) : T((sp * Yv) / Yv_scale)); // reflection formula + if((cp != 0) && (tools::max_value() * fabs(Yv_scale) < fabs(cp * Yv))) + *Y = org_kind & need_y ? T(-sign(cp) * sign(Yv) * (Yv_scale != 0 ? sign(Yv_scale) : 1) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *Y = (sp != 0 ? sp * Jv : T(0)) + (cp == 0 ? T(0) : T((cp * Yv) / Yv_scale)); + } + else + { + *J = Jv; + if(tools::max_value() * fabs(Yv_scale) < fabs(Yv)) + *Y = org_kind & need_y ? T(sign(Yv) * sign(Yv_scale) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *Y = Yv / Yv_scale; + } + + return 0; + } + + } // namespace detail + +}} // namespaces + +#endif // BOOST_MATH_BESSEL_JY_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_asym.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_asym.hpp new file mode 100644 index 0000000000000..51e4efafca8b7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_asym.hpp @@ -0,0 +1,230 @@ +// Copyright (c) 2007 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Contains asymptotic expansions for Bessel J(v,x) and Y(v,x) +// functions, as x -> INF. +// +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_amplitude(T v, T x) +{ + // Calculate the amplitude of J(v, x) and Y(v, x) for large + // x: see A&S 9.2.28. + BOOST_MATH_STD_USING + T s = 1; + T mu = 4 * v * v; + T txq = 2 * x; + txq *= txq; + + s += (mu - 1) / (2 * txq); + s += 3 * (mu - 1) * (mu - 9) / (txq * txq * 8); + s += 15 * (mu - 1) * (mu - 9) * (mu - 25) / (txq * txq * txq * 8 * 6); + + return sqrt(s * 2 / (constants::pi() * x)); +} + +template +BOOST_MATH_GPU_ENABLED T asymptotic_bessel_phase_mx(T v, T x) +{ + // + // Calculate the phase of J(v, x) and Y(v, x) for large x. + // See A&S 9.2.29. + // Note that the result returned is the phase less (x - PI(v/2 + 1/4)) + // which we'll factor in later when we calculate the sines/cosines of the result: + // + T mu = 4 * v * v; + T denom = 4 * x; + T denom_mult = denom * denom; + + T s = 0; + s += (mu - 1) / (2 * denom); + denom *= denom_mult; + s += (mu - 1) * (mu - 25) / (6 * denom); + denom *= denom_mult; + s += (mu - 1) * (mu * mu - 114 * mu + 1073) / (5 * denom); + denom *= denom_mult; + s += (mu - 1) * (5 * mu * mu * mu - 1535 * mu * mu + 54703 * mu - 375733) / (14 * denom); + return s; +} + +template +BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_y_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.19. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + T ampl = asymptotic_bessel_amplitude(v, x); + if (0 == ampl) + return ampl; + T phase = asymptotic_bessel_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 + 1/4) term not added to the + // phase when we calculated it. + // + T cx = cos(x); + T sx = sin(x); + T ci = boost::math::cos_pi(v / 2 + 0.25f, pol); + T si = boost::math::sin_pi(v / 2 + 0.25f, pol); + T sin_phase = sin(phase) * (cx * ci + sx * si) + cos(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + return sin_phase * ampl; +} + +template +BOOST_MATH_GPU_ENABLED inline T asymptotic_bessel_j_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.19. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + T ampl = asymptotic_bessel_amplitude(v, x); + if (0 == ampl) + return ampl; // shortcut. + T phase = asymptotic_bessel_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 + 1/4) term not added to the + // phase when we calculated it. + // + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + T cx = cos(x); + T sx = sin(x); + T ci = boost::math::cos_pi(v / 2 + 0.25f, pol); + T si = boost::math::sin_pi(v / 2 + 0.25f, pol); + T sin_phase = cos(phase) * (cx * ci + sx * si) - sin(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_VARIABLE(sin_phase); + return sin_phase * ampl; +} + +template +BOOST_MATH_GPU_ENABLED inline bool asymptotic_bessel_large_x_limit(int v, const T& x) +{ + BOOST_MATH_STD_USING + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + BOOST_MATH_ASSERT(v >= 0); + return (v ? v : 1) < x * 0.004f; +} + +template +BOOST_MATH_GPU_ENABLED inline bool asymptotic_bessel_large_x_limit(const T& v, const T& x) +{ + BOOST_MATH_STD_USING + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + return BOOST_MATH_GPU_SAFE_MAX(T(fabs(v)), T(1)) < x * sqrt(tools::forth_root_epsilon()); +} + +template +BOOST_MATH_GPU_ENABLED void temme_asymptotic_y_small_x(T v, T x, T* Y, T* Y1, const Policy& pol) +{ + T c = 1; + T p = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, -v) / boost::math::tgamma(1 - v, pol); + T q = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, v) / boost::math::tgamma(1 + v, pol); + T f = (p - q) / v; + T g_prefix = boost::math::sin_pi(v / 2, pol); + g_prefix *= g_prefix * 2 / v; + T g = f + g_prefix * q; + T h = p; + T c_mult = -x * x / 4; + + T y(c * g), y1(c * h); + + for(int k = 1; k < policies::get_max_series_iterations(); ++k) + { + f = (k * f + p + q) / (k*k - v*v); + p /= k - v; + q /= k + v; + c *= c_mult / k; + T c1 = pow(-x * x / 4, T(k)) / factorial(k, pol); + g = f + g_prefix * q; + h = -k * g + p; + y += c * g; + y1 += c * h; + if(c * g / tools::epsilon() < y) + break; + } + + *Y = -y; + *Y1 = (-2 / x) * y1; +} + +template +BOOST_MATH_GPU_ENABLED T asymptotic_bessel_i_large_x(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + T s = 1; + T mu = 4 * v * v; + T ex = 8 * x; + T num = mu - 1; + T denom = ex; + + s -= num / denom; + + num *= mu - 9; + denom *= ex * 2; + s += num / denom; + + num *= mu - 25; + denom *= ex * 3; + s -= num / denom; + + // Try and avoid overflow to the last minute: + T e = exp(x/2); + + s = e * (e * s / sqrt(2 * x * constants::pi())); + + return (boost::math::isfinite)(s) ? + s : policies::raise_overflow_error("boost::math::asymptotic_bessel_i_large_x<%1%>(%1%,%1%)", nullptr, pol); +} + +}}} // namespaces + +#endif + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp new file mode 100644 index 0000000000000..9bdbb8584218d --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp @@ -0,0 +1,141 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Contains asymptotic expansions for derivatives of Bessel J(v,x) and Y(v,x) +// functions, as x -> INF. +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +inline T asymptotic_bessel_derivative_amplitude(T v, T x) +{ + // Calculate the amplitude for J'(v,x) and I'(v,x) + // for large x: see A&S 9.2.30. + BOOST_MATH_STD_USING + T s = 1; + const T mu = 4 * v * v; + T txq = 2 * x; + txq *= txq; + + s -= (mu - 3) / (2 * txq); + s -= ((mu - 1) * (mu - 45)) / (txq * txq * 8); + + return sqrt(s * 2 / (boost::math::constants::pi() * x)); +} + +template +inline T asymptotic_bessel_derivative_phase_mx(T v, T x) +{ + // Calculate the phase of J'(v, x) and Y'(v, x) for large x. + // See A&S 9.2.31. + // Note that the result returned is the phase less (x - PI(v/2 - 1/4)) + // which we'll factor in later when we calculate the sines/cosines of the result: + const T mu = 4 * v * v; + const T mu2 = mu * mu; + const T mu3 = mu2 * mu; + T denom = 4 * x; + T denom_mult = denom * denom; + + T s = 0; + s += (mu + 3) / (2 * denom); + denom *= denom_mult; + s += (mu2 + (46 * mu) - 63) / (6 * denom); + denom *= denom_mult; + s += (mu3 + (185 * mu2) - (2053 * mu) + 1899) / (5 * denom); + return s; +} + +template +inline T asymptotic_bessel_y_derivative_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.20. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + const T ampl = asymptotic_bessel_derivative_amplitude(v, x); + const T phase = asymptotic_bessel_derivative_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 - 1/4) term not added to the + // phase when we calculated it. + // + const T cx = cos(x); + const T sx = sin(x); + const T vd2shifted = (v / 2) - 0.25f; + const T ci = cos_pi(vd2shifted, pol); + const T si = sin_pi(vd2shifted, pol); + const T sin_phase = sin(phase) * (cx * ci + sx * si) + cos(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + return sin_phase * ampl; +} + +template +inline T asymptotic_bessel_j_derivative_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.20. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + const T ampl = asymptotic_bessel_derivative_amplitude(v, x); + const T phase = asymptotic_bessel_derivative_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 - 1/4) term not added to the + // phase when we calculated it. + // + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + const T cx = cos(x); + const T sx = sin(x); + const T vd2shifted = (v / 2) - 0.25f; + const T ci = cos_pi(vd2shifted, pol); + const T si = sin_pi(vd2shifted, pol); + const T sin_phase = cos(phase) * (cx * ci + sx * si) - sin(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_VARIABLE(sin_phase); + return sin_phase * ampl; +} + +template +inline bool asymptotic_bessel_derivative_large_x_limit(const T& v, const T& x) +{ + BOOST_MATH_STD_USING + // + // This function is the copy of math::asymptotic_bessel_large_x_limit + // It means that we use the same rules for determining how x is large + // compared to v. + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + return (std::max)(T(fabs(v)), T(1)) < x * sqrt(boost::math::tools::forth_root_epsilon()); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp new file mode 100644 index 0000000000000..d7bb64f8cd507 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp @@ -0,0 +1,219 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) + +#ifndef BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP +#define BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct bessel_j_derivative_small_z_series_term +{ + typedef T result_type; + + bessel_j_derivative_small_z_series_term(T v_, T x) + : N(0), v(v_), term(1), mult(x / 2) + { + mult *= -mult; + // iterate if v == 0; otherwise result of + // first term is 0 and tools::sum_series stops + if (v == 0) + iterate(); + } + T operator()() + { + T r = term * (v + 2 * N); + iterate(); + return r; + } +private: + void iterate() + { + ++N; + term *= mult / (N * (N + v)); + } + unsigned N; + T v; + T term; + T mult; +}; +// +// Series evaluation for BesselJ'(v, z) as z -> 0. +// It's derivative of http://functions.wolfram.com/Bessel-TypeFunctions/BesselJ/06/01/04/01/01/0003/ +// Converges rapidly for all z << v. +// +template +inline T bessel_j_derivative_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if (v < boost::math::max_factorial::value) + { + prefix = pow(x / 2, v - 1) / 2 / boost::math::tgamma(v + 1, pol); + } + else + { + prefix = (v - 1) * log(x / 2) - constants::ln_two() - boost::math::lgamma(v + 1, pol); + prefix = exp(prefix); + } + if (0 == prefix) + return prefix; + + bessel_j_derivative_small_z_series_term s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + boost::math::policies::check_series_iterations("boost::math::bessel_j_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +template +struct bessel_y_derivative_small_z_series_term_a +{ + typedef T result_type; + + bessel_y_derivative_small_z_series_term_a(T v_, T x) + : N(0), v(v_) + { + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term * (-v + 2 * N); + ++N; + term *= mult / (N * (N - v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; + +template +struct bessel_y_derivative_small_z_series_term_b +{ + typedef T result_type; + + bessel_y_derivative_small_z_series_term_b(T v_, T x) + : N(0), v(v_) + { + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term * (v + 2 * N); + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series form for BesselY' as z -> 0, +// It's derivative of http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/01/0003/ +// This series is only useful when the second term is small compared to the first +// otherwise we get catastrophic cancellation errors. +// +// Approximating tgamma(v) by v^v, and assuming |tgamma(-z)| < eps we end up requiring: +// eps/2 * v^v(x/2)^-v > (x/2)^v or log(eps/2) > v log((x/2)^2/v) +// +template +inline T bessel_y_derivative_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "bessel_y_derivative_small_z_series<%1%>(%1%,%1%)"; + T prefix; + T gam; + T p = log(x / 2); + T scale = 1; + bool need_logs = (v >= boost::math::max_factorial::value) || (boost::math::tools::log_max_value() / v < fabs(p)); + + if (!need_logs) + { + gam = boost::math::tgamma(v, pol); + p = pow(x / 2, v + 1) * 2; + if (boost::math::tools::max_value() * p < gam) + { + scale /= gam; + gam = 1; + if (boost::math::tools::max_value() * p < gam) + { + // This term will overflow to -INF, when combined with the series below it becomes +INF: + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -gam / (boost::math::constants::pi() * p); + } + else + { + gam = boost::math::lgamma(v, pol); + p = (v + 1) * p + constants::ln_two(); + prefix = gam - log(boost::math::constants::pi()) - p; + if (boost::math::tools::log_max_value() < prefix) + { + prefix -= log(boost::math::tools::max_value() / 4); + scale /= (boost::math::tools::max_value() / 4); + if (boost::math::tools::log_max_value() < prefix) + { + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -exp(prefix); + } + bessel_y_derivative_small_z_series_term_a s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + boost::math::policies::check_series_iterations("boost::math::bessel_y_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + result *= prefix; + + p = pow(x / 2, v - 1) / 2; + if (!need_logs) + { + prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v, pol) * p / boost::math::constants::pi(); + } + else + { + int sgn {}; + prefix = boost::math::lgamma(-v, &sgn, pol) + (v - 1) * log(x / 2) - constants::ln_two(); + prefix = exp(prefix) * sgn / boost::math::constants::pi(); + } + bessel_y_derivative_small_z_series_term_b s2(v, x); + max_iter = boost::math::policies::get_max_series_iterations(); + + T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon(), max_iter); + + result += scale * prefix * b; + if(scale * tools::max_value() < result) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + return result / scale; +} + +// Calculating of BesselY'(v,x) with small x (x < epsilon) and integer x using derivatives +// of formulas in http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/02/ +// seems to lose precision. Instead using linear combination of regular Bessel is preferred. + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_series.hpp new file mode 100644 index 0000000000000..d9acfc4441880 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_series.hpp @@ -0,0 +1,267 @@ +// Copyright (c) 2011 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) + +#ifndef BOOST_MATH_BESSEL_JN_SERIES_HPP +#define BOOST_MATH_BESSEL_JN_SERIES_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost { namespace math { namespace detail{ + +template +struct bessel_j_small_z_series_term +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED bessel_j_small_z_series_term(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = term; + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series evaluation for BesselJ(v, z) as z -> 0. +// See http://functions.wolfram.com/Bessel-TypeFunctions/BesselJ/06/01/04/01/01/0003/ +// Converges rapidly for all z << v. +// +template +BOOST_MATH_GPU_ENABLED inline T bessel_j_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if(v < max_factorial::value) + { + prefix = pow(x / 2, v) / boost::math::tgamma(v+1, pol); + } + else + { + prefix = v * log(x / 2) - boost::math::lgamma(v+1, pol); + prefix = exp(prefix); + } + if(0 == prefix) + return prefix; + + bessel_j_small_z_series_term s(v, x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +template +struct bessel_y_small_z_series_term_a +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED bessel_y_small_z_series_term_a(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + BOOST_MATH_GPU_ENABLED T operator()() + { + BOOST_MATH_STD_USING + T r = term; + ++N; + term *= mult / (N * (N - v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; + +template +struct bessel_y_small_z_series_term_b +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED bessel_y_small_z_series_term_b(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = term; + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series form for BesselY as z -> 0, +// see: http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/01/0003/ +// This series is only useful when the second term is small compared to the first +// otherwise we get catastrophic cancellation errors. +// +// Approximating tgamma(v) by v^v, and assuming |tgamma(-z)| < eps we end up requiring: +// eps/2 * v^v(x/2)^-v > (x/2)^v or log(eps/2) > v log((x/2)^2/v) +// +template +BOOST_MATH_GPU_ENABLED inline T bessel_y_small_z_series(T v, T x, T* pscale, const Policy& pol) +{ + BOOST_MATH_STD_USING + constexpr auto function = "bessel_y_small_z_series<%1%>(%1%,%1%)"; + T prefix; + T gam; + T p = log(x / 2); + T scale = 1; + bool need_logs = (v >= max_factorial::value) || (tools::log_max_value() / v < fabs(p)); + + if(!need_logs) + { + gam = boost::math::tgamma(v, pol); + p = pow(x / 2, v); + if(tools::max_value() * p < gam) + { + scale /= gam; + gam = 1; + /* + * We can never get here, it would require p < 1/max_value. + if(tools::max_value() * p < gam) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + */ + } + prefix = -gam / (constants::pi() * p); + } + else + { + gam = boost::math::lgamma(v, pol); + p = v * p; + prefix = gam - log(constants::pi()) - p; + if(tools::log_max_value() < prefix) + { + prefix -= log(tools::max_value() / 4); + scale /= (tools::max_value() / 4); + if(tools::log_max_value() < prefix) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -exp(prefix); + } + bessel_y_small_z_series_term_a s(v, x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + *pscale = scale; + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_y_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + result *= prefix; + + if(!need_logs) + { + prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v, pol) * p / constants::pi(); + } + else + { + int sgn {}; + prefix = boost::math::lgamma(-v, &sgn, pol) + p; + prefix = exp(prefix) * sgn / constants::pi(); + } + bessel_y_small_z_series_term_b s2(v, x); + max_iter = policies::get_max_series_iterations(); + + T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon(), max_iter); + + result -= scale * prefix * b; + return result; +} + +template +BOOST_MATH_GPU_ENABLED T bessel_yn_small_z(int n, T z, T* scale, const Policy& pol) +{ + // + // See http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/02/ + // + // Note that when called we assume that x < epsilon and n is a positive integer. + // + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(n >= 0); + BOOST_MATH_ASSERT((z < policies::get_epsilon())); + + if(n == 0) + { + return (2 / constants::pi()) * (log(z / 2) + constants::euler()); + } + else if(n == 1) + { + return (z / constants::pi()) * log(z / 2) + - 2 / (constants::pi() * z) + - (z / (2 * constants::pi())) * (1 - 2 * constants::euler()); + } + else if(n == 2) + { + return (z * z) / (4 * constants::pi()) * log(z / 2) + - (4 / (constants::pi() * z * z)) + - ((z * z) / (8 * constants::pi())) * (T(3)/2 - 2 * constants::euler()); + } + else + { + #if (defined(__GNUC__) && __GNUC__ == 13) + auto p = static_cast(pow(z / 2, T(n))); + #else + auto p = static_cast(pow(z / 2, n)); + #endif + + T result = -((boost::math::factorial(static_cast(n - 1), pol) / constants::pi())); + if(p * tools::max_value() < fabs(result)) + { + T div = tools::max_value() / 8; + result /= div; + *scale /= div; + if(p * tools::max_value() < result) + { + // Impossible to get here?? + return -policies::raise_overflow_error("bessel_yn_small_z<%1%>(%1%,%1%)", nullptr, pol); // LCOV_EXCL_LINE + } + } + return result / p; + } +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JN_SERIES_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_zero.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_zero.hpp new file mode 100644 index 0000000000000..15671c0df75db --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_jy_zero.hpp @@ -0,0 +1,643 @@ +// Copyright (c) 2013 Christopher Kormanyos +// 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) +// +// This work is based on an earlier work: +// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", +// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 +// +// This header contains implementation details for estimating the zeros +// of cylindrical Bessel and Neumann functions on the positive real axis. +// Support is included for both positive as well as negative order. +// Various methods are used to estimate the roots. These include +// empirical curve fitting and McMahon's asymptotic approximation +// for small order, uniform asymptotic expansion for large order, +// and iteration and root interlacing for negative order. +// +#ifndef BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ + #define BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ + + #include + #include + #include + #include + #include + #include + #include + #include + + #ifndef BOOST_MATH_HAS_NVRTC + #include + #endif + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_suppress 20012 + #endif + + namespace boost { namespace math { + namespace detail + { + namespace bessel_zero + { + template + BOOST_MATH_GPU_ENABLED T equation_nist_10_21_19(const T& v, const T& a) + { + // Get the initial estimate of the m'th root of Jv or Yv. + // This subroutine is used for the order m with m > 1. + // The order m has been used to create the input parameter a. + + // This is Eq. 10.21.19 in the NIST Handbook. + const T mu = (v * v) * 4U; + const T mu_minus_one = mu - T(1); + const T eight_a_inv = T(1) / (a * 8U); + const T eight_a_inv_squared = eight_a_inv * eight_a_inv; + + const T term3 = ((mu_minus_one * 4U) * ((mu * 7U) - T(31U) )) / 3U; + const T term5 = ((mu_minus_one * 32U) * ((((mu * 83U) - T(982U) ) * mu) + T(3779U) )) / 15U; + const T term7 = ((mu_minus_one * 64U) * ((((((mu * 6949U) - T(153855UL)) * mu) + T(1585743UL)) * mu) - T(6277237UL))) / 105U; + + return a + (((( - term7 + * eight_a_inv_squared - term5) + * eight_a_inv_squared - term3) + * eight_a_inv_squared - mu_minus_one) + * eight_a_inv); + } + + template + class equation_as_9_3_39_and_its_derivative + { + public: + BOOST_MATH_GPU_ENABLED explicit equation_as_9_3_39_and_its_derivative(const T& zt) : zeta(zt) { } + + BOOST_MATH_GPU_ENABLED equation_as_9_3_39_and_its_derivative(const equation_as_9_3_39_and_its_derivative&) = default; + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& z) const + { + BOOST_MATH_STD_USING // ADL of std names, needed for acos, sqrt. + + // Return the function of zeta that is implicitly defined + // in A&S Eq. 9.3.39 as a function of z. The function is + // returned along with its derivative with respect to z. + + const T zsq_minus_one_sqrt = sqrt((z * z) - T(1)); + + const T the_function( + zsq_minus_one_sqrt + - ( acos(T(1) / z) + ((T(2) / 3U) * (zeta * sqrt(zeta))))); + + const T its_derivative(zsq_minus_one_sqrt / z); + + return boost::math::tuple(the_function, its_derivative); + } + + private: + const equation_as_9_3_39_and_its_derivative& operator=(const equation_as_9_3_39_and_its_derivative&) = delete; + const T zeta; + }; + + template + BOOST_MATH_GPU_ENABLED T equation_as_9_5_26(const T& v, const T& ai_bi_root, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Obtain the estimate of the m'th zero of Jv or Yv. + // The order m has been used to create the input parameter ai_bi_root. + // Here, v is larger than about 2.2. The estimate is computed + // from Abramowitz and Stegun Eqs. 9.5.22 and 9.5.26, page 371. + // + // The inversion of z as a function of zeta is mentioned in the text + // following A&S Eq. 9.5.26. Here, we accomplish the inversion by + // performing a Taylor expansion of Eq. 9.3.39 for large z to order 2 + // and solving the resulting quadratic equation, thereby taking + // the positive root of the quadratic. + // In other words: (2/3)(-zeta)^(3/2) approx = z + 1/(2z) - pi/2. + // This leads to: z^2 - [(2/3)(-zeta)^(3/2) + pi/2]z + 1/2 = 0. + // + // With this initial estimate, Newton-Raphson iteration is used + // to refine the value of the estimate of the root of z + // as a function of zeta. + + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + // Obtain zeta using the order v combined with the m'th root of + // an airy function, as shown in A&S Eq. 9.5.22. + const T zeta = v_pow_minus_two_thirds * (-ai_bi_root); + + const T zeta_sqrt = sqrt(zeta); + + // Set up a quadratic equation based on the Taylor series + // expansion mentioned above. + const T b = -((((zeta * zeta_sqrt) * 2U) / 3U) + boost::math::constants::half_pi()); + + // Solve the quadratic equation, taking the positive root. + const T z_estimate = (-b + sqrt((b * b) - T(2))) / 2U; + + // Establish the range, the digits, and the iteration limit + // for the upcoming root-finding. + const T range_zmin = (std::max)(z_estimate - T(1), T(1)); + const T range_zmax = z_estimate + T(1); + + const auto my_digits10 = static_cast(static_cast(boost::math::tools::digits() * 0.301F)); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const auto iterations_allowed = static_cast(BOOST_MATH_GPU_SAFE_MAX(12, my_digits10 * 2)); + + boost::math::uintmax_t iterations_used = iterations_allowed; + + // Calculate the root of z as a function of zeta. + const T z = boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::equation_as_9_3_39_and_its_derivative(zeta), + z_estimate, + range_zmin, + range_zmax, + BOOST_MATH_GPU_SAFE_MIN(boost::math::tools::digits(), boost::math::tools::digits()), + iterations_used); + + static_cast(iterations_used); + + // Continue with the implementation of A&S Eq. 9.3.39. + const T zsq_minus_one = (z * z) - T(1); + const T zsq_minus_one_sqrt = sqrt(zsq_minus_one); + + // This is A&S Eq. 9.3.42. + const T b0_term_5_24 = T(5) / ((zsq_minus_one * zsq_minus_one_sqrt) * 24U); + const T b0_term_1_8 = T(1) / ( zsq_minus_one_sqrt * 8U); + const T b0_term_5_48 = T(5) / ((zeta * zeta) * 48U); + + const T b0 = -b0_term_5_48 + ((b0_term_5_24 + b0_term_1_8) / zeta_sqrt); + + // This is the second line of A&S Eq. 9.5.26 for f_k with k = 1. + const T f1 = ((z * zeta_sqrt) * b0) / zsq_minus_one_sqrt; + + // This is A&S Eq. 9.5.22 expanded to k = 1 (i.e., one term in the series). + return (v * z) + (f1 / v); + } + + namespace cyl_bessel_j_zero_detail + { + template + BOOST_MATH_GPU_ENABLED T equation_nist_10_21_40_a(const T& v, const Policy& pol) + { + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + return v * ((((( + T(0.043) + * v_pow_minus_two_thirds - T(0.0908)) + * v_pow_minus_two_thirds - T(0.00397)) + * v_pow_minus_two_thirds + T(1.033150)) + * v_pow_minus_two_thirds + T(1.8557571)) + * v_pow_minus_two_thirds + T(1)); + } + + template + class function_object_jv + { + public: + BOOST_MATH_GPU_ENABLED function_object_jv(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + BOOST_MATH_GPU_ENABLED function_object_jv(const function_object_jv&) = default; + + BOOST_MATH_GPU_ENABLED T operator()(const T& x) const + { + return boost::math::cyl_bessel_j(my_v, x, my_pol); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_jv& operator=(const function_object_jv&) = delete; + }; + + template + class function_object_jv_and_jv_prime + { + public: + BOOST_MATH_GPU_ENABLED function_object_jv_and_jv_prime( + const T& v, + const bool order_is_zero, + const Policy& pol) : my_v(v), + my_order_is_zero(order_is_zero), + my_pol(pol) { } + + function_object_jv_and_jv_prime(const function_object_jv_and_jv_prime&) = default; + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& x) const + { + // Obtain Jv(x) and Jv'(x). + // Chris's original code called the Bessel function implementation layer direct, + // but that circumvented optimizations for integer-orders. Call the documented + // top level functions instead, and let them sort out which implementation to use. + T j_v; + T j_v_prime; + + if(my_order_is_zero) + { + j_v = boost::math::cyl_bessel_j(0, x, my_pol); + j_v_prime = -boost::math::cyl_bessel_j(1, x, my_pol); + } + else + { + j_v = boost::math::cyl_bessel_j( my_v, x, my_pol); + const T j_v_m1 (boost::math::cyl_bessel_j(T(my_v - 1), x, my_pol)); + j_v_prime = j_v_m1 - ((my_v * j_v) / x); + } + + // Return a tuple containing both Jv(x) and Jv'(x). + return boost::math::make_tuple(j_v, j_v_prime); + } + + private: + const T my_v; + const bool my_order_is_zero; + const Policy& my_pol; + const function_object_jv_and_jv_prime& operator=(const function_object_jv_and_jv_prime&) = delete; + }; + + template BOOST_MATH_GPU_ENABLED bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; } + + template + BOOST_MATH_GPU_ENABLED T initial_guess(const T& v, const int m, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + // Compute an estimate of the m'th root of cyl_bessel_j. + + T guess; + + // There is special handling for negative order. + if(v < 0) + { + if((m == 1) && (v > -0.5F)) + { + // For small, negative v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselJZero[n, 1]}, {n, -(1/2), 0, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.2321156900729) + * v - T(0.1493247777488)) + * v - T(0.15205419167239)) + * v + T(0.07814930561249)) + * v - T(0.17757573537688)) + * v + T(1.542805677045663)) + * v + T(2.40482555769577277); + + return guess; + } + + // Create the positive order and extract its positive floor integer part. + const T vv(-v); + const T vv_floor(floor(vv)); + + // The to-be-found root is bracketed by the roots of the + // Bessel function whose reflected, positive integer order + // is less than, but nearest to vv. + + T root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m, pol); + T root_lo; + + if(m == 1) + { + // The estimate of the first root for negative order is found using + // an adaptive range-searching algorithm. + root_lo = T(root_hi - 0.1F); + + const bool hi_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_hi, pol) < 0); + + while((root_lo > boost::math::tools::epsilon())) + { + const bool lo_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_lo, pol) < 0); + + if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative) + { + break; + } + + root_hi = root_lo; + + // Decrease the lower end of the bracket using an adaptive algorithm. + if(root_lo > 0.5F) + { + root_lo -= 0.5F; + } + else + { + root_lo *= 0.75F; // LCOV_EXCL_LINE probably unreachable, but hard to prove? + } + } + } + else + { + root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m - 1, pol); + } + + // Perform several steps of bisection iteration to refine the guess. + boost::math::uintmax_t number_of_iterations(12U); + + // Do the bisection iteration. + const boost::math::tuple guess_pair = + boost::math::tools::bisect( + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv(v, pol), + root_lo, + root_hi, + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::my_bisection_unreachable_tolerance, + number_of_iterations); + + return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U; + } + + if(m == 1U) + { + // Get the initial estimate of the first root. + + if(v < 2.2F) + { + // For small v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselJZero[n, 1]}, {n, 0, 22/10, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.0008342379046010) + * v + T(0.007590035637410)) + * v - T(0.030640914772013)) + * v + T(0.078232088020106)) + * v - T(0.169668712590620)) + * v + T(1.542187960073750)) + * v + T(2.4048359915254634); + } + else + { + // For larger v, use the first line of Eqs. 10.21.40 in the NIST Handbook. + guess = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::equation_nist_10_21_40_a(v, pol); + } + } + else + { + if(v < 2.2F) + { + // Use Eq. 10.21.19 in the NIST Handbook. + const T a(((v + T(m * 2U)) - T(0.5)) * boost::math::constants::half_pi()); + + guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a); + } + else + { + // Get an estimate of the m'th root of airy_ai. + const T airy_ai_root(boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess(m, pol)); + + // Use Eq. 9.5.26 in the A&S Handbook. + guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_ai_root, pol); + } + } + + return guess; + } + } // namespace cyl_bessel_j_zero_detail + + namespace cyl_neumann_zero_detail + { + template + BOOST_MATH_GPU_ENABLED T equation_nist_10_21_40_b(const T& v, const Policy& pol) + { + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + return v * ((((( - T(0.001) + * v_pow_minus_two_thirds - T(0.0060)) + * v_pow_minus_two_thirds + T(0.01198)) + * v_pow_minus_two_thirds + T(0.260351)) + * v_pow_minus_two_thirds + T(0.9315768)) + * v_pow_minus_two_thirds + T(1)); + } + + template + class function_object_yv + { + public: + BOOST_MATH_GPU_ENABLED function_object_yv(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + BOOST_MATH_GPU_ENABLED function_object_yv(const function_object_yv&) = default; + + BOOST_MATH_GPU_ENABLED T operator()(const T& x) const + { + return boost::math::cyl_neumann(my_v, x, my_pol); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_yv& operator=(const function_object_yv&) = delete; + }; + + template + class function_object_yv_and_yv_prime + { + public: + BOOST_MATH_GPU_ENABLED function_object_yv_and_yv_prime(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + BOOST_MATH_GPU_ENABLED function_object_yv_and_yv_prime(const function_object_yv_and_yv_prime&) = default; + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& x) const + { + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + const bool order_is_zero = ((my_v > -half_epsilon) && (my_v < +half_epsilon)); + + // Obtain Yv(x) and Yv'(x). + // Chris's original code called the Bessel function implementation layer direct, + // but that circumvented optimizations for integer-orders. Call the documented + // top level functions instead, and let them sort out which implementation to use. + T y_v; + T y_v_prime; + + if(order_is_zero) + { + y_v = boost::math::cyl_neumann(0, x, my_pol); + y_v_prime = -boost::math::cyl_neumann(1, x, my_pol); + } + else + { + y_v = boost::math::cyl_neumann( my_v, x, my_pol); + const T y_v_m1 (boost::math::cyl_neumann(T(my_v - 1), x, my_pol)); + y_v_prime = y_v_m1 - ((my_v * y_v) / x); + } + + // Return a tuple containing both Yv(x) and Yv'(x). + return boost::math::make_tuple(y_v, y_v_prime); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_yv_and_yv_prime& operator=(const function_object_yv_and_yv_prime&) = delete; + }; + + template BOOST_MATH_GPU_ENABLED bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; } + + template + BOOST_MATH_GPU_ENABLED T initial_guess(const T& v, const int m, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + // Compute an estimate of the m'th root of cyl_neumann. + + T guess; + + // There is special handling for negative order. + if(v < 0) + { + // Create the positive order and extract its positive floor and ceiling integer parts. + const T vv(-v); + const T vv_floor(floor(vv)); + + // The to-be-found root is bracketed by the roots of the + // Bessel function whose reflected, positive integer order + // is less than, but nearest to vv. + + // The special case of negative, half-integer order uses + // the relation between Yv and spherical Bessel functions + // in order to obtain the bracket for the root. + // In these special cases, cyl_neumann(-n/2, x) = sph_bessel_j(+n/2, x) + // for v = -n/2. + + T root_hi; + T root_lo; + + if(m == 1) + { + // The estimate of the first root for negative order is found using + // an adaptive range-searching algorithm. + // Take special precautions for the discontinuity at negative, + // half-integer orders and use different brackets above and below these. + if(T(vv - vv_floor) < 0.5F) + { + root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol); + } + else + { + root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol); + } + + root_lo = T(root_hi - 0.1F); + + const bool hi_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_hi, pol) < 0); + + while((root_lo > boost::math::tools::epsilon())) + { + const bool lo_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_lo, pol) < 0); + + if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative) + { + break; + } + + root_hi = root_lo; + + // Decrease the lower end of the bracket using an adaptive algorithm. + if(root_lo > 0.5F) + { + root_lo -= 0.5F; + } + else + { + root_lo *= 0.75F; // LCOV_EXCL_LINE probably unreachable, but hard to prove? + } + } + } + else + { + if(T(vv - vv_floor) < 0.5F) + { + root_lo = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m - 1, pol); + root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol); + root_lo += 0.01F; + root_hi += 0.01F; + } + else + { + root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m - 1, pol); + root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol); + root_lo += 0.01F; + root_hi += 0.01F; + } + } + + // Perform several steps of bisection iteration to refine the guess. + boost::math::uintmax_t number_of_iterations(12U); + + // Do the bisection iteration. + const boost::math::tuple guess_pair = + boost::math::tools::bisect( + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv(v, pol), + root_lo, + root_hi, + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::my_bisection_unreachable_tolerance, + number_of_iterations); + + return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U; + } + + if(m == 1U) + { + // Get the initial estimate of the first root. + + if(v < 2.2F) + { + // For small v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselYZero[n, 1]}, {n, 0, 22/10, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.0025095909235652) + * v + T(0.021291887049053)) + * v - T(0.076487785486526)) + * v + T(0.159110268115362)) + * v - T(0.241681668765196)) + * v + T(1.4437846310885244)) + * v + T(0.89362115190200490); + } + else + { + // For larger v, use the second line of Eqs. 10.21.40 in the NIST Handbook. + guess = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::equation_nist_10_21_40_b(v, pol); + } + } + else + { + if(v < 2.2F) + { + // Use Eq. 10.21.19 in the NIST Handbook. + const T a(((v + T(m * 2U)) - T(1.5)) * boost::math::constants::half_pi()); + + guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a); + } + else + { + // Get an estimate of the m'th root of airy_bi. + const T airy_bi_root(boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess(m, pol)); + + // Use Eq. 9.5.26 in the A&S Handbook. + guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_bi_root, pol); + } + } + + return guess; + } + } // namespace cyl_neumann_zero_detail + } // namespace bessel_zero + } } } // namespace boost::math::detail + + #ifdef BOOST_MATH_ENABLE_CUDA + # pragma nv_diag_default 20012 + #endif + +#endif // BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k0.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k0.hpp new file mode 100644 index 0000000000000..1841983dfdf3d --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k0.hpp @@ -0,0 +1,485 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 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) + +#ifndef BOOST_MATH_BESSEL_K0_HPP +#define BOOST_MATH_BESSEL_K0_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the second kind of order zero +// minimax rational approximations on intervals, see +// Russon and Blair, Chalk River Report AECL-3461, 1969, +// as revised by Pavel Holoborodko in "Rational Approximations +// for the Modified Bessel Function of the Second Kind - K0(x) +// for Computations with Double Precision", see +// http://www.advanpix.com/2015/11/25/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k0-for-computations-with-double-precision/ +// +// The actual coefficients used are our own derivation (by JM) +// since we extend to both greater and lesser precision than the +// references above. We can also improve performance WRT to +// Holoborodko without loss of precision. + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T&, const boost::math::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found : 2.358e-09 + // Expected Error Term : -2.358e-09 + // Maximum Relative Change in Control Points : 9.552e-02 + // Max Error found at float precision = Poly : 4.448220e-08 + BOOST_MATH_STATIC const T Y = 1.137250900268554688f; + BOOST_MATH_STATIC const T P[] = + { + -1.372508979104259711e-01f, + 2.622545986273687617e-01f, + 5.047103728247919836e-03f + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000000000000e+00f, + -8.928694018000029415e-02f, + 2.985980684180969241e-03f + }; + T a = x * x / 4; + a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 1.346e-09 + // Expected Error Term : -1.343e-09 + // Maximum Relative Change in Control Points : 2.405e-02 + // Max Error found at float precision = Poly : 1.354814e-07 + BOOST_MATH_STATIC const T P2[] = { + 1.159315158e-01f, + 2.789828686e-01f, + 2.524902861e-02f, + 8.457241514e-04f, + 1.530051997e-05f + }; + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 1.587e-08 + // Expected Error Term : 1.531e-08 + // Maximum Relative Change in Control Points : 9.064e-02 + // Max Error found at float precision = Poly : 5.065020e-08 + + BOOST_MATH_STATIC const T P[] = + { + 2.533141220e-01f, + 5.221502603e-01f, + 6.380180669e-02f, + -5.934976547e-02f + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000e+00f, + 2.679722431e+00f, + 1.561635813e+00f, + 1.573660661e-01f + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * ex / sqrt(x)) * ex; + } + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 6.077e-17 + // Expected Error Term : -6.077e-17 + // Maximum Relative Change in Control Points : 7.797e-02 + // Max Error found at double precision = Poly : 1.003156e-16 + BOOST_MATH_STATIC const T Y = 1.137250900268554688; + BOOST_MATH_STATIC const T P[] = + { + -1.372509002685546267e-01, + 2.574916117833312855e-01, + 1.395474602146869316e-02, + 5.445476986653926759e-04, + 7.125159422136622118e-06 + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000000000000e+00, + -5.458333438017788530e-02, + 1.291052816975251298e-03, + -1.367653946978586591e-05 + }; + + T a = x * x / 4; + a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 3.429e-18 + // Expected Error Term : 3.392e-18 + // Maximum Relative Change in Control Points : 2.041e-02 + // Max Error found at double precision = Poly : 2.513112e-16 + BOOST_MATH_STATIC const T P2[] = + { + 1.159315156584124484e-01, + 2.789828789146031732e-01, + 2.524892993216121934e-02, + 8.460350907213637784e-04, + 1.491471924309617534e-05, + 1.627106892422088488e-07, + 1.208266102392756055e-09, + 6.611686391749704310e-12 + }; + + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 4.316e-17 + // Expected Error Term : 9.570e-18 + // Maximum Relative Change in Control Points : 2.757e-01 + // Max Error found at double precision = Poly : 1.001560e-16 + + BOOST_MATH_STATIC const T Y = 1; + BOOST_MATH_STATIC const T P[] = + { + 2.533141373155002416e-01, + 3.628342133984595192e+00, + 1.868441889406606057e+01, + 4.306243981063412784e+01, + 4.424116209627428189e+01, + 1.562095339356220468e+01, + -1.810138978229410898e+00, + -1.414237994269995877e+00, + -9.369168119754924625e-02 + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000000000000e+00, + 1.494194694879908328e+01, + 8.265296455388554217e+01, + 2.162779506621866970e+02, + 2.845145155184222157e+02, + 1.851714491916334995e+02, + 5.486540717439723515e+01, + 6.118075837628957015e+00, + 1.586261269326235053e-01 + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 2.180e-22 + // Expected Error Term : 2.180e-22 + // Maximum Relative Change in Control Points : 2.943e-01 + // Max Error found at float80 precision = Poly : 3.923207e-20 + BOOST_MATH_STATIC const T Y = 1.137250900268554687500e+00; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.372509002685546875002e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.566481981037407600436e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.551881122448948854873e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.646112454323276529650e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.213747930378196492543e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.423709328020389560844e-08) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.843828412587773008342e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.088484822515098936140e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.374724008530702784829e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.452665455952581680339e-08) + }; + + + T a = x * x / 4; + a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 2.440e-21 + // Expected Error Term : -2.434e-21 + // Maximum Relative Change in Control Points : 2.459e-02 + // Max Error found at float80 precision = Poly : 1.482487e-19 + BOOST_MATH_STATIC const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.159315156584124488110e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.764832791416047889734e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.926062887220923354112e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.660777862036966089410e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.094942446930673386849e-06) + }; + BOOST_MATH_STATIC const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.156100313881251616320e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.315993873344905957033e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.529444499350703363451e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.524988589917857531177e-09) + }; + return tools::evaluate_rational(P2, Q2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 4.291e-20 + // Expected Error Term : 2.236e-21 + // Maximum Relative Change in Control Points : 3.021e-01 + //Max Error found at float80 precision = Poly : 8.727378e-20 + BOOST_MATH_STATIC const T Y = 1; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 2.533141373155002512056e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.417942070721928652715e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.477464607463971754433e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.838745728725943889876e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.009736314927811202517e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.557411293123609803452e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.360222564015361268955e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.385435333168505701022e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.750195760942181592050e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.059789241612946683713e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.612783121537333908889e-01) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.200669254769325861404e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.900177593527144126549e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.361003989965786932682e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.041319870804843395893e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.828491555113790345068e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.190342229261529076624e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.003330795963812219852e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.773371397243777891569e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.368634935531158398439e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.543310879400359967327e-01) + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T& x, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 5.682e-37 + // Expected Error Term : 5.682e-37 + // Maximum Relative Change in Control Points : 6.094e-04 + // Max Error found at float128 precision = Poly : 5.338213e-35 + BOOST_MATH_STATIC const T Y = 1.137250900268554687500000000000000000e+00f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -1.372509002685546875000000000000000006e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.556212905071072782462974351698081303e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.742459135264203478530904179889103929e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.077860530453688571555479526961318918e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.868173911669241091399374307788635148e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.496405768838992243478709145123306602e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.752489221949580551692915881999762125e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.243010555737173524710512824955368526e-12) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.095631064064621099785696980653193721e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.313880983725212151967078809725835532e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.095229912293480063501285562382835142e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.022828799511943141130509410251996277e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.860874007419812445494782795829046836e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.107297802344970725756092082686799037e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.460529579244623559164763757787600944e-15) + }; + T a = x * x / 4; + a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 5.173e-38 + // Expected Error Term : 5.105e-38 + // Maximum Relative Change in Control Points : 9.734e-03 + // Max Error found at float128 precision = Poly : 1.688806e-34 + BOOST_MATH_STATIC const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.159315156584124488107200313757741370e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.789828789146031122026800078439435369e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.524892993216269451266750049024628432e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.460350907082229957222453839935101823e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.491471929926042875260452849503857976e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.627105610481598430816014719558896866e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.208426165007797264194914898538250281e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.508697838747354949164182457073784117e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.659784680639805301101014383907273109e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.531090131964391104248859415958109654e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.205195117066478034260323124669936314e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.692219280289030165761119775783115426e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.362350161092532344171965861545860747e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.277990623924628999539014980773738258e-27) + }; + + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 1.462e-34 + // Expected Error Term : 4.917e-40 + // Maximum Relative Change in Control Points : 3.385e-01 + // Max Error found at float128 precision = Poly : 1.567573e-34 + BOOST_MATH_STATIC const T Y = 1; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 2.533141373155002512078826424055226265e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.001949740768235770078339977110749204e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.991516715983883248363351472378349986e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.429587951594593159075690819360687720e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.911933815201948768044660065771258450e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.769943016204926614862175317962439875e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.170866154649560750500954150401105606e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.634687099724383996792011977705727661e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.989524036456492581597607246664394014e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.160394785715328062088529400178080360e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.778173054417826368076483100902201433e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.335667778588806892764139643950439733e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.283635100080306980206494425043706838e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.300616188213640626577036321085025855e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.277591957076162984986406540894621482e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.564360536834214058158565361486115932e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.043505161612403359098596828115690596e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.217035248223503605127967970903027314e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.422938158797326748375799596769964430e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.229125746200586805278634786674745210e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.201632288615609937883545928660649813e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.690820607338480548346746717311811406e+01) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.964877874035741452203497983642653107e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.808929943826193766839360018583294769e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.814524004679994110944366890912384139e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.897794522506725610540209610337355118e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.456339470955813675629523617440433672e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.057818717813969772198911392875127212e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.513821619536852436424913886081133209e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.255938846873380596038513316919990776e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.537077551699028079347581816919572141e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.176769339768120752974843214652367321e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.828722317390455845253191337207432060e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.698864296569996402006511705803675890e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.007803261356636409943826918468544629e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.016564631288740308993071395104715469e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.595893010619754750655947035567624730e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.241241839120481076862742189989406856e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.168778094393076220871007550235840858e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.156200301360388147635052029404211109e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.752130382550379886741949463587008794e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.370574966987293592457152146806662562e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.871254714311063594080644835895740323e+01) + }; + if(-x > tools::log_min_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +BOOST_MATH_GPU_ENABLED T bessel_k0_imp(const T& x, const boost::math::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_k0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_k0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_k0_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_k0_imp(x, boost::math::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +BOOST_MATH_GPU_ENABLED inline T bessel_k0(const T& x) +{ + typedef boost::math::integral_constant::digits == 0) || (boost::math::numeric_limits::radix != 2)) ? + 0 : + boost::math::numeric_limits::digits <= 24 ? + 24 : + boost::math::numeric_limits::digits <= 53 ? + 53 : + boost::math::numeric_limits::digits <= 64 ? + 64 : + boost::math::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + return bessel_k0_imp(x, tag_type()); +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_K0_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k1.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k1.hpp new file mode 100644 index 0000000000000..eeeaa5d285495 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_k1.hpp @@ -0,0 +1,526 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 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) + +#ifndef BOOST_MATH_BESSEL_K1_HPP +#define BOOST_MATH_BESSEL_K1_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the second kind of order zero +// minimax rational approximations on intervals, see +// Russon and Blair, Chalk River Report AECL-3461, 1969, +// as revised by Pavel Holoborodko in "Rational Approximations +// for the Modified Bessel Function of the Second Kind - K0(x) +// for Computations with Double Precision", see +// http://www.advanpix.com/2016/01/05/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k1-for-computations-with-double-precision/ +// +// The actual coefficients used are our own derivation (by JM) +// since we extend to both greater and lesser precision than the +// references above. We can also improve performance WRT to +// Holoborodko without loss of precision. + +namespace boost { namespace math { namespace detail{ + + template + BOOST_MATH_GPU_ENABLED inline T bessel_k1_imp(const T&, const boost::math::integral_constant&) + { + BOOST_MATH_ASSERT(0); + return 0; + } + + template + BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 3.090e-12 + // Expected Error Term : -3.053e-12 + // Maximum Relative Change in Control Points : 4.927e-02 + // Max Error found at float precision = Poly : 7.918347e-10 + BOOST_MATH_STATIC const T Y = 8.695471287e-02f; + BOOST_MATH_STATIC const T P[] = + { + -3.621379531e-03f, + 7.131781976e-03f, + -1.535278300e-05f + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000e+00f, + -5.173102701e-02f, + 9.203530671e-04f + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 3.556e-08 + // Expected Error Term : -3.541e-08 + // Maximum Relative Change in Control Points : 8.203e-02 + BOOST_MATH_STATIC const T P2[] = + { + -3.079657469e-01f, + -8.537108913e-02f, + -4.640275408e-03f, + -1.156442414e-04f + }; + + return tools::evaluate_polynomial(P2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 3.369e-08 + // Expected Error Term : -3.227e-08 + // Maximum Relative Change in Control Points : 9.917e-02 + // Max Error found at float precision = Poly : 6.084411e-08 + BOOST_MATH_STATIC const T Y = 1.450342178f; + BOOST_MATH_STATIC const T P[] = + { + -1.970280088e-01f, + 2.188747807e-02f, + 7.270394756e-01f, + 2.490678196e-01f + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.000000000e+00f, + 2.274292882e+00f, + 9.904984851e-01f, + 4.585534549e-02f + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 1.922e-17 + // Expected Error Term : 1.921e-17 + // Maximum Relative Change in Control Points : 5.287e-03 + // Max Error found at double precision = Poly : 2.004747e-17 + BOOST_MATH_STATIC const T Y = 8.69547128677368164e-02f; + BOOST_MATH_STATIC const T P[] = + { + -3.62137953440350228e-03, + 7.11842087490330300e-03, + 1.00302560256614306e-05, + 1.77231085381040811e-06 + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.00000000000000000e+00, + -4.80414794429043831e-02, + 9.85972641934416525e-04, + -8.91196859397070326e-06 + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 4.053e-17 + // Expected Error Term : -4.053e-17 + // Maximum Relative Change in Control Points : 3.103e-04 + // Max Error found at double precision = Poly : 1.246698e-16 + + BOOST_MATH_STATIC const T P2[] = + { + -3.07965757829206184e-01, + -7.80929703673074907e-02, + -2.70619343754051620e-03, + -2.49549522229072008e-05 + }; + BOOST_MATH_STATIC const T Q2[] = + { + 1.00000000000000000e+00, + -2.36316836412163098e-02, + 2.64524577525962719e-04, + -1.49749618004162787e-06 + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 8.883e-17 + // Expected Error Term : -1.641e-17 + // Maximum Relative Change in Control Points : 2.786e-01 + // Max Error found at double precision = Poly : 1.258798e-16 + + BOOST_MATH_STATIC const T Y = 1.45034217834472656f; + BOOST_MATH_STATIC const T P[] = + { + -1.97028041029226295e-01, + -2.32408961548087617e+00, + -7.98269784507699938e+00, + -2.39968410774221632e+00, + 3.28314043780858713e+01, + 5.67713761158496058e+01, + 3.30907788466509823e+01, + 6.62582288933739787e+00, + 3.08851840645286691e-01 + }; + BOOST_MATH_STATIC const T Q[] = + { + 1.00000000000000000e+00, + 1.41811409298826118e+01, + 7.35979466317556420e+01, + 1.77821793937080859e+02, + 2.11014501598705982e+02, + 1.19425262951064454e+02, + 2.88448064302447607e+01, + 2.27912927104139732e+00, + 2.50358186953478678e-02 + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 5.549e-23 + // Expected Error Term : -5.548e-23 + // Maximum Relative Change in Control Points : 2.002e-03 + // Max Error found at float80 precision = Poly : 9.352785e-22 + BOOST_MATH_STATIC const T Y = 8.695471286773681640625e-02f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -3.621379534403483072861e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.102135866103952705932e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.167545240236717601167e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.537484002571894870830e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.603228256820000135990e-09) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.354457194045068370363e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.709137201220209072820e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.676151796359590545143e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.162715192766245311659e-08) + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 1.995e-23 + // Expected Error Term : 1.995e-23 + // Maximum Relative Change in Control Points : 8.174e-04 + // Max Error found at float80 precision = Poly : 4.137325e-20 + BOOST_MATH_STATIC const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -3.079657578292062244054e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.963049154965966503231e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.103277523735639924895e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.023052834702215699504e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.719459155018493821839e-07) + }; + BOOST_MATH_STATIC const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.863917670410152669768e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.699367098849735298090e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.309358790546076298429e-07), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.708893480271612711933e-09) + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 9.785e-20 + // Expected Error Term : -3.302e-21 + // Maximum Relative Change in Control Points : 3.432e-01 + // Max Error found at float80 precision = Poly : 1.083755e-19 + BOOST_MATH_STATIC const T Y = 1.450342178344726562500e+00f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.970280410292263112917e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.058564803062959169322e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.036658174194917777473e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.576825392332820142173e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.706969489248020941949e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.264572499406168221382e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.584972047303151034100e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.422082733280017909550e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.738005441471368178383e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.016938390144121276609e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.319614662598089438939e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.710715864316521856193e-02) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.298433045824439052398e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.082047745067709230037e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.662367854250262046592e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.504148628460454004686e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.712730364911389908905e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.108002081150068641112e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.400149940532448553143e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.083303048095846226299e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.748706060530351833346e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.321900849331506946977e-01), + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 7.120e-35 + // Expected Error Term : -7.119e-35 + // Maximum Relative Change in Control Points : 1.207e-03 + // Max Error found at float128 precision = Poly : 7.143688e-35 + BOOST_MATH_STATIC const T Y = 8.695471286773681640625000000000000000e-02f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -3.621379534403483072916666666666595475e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.074117676930975433219826471336547627e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.631337631362776369069668419033041661e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.468935967870048731821071646104412775e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.956705020559599861444492614737168261e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.347140307321161346703214099534250263e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.569608494081482873946791086435679661e-13) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.580768910152105375615558920428350204e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.197467671701485365363068445534557369e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.707466533308630411966030561446666237e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.846687802282250112624373388491123527e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.248493131151981569517383040323900343e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.319279786372775264555728921709381080e-13) + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 4.473e-37 + // Expected Error Term : 4.473e-37 + // Maximum Relative Change in Control Points : 8.550e-04 + // Max Error found at float128 precision = Poly : 8.167701e-35 + BOOST_MATH_STATIC const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -3.079657578292062244053600156878870690e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.133183745732467770755578848987414875e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.548968792764174773125420229299431951e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.886125468718182876076972186152445490e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.506712111733707245745396404449639865e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.632502325880313239698965376754406011e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.311973065898784812266544485665624227e-12) + }; + BOOST_MATH_STATIC const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.311471216733781016657962995723287450e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.571876054797365417068164018709472969e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.630181215268238731442496851497901293e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.070176111227805048604885986867484807e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.129046580769872602793220056461084761e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.294906469421390890762001971790074432e-15) + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else if(x < 4) + { + // Max error in interpolated form: 5.307e-37 + // Max Error found at float128 precision = Poly: 7.087862e-35 + BOOST_MATH_STATIC const T Y = 1.5023040771484375f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -2.489899398329369710528254347931380044e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.819080211203854781858815596508456873e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.599915699069767382647695624952723034e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.450211910821295507926582231071300718e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.451374687870925175794150513723956533e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.405805746895098802803503988539098226e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.638808326778389656403861103277220518e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.513958744081268456191778822780865708e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.121301640926540743072258116122834804e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.080094900175649541266613109971296190e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.896531083639613332407534434915552429e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.856602122319645694042555107114028437e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.237121918853145421414003823957537419e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.842072954561323076230238664623893504e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.039705646510167437971862966128055524e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.008418100718254816100425022904039530e-02) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.927456835239137986889227412815459529e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.598985593265577043711382994516531273e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.449897377085510281395819892689690579e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.025555887684561913263090023158085327e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.774140447181062463181892531100679195e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.962055507843204417243602332246120418e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.908269326976180183216954452196772931e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.655160454422016855911700790722577942e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.383586885019548163464418964577684608e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.679920375586960324298491662159976419e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.478586421028842906987799049804565008e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.565384974896746094224942654383537090e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.902617937084010911005732488607114511e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.429293010387921526110949911029094926e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.880342607911083143560111853491047663e-04) + }; + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + } + else + { + // Maximum Deviation Found: 4.359e-37 + // Expected Error Term : -6.565e-40 + // Maximum Relative Change in Control Points : 1.880e-01 + // Max Error found at float128 precision = Poly : 2.943572e-35 + BOOST_MATH_STATIC const T Y = 1.308816909790039062500000000000000000f; + BOOST_MATH_STATIC const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -5.550277247453881129211735759447737350e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.485883080219574328217554864956175929e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.903760658131484239300875153154881958e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.144813672213626237418235110712293337e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.498400501156131446691826557494158173e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.573531831870363502604119835922166116e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.417416550054632009958262596048841154e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.271266450613557412825896604269130661e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.898386013314389952534433455681107783e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.353798784656436259250791761023512750e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.839619195427352438957774052763490067e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.169246368651532232388152442538005637e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.696368884166831199967845883371116431e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.810226630422736458064005843327500169e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.854996610560406127438950635716757614e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.981057433937398731355768088809437625e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.519440069856232098711793483639792952e+04) + }; + BOOST_MATH_STATIC const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.127348248283623146544565916604103560e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.205092684176906740104488180754982065e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.911249195069050636298346469740075758e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.426103406579046249654548481377792614e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.365861555422488771286500241966208541e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.765377714160383676864913709252529840e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.453822726931857253365138260720815246e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.643207885048369990391975749439783892e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.882540678243694621895816336640877878e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.410120808992380266174106812005338148e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.628138016559335882019310900426773027e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.250794693811010646965360198541047961e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.378723408195485594610593014072950078e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.488253856312453816451380319061865560e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.202167197882689873967723350537104582e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.673233230356966539460728211412989843e+03) + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant&) + { + if(boost::math::tools::digits() <= 24) + return bessel_k1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_k1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_k1_imp(x, boost::math::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_k1_imp(x, boost::math::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; + } + + template + BOOST_MATH_GPU_ENABLED inline T bessel_k1(const T& x) + { + typedef boost::math::integral_constant::digits == 0) || (boost::math::numeric_limits::radix != 2)) ? + 0 : + boost::math::numeric_limits::digits <= 24 ? + 24 : + boost::math::numeric_limits::digits <= 53 ? + 53 : + boost::math::numeric_limits::digits <= 64 ? + 64 : + boost::math::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + return bessel_k1_imp(x, tag_type()); + } + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_K1_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_kn.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_kn.hpp new file mode 100644 index 0000000000000..41becc8aa9d2f --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_kn.hpp @@ -0,0 +1,91 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_KN_HPP +#define BOOST_MATH_BESSEL_KN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Modified Bessel function of the second kind of integer order +// K_n(z) is the dominant solution, forward recurrence always OK (though unstable) + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_kn(int n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T value, current, prev; + + using namespace boost::math::tools; + + constexpr auto function = "boost::math::bessel_kn<%1%>(%1%,%1%)"; + + if (x < 0) + { + return policies::raise_domain_error(function, "Got x = %1%, but argument x must be non-negative, complex number result not supported.", x, pol); + } + if (x == 0) + { + return (n == 0) ? + policies::raise_overflow_error(function, nullptr, pol) + : policies::raise_domain_error(function, "Got x = %1%, but argument x must be positive, complex number result not supported.", x, pol); + } + + if (n < 0) + { + n = -n; // K_{-n}(z) = K_n(z) + } + if (n == 0) + { + value = bessel_k0(x); + } + else if (n == 1) + { + value = bessel_k1(x); + } + else + { + prev = bessel_k0(x); + current = bessel_k1(x); + int k = 1; + BOOST_MATH_ASSERT(k < n); + T scale = 1; + do + { + T fact = 2 * k / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + scale /= current; + prev /= current; + current = 1; + } + value = fact * current + prev; + prev = current; + current = value; + ++k; + } + while(k < n); + if (tools::max_value() * scale < fabs(value)) + return ((boost::math::signbit)(scale) ? -1 : 1) * sign(value) * policies::raise_overflow_error(function, nullptr, pol); + value /= scale; + } + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_KN_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y0.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y0.hpp new file mode 100644 index 0000000000000..f1aea6acbdd40 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y0.hpp @@ -0,0 +1,205 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_Y0_HPP +#define BOOST_MATH_BESSEL_Y0_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the second kind of order zero +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_y0(T x, const Policy&); + +template +BOOST_MATH_GPU_ENABLED T bessel_y0(T x, const Policy&) +{ + BOOST_MATH_STATIC const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0723538782003176831e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.3716255451260504098e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.0422274357376619816e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.1287548474401797963e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0102532948020907590e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8402381979244993524e+01)), + }; + BOOST_MATH_STATIC const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.8873865738997033405e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.1617187777290363573e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.5662956624278251596e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.3889393209447253406e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6475986689240190091e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2213976967566192242e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.5107435206722644429e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.3600098638603061642e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.9590439394619619534e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.6905288611678631510e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4566865832663635920e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7427031242901594547e+01)), + }; + BOOST_MATH_STATIC const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.3386146580707264428e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4266824419412347550e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4015103849971240096e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3960202770986831075e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0669982352539552018e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.3030857612070288823e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T P3[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.0728726905150210443e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.7016641869173237784e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2829912364088687306e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.9363051266772083678e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1958827170518100757e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0085539923498211426e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1363534169313901632e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.7439661319197499338e+01)), + }; + BOOST_MATH_STATIC const T Q3[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4563724628846457519e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.9272425569640309819e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2598377924042897629e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6926121104209825246e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4727219475672302327e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.3924739209768057030e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.7903362168128450017e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684302e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1345386639580765797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1170523380864944322e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4806486443249270347e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5376201909008354296e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.8961548424210455236e-01)), + }; + BOOST_MATH_STATIC const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684318e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1370412495510416640e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1215350561880115730e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5028735138235608207e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5711159858080893649e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.9226600200800094098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8591953644342993800e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1183429920482737611e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2300261666214198472e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2441026745835638459e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.8033303048680751817e-03)), + }; + BOOST_MATH_STATIC const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.7105024128512061905e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1951131543434613647e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2642780169211018836e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4887231232283756582e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.0593769594993125859e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.9357696627916752158e-01)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.9576784193148578684e+00)), + x3 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0860510603017726976e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.280e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.9519662791675215849e-03)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0130e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.4716931485786837568e-04)), + x31 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8140e+03)), + x32 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1356030177269762362e-04)) + ; + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + BOOST_MATH_ASSERT(x > 0); + + if (x <= 3) // x in (0, 3] + { + T y = x * x; + T z = 2 * log(x/x1) * bessel_j0(x) / pi(); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12); + value = z + factor * r; + } + else if (x <= 5.5f) // x in (3, 5.5] + { + T y = x * x; + T z = 2 * log(x/x2) * bessel_j0(x) / pi(); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22); + value = z + factor * r; + } + else if (x <= 8) // x in (5.5, 8] + { + T y = x * x; + T z = 2 * log(x/x3) * bessel_j0(x) / pi(); + r = evaluate_rational(P3, Q3, y); + factor = (x + x3) * ((x - x31/256) - x32); + value = z + factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = constants::one_div_root_pi() / sqrt(x); + // + // The following code is really just: + // + // T z = x - 0.25f * pi(); + // value = factor * (rc * sin(z) + y * rs * cos(z)); + // + // But using the sin/cos addition formulae and constant values for + // sin/cos of PI/4 which then cancel part of the "factor" term as they're all + // 1 / sqrt(2): + // + T sx = sin(x); + T cx = cos(x); + value = factor * (rc * (sx - cx) + y * rs * (cx + sx)); + } + + return value; +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_Y0_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y1.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y1.hpp new file mode 100644 index 0000000000000..0f0dbdf3bb8c3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_y1.hpp @@ -0,0 +1,183 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_Y1_HPP +#define BOOST_MATH_BESSEL_Y1_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the second kind of order one +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_y1(T x, const Policy&); + +template +BOOST_MATH_GPU_ENABLED T bessel_y1(T x, const Policy&) +{ + BOOST_MATH_STATIC const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0535726612579544093e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4708611716525426053e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.7595974497819597599e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2144548214502560419e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.9157479997408395984e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2157953222280260820e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.1714424660046133456e+02)), + }; + BOOST_MATH_STATIC const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0737873921079286084e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1272286200406461981e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7800352738690585613e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.2250435122182963220e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.8136470753052572164e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.2079908168393867438e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1514276357909013326e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.6808094574724204577e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.3638408497043134724e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0686275289804744814e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.9530713129741981618e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7453673962438488783e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1957961912070617006e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.9153806858264202986e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2337180442012953128e+03)), + }; + BOOST_MATH_STATIC const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.3321844313316185697e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.6968198822857178911e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0837179548112881950e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1187010065856971027e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0221766852960403645e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.3550318087088919566e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0453748201934079734e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.2855164849321609336e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278571e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9422465050776411957e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.6033732483649391093e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5235293511811373833e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0982405543459346727e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.6116166443246101165e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)), + }; + BOOST_MATH_STATIC const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278568e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9341243899345856590e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.5853394797230870728e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5118095066341608816e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0726385991103820119e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4550094401904961825e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3220913409857223519e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.5145160675335701966e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6178836581270835179e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8494262873223866797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7063754290207680021e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5265133846636032186e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)), + }; + BOOST_MATH_STATIC const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0871281941028743574e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8194580422439972989e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4194606696037208929e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0029443582266975117e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7890229745772202641e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6383677696049909675e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + BOOST_MATH_STATIC const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1971413260310170351e+00)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4296810407941351328e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.620e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8288260310170351490e-03)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3900e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.4592058648672279948e-06)) + ; + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + BOOST_MATH_ASSERT(x > 0); + + if (x <= 4) // x in (0, 4] + { + T y = x * x; + T z = 2 * log(x/x1) * bessel_j1(x) / pi(); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12) / x; + value = z + factor * r; + } + else if (x <= 8) // x in (4, 8] + { + T y = x * x; + T z = 2 * log(x/x2) * bessel_j1(x) / pi(); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22) / x; + value = z + factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = 1 / (sqrt(x) * root_pi()); + // + // This code is really just: + // + // T z = x - 0.75f * pi(); + // value = factor * (rc * sin(z) + y * rs * cos(z)); + // + // But using the sin/cos addition rules, plus constants for sin/cos of 3PI/4 + // which then cancel out with corresponding terms in "factor". + // + T sx = sin(x); + T cx = cos(x); + value = factor * (y * rs * (sx - cx) - rc * (sx + cx)); + } + + return value; +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_Y1_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/bessel_yn.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_yn.hpp new file mode 100644 index 0000000000000..f95167a73bd39 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/bessel_yn.hpp @@ -0,0 +1,113 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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) + +#ifndef BOOST_MATH_BESSEL_YN_HPP +#define BOOST_MATH_BESSEL_YN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// Bessel function of the second kind of integer order +// Y_n(z) is the dominant solution, forward recurrence always OK (though unstable) + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T bessel_yn(int n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T value, factor, current, prev; + + using namespace boost::math::tools; + + constexpr auto function = "boost::math::bessel_yn<%1%>(%1%,%1%)"; + + if ((x == 0) && (n == 0)) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + if (x <= 0) + { + return policies::raise_domain_error(function, "Got x = %1%, but x must be > 0, complex result not supported.", x, pol); + } + + // + // Reflection comes first: + // + if (n < 0) + { + factor = static_cast((n & 0x1) ? -1 : 1); // Y_{-n}(z) = (-1)^n Y_n(z) + n = -n; + } + else + { + factor = 1; + } + if(x < policies::get_epsilon()) + { + T scale = 1; + value = bessel_yn_small_z(n, x, &scale, pol); + if (tools::max_value() * fabs(scale) < fabs(value)) + return boost::math::sign(scale) * boost::math::sign(value) * policies::raise_overflow_error(function, nullptr, pol); + value = (factor * value) / scale; + } + else if(asymptotic_bessel_large_x_limit(n, x)) + { + value = factor * asymptotic_bessel_y_large_x_2(static_cast(abs(n)), x, pol); + } + else if (n == 0) + { + value = bessel_y0(x, pol); + } + else if (n == 1) + { + value = factor * bessel_y1(x, pol); + } + else + { + prev = bessel_y0(x, pol); + current = bessel_y1(x, pol); + int k = 1; + BOOST_MATH_ASSERT(k < n); + policies::check_series_iterations("boost::math::bessel_y_n<%1%>(%1%,%1%)", n, pol); + T mult = 2 * k / x; + value = mult * current - prev; + prev = current; + current = value; + ++k; + if((mult > 1) && (fabs(current) > 1)) + { + prev /= current; + factor /= current; + value /= current; + current = 1; + } + while(k < n) + { + mult = 2 * k / x; + value = mult * current - prev; + prev = current; + current = value; + ++k; + } + if (fabs(tools::max_value() * factor) < fabs(value)) + return sign(value) * sign(factor) * policies::raise_overflow_error(function, nullptr, pol); + value /= factor; + } + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_YN_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp new file mode 100644 index 0000000000000..f680c2b0f6fc7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp @@ -0,0 +1,244 @@ +/* + * Copyright Nick Thompson, 2019 + * Copyright John Maddock, 2020 + * 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) + */ +// THIS FILE GENERATED BY EXAMPLE/DAUBECHIES_SCALING_INTEGER_GRID.CPP, DO NOT EDIT. +#ifndef BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP +#define BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP +#include +#include +#include +/* +In order to keep the character count as small as possible and speed up +compiler parsing times, we define a macro C_ which appends an appropriate +suffix to each literal, and then casts it to type Real. +The suffix is as follows: + +* Q, when we have __float128 support. +* L, when we have either 80 or 128 bit long doubles. +* Nothing otherwise. +*/ + +#ifdef BOOST_MATH_USE_FLOAT128 +# define C_(x) static_cast(x##Q) +#elif (LDBL_MANT_DIG > DBL_MANT_DIG) +# define C_(x) static_cast(x##L) +#else +# define C_(x) static_cast(x) +#endif + +namespace boost::math::detail { + +template struct daubechies_scaling_integer_grid_imp; + +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5db3d742c265539d92ba16b83c5cp+0), C_(-0x1.76cf5d0b09954e764ae85ae0f17p-2), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1p+0), C_(-0x1p+0), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.494d414ee19a0fc1701f9345a28bp+0), C_(-0x1.8b18d8251ec886399fc357ab26c9p-2), C_(0x1.863743274d78cfe42daf1d262e43p-4), C_(0x1.158087f14084ceb4f650d2c442e1p-8), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a3719cd426dbd5c2283e8b6cd98bp+0), C_(-0x1.1dcb0537f52904105ab1d13c6abfp+1), C_(0x1.19ae7cc6c0211df5e41745563cbbp-1), C_(0x1.69a5e70c6cb46c73632e8c1bb2d3p-5), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cef9cbb90bf242979b344cdd1e02p-1), C_(-0x1.b676b19591eb63e368ce734bad03p+0), C_(0x1.6ced632b23d6c7c6d19ce6975a06p-1), C_(0x1.8831a237a06deb43265d99170ff1p-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.01d5e443d831d2252369827793d3p+0), C_(-0x1.15313c61b3acb474231dab078158p-5), C_(0x1.447d293e37264e578b865081223fp-5), C_(-0x1.817e96e0425ed094fa1a3a5cf10cp-7), C_(-0x1.3a0992ca5111744ed1b4ed1a6607p-10), C_(0x1.3be7b6cb6309fefbda0c9fa167f8p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c6aca7b3a61af838bb320835a00cp+0), C_(-0x1.6486543c8460b11f1a4b4a357fbcp+1), C_(0x1.314491c6de2d2b798153746ca822p+0), C_(-0x1.0d0e14f1f7dc5a54f21ce3ff424bp-3), C_(-0x1.b6da96c702377f43a25f74c9467p-5), C_(0x1.d0194bee1a1742cd9ebfbba717b8p-10), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cf8cc69cc42a410e51b272a7a3c6p+0), C_(-0x1.0eaaa0c1e1c354610b35262e9078p+2), C_(0x1.66e46b718b500bb2be3ec05c7ac3p+1), C_(-0x1.26d9a4de19b73d34cbab42cdd8ccp-3), C_(-0x1.0ae7c18dd841d8689ede2f52570cp-2), C_(0x1.3a82a1b96295b447f46661fe5bd8p-6), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bb2f43bc30b80d947c8a537a20b2p-1), C_(-0x1.2d48b852668c646a630392a2b66dp+1), C_(0x1.c2596fe640cadf6ca968f3b30ff3p+0), C_(0x1.83800be8c4de9681c9e31925ce79p-3), C_(-0x1.233972e07202850d1be1b9fc8392p-1), C_(0x1.bcd16d394575254330d81aed4886p-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.646bf1ec64a308c5df07d89c8e9bp-1), C_(0x1.cbd5c1bab5148530b0e77ecbff92p-2), C_(-0x1.754196833f706c7834855fa5579ep-3), C_(0x1.3100cab7c3f5f4fa75b80a67ed4bp-5), C_(0x1.8dd2be8c89c51e7b28b04315346bp-10), C_(-0x1.c4ab558ff2dcebdfdc6142054ddep-10), C_(0x1.3b27d2d798eecea1adaf099c04dp-15), C_(0x1.75f2b16626e9875840e692dcf344p-23), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8eee7927087b240ec5ade1ac81aep+0), C_(-0x1.37cf445237f1b72a99ae1be2616ep+1), C_(0x1.3c64475174b4a0c9b8a3ee3dfc2p+0), C_(-0x1.7841978e876db6599aa4ad10992fp-2), C_(-0x1.64d969ffaac153a6af06dc9cfb72p-6), C_(0x1.08fcfb4783fa7d234eba36053968p-5), C_(-0x1.5e1fef6185af966378a125175a7fp-10), C_(-0x1.984da1089743964ff5ac0959c3bcp-17), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.22c5cb8d3f23b44faf592c365f5dp+1), C_(-0x1.83cca07a3ead78a73330d7cf1a39p+2), C_(0x1.5245172406b77d1d4fdfd2192d87p+2), C_(-0x1.2d10dba463fc1840fd45963c568fp+0), C_(-0x1.549f4c5e04f3991456e630b1555ep-1), C_(0x1.882ac9029ddc72b4c74d388da98p-2), C_(-0x1.3d5d0eda32d8b61e7ff27a395899p-5), C_(-0x1.65cdc06ecf6547344a6a8d527f6ap-11), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9877ac926fb3bdd992f46d848f57p+1), C_(-0x1.48c27a70b93cdddc043571f47b88p+3), C_(0x1.f7fdf60845cfba22e0c6bd043e1ep+2), C_(0x1.0b1ea0ee5f9ed06f5107d79a1aafp+3), C_(-0x1.15aaf38ada16a6358cd77355f075p+4), C_(0x1.4a45041b91e1bb24fe9a63ad188p+3), C_(-0x1.05013480812df4c7388d78daa7bap+1), C_(-0x1.13ee46114fd8519c5d7f29b7d91dp-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.13b9e8c4fdc4ff9d9c7b93fda5d3p-1), C_(-0x1.e1e5e5cfd0a801f531eaef0fe6ap+0), C_(0x1.29ab2ec864d44a65c8f8abfdabb3p+1), C_(-0x1.3d6cc61e0f6a43e21f6553d10792p+0), C_(0x1.0227f72aa277daecfc1fddb3c5aep-1), C_(-0x1.9ada2a6a9a217e8dbe2b55c6bb8bp-2), C_(0x1.2c68da3893cd5c4c84ac50c60f2ap-3), C_(0x1.1a66dc6d2cfbf029033eb2e70439p-7), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bf65e79817d27ca7c78972c65f3p-2), C_(0x1.aa2466d50e4a4fcbbebe54f94c3cp-1), C_(-0x1.89fd104c6ff149bf7514a7ddf37fp-2), C_(0x1.24737e6f8ebf0ec8bb9fcc85bb71p-3), C_(-0x1.a1e9c758a51a08321aa63e9af1d7p-6), C_(-0x1.cec09a7ccf05b6ee1ea8f3c17f4ep-9), C_(0x1.cd4feb82d24938f30e41e1af2eap-10), C_(0x1.05937b8388af24ac43ec83967a2ep-16), C_(-0x1.5a00cfad970a7cbc309138fd3facp-19), C_(0x1.0fbc42c672231485a0bcbfe7e34bp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2faeacbb8e753b40eb856e00f522p+0), C_(-0x1.8014975295b2136d5a1adb454387p+0), C_(0x1.05033635f5401c9b60636a32526ap-1), C_(-0x1.0ffe44cc8bc7ea4a6ce4734d8d36p-2), C_(0x1.0b11b28c7d67ad63229fbc3aa7dap-4), C_(0x1.721a1d14b8322b2431432e8b800fp-7), C_(-0x1.af662c52c3b7ae55063672df3c7fp-8), C_(-0x1.a69b860b67a33179a8c7a5f6b2acp-15), C_(0x1.45b12643cf8203bdf796367d51eep-16), C_(-0x1.01892163486cb41cb64453f7616fp-24), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1e62ddd540b05b0cc5ce587007d5p+1), C_(-0x1.980b3fe2011f7bc878be7d399794p+2), C_(0x1.a34dea8cd59b4187717c6efb0662p+2), C_(-0x1.45eb5e5e7e3c9e9ae26ca4aa207cp+1), C_(-0x1.0310f5a5d86de60ba877dea685a5p-1), C_(0x1.da7724c65802bc95482213f980a5p-1), C_(-0x1.4137cfe85b9e5b04e10239758a3cp-2), C_(0x1.7eb866ddca6ba425f9e4eb854a4dp-6), C_(0x1.4ebb22d1ac0760e1461881059843p-9), C_(-0x1.0c5bdfb916a449da5acc3ccfdc72p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.422f9f5227e7facaa94dd7d9e31p-2), C_(-0x1.255a76df553cbf84e8a0b0613039p+0), C_(0x1.484b537c56deca3daefc656e3b6ep+3), C_(-0x1.3c98d8a74cd7736b60af4e604261p+5), C_(0x1.10b7f9c607064185ab2dfc58353fp+6), C_(-0x1.d54dd14cd31af65e5343fc875b57p+5), C_(0x1.8049478b6740d0c6b010047a06c3p+4), C_(-0x1.77f8847acd28ad3549099ae2105ep+1), C_(-0x1.d3687a3bc39335bac7f281e76bbep-2), C_(0x1.816ef86832621ebc63e47cd2b70fp-8), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8faeef62b3a7fd26eb98dd7f984ap+0), C_(-0x1.93816e52ba1c8483ff81ea3e324ep+2), C_(0x1.337880b3a9a717e67b9cd7fec812p+3), C_(-0x1.c3f2cd3d53132aa78f87aee07639p+2), C_(0x1.c7801db7678046e8ebdb22cf642bp+1), C_(-0x1.46377db27f624959a2b9b7777bb1p+1), C_(0x1.77a6f5e8321cd39a930db39033fap+0), C_(-0x1.c4188733407f241acae534ed0f5dp-3), C_(-0x1.f8b0a606c7f795229d5947447836p-5), C_(0x1.b965933f534b1af276b67227f89dp-10), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cb91942378a6b29e2dd51c51bfa9p-2), C_(-0x1.e6b982120ca31c68b89329c09872p+0), C_(0x1.7b2e4714b270342ea6ba899785ecp+1), C_(-0x1.fa645ee8ca231003817fbe32a47bp+0), C_(0x1.29da9349c32a19bed5b810cc4b88p-1), C_(-0x1.8461e6acf9cb2af90934d76c7932p-2), C_(0x1.67c137342024d6c8052e3d876acdp-2), C_(-0x1.c1a09b7773a59d1a65f356773daap-5), C_(-0x1.0c11f4efd5c0b7d44ac1c3a0720ap-5), C_(0x1.0ac90a45b7a47759a7a92738fc7ep-9), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.033291a6c76d6a2177301a6491e8p-2), C_(0x1.027f6bf7952cdbcf397ade5b83ap+0), C_(-0x1.919d92c6034c44a7ed45a578713cp-2), C_(0x1.7a0ca906acc4841a1191b023a485p-3), C_(-0x1.1142c3515ec433047c393c69962fp-4), C_(0x1.50e2d6421ee2654230b309723685p-7), C_(0x1.d0243aab613f83777184da54a80dp-10), C_(-0x1.1d4c6c249bf0ee08cde9105ae0e2p-11), C_(-0x1.17d0b3032ba5c5edbe3115298755p-14), C_(0x1.310ffd8b564011dafec30497e547p-19), C_(-0x1.509d126dab99ceafee21c5b15f2ep-25), C_(-0x1.57f8e6955253718d03dd42dcc06ep-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9ec434341eaed8ccc6e8d7244a33p-1), C_(-0x1.ca0692ca77439e8f752ca148c144p-2), C_(-0x1.2d988a986b0dea756341b6b8b7c2p-1), C_(0x1.145887eacb10f9d392eed69a9335p-2), C_(-0x1.4ab3cf0bae2a5b8432a0a181639cp-6), C_(-0x1.4e8938899ee371e40cd7b7528ae9p-5), C_(0x1.5cb5de436bfadb9e555d33c55719p-6), C_(-0x1.051eebbefaf7bd71954e297a61ffp-8), C_(0x1.0efaec65edbcc11b181ba7073e2cp-14), C_(0x1.6a87a6b931edc5ab5423dbf1babfp-15), C_(-0x1.4e8b2a27fe064ec01f627183042bp-23), C_(-0x1.54fd8f0625f118cd9bcdded88d81p-33), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e0eacca617ebb860573873f7b1a4p+0), C_(-0x1.5362d7fe36c56b6a443e9d6141a8p+2), C_(0x1.70aa17b7adc0e75a9ffe0b5a33b6p+2), C_(-0x1.86bc52429f3a3f79bb4f1cb73763p+1), C_(0x1.5709310e8d1f635f77e733f31613p-2), C_(0x1.9d599937b31fafd3d66db2bf1cbbp-1), C_(-0x1.18b244e50df675a487d76601b0e9p-1), C_(0x1.fe16d1a3cfb3e7ecc6834f2061cfp-4), C_(0x1.eb4cc917dd1cd56dce6a9280b03bp-12), C_(-0x1.4e09cf12f0cdcfd873bae5583582p-9), C_(0x1.c4a78957d279804ccd5115f6146ap-16), C_(0x1.cb0ccbca08e7961d7bc2f676b666p-25), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4ca9343b3236825367445e2a7e79p-1), C_(-0x1.492e70f2635c16c262e6190afacep+1), C_(0x1.171de5ca88cec2afbea5499914ebp+4), C_(-0x1.1e704d84a10750732762c3f4d8bap+6), C_(0x1.23bcc34d6a529b0b422faf672516p+7), C_(-0x1.415156a34428a6a6c08cde7dee49p+7), C_(0x1.7ff7929036ddd78bf54cfc378272p+6), C_(-0x1.a43b4147c122c6f143d7b591007fp+4), C_(0x1.833e6f5afaca4c566ce598593c06p-4), C_(0x1.13b5aaaf6c71d5b914583e48ae7dp+0), C_(-0x1.6365af2495a86c5f48d9bd1a47dp-6), C_(-0x1.64d19861a833792a3ce80f84d83cp-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.525f0cb11c2720485c66b9e19f02p+1), C_(-0x1.7eda4b6a23328f4e2cec098f6666p+3), C_(0x1.578437542fe4f5fbe4cefec73f0cp+4), C_(-0x1.40c582473fa8c93703a1216d1613p+4), C_(0x1.9815cb7223c105bc2b63ed01a5fep+3), C_(-0x1.222479cd96ee9d17f59bff4df592p+3), C_(0x1.8c2cccc6ee34ca0f24458389d35dp+2), C_(-0x1.ffd4fb5b3918044492967474d1cep+0), C_(-0x1.3be427404fe7d12432d600f4382ep-3), C_(0x1.7c490d447fad2e27fa6b12a0d504p-3), C_(-0x1.23f9756392d0ee9915448c1be2b1p-7), C_(-0x1.1f66b1e7815295f48755fd4e3126p-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.80a316d21a0eed480c84ea711d9ep+0), C_(-0x1.ce7e6827143677fbd12dabe06e9fp+2), C_(0x1.ac8b3ccd718c41df56b9c167f638p+3), C_(-0x1.74c81d1a27df5c33454de2219e89p+3), C_(0x1.4010d1eedca99cac8148c11888d4p+2), C_(-0x1.34da807d2aaec910bcf3aa770bf1p+1), C_(0x1.2d09c9846b581b01a4323f49de6p+1), C_(-0x1.97de12ea03ca10913f6e6b1c03cap-1), C_(-0x1.9df5b4fe2e271a26f87f7a1f78fbp-2), C_(0x1.16c54a229aae12ed509d340bab6bp-2), C_(-0x1.e323c5b92bd166e33ab5b4f9635p-6), C_(-0x1.c9a573f22c19a9032c5430df4c8ep-12), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a096c8f7fc8ab1575820ee7a8d4ep-3), C_(-0x1.01d8c748e11fa735da05e73f8394p+0), C_(0x1.099a073a7c7b41898468a5bd14cep+1), C_(-0x1.40ce386ca776e06ba6f31ba7dadep+1), C_(0x1.2a57634989c51fb583fc11fc2c8bp+1), C_(-0x1.e6f030cb23fbfde6dfddcd33a7b8p+0), C_(0x1.3544c2755b1d82eac792a5860a61p+0), C_(-0x1.6af581a622d416ac06a3c40b5b79p-1), C_(0x1.256afda077267e050d8164debfb4p-1), C_(-0x1.6569331439297d46e21a065d5029p-2), C_(0x1.4b88409bdd1172b9682df8963184p-4), C_(0x1.24061e2653bdb3c5fd153e823b33p-9), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.184a0c288d22add7ea26104df2f3p-3), C_(0x1.fbaa047a94a613069e6f550b4e09p-1), C_(-0x1.596f5b6b28cb0681bf78a3e54b72p-3), C_(0x1.234875f46000e28dce7c3f342092p-4), C_(-0x1.90a568ef3b94afacf755834bab9ap-5), C_(0x1.82b42ea0f8a1613dc5ff9725c05p-6), C_(-0x1.96b60b10e59567d6b2c6577bad3bp-8), C_(0x1.8430d19335684e7577fd3b699763p-11), C_(-0x1.92df0230079088d5ad0746147153p-14), C_(0x1.da6faa767962723e71f08f2e9083p-16), C_(0x1.b237bc2c3b5257b1d937078b7396p-20), C_(0x1.66eb1a28068ae3ea1bd5d2683257p-25), C_(-0x1.f6ebd7398c4a3aa441e024a5714bp-33), C_(0x1.5690727034a8a4b1353895ae261dp-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.03033f41d994757a2b4934423538p-1), C_(0x1.8347da7a3030b8b37cdc36ec3c9cp-2), C_(-0x1.7d2f17f2a95af6988be8eca125f4p+0), C_(0x1.c3013eaebde946f9eaa42bce8cf9p-1), C_(-0x1.4be40ed86f2cd0c168ad249492a4p-2), C_(0x1.4580356ca34ff1cf3c18408b1d74p-6), C_(0x1.7e9e8eefc30b45959dcb8ab52383p-5), C_(-0x1.594cf912461bb959724fb77ad3bbp-6), C_(0x1.27c56651be6ed873712071c19324p-9), C_(0x1.e972a09b0f4dc8fdb93114f9ed4p-12), C_(-0x1.1649ec5e541409b8483ac00aa989p-14), C_(0x1.c99c42a59648ab096d412a58741fp-23), C_(0x1.81519dee82f001d0cfd286a4bf1ep-26), C_(-0x1.06b5ee4f0711fc96e3337209d4e2p-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.666d532df9def8a39e69d4c9dbd1p+0), C_(-0x1.c0374596ee4d8e750b0b0f065b11p+1), C_(0x1.a43eb9f4500c29913bdae70f2e12p+1), C_(-0x1.d627359f84d250c8825852fe20e7p+0), C_(0x1.891e36789053a132cb4397963bd6p-1), C_(0x1.a23c19ecf2deb44f4177f3e9336bp-6), C_(-0x1.d9c16d05d77872764189280b3978p-3), C_(0x1.b6728d569b4c6b3f03c9c20fd79fp-4), C_(-0x1.66849bebd2ebdfafabb131375ec9p-7), C_(-0x1.fc6301aedca903a123de4bceca69p-9), C_(0x1.7e62ae52149bd7e06a18746f5b91p-11), C_(-0x1.2c21c0130a3eaea0bd3721b2b8d6p-17), C_(-0x1.15f344e8ed1b26069acbf2a1a453p-21), C_(0x1.7bbd836b1bf84d53feb61580dc74p-32), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.b44c4e267cbb4d43745305f720c9p+1), C_(-0x1.c1f7df3ad7ab79897dce80d62718p+3), C_(0x1.1601a8a979c78f82e398ce8545b9p+4), C_(0x1.e5bffb29b3c52bb885497a60d3d6p+3), C_(-0x1.38f35bf0e9ee0ae5b1772951f4d5p+6), C_(0x1.d1869b3f8e2b44288688d26e70d1p+6), C_(-0x1.70d2038145a54625eb25d875d7e5p+6), C_(0x1.34930dde67aea02e0a703b76a197p+5), C_(-0x1.4b77b4fb3674956338abd1824db4p+2), C_(-0x1.d27f3b25c1fd6ce83b2a8b0a4ac9p+0), C_(0x1.32a2c5a3dfe8119d379b71453288p-1), C_(-0x1.2fc64ff8d3420e31f2a6dd47d615p-7), C_(-0x1.c48021ad9bc1646021c012f5b071p-11), C_(0x1.364c0a7c4c64aef45189b312edb4p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.afe05c7a6ada1cb6172616d2c6a8p+1), C_(-0x1.0a8c44cdd47bf4e495a5398413fbp+4), C_(0x1.0f6c0325c5e1414a9285f59e5f14p+5), C_(-0x1.306ff1c62c8336aad5c3f9886bcep+5), C_(0x1.da69559cc91130d28dd4b63660e6p+4), C_(-0x1.6a2c1f828fe2d81030f1ad524eb7p+4), C_(0x1.0e28c771588c30581ce7071741b8p+4), C_(-0x1.ee4b3cc46d890789fa8b15b7da8p+2), C_(0x1.050e3e4d4732a1c55c0c971f3557p-1), C_(0x1.0ea6cad7a5a7fae2eab7d74b22a1p+0), C_(-0x1.6566f5ac7d80487971d04a5944efp-2), C_(0x1.0b828ad29e43eb178f6b65b8f31p-6), C_(0x1.3201b5c3bc1c21bf7086981ccb12p-10), C_(-0x1.a6f0242017b1488503cf0ef046e5p-19), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.77885e6e270a744c868654d7cbb5p+1), C_(-0x1.f5abb22b1b6ebb333fd9f11e8f7cp+3), C_(0x1.0a779dee6c7bddbff2f0d8b9981bp+5), C_(-0x1.164d9f148bde4aa13b66fabbc2fp+5), C_(0x1.2333738e736f124a0ec3de563f7bp+4), C_(-0x1.af306993826a689f7543995893acp+2), C_(0x1.6dba5c59397a4426e98586aad789p+2), C_(-0x1.17ffc928dd1d8bf0f209d0c36abep+1), C_(-0x1.9f39e7400cf5d234f22720c7748ap+1), C_(0x1.d0d0a8f3b805dafc2d2b539d9bb4p+1), C_(-0x1.4ac5cadf9fb14bc48382ff0ecfb1p+0), C_(0x1.049faf6ae689948e66d5e5134564p-3), C_(0x1.5ad3792bdac35c5163486d9087edp-7), C_(-0x1.e6e9a51e36639d68c6db7d7495a4p-15), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1912b6ad90d43603284e290418eep+0), C_(-0x1.85c00c80d7a18fcc693e47644de7p+2), C_(0x1.b7d753e3c818997a04ded98f86e3p+3), C_(-0x1.076d50e7f7850b94ae780b4bf285p+4), C_(0x1.92a29d7ac0e1e0002558af869ed1p+3), C_(-0x1.20f516098425bb22664ce4ad84a9p+3), C_(0x1.dcba519c323cedf78dcb7794def8p+2), C_(-0x1.3fe31292805c0462ca96ae20fe5p+2), C_(0x1.5e9b74431b072dba61e526c0393fp+1), C_(-0x1.a6996ae95f76ef890f12b5a6c626p+0), C_(0x1.806826de1640aff2fbfd8d0d7d09p-1), C_(-0x1.ddc83de4acfaf20be5fee513819ep-4), C_(-0x1.e09e81650c6b74fbce41e5378d99p-7), C_(0x1.5c5b71613d71b7692e7e5f0ba23p-13), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.eae80165a34ad1f2080107f7b7a5p-3), C_(-0x1.5a965a7535366541f0a1afe5172fp+0), C_(0x1.851adfd49d1a76d9d23c35315fc3p+1), C_(-0x1.b139c010d5d8ef58fb69c4f0efd8p+1), C_(0x1.ffefb7038043737a18fc832f1fb7p+0), C_(-0x1.0254056f57103b364cf4bcafdd14p+0), C_(0x1.ff103b26e087e22aa6dbe2498954p-1), C_(-0x1.7a4f70cc2f5d7a6d2a4e62aee34dp-1), C_(0x1.09dce627745a61500e9471981ea7p-2), C_(-0x1.c2f7ce5c8a37b8fcabdaf25d6d6bp-4), C_(0x1.41c46b919c33ee1c6941aae7132bp-4), C_(-0x1.03531c096423a7a88f95e3dc08eep-6), C_(-0x1.c24ed1e998c51356546e2437d6p-9), C_(0x1.5d1ed72a09587166cbb2e531d26cp-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1d2fbfac23949a1e129ec9f8391bp-4), C_(0x1.b1b6520101e0e6c7ddaa9da59f23p-1), C_(0x1.8b08d5cd4a2ad4b181244736a713p-3), C_(-0x1.4aef16c7e666f719f7698e178af1p-3), C_(0x1.fd1877f1138be38ba53889d724ecp-5), C_(-0x1.7ee87092fa242b1ef789aaf8def8p-8), C_(-0x1.09758849af60512fff4fa06073a6p-7), C_(0x1.3d3ef7388a3ade9f5adf4b3f580dp-8), C_(-0x1.29147421d57112477f4b7b3491f7p-10), C_(0x1.b33acccf47f1bda17f46b8106497p-15), C_(0x1.7e6498cdbddd4dce209effce7062p-16), C_(-0x1.53f9494edf1282277c1de6dc67e4p-19), C_(-0x1.58c1d88e09b30b0364784ebc1f68p-24), C_(0x1.278ba12dc249a4cd49c8d69ab623p-29), C_(-0x1.705a7a4d83450688cb9e189ad73ep-38), C_(-0x1.4fb4ee678fa0e1946f2bc7ed6f9ap-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2b90f770700937399f9f525fd17p-2), C_(0x1.af96b810375ae30c4c41bf8dddd3p-1), C_(-0x1.d3c16b16ba8799042d28d9c49845p+0), C_(0x1.1690032de8cfad91fdf041ea0eb6p+0), C_(-0x1.1f4f37268ff73d0393fe0f67790ep-1), C_(0x1.82c9256a70f8e96c68d16f2e3327p-3), C_(-0x1.540e9bea7c732170245209a302fbp-7), C_(-0x1.49841c554fed1d5f2443e15a5a95p-6), C_(0x1.96a364065f27ccd19657d67cdf64p-8), C_(0x1.0c49493de5a6ec95d0bb4c3aca89p-11), C_(-0x1.b592fbb7be41b5e92f003f6109fcp-12), C_(0x1.9d3f09be0cea6d8d6f8ed455255ap-16), C_(0x1.8562af0388b7df01536ccb66a5b4p-23), C_(-0x1.13cc2e0d34f2575dd283b068f4bap-24), C_(0x1.2234e02ed8630c149658a9630026p-34), C_(0x1.08644a120d1ef6f0d4b961ae1879p-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e4c00e361fc67a2e12b083b2df48p-1), C_(-0x1.aad6ffd5d77f153c17f1c8823935p+0), C_(0x1.135c57711e67099c1758b9c717c8p-2), C_(0x1.5b41454ff095722d0f803ea68127p-1), C_(-0x1.c92ba77b267a297500d5b5d44785p-4), C_(-0x1.4f00ea2c2d363149504e045fbe84p-2), C_(0x1.61aa479f9dc67b53226c771010fp-2), C_(-0x1.667619426289632c2e8907dc1851p-3), C_(0x1.7235017b58d31cc6ca2ab84f7b8bp-5), C_(-0x1.85c5f4a449272d8bf24d90db58c1p-10), C_(-0x1.2bb318efa4d23587f50785ea34e5p-9), C_(0x1.b3d73e818e5c9557fa6b95207f02p-12), C_(0x1.bca3f26f194cf877e2358ca6efddp-17), C_(-0x1.261d8947cb7277733f476ea3b7dfp-20), C_(0x1.36693a4632268e426c40140353cep-28), C_(0x1.1a9906065291eec094ff6b8172d8p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.27d6df36685a79598b6c86ce474dp+1), C_(-0x1.2ded79e41fdb0c43d1210e12de17p+3), C_(0x1.e79fd7c0b1c0ebd84f460885ecf3p+3), C_(-0x1.304a1a210a5f9ce8bc8b8a0cdf19p+3), C_(-0x1.effd2573aa9aafcb53e588a096b7p+2), C_(0x1.7ce72fdc2cb91189ae6d5e090c6bp+4), C_(-0x1.985f0196c72e53e6d1cfdee84e02p+4), C_(0x1.d3cfac07a9d2a8c51198c074937dp+3), C_(-0x1.e1a24f8472a680b7d24d058147a3p+1), C_(-0x1.9b8563bd7c7d7dc5768ba3df017ep-2), C_(0x1.fe4766e3faf53b0d124828083686p-2), C_(-0x1.73f12d4155f35b3e8452b4ff00abp-4), C_(-0x1.20dddf659ee509c6befdf1c7addep-10), C_(0x1.ffd28fb3400bf45efe5c328fc188p-12), C_(-0x1.fa83788d3f78d19a901b7477bae6p-20), C_(-0x1.cc794a76e5f165fc8108c92b057bp-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c7ced0f66aeaccfcda16588f9d75p+1), C_(-0x1.2ab8c9c81252e46b55777de43246p+4), C_(0x1.4df684dede46d3a014591fcfc934p+5), C_(-0x1.af3bf949d62b9c07b05b4ac4bf21p+5), C_(0x1.8eeb17bed133c367f65a67fc6e9fp+5), C_(-0x1.541e9c27826e49d24f626bb1a338p+5), C_(0x1.12ea47c60dec043f14d3664c7b9cp+5), C_(-0x1.35c8b07214e140ed7f1d446f3113p+4), C_(0x1.d829e1a7628821bc837255b88e76p+1), C_(0x1.69d6e9c20f73cb2d14ff7351adb6p+1), C_(-0x1.0235621854eeef97bfd3d4e3b1cp+1), C_(0x1.b423243b8b46906701ef92e0fa6p-2), C_(-0x1.2e290398a3fe2fc8cc3aebacf78cp-8), C_(-0x1.22b4e2598d44b0dd2f4a293dacc9p-8), C_(0x1.654cdf573874b672ebfe3509d857p-16), C_(0x1.43e711e67867252f78e7e45afce7p-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1617a4f9d885755cd3477307254fp+2), C_(-0x1.94d9c534a28d3ee0a8bf210cb612p+4), C_(0x1.dd0eb6aa76ffda42c87706ac442ap+5), C_(-0x1.168c0447c1b6e90c330602b02462p+6), C_(0x1.24c19c047007f67f0d2fc486ec63p+5), C_(-0x1.016a68491e4d871ca5058cc8b9fbp+0), C_(-0x1.c94ed28aba0f51cc92c5b4dc5aacp+2), C_(0x1.669c08c9522f315c7b041fb5fb05p+3), C_(-0x1.88dca456f345655b7cb4359a3262p+4), C_(0x1.b958d77e385a9163a2eb3b4f73aep+4), C_(-0x1.eccebab605f4b2d725512d8939ecp+3), C_(0x1.f4375d664ce342e4e51867996bcdp+1), C_(-0x1.2ade5d60c45811382f7ff19a5bd5p-3), C_(-0x1.491f178ce56460d544cbe167fd8cp-4), C_(0x1.5bccddec65e53c1b0416c330319fp-11), C_(0x1.398367062ce373b6810676d67904p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3841475e9a3639fcb27c2a85a863p+1), C_(-0x1.dd3c5aa19c52e5c8a273f6da1b5ap+3), C_(0x1.303529a28e46fac3a8f56ea5a2b3p+5), C_(-0x1.a86d9ebb6edc3ca33aa7af7132e4p+5), C_(0x1.7d0e6c4e24170b40a4b9574c4b78p+5), C_(-0x1.25c8439d2df89fa5007905a011dap+5), C_(0x1.f5b3e1ac9966686ed844c7042856p+4), C_(-0x1.815ee05c85e8aa704180612d3a88p+4), C_(0x1.ca4482f4236a5516d7f638f2b575p+3), C_(-0x1.050825dec75a966028608d12e5c4p+3), C_(0x1.1eeca8acc3a791ffedf80be8793bp+2), C_(-0x1.6df69657c972c8ebec75c924bb61p+0), C_(0x1.75a7ac677c4eee273d03fc609c7dp-5), C_(0x1.ebd49f3810c888c69855752e166p-5), C_(-0x1.4344372e1b6fc786ddf90f275fd2p-10), C_(-0x1.20264586c6bb91b0aa0b4d170d57p-18), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.041f759e862aa2196b99e32b0e5p+0), C_(-0x1.96fe795439508b28db4265486c81p+2), C_(0x1.04a7fd5b5e5923f7f627bd6af411p+4), C_(-0x1.5c5ede521aae5e58438f3722aadep+4), C_(0x1.0b593b29c51bbefd0a21a469361ap+4), C_(-0x1.3ddf512850559b028d83098aa4f2p+3), C_(0x1.12f0bcbe3fa44419a6b52304dc22p+3), C_(-0x1.d4ebfbf56d99633e38e5753902fdp+2), C_(0x1.d31827f76dc61557ae5c1ea99bcdp+1), C_(-0x1.6bf237312f18cf3b573ffc6eb123p+0), C_(0x1.d1d5c0ac4dc0c7147f916f90f5c1p-1), C_(-0x1.794e93c6506dcbe26714d9f89e44p-2), C_(-0x1.2e59e90e0a11c8b7ce9f9105aca7p-6), C_(0x1.26fbfe966bb82001d50ae928dc43p-5), C_(-0x1.e662faa96110f417469ce785ece9p-10), C_(-0x1.a81802ebf94f0a8bc8124e2acfbp-17), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9024e0f887aa33deb80194db4775p-3), C_(-0x1.3caa56e1c68f9f7ad07fd686ffdbp+0), C_(0x1.947e636a9e373f489450f999fe93p+1), C_(-0x1.033a79f260cef0d616212b14afddp+2), C_(0x1.51b6c9e0d0443759a67a3c3505fdp+1), C_(-0x1.0bd62fc1e045579c86e940e51c15p+0), C_(0x1.028bee5b6619ea0406791e99a571p+0), C_(-0x1.1620d9bfc03eb662d8d654bb6c17p+0), C_(0x1.b5ef819dccd9a27cb2716f32a404p-2), C_(-0x1.b7954b06be8aeb961960232f51e9p-6), C_(0x1.054d18d1cc90c79a1ef036069b3dp-4), C_(-0x1.4817258dd284697ebc00b788ccd7p-5), C_(-0x1.8ce86e181d4254ae37719aa28183p-6), C_(0x1.2926b8981e2a739eefaa1e5b0722p-6), C_(-0x1.20ae937e7a9305bbde13268a4994p-9), C_(-0x1.e260b0ee2a092f8355b87bfdf959p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.12cb0a33640b56e423474a1328bap-5), C_(0x1.4e2c27be21e0e479b88ad4851607p-1), C_(0x1.1c4636ef189eccc399682014d9d6p-1), C_(-0x1.85d2edb33e46dde58a5a504a9ab1p-2), C_(0x1.9e3dada7662a9865be6b99b24294p-3), C_(-0x1.494bbf8e53bfc023fe7e0915ab63p-4), C_(0x1.1d23df75685c890f2df5ab229b96p-6), C_(0x1.d4ed15a06848811344377f87f7eap-10), C_(-0x1.2885ec240634157f42540c2ec5a5p-9), C_(0x1.94f202846521b8fb6dee9352c088p-12), C_(0x1.44e94de53f6f632a67cbb5854d1fp-14), C_(-0x1.b37df99b75f08af621654dd8f54ep-16), C_(0x1.403905df41d323c0c33072aaf3cp-24), C_(0x1.c94370d7ecc9194547661e1cf7cp-24), C_(-0x1.58dbb791a7fb6c3e33eb2a850b1bp-28), C_(0x1.db358382953c45bea25d9891f3bcp-37), C_(0x1.afee7cd299cd64600d2193c416f4p-44), C_(-0x1.0988745ca3ec3e945e33c4d42e22p-59), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.43cfcb9d739232114ccf7b42f286p-3), C_(0x1.f5f9c20090df2cd39669639ec7fdp-1), C_(-0x1.94bc27297b9f96d98ca06b8b780fp+0), C_(0x1.61584eb9fe3a67acec590408bca7p-1), C_(-0x1.a2cb67ff996a90130726bb551867p-2), C_(0x1.eef0eaaf4989e29be4ba95e2f12bp-3), C_(-0x1.ac22308c89e820172f07afea77d8p-4), C_(0x1.c84ec23c8cdbe0f0d252ca4a5fdap-6), C_(-0x1.213456d8479d5a0a002e8a35424cp-8), C_(0x1.2c315a17e4063f457d1b74aaa54fp-10), C_(-0x1.f375455c5c9e61be4fa670796c8cp-12), C_(0x1.ce035ff90a79b6418f9714e02027p-15), C_(0x1.06ba9aa22e87c46e9b5b517bf9e8p-17), C_(0x1.2eea964fb1e803735b7cbdec445fp-21), C_(0x1.f125f98e34b07ec90a3117922ea9p-26), C_(-0x1.51db791710be9863d69c55fb8f8fp-33), C_(-0x1.3ced9d37da5d28d7002692ae731fp-40), C_(0x1.85b82452d92694835d294f84ac62p-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2d6cb779664d44484073db45447cp-1), C_(-0x1.01b00cc8d5d0650bb7d9e8758312p-2), C_(-0x1.0fd0995df5aa2a4c5f39f93180c2p+1), C_(0x1.8bd77a675e82837408b645325bb2p+1), C_(-0x1.c8684eac579b3e1019c502de8594p+0), C_(0x1.6e6d859b2e72f80278552877464cp-2), C_(0x1.86e851ba85834ec58a127f16fe28p-2), C_(-0x1.9dcbe6db3790670c84be0eec2f7fp-2), C_(0x1.55c762fd5a0df64b9c06acd53195p-3), C_(-0x1.35a481158ac33b4716b6e91c5435p-6), C_(-0x1.51b88ceed7addc9a97168ddbed49p-7), C_(0x1.0767285c8f10645316c4c221fa2p-8), C_(-0x1.67961ae7bb99fbfcc0d26144bc53p-12), C_(-0x1.2b4a0836ed60ae3a1490ad53cc1ep-15), C_(0x1.bb4b6c6c9a6faf8c7dd84be23c4bp-19), C_(0x1.3f418b80d3d44c3e61fe90bb843bp-28), C_(-0x1.0d99c100eff2e6c61779a485054cp-32), C_(0x1.4b9c0643323fb1c0ce2d07b0b092p-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a8dadfc02dd0428b41cd0c1bb0afp+0), C_(-0x1.8d688d31d04a4214094b65c4cddp+2), C_(0x1.317cc4a10faf3ff9c44aa07180dp+3), C_(-0x1.00fa12867f49132d26f6109f1a1ep+3), C_(0x1.9e984b48af59218135976f585487p+1), C_(0x1.0dcc3bbac5e0885ef946fb573bd9p+1), C_(-0x1.41a435a1df480f6b501eca7093bep+2), C_(0x1.075a464fd9703954dc501fa9230ap+2), C_(-0x1.9984cb75bad50ddd23b7c6a931c3p+0), C_(0x1.9cf2e7196d1cbd2ef1ba36ca5473p-5), C_(0x1.c915787e3612e2d3277f4d8526a2p-3), C_(-0x1.60b8b0c3b1138df4716646253571p-4), C_(0x1.324229742ef4416185466d935171p-7), C_(0x1.dd5da666efa58ec47474db0b6e86p-11), C_(-0x1.351528a4bd8176153593c8a5a1a8p-13), C_(-0x1.03c4250827b68f69b983f4479114p-22), C_(0x1.77139f17861eb1acd308dc031079p-26), C_(-0x1.cd96fccfe9f0afba4ba09dac3a7dp-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a04f8069ea8b4e447d853aa2b3fp+1), C_(-0x1.18f0a34d9f68e4d06a24b5c8413dp+4), C_(0x1.4ce3831796a61ef6af32be9a023fp+5), C_(-0x1.dc75f9b0b9a1041da91933762b9bp+5), C_(0x1.fdbc97313e6ed6865f9096ac8807p+5), C_(-0x1.eefc0cdda4efa281b21fc89e970ap+5), C_(0x1.b92a7c1b6a889c31c867c0ce8c52p+5), C_(-0x1.2299d502734c3c9b7e4c9a6f523fp+5), C_(0x1.6502b707871df45089990b5055fdp+3), C_(0x1.11f33f4ede647d59a412fb3857a3p+2), C_(-0x1.73b0a319e6889e9aa2e82f2679b8p+2), C_(0x1.244d452e7630092d6c490c8cc448p+1), C_(-0x1.35466c5650c61e120220d045b2f3p-2), C_(-0x1.fc20c8dd92f19b8d6ed30b1d9872p-6), C_(0x1.0d9c8b9d476f7d129de2a5d13304p-7), C_(0x1.a4010b80e5495d0ed9331140ed28p-19), C_(-0x1.49b0c99eb9c648511ea730b4e4dp-19), C_(0x1.962a6dd57b7daa6dc5023a314835p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.55886d2f64380baeb961078fa176p+2), C_(-0x1.09d95f1cede31fcd15d2c7fab39ep+5), C_(0x1.505f98e4bf27766f2f4d3b7ea8ddp+6), C_(-0x1.96ec354b303069fd664614786911p+6), C_(0x1.17b23075f8010224c348afb3ebb9p+5), C_(0x1.fc17211fa4d6f3f6a32616561c88p+5), C_(-0x1.b35f4a36b31c3849a4f062a53c98p+6), C_(0x1.d17f22f2480f88bf1a425e0d999bp+6), C_(-0x1.12118c5678b4d442de8a0eef777p+7), C_(0x1.207a74ca5ad8bfc2ee103b7bf96dp+7), C_(-0x1.934735f943481c7f74f56dd5b187p+6), C_(0x1.3fa55ba9206e3812ee32da2442b6p+5), C_(-0x1.959601005ec548729558e21c9eb1p+2), C_(-0x1.9505e84d98e613cfe4ec3f6fdae5p-1), C_(0x1.43d2632e32cd0df0bb4a95d727cp-2), C_(-0x1.38e017336cd0614a6ed2ffd943cap-10), C_(-0x1.968e83ac595b8c6d9c172a00fddap-13), C_(0x1.f5ed4b124df3ad0700a32c86e4bbp-24), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f3cda2f9b135402362018230e37ap+1), C_(-0x1.9eeda12641b61ebb7d840ecfaa6cp+4), C_(0x1.260fdaadd19eb1efc078d7fded1bp+6), C_(-0x1.d673d80eeade4a070ce0e7052e5ep+6), C_(0x1.f01b2fa154d0352990b16aa70967p+6), C_(-0x1.addb2c4ad791e217324c7aafb066p+6), C_(0x1.7db87bda6fdf8a74bb08213b9495p+6), C_(-0x1.3f9860f6c4905e7132b1781ae693p+6), C_(0x1.ae731643e9198e621648583330d8p+5), C_(-0x1.fb5cc3351ebc176988bf6478c6bp+4), C_(0x1.259afcbb8804d6eae552ab39c09p+4), C_(-0x1.fe186e460309fdcedab5ec38f6a8p+2), C_(0x1.4d0298c21892754606c3d8ebb24fp+0), C_(0x1.a1f0a66406a122ae435ed98406f7p-2), C_(-0x1.40c0addfd85543af466cc7de08d7p-3), C_(0x1.ba72fac37f087c7aee39dd6d7d9ep-9), C_(0x1.c193f16bb678e5af6510cd4d8f9fp-13), C_(-0x1.16b4995bb4f073263c20b5b2b14bp-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3586d9a9e0e3d99d2b93a01af7d5p+1), C_(-0x1.08fa63342ecc1c41a46b365c4c22p+4), C_(0x1.7c41f01d6960cbda171d22b314bap+5), C_(-0x1.276b64d22e134fe39031785d1e73p+6), C_(0x1.14f1cf74869c077b4ddd600b6793p+6), C_(-0x1.83d54ac636b8244258f1e3c9d507p+5), C_(0x1.4053c8a2c8d2fc6aef1621e8f43ep+5), C_(-0x1.209b538b18df262448ee3cebbe29p+5), C_(0x1.65783340b3782c7d703e94b54e85p+4), C_(-0x1.2ddf670e51dfca7d85e8eeab11aep+3), C_(0x1.38744fdae212579791ea9e59ba4ep+2), C_(-0x1.4065c212ba5c0456783637741afcp+1), C_(0x1.6763c5d11b774e2d99bb54d3a752p-4), C_(0x1.181d4d676ea1f03e7d8c57b5965ap-1), C_(-0x1.87564028831fbd4eb29dad95b0cfp-3), C_(0x1.843d22529bb49b17cf15d645bef3p-7), C_(0x1.52be3b0b8c7af55af9d914b56a01p-11), C_(-0x1.a79c626c8654ebdb591ae5793d64p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7a3cf471120ec198713994eca41fp+0), C_(-0x1.48b25e52d274b1e47c8864a7164p+3), C_(0x1.cbd93276e7d596419b912da6ea19p+4), C_(-0x1.37885d5242030806d66e5cf9cc78p+5), C_(0x1.4db4fb7a5ecdb9227e8824c1b905p+4), C_(0x1.74ac2dca21f55bb24886b2e8488cp+2), C_(-0x1.11ca2f9f0b7d05f1c16189874d5cp+3), C_(0x1.9fa6aaf0c8d980502f82ac3f1ed7p-4), C_(-0x1.8ceb3288570cd32c25919a739d51p+2), C_(0x1.e686e3fbc3fbf35811a68b06fad4p+3), C_(-0x1.7e0b780d60231a4c786ec3f17781p+3), C_(0x1.7e1a3482e160bfcf5bb1945be474p+2), C_(-0x1.247b57131543bcbee8b05ee74f53p+2), C_(0x1.b8a4e1c96768c895a2f3649c4cc8p+1), C_(-0x1.4f17d502240a8e6f55c9dea2c968p+0), C_(0x1.4b408438ac8689521da23d7beaedp-3), C_(0x1.7264788c9473dca575636b8d6c86p-7), C_(-0x1.d74fd6a021547c7f9f7dd044fd0ep-15), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f6438a3a88460091e0ea8516e904p-4), C_(-0x1.b7ba9255f9c77a442c3315f3c4dep-1), C_(0x1.3f509b3842148b5acdb05dfc7ebdp+1), C_(-0x1.eac616f0d4f869be16ce06d469adp+1), C_(0x1.ae9244fef585d2a56f1cb69c0c8dp+1), C_(-0x1.00d5d03220f3bbc8a51448aa67eep+1), C_(0x1.9413f3bab26fc85ab60692eb482fp+0), C_(-0x1.9bd9847a10dd537f2de875e0ae85p+0), C_(0x1.16aae27d18a67638fdda8c9d9188p+0), C_(-0x1.1587682f48215c21c42b36d23f1dp-1), C_(0x1.8145e3cc3cfcbcc409c895dd9662p-2), C_(-0x1.faf556e68970db4f5325d20bccb9p-3), C_(0x1.8ec972676b06aaf4a1909e5ab3bfp-4), C_(-0x1.49980ed40883cadc7b702f6c3e9fp-5), C_(0x1.5730c48bae56a4ea4426b047bab7p-6), C_(-0x1.0952d6b855c638b977457b4c3a4p-8), C_(-0x1.ce071dd8df1eee9d16331f022e54p-12), C_(0x1.30a4361eb25b38fd9207742aba25p-18), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f82d860ed311d7772f0a5fc02a6dp-7), C_(0x1.da87adf545dea36f29603c50206cp-2), C_(0x1.a074ea6831a179cbcefe13bdeb26p-1), C_(-0x1.d3dbc22db33632cb9d3eeea93097p-2), C_(0x1.07dc8c4b588098d99d74923fef1p-2), C_(-0x1.17e06a0deb06ffc5a354422c2913p-3), C_(0x1.d85300a8e9a59db3d8e328544719p-5), C_(-0x1.0710616766f9db787dd78480360dp-6), C_(0x1.0182a0c9a44ba81f2b490da87cf1p-9), C_(0x1.d91cd19825f46395eba40bde2534p-14), C_(0x1.f2bfaace30f58a825ed0b3a11e2p-15), C_(-0x1.d7e9ba7b3ac4736029b548526137p-15), C_(0x1.5c274e2e04a6575e26e75abeb4c3p-18), C_(0x1.63562e1b18da7fac5905b88575e8p-20), C_(-0x1.0af5800900ccbea5a647053aa052p-26), C_(0x1.1409cb495cfaa9cc50f1fb279896p-28), C_(-0x1.1601287f207dc804b32b2b372befp-35), C_(-0x1.4f944d6c974a0ba10244cbd7bf57p-42), C_(-0x1.ad914b3b9c6449c459a4d882621ap-53), C_(-0x1.65d8440cb5909e7eb82f547cb81ep-70), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4988f615d8fc2101372678651696p-4), C_(0x1.cd9786f046dbd06d9795ae5305eep-1), C_(-0x1.f034187a5d75333e9dbb5b1046e1p-1), C_(-0x1.075e3bcf1d71f31524cf997afbe8p-3), C_(0x1.303436308c600230256305532d57p-3), C_(-0x1.71d07ef81053ea5196f6a9c9ea93p-12), C_(-0x1.321c6b5970b994e47d89204a7726p-4), C_(0x1.0f00f0747578208709a35dbb5672p-4), C_(-0x1.fec807d6bcde2f6b9da93df4aa6dp-6), C_(0x1.092c0960e80ebe73a0fb5f592a81p-7), C_(-0x1.1857810566102a80b03f6d57486cp-11), C_(-0x1.693105a2bb706882bf9e39158aa2p-12), C_(0x1.a2acf3b1f9d0749452e4dc44d918p-14), C_(-0x1.c4d81f25bbab666371fdd702fceap-19), C_(-0x1.e0284772a21eeb07c87b76642d8fp-20), C_(0x1.7db784c0b013093ad9874c402637p-25), C_(0x1.739c15dc80c555f970d134b64517p-30), C_(-0x1.d9433a2520a2e30f13e7c351f17bp-36), C_(0x1.651bd505e5aaae5cab5b708f20cp-46), C_(0x1.29782f98b98d8b31230d837a9eccp-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5c07e5083d7090314f404490267fp-2), C_(0x1.307a2a8e783ea1f99bb361a3ce3fp-1), C_(-0x1.a41fd4c6e53047b890408086b518p+1), C_(0x1.08f3303fd9b5f02cbec87edc442ap+2), C_(-0x1.6a2a8758fd08bb3ed6b347424cecp+1), C_(0x1.5f04ae9c9034ab19fcfae00d09b9p+0), C_(-0x1.150c77d31565d35edf80240e5e1cp-2), C_(-0x1.78ed1cb9b0ec1e760990f81b60f9p-3), C_(0x1.4f99902d11603738023acee050bdp-3), C_(-0x1.41156e1c846c464a303629e298b7p-5), C_(-0x1.6c5861062a83616dee9275c18c97p-7), C_(0x1.21e04958552e6f03502dd7935724p-7), C_(-0x1.cd1c35ab2ad92bf156188522c5bfp-10), C_(0x1.af6480e4adc46cb9e0c7649b6f56p-17), C_(0x1.0136c3fb4b19b9b10157d7a834f7p-15), C_(-0x1.6928b0e495d07fb474aad6800549p-19), C_(-0x1.6377af73884bfae0ae8534a7569p-25), C_(0x1.64323c063686a79e3f723a6f6b93p-30), C_(-0x1.6fb51174aa8e375496c635af829fp-40), C_(-0x1.32449da1b960881894abd2226adap-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1c297e1a722977a767a1ff227742p+0), C_(-0x1.a72bc3c00615f73ba93716b01e65p+1), C_(0x1.8e98178e99b31d46ae26eec0b1cap+1), C_(-0x1.8f506e2a5e0eb5edc0313f13b62bp-1), C_(0x1.02364935e2222846b9cdda1bc87p-1), C_(-0x1.0fb2290536b31f2a2fbff3404bbdp+1), C_(0x1.80597d49465bf4c4d8869fb534fap+1), C_(-0x1.38ad9781c750136475272cd6e902p+1), C_(0x1.339d144fd9550bb8463b544a6643p+0), C_(-0x1.08b97b33caecc76a026ab8335d28p-2), C_(-0x1.3f8a268debfb77a1cde76d550fe7p-4), C_(0x1.2b8bd1a4fd0eaf4aaa08a96cf3ep-4), C_(-0x1.35b764060a713cc242948b5c4153p-6), C_(0x1.f33a86db42465a05a6ee3ed1f4ffp-12), C_(0x1.1c307da269dee355c5c2d340dfe6p-11), C_(-0x1.950dcb7c8e981d2c1ff88549cb89p-15), C_(-0x1.f904916865d4cb30ef383c46ae0fp-21), C_(0x1.8b6cb6bf7586b0f4f1fcded4430cp-25), C_(-0x1.21dedfd7476c5553241f507ac2d7p-34), C_(-0x1.e2c7778c519a040a7c97727ee351p-49), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.51d8dbccf9206bcc4420e8d9ae07p+1), C_(-0x1.c33b049bfbce5ed995e58045194fp+3), C_(0x1.0e79522ccf3dd0b86ea89a5531bfp+5), C_(-0x1.9aba40cee29c09f71dc38c35a548p+5), C_(0x1.f144c4df7513d73b0fd71dc9df3fp+5), C_(-0x1.17ce56ad9d9026c80fe9053e3b69p+6), C_(0x1.1abf8d1adcc3e5071c7209bb8006p+6), C_(-0x1.aeeda88b7fe87fd16bcf8e054d05p+5), C_(0x1.6d1975fc2f42e1b2096263c969bbp+4), C_(0x1.64c18afe2844c60255dd74d07edbp+1), C_(-0x1.4b3d36d8f9770ee95e2721f907e9p+3), C_(0x1.8e75251a7f5bee7754c2a9513fecp+2), C_(-0x1.9e20d16541319f6d732cb61c018ap+0), C_(0x1.8f713f264dac28b16bf91d504bd5p-5), C_(0x1.002e9aac591974da848a16c844c8p-4), C_(-0x1.22b5d07d79f24f7de83980b5ed9fp-7), C_(-0x1.695b63166e6d63ad77759faf33b7p-13), C_(0x1.ba1b21857af82fb76bf4742957f6p-17), C_(-0x1.df066d7576ffcacbc6c94f3c14p-26), C_(-0x1.8ec06f9de2f7d48618cf3f2e0232p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.553841cb8504c59ec8828722c9cp+2), C_(-0x1.1648a261cfac86a07a577122f4eep+5), C_(0x1.7429c31b8bcdc777e06851df4ff3p+6), C_(-0x1.d2259be1a7818ecd1bf98b71d684p+6), C_(0x1.36cbd86221f4c1c381302622675ep+4), C_(0x1.4a282d1320ed73864b5c73d42965p+7), C_(-0x1.2e04ab290e2e062d6018a7405d3cp+8), C_(0x1.5f18c6755ba04a0fe5846dc7ce5fp+8), C_(-0x1.80bbefefb89592a7731263e58b6ep+8), C_(0x1.90ad4b61c673e71a7b1a638ff4cp+8), C_(-0x1.4159e0e62036c0e7d3a9372888dep+8), C_(0x1.4eba06db33d52e049a499539c59ap+7), C_(-0x1.6db5a82568a43d359e1324f88c7ep+5), C_(0x1.6613709f48645b09020d1137193bp-1), C_(0x1.7dbb7d4fa2b472146ed131c42bb3p+1), C_(-0x1.1851a9519e35d94904835e4c0f44p-1), C_(-0x1.230c93cadc0b78607a6df63dd398p-7), C_(0x1.7e95e283d8ce34ce8180e79a24c3p-10), C_(-0x1.136d2374e371184371f11564efd5p-18), C_(-0x1.ca2f0f4b750065dbf1a91e494693p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.43e579b56aec6db8f44fad1a2ca3p+2), C_(-0x1.2015783789a1305c4b04f4299082p+5), C_(0x1.be9eb07640a6e4dcf71e8edd1986p+6), C_(-0x1.917bfbcd50104121d7cf2e5fb61ap+7), C_(0x1.e7564ac670464ea6f5bb03253324p+7), C_(-0x1.dd46b6e14bd993fb7d27e4be31d5p+7), C_(0x1.c24b2cb18bb303674bf661030f65p+7), C_(-0x1.9299f7098407dc40f69f41f42557p+7), C_(0x1.2da088f392f175bbf1502b058265p+7), C_(-0x1.7f74fc0a8fbbbd2a662926cc0952p+6), C_(0x1.cafceab55c22225d33d140f11ba1p+5), C_(-0x1.cfad0a751fefca13c3b326a88e5bp+4), C_(0x1.f4f5eade96653abb41ce93f1a983p+2), C_(0x1.14b6d949957a5646a550369bc7aap+0), C_(-0x1.5e908a00f74d9f8f6b65d286f0e6p+0), C_(0x1.1ee7d490234e22c547ade0704929p-2), C_(-0x1.1e667fbdaff187310b0173bcb94dp-11), C_(-0x1.81c4231f27f23e6bc64b0c2f2493p-10), C_(0x1.28216d550397d430f8799924705dp-18), C_(0x1.ebdb45ca159a64fa9f199a16a149p-30), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0e918e0751a5f26d66d326215241p+2), C_(-0x1.f54b1dc71e94b922c8b7d974b91p+4), C_(0x1.8cc935a5962f326b8767e9c68e69p+6), C_(-0x1.5d87f4fd9af883e7ca8f85ba9a3ep+7), C_(0x1.7fbdfc1f5c92ac9439f72d5fc5fbp+7), C_(-0x1.356154b8ce2bfbb26ff26135d3d6p+7), C_(0x1.00a2f00b6f35fbd2365b8c4d7e4cp+7), C_(-0x1.d61ad68084631dc5b1cb350d96d3p+6), C_(0x1.4b192d7116369fcf46bbc7590d76p+6), C_(-0x1.2bd7eeccbbd8b3529c9ec7ea0986p+5), C_(0x1.d23af72a9213134d138ab79fb28fp+3), C_(-0x1.a5a3f6309aca858b5548cc51629cp+2), C_(-0x1.0097ba319005f0b824ee39f7e25p+0), C_(0x1.29abec5ca24e481b150656fa7b24p+2), C_(-0x1.6d63c669ef72a15dead10bbf465bp+1), C_(0x1.521b96f1f011ffd834fe0c4deb25p-1), C_(-0x1.89a1e9b6409a39917b2558fc77d9p-6), C_(-0x1.cc0f8b0b31975b1da167d6d21402p-8), C_(0x1.9e94a90cc2ee8162e5d90cf2df7p-16), C_(0x1.5739a9ee6eb1c850a9597f22010bp-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c2a4ffe9661190c09a7af8b79479p+0), C_(-0x1.a9c9682497d4356cc97c7817608dp+3), C_(0x1.5bbb8c487ae5bb615e8e73227ceep+5), C_(-0x1.452573aebb3bf474bf24d5595fd4p+6), C_(0x1.91c80b52c3671525c3375a1dd5efp+6), C_(-0x1.84d65b83affb5ca97ccaf8b73947p+6), C_(0x1.678e1d36597adc53993fd96dab7ap+6), C_(-0x1.4933025bdb6895888c173cc7b2a5p+6), C_(0x1.14413c8e18075f1444cc540dc34bp+6), C_(-0x1.b51d99f6678421b18139d5beb61cp+5), C_(0x1.483818775e0cb14480b32b95042cp+5), C_(-0x1.a72562d5d8064b092b7bae77a4cbp+4), C_(0x1.e00e48c9f77143cec0c43c67669bp+3), C_(-0x1.1522f77734c2edb19342e41508e1p+3), C_(0x1.152961e6e0f56f5672007e36f948p+2), C_(-0x1.3d9d88a64fae43ec46db73db181ap+0), C_(0x1.3f1c58e4e2a682bc6ff059fa1f8dp-4), C_(0x1.b3efb441a4e1aa6b7bfceb788233p-6), C_(-0x1.baa159e67dd4ea14a46828d67fefp-13), C_(-0x1.6c2d94cde3ae1bef5e760e39de7cp-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.480f31520e3f310c306bdafaf042p-1), C_(-0x1.38fe2f09aac57b92aacdaa15d1b7p+2), C_(0x1.f8f411bacc9f961bc5fe5499f875p+3), C_(-0x1.bc60c3b54f90a9241998e0192f5ep+4), C_(0x1.d3d44a6a16adb2540f6bfe5db93ap+4), C_(-0x1.536d6f833b66773a970214ff031cp+4), C_(0x1.0953a7a524aca913282b24103258p+4), C_(-0x1.0c0dca303e8e262fc9682f1cf736p+4), C_(0x1.af56b1534f29dd21b9240915b75ap+3), C_(-0x1.f628948ceff73b6d1ae732743415p+2), C_(0x1.3ef834c3289aa35b262757674e4bp+2), C_(-0x1.c75ab5e1afc75a2d9d28a11fcce2p+1), C_(0x1.cb38bb2c5f4bebadf622e599ec8fp+0), C_(-0x1.624785bf15dbe093496b9f1d5135p-1), C_(0x1.61b17ae5ff0c0c37a77be972ec5ep-2), C_(-0x1.0b62472bd3d7849095f6dced344cp-3), C_(0x1.c9b3ef0688e890b76d9f130077d8p-8), C_(0x1.7c528a3f2156c588899985294901p-8), C_(-0x1.0c4738028aec930d4308df6549ap-13), C_(-0x1.b40e785cb88086ef360909630572p-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a25fe79d1c4ddac335be8819a8ap-4), C_(-0x1.79dddd860d2147a7416541793f71p-1), C_(0x1.2f92842080f0827925b022200689p+1), C_(-0x1.04a53246109b6b6c0d3ef73b505ap+2), C_(0x1.fbc727fc23eefb6381085fb0ea64p+1), C_(-0x1.2e8a4ebac6b5e49a84fad5dff777p+1), C_(0x1.96ff87cfe4cc502ebda973db1ba2p+0), C_(-0x1.db8c7f7bf2c3a242351f9975276ep+0), C_(0x1.8867eccd39d1aef372869101502fp+0), C_(-0x1.7019bc278ffc03b406b2ff135206p-1), C_(0x1.a30d20b4e67c690471d7cbcbb0dfp-2), C_(-0x1.7340e7a399e63a19859bd6b84d4cp-2), C_(0x1.68181929e64c530045ddd9e48ddfp-3), C_(-0x1.50a6f5e8f3b308d50e585f11b7ap-5), C_(0x1.8d3b211eb839ac11193734372a7dp-6), C_(-0x1.b7227d5381373569d6206c572353p-7), C_(-0x1.a3114fdf2fbc06953fcb9931063cp-12), C_(0x1.71e7a3b4d88bf16a9f3c256dd239p-10), C_(-0x1.4eea023db8bd4900ec558c766ab3p-14), C_(-0x1.09aed93888304346e30d148d3c14p-21), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ba5636194c0939c427c9ec59581bp-8), C_(0x1.3af72853b1890334601f92a1284ap-2), C_(0x1.da1521352f487f1b71f5ba208041p-1), C_(-0x1.5c6f665240adde3380bdc0aea438p-2), C_(0x1.4840a35a3e5076b07b9bb98536cdp-3), C_(-0x1.9d4fdc34ae4edcb2a06a461fd21ap-4), C_(0x1.042a86a360591d6b2ba9327c6214p-4), C_(-0x1.08554bd18ab256f6f2efbe750de9p-5), C_(0x1.86c905bef28a68962be82a3bfae8p-7), C_(-0x1.8785b403c86f6f7548c23ebef922p-9), C_(0x1.f00fc00fce26eee7a53c75fa9287p-12), C_(-0x1.43b7ce1fa4e5b162d9e05ba1624fp-15), C_(-0x1.dafa2eb6c7f5cbd9451ac8b8db32p-18), C_(0x1.2d678c174b94d04aa232fc24fe09p-18), C_(-0x1.f0554b8e5712d06e0273c8cb503bp-22), C_(-0x1.934a0de4da29338aed7c3945f15bp-24), C_(-0x1.3a5d95f1928eec0223d4d93358b6p-29), C_(0x1.0e0d2138861875f5d48c437e1957p-33), C_(-0x1.652333b327609e7169123d062941p-41), C_(0x1.02e74c07e60809b1acff78842ce2p-47), C_(0x1.bb358cf4adf4da69e5fa9c480499p-60), C_(-0x1.f67e04f08f2152aabe6eb786996dp-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3daa1461d0cf47fff25f3df963e7p-5), C_(0x1.716f56bac1b1102dab376b1a3fe7p-1), C_(-0x1.16bee9987071960277d4321df078p-2), C_(-0x1.f51bd9fa1cf2d9e12262aabd1401p-1), C_(0x1.97243be7bf08455883f653e158edp-1), C_(-0x1.b8eef0110c9fa4de8e71d38444bcp-2), C_(0x1.2402bce395301d2ffcfa2c7a4938p-3), C_(0x1.80595820660c8830537a9f5a0e29p-10), C_(-0x1.fa47fa3f4b021cbace01025dd941p-6), C_(0x1.025a88022a413b155a9680077b35p-6), C_(-0x1.3d712aaad77758afb71e5644bf72p-9), C_(-0x1.c5c0d04fc87430265835a2d868c3p-11), C_(0x1.c45b69075cdb62e0f0501d72eab3p-12), C_(-0x1.6a1670435bfdd529f00d82c5e437p-15), C_(-0x1.13c0d643a27dc3e64f7aa5ea1b1dp-17), C_(0x1.b2cff794384635cf6c5bd8331af5p-20), C_(-0x1.9ee90facd3d1333133d7e205e062p-25), C_(-0x1.c87e1185ca55b3b93aa74571695cp-29), C_(0x1.b076e966620448a8ccbae1de5619p-34), C_(0x1.71c42c5b1e646b3eaaa36a5a302fp-44), C_(-0x1.e6d8e5785ac9381d9a7b90929674p-52), C_(0x1.13fd176d0c254d2994cc4f8bbae7p-69), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.77fed2e01693602fb84977597092p-3), C_(0x1.e1d10780fb06110288f8999dc16cp-1), C_(-0x1.9e9c7ce63835ce70bd9f1949b4bp+1), C_(0x1.bc153af50c24b9575bdc1b7eea9p+1), C_(-0x1.240fe3f248860f90966b383ce203p+1), C_(0x1.80cee17390c17dd6afdc8b5e9bd2p+0), C_(-0x1.abf5df7fd7abfb9aaab015caa888p-1), C_(0x1.50c7e71a108baf578aa06cfc537p-2), C_(-0x1.4654ed4660723ccc0f0acc159e52p-4), C_(0x1.091b1dd62c3e5f033d13bd90e92bp-6), C_(-0x1.59c475f85d7f3ec16b121b44eccep-7), C_(0x1.935e464b93aa450281cf24f671a9p-8), C_(-0x1.8fe1513629011cd322fa61848df6p-10), C_(0x1.90feb0894b434ddffdbc8185f2a5p-15), C_(0x1.09bd1f2d4e386644ae469eb863f8p-15), C_(-0x1.da6da6ad5e76b858534775753bfcp-19), C_(0x1.a3886fa6d48c5693a0b3ec42e08ep-21), C_(0x1.0f7850b94c92b737f20b8005c4e4p-26), C_(-0x1.63226d50629bfc487dd5a4e8ef38p-31), C_(-0x1.84d7e34db15d3108fdfa03f5836dp-38), C_(0x1.75cc98099352929e39911fd43962p-48), C_(-0x1.a7d23115de5731da90d3ce0c96c3p-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.60087b087d2ef4b82953952d9084p-1), C_(-0x1.1c49e2797e56cac67a206b14e7b4p+0), C_(-0x1.f023b1706ef0dac15d9852fec6b7p+0), C_(0x1.8d30c07e51574352c1f1eb2006b7p+2), C_(-0x1.80e0de445b219fbdea6ef733a307p+2), C_(0x1.c1feac4e70c181d6b4fca6d1ffb9p+0), C_(0x1.3621ab0ea1b052aecf48cff7492ap+1), C_(-0x1.f3ab98611d47a796d9c546361f74p+1), C_(0x1.5e6794d526a24de36780aeb9efa6p+1), C_(-0x1.c702eca93a33cb508d7b1d00211fp-1), C_(-0x1.ee149aa686bb2faa29ff6d4bcf1dp-4), C_(0x1.ffde0ca5fc1a1519c08ba08ef931p-3), C_(-0x1.a2cbb989ecd0a0b85c48b0eeedfp-4), C_(0x1.d58bf4f6c76ea5b68a5554193d1p-7), C_(0x1.206affc103ba0a875625f4581693p-9), C_(-0x1.dfc88961f6b157e54f77890bbc2ap-11), C_(0x1.f86e53415f2a00da542f82562b56p-15), C_(0x1.28c920e4a3f6bb0fc001a36c54d3p-18), C_(-0x1.9c90e430666c8d48daf021826ab7p-23), C_(-0x1.7e8cf0898f3336a3b6d1b959b3ebp-32), C_(0x1.cc8984cca607f1a4cd24395b33dcp-39), C_(-0x1.051a1f819156ba9bc5cb80611a1ep-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.efa01fe281c907b167ef08b2a819p+0), C_(-0x1.34df3dac7fcd3f885ed5b13d2111p+3), C_(0x1.5961138d5be957877d8cfd1f8beep+4), C_(-0x1.014d7a672544a1c4d790253c77afp+5), C_(0x1.5a4b6fa251eaf90e3115b0c8a7d1p+5), C_(-0x1.d72d9b409f2b1bb94911072e35d5p+5), C_(0x1.1a6ca7d65632cc9e3b88e527a77dp+6), C_(-0x1.f8d9ef0a2890c5946bb98eca1feap+5), C_(0x1.142ce1c1f06e19e0c6f07b093cf5p+5), C_(-0x1.90f390767ce4703536c74e99b357p+1), C_(-0x1.822b1a96e2d91cc911472934db6dp+3), C_(0x1.52a34d125b1be5508a31d4593a7ep+3), C_(-0x1.0b934a511e088d9de4577e6b9d58p+2), C_(0x1.335fd67def29efb717b66730db11p-1), C_(0x1.17c48a3b6f0b811400fc04e29772p-3), C_(-0x1.0033850ae88073da0780e3e4b1ccp-4), C_(0x1.68d4635bbce683527c347878fb17p-8), C_(0x1.b6ad0e03e206f2cc34c3ad57b135p-12), C_(-0x1.c361dbb11082ba0b86af7e7039cep-16), C_(-0x1.d59d4ba004a567edb22672d12e01p-25), C_(0x1.f6c8c69c71b982736f46aec1c2fcp-31), C_(-0x1.1d186572e3d30ab58425e9b0d124p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1672f76c48a3b085a419d3d84efep+2), C_(-0x1.d05e83fe81471c548c37702884afp+4), C_(0x1.49fc051fc99a825862e53c41bd9dp+6), C_(-0x1.e442104e65335b30f1932ff3fcdp+6), C_(0x1.09c52f838d2fca1c275b6ba1ca01p+6), C_(0x1.677b64cbf326e55bcfc76402e361p+6), C_(-0x1.fbf39786bea7b138ef97d391fb5cp+7), C_(0x1.628081b6fdd810aa965a5c98d2cp+8), C_(-0x1.a2714ddd5c22b603c83ee77be92bp+8), C_(0x1.cb4de777b4f362d79e6f05e8e906p+8), C_(-0x1.9cacd3aee3a7e296cd71908c1c97p+8), C_(0x1.055f4806a834671e4070618a5f49p+8), C_(-0x1.8ddf94a470b86c5104b74cbf3618p+6), C_(0x1.95561c2d77ea7cb1b418f1ad675dp+3), C_(0x1.8ab9cc38b4948a55522c2ec1bb2ep+2), C_(-0x1.6e4f007cb3f6f6544bd7c8aa8418p+1), C_(0x1.43d7023213a802dd64335ed45bfdp-2), C_(0x1.951cff21de4ac7e4a1f0a692a613p-6), C_(-0x1.5137c147339bc2af2a690f130f2cp-9), C_(-0x1.3e3df8b2da2752dcb7f745d4f5a7p-18), C_(0x1.78040f51a9567ebaa0b6d793cafp-23), C_(-0x1.aa8cd8e6f8971ce4ff33741ce32dp-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6688e31cf50e0564efea7c707539p+2), C_(-0x1.50ba2688bc0430a9ee7461099f42p+5), C_(0x1.18d5fc503a1772d2730b3ea50efdp+7), C_(-0x1.16422099d0e700c2cc83b554b1d3p+8), C_(0x1.7cdc33f38c2d168782ab512e0152p+8), C_(-0x1.a2f3c3b8e6e4ab101396a900d9eap+8), C_(0x1.aa319d6af6ec967e381e232c3d8cp+8), C_(-0x1.958a02a1024489567edfcd9f60c3p+8), C_(0x1.4bb5b15c50a647500af490b1348fp+8), C_(-0x1.caa9291eb011f2ccec525396312bp+7), C_(0x1.1f2d7abf22a7296277eac06229bap+7), C_(-0x1.3b920d0f7e0d09abc1f29bae2433p+6), C_(0x1.bc14b21b62b9334a0ec0723419b6p+4), C_(0x1.8c237a0fa26d7404976151e77cdep-1), C_(-0x1.7f694c35d9d2245677a758a1954ep+2), C_(0x1.3f67e104a689bca4d8d6dcd2113cp+1), C_(-0x1.4cc6c058f371d1d7aadbd425ad1p-2), C_(-0x1.6b557354b8d84aa675e72eefd888p-6), C_(0x1.38d6e371bb0518c7efdfa510e3cep-8), C_(0x1.260d95329ea8e0edce58683df434p-17), C_(-0x1.5c7911e0053bc1a14fff7c706e19p-21), C_(0x1.8b88d3fa551bf844985173c27b89p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.80f665163dff60603105460968d1p+2), C_(-0x1.7dd2228ef04492e49ffcbc26de51p+5), C_(0x1.48b0d88030936751bd070f0b70d7p+7), C_(-0x1.41512ba753d055c75dc8c75f4172p+8), C_(0x1.8f56f07493ef05c30063bd380daep+8), C_(-0x1.675a39773b2485da34f83484320cp+8), C_(0x1.2e9626a21624df1cdd8e35d51165p+8), C_(-0x1.1263590aebe88d200657c008c834p+8), C_(0x1.9699942af2221429cba47418cbf5p+7), C_(-0x1.59e9b6e0b9c21128db1641974871p+6), C_(0x1.09d1a0b7c583242c5ad30248e848p+3), C_(0x1.cc8ab1005087bf119ad7a75bf51cp+3), C_(-0x1.93c8d5094509572acb009457fd8ep+4), C_(0x1.013c24badc62703530bdc2a89abep+5), C_(-0x1.784654bbd73679c9f2def5413da7p+4), C_(0x1.21acdd98ca7e3a8d97a584ca3cd3p+3), C_(-0x1.6fa583815aba1a21d8ba9c3f6b87p+0), C_(-0x1.39156fe5f0a3b45977f7c9849262p-4), C_(0x1.34372727b2154e0f63382ce7b14dp-5), C_(0x1.c53d49d19717546a3333946ded1p-15), C_(-0x1.57bc52155abea4723bbb438d51fep-17), C_(0x1.869c11b6398bbfee9ec137b2aadp-29), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d573db31c98a592a2b6a796753f8p+1), C_(-0x1.ddfb9c5686a4efd2bd1e36073e0cp+4), C_(0x1.a873c238f1ad89ace04b7607dff2p+6), C_(-0x1.b2204de17a53a3315364d57fc2b6p+7), C_(0x1.23910ebcbe60d3ac86902adcdaa4p+8), C_(-0x1.29c6cec6860250c0db3c6f8b8962p+8), C_(0x1.1c64b27b4c107ca71ade24985867p+8), C_(-0x1.156985f5c8bce6de73bf23e5601fp+8), C_(0x1.ef2b60fc7ce315a6b8de2d939461p+7), C_(-0x1.84734ae811782beee80a7af9899ep+7), C_(0x1.20e874beb6697ebef627268d4461p+7), C_(-0x1.93d454c0120c50c5e5f45ca0c342p+6), C_(0x1.e8c645d5034483f58d32c0b8709p+5), C_(-0x1.0a8b2e2c06173020781b6687242cp+5), C_(0x1.14ef6d11452bbb05715fcae8f362p+4), C_(-0x1.bab6f3f4dbb55284f9925c8a3ab9p+2), C_(0x1.4e6aaf12e910db6611cb145f554fp+0), C_(0x1.e57ecc0ee730e09fd58c293b9a01p-4), C_(-0x1.0f174cea8c305d809bddd1a456bfp-4), C_(0x1.a1f2dc12ec55c96d12f54fd03177p-12), C_(0x1.4002914419fbb27ad65f422d91cep-15), C_(-0x1.6c7e600f14b10472b7579cd8544fp-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d2f4e044749b4e7a1c71b105042dp+0), C_(-0x1.e196df480fe71bea5cbbf6f938ep+3), C_(0x1.ab061d20276f0750e2a72080d7a9p+5), C_(-0x1.a7b259e6037ebf7c8e2adb89e41bp+6), C_(0x1.04d3977e22f60f45b515e3221088p+7), C_(-0x1.c308c46a51aa08f31731ad9b7844p+6), C_(0x1.759cb70549060301bbf1ea932595p+6), C_(-0x1.73a4db524ebc2efdc465e09da17dp+6), C_(0x1.4d02e405c663ff8abf63f28cd74p+6), C_(-0x1.c4dfc682dd95df4b0a54f646c034p+5), C_(0x1.217c835a844bf319c913aad35977p+5), C_(-0x1.9d3e5e5e092523c01057547d3214p+4), C_(0x1.eced01c912f6c17b1d536b46140dp+3), C_(-0x1.ab15772777a65a90ae2d7ecf56cbp+2), C_(0x1.780b7892927c5280dd5bee9ee8edp+1), C_(-0x1.59e4e79f9d38488dc3c59417b41ap+0), C_(0x1.04013ac7f90eca1ecf033aafa30cp-2), C_(0x1.63e903ad632e7f30307040928615p-4), C_(-0x1.26b339b06c46eff13165e32f7c85p-5), C_(0x1.1fc083a0e2c35a300d5c6fbf948ep-10), C_(0x1.9c18e59aa15ab3ece464b6468819p-15), C_(-0x1.d792baac952f2e4df120dee003e6p-25), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.19eec26520f7247ef7c6a243923bp-1), C_(-0x1.249f95db3c6a85ee06007305aedcp+2), C_(0x1.0297dba66cdd344c6014ab433b38p+4), C_(-0x1.f4e8dc0eb78aa7eff1fa727c9c71p+4), C_(0x1.1efd1b3c60e0b36de4fe266b9d8ap+5), C_(-0x1.a397a05a5f774f4ee2078a58f21cp+4), C_(0x1.239464bf9e82c4fc4fdd79af7e82p+4), C_(-0x1.3946d065739beaad7a01650a25b9p+4), C_(0x1.2898316e66a7f2a70e1a6a12eca5p+4), C_(-0x1.5bb8e2c4642782930886e32d2ea4p+3), C_(0x1.68255c99ba4c6b07d82156e3f9d9p+2), C_(-0x1.21aae7ae7df31c29928804e58d84p+2), C_(0x1.64fab317448fb0474311942daf3fp+1), C_(-0x1.75b64c97e09686a5bb55f9818d82p-1), C_(0x1.22ff2ac4d8b9c4ff1397fddfa477p-3), C_(-0x1.07ed621dcab476dea8f9bcc8470ap-3), C_(-0x1.4a01e6ee0860d89681b645bb0864p-6), C_(0x1.2e7cdbbc900312ead84b8d7e757cp-4), C_(-0x1.b7f6865bae122ce58cd5b4105bcap-6), C_(0x1.17b65cad3d540e056708b80ca432p-9), C_(0x1.910e0462410b5b96ed51c4c46ef3p-14), C_(-0x1.cf434a44d45d4684dfb9a827c309p-23), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a6c51bc471a3098c7c3ba4b2e396p-5), C_(-0x1.b8315371d42a542d22b52e160edap-2), C_(0x1.89e13c889a74c808a95f3ae5db18p+0), C_(-0x1.8aa497719f070f6dc765c7af4f82p+1), C_(0x1.eb2b7ee2bc88d2eef92b780b6136p+1), C_(-0x1.a91739cfcb4374adc78a339981b3p+1), C_(0x1.4e87023b22be1f061884b91ff276p+1), C_(-0x1.31bb74af8ae4dfa54f812e36b5bep+1), C_(0x1.0e1263d4463c809bd8442e6ab9d2p+1), C_(-0x1.9cd0db1b42b96cb6927f614da713p+0), C_(0x1.3cec213a53551ad84004d758bdadp+0), C_(-0x1.daf35f59b2441d717c1690c25188p-1), C_(0x1.329c321d7ff6b77198e76070d6c7p-1), C_(-0x1.8936ae8cb907bb56ce7124a40ebp-2), C_(0x1.00dee0f339229a14bdfc063bfb91p-2), C_(-0x1.07bd180d959690eaf41df5a4ee44p-3), C_(0x1.cec01fe9b05f624125be250b50a9p-5), C_(-0x1.e6ef9d5209f879f2bf7a379cfa32p-6), C_(0x1.8f4f47250e3a4f324676c24519f5p-7), C_(-0x1.e72d4f4950c89aa59da6edc504bdp-10), C_(-0x1.e19176d7ba69146eb048e9181ac9p-14), C_(0x1.1b79fa688c946fc4993e527c8905p-21), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.749078c0867a9a724454443e75a7p-9), C_(0x1.8ae6a79b4938fbd909b199343609p-3), C_(0x1.d008898983913d9bf1d194ac98f7p-1), C_(-0x1.20e16d5539e3f25296b1c6880b53p-4), C_(-0x1.f688bd1280c70194203f744266d5p-5), C_(0x1.2fca4301354a4e285e82fc4b6183p-5), C_(-0x1.505c64431d7a6f1e36954a7c80cp-12), C_(-0x1.0145189baf0142f2a8862b8be415p-6), C_(0x1.c908becee5a6a6fcccc95605355fp-7), C_(-0x1.beac12be1e7de0939dd15f031644p-8), C_(0x1.0006a916adee342c6b2792c6bd7ep-9), C_(-0x1.d4cc286b09e13557f3e87a0f9caep-13), C_(-0x1.a08b65bbb598677114fddb7b661ep-15), C_(0x1.5f413ab3a7eb94dcb396b2657edap-16), C_(-0x1.5c34d16af592037a11107a487b39p-20), C_(-0x1.2dc4454eebde3379c7645c4ba87ep-21), C_(0x1.74f33a2ccbc6518fcdedc7d5aa01p-24), C_(0x1.ddb5df0a412fd407d061c573b81ep-29), C_(-0x1.07969b3a158bd160a5cdad0ece81p-32), C_(0x1.2c5958b74836c10a9059d0bfc767p-38), C_(0x1.52fae6e83091fa686190e11a0d2cp-45), C_(-0x1.d83da475a639c307966abb294b63p-53), C_(0x1.1342e56840ec19da921d2c329c6fp-65), C_(0x1.aa25edf8f64fee132e1b30933b5p-86), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.23923550f457ca7814b0bb3fd653p-6), C_(0x1.0c0767795d12ae5d156ec5cf4423p-1), C_(0x1.3373be839b47c40b1d36ec3e47ecp-2), C_(-0x1.856d7e6b6468c2deff8342e75baep+0), C_(0x1.22d30ac28dd9c9a5de5413538cd2p+0), C_(-0x1.72e38df054a23a8a5ebabc499005p-1), C_(0x1.8e439b194a1c16626ebcbea59c81p-2), C_(-0x1.3bc2524066e83eb2d5b3ff97e1edp-3), C_(0x1.1bc8f6e41059663daa79bf4a8b55p-5), C_(0x1.2884461caa1e3207b6de1334a7c9p-11), C_(-0x1.db22a9804aa1133069d05b96cb0fp-10), C_(-0x1.3482dca87f01c45e946a258c3e06p-11), C_(0x1.3285223dae55992a1d57ada1533cp-11), C_(-0x1.bbf1c4306d1a37f02d18135ce323p-14), C_(-0x1.17497a4dcd44ffdc92c6ebd1a068p-16), C_(0x1.bebec0cbd1f99371a7867cbe3fbap-18), C_(-0x1.bc40d833ef3598561d72cdf89bb4p-22), C_(0x1.6454c6cebdf97f43adbbdee1eeb8p-26), C_(0x1.5fce040bf0fa22a0bb7f52a52e7bp-29), C_(-0x1.1241493325c926f92e656210ed16p-33), C_(-0x1.ce70ab06ee7eb593175a3e65f68ep-41), C_(0x1.8616f674ef405eeabf053da9c72dp-48), C_(-0x1.7b38ad7c07a3a058098173d3a8bcp-60), C_(-0x1.258ba4702de85ac45e001504a52p-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7e9e99d93265e1ecb27f1a82e385p-4), C_(0x1.e81e73bf7d4e6759d9f3db761257p-1), C_(-0x1.368292c7be10e513188a104c5c4ap+1), C_(0x1.a1c192a939b9674ffcca9b2f1e48p+0), C_(-0x1.58e6f9045a40dd2a472104dd0f2ep-2), C_(0x1.2f82100ba4f2879faa0ab7316342p-2), C_(-0x1.f8fd9be6cc910f763e95aa8aafdap-2), C_(0x1.017de77081fc30f9ad09eddaf43dp-1), C_(-0x1.5831ad14642112326c714ae42463p-2), C_(0x1.30d718554c4cabcfafc1434f8a7fp-3), C_(-0x1.30a6075105b3aa4d5336fc1950e8p-5), C_(-0x1.632f9e9eb99fc711faf42ce203b1p-11), C_(0x1.1cbed37ba4dbd96c225d81054e88p-8), C_(-0x1.77d86fa7164bfc8c126a64816ac4p-10), C_(0x1.50ec238da00966f5e3d28fc9265ep-14), C_(0x1.f99c3b6dd2e633388ada35d1bfe8p-15), C_(-0x1.8453f2cbc2d996b7775a123e9384p-17), C_(-0x1.b4056601f4bff8b5e7d36857cb2ap-23), C_(0x1.4c2776a5f116e1d85dd046bd9786p-24), C_(-0x1.287daf168a219aa1132a37934711p-29), C_(-0x1.b00a66e2af603b8210a104b463bdp-36), C_(0x1.401eb1fad689de068ef9a337dfddp-42), C_(-0x1.71528144e6954a34804ddc8b7672p-54), C_(-0x1.1de10823e626bbef4adf3610f4fep-72), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.95e033565cd465e59fc64a849ff5p-2), C_(0x1.e7908dd5753c97550b1b562a02c1p-3), C_(-0x1.293799fcf6c8da1f93fe2d057e3ap+2), C_(0x1.36cc467b08bf7d8a89d5be8f934fp+3), C_(-0x1.4335983e135774c5e5156a45190ap+3), C_(0x1.9c4d14b5414867b3e2c99a21a031p+2), C_(-0x1.ef81d85b23a01ac83af86d64d1abp+0), C_(-0x1.2378e73c6b10a2f7957b04478d3fp+0), C_(0x1.c6e27151761e3e586f5403563b06p+0), C_(-0x1.c857e67243153a965a648f8e6a77p-1), C_(0x1.3531afa42b77f4c754018d3dff11p-8), C_(0x1.05f57c1a6464d742d9d2e202da9bp-2), C_(-0x1.38a2db882124dfc4e44179ad6816p-3), C_(0x1.35c4a5041d9b9456d2520e65bc23p-5), C_(-0x1.fddc3c9f813d6aef1f4f22d0ffb3p-14), C_(-0x1.2653a0321997d1fa4ad992783a03p-9), C_(0x1.ec5d6f7ab50c177dc61e0a189fcdp-12), C_(-0x1.dc01f8633f4c61396f200866480ap-17), C_(-0x1.379717b64ca37d0f86a74f664124p-18), C_(0x1.7e5cfdc9a1b17dce328c7c0b5cf9p-23), C_(0x1.a124166c5786174e1b984a588c59p-29), C_(-0x1.4171311c3a7b2623f4df8ab8200ep-35), C_(0x1.65f402b77f1ab227d7a791609ed8p-46), C_(0x1.15123cc4efb60d3af1736012e615p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4c5d516dd5340d0879832abfae77p+0), C_(-0x1.5d2571cda5543923016a360261d3p+2), C_(0x1.24b0f03522629e31e5a0ddf9b0acp+3), C_(-0x1.39e0f8d13e8db1f029ce62587cecp+3), C_(0x1.f006cc927be5328f1a33d6aed069p+3), C_(-0x1.0ce2ffa4646117df99ed92fff69cp+5), C_(0x1.b8b8afcf323d00e8ad39d1ccb61dp+5), C_(-0x1.e6925570e3f510211d732b9179c8p+5), C_(0x1.503102590c0b7b7ae2742f43b1bp+5), C_(-0x1.6d86add093f074bc432a452b5189p+3), C_(-0x1.35b5dc1025f2d34a60aa7bf9f93dp+3), C_(0x1.a6237c764b4a28340b8488817371p+3), C_(-0x1.cda455c3ae3929d25c3c5a324857p+2), C_(0x1.d5a02bb93708a320124accef7fd1p+0), C_(0x1.ecd4c4adc075fe2457753c0ae29ap-5), C_(-0x1.660ee59df078b432fb4f889b38bfp-3), C_(0x1.5158e51b27e5dbfe89f577f9dcaep-5), C_(-0x1.73814bfd57b681fa89fa6df52a98p-10), C_(-0x1.23460c48f636fa706d007acb283p-11), C_(0x1.fa353cdebaaaaa09ad0c40e9cfcp-16), C_(0x1.19c5738584246e6431d3352c6ae1p-21), C_(-0x1.4bb4308ed51fff3108f30cb71f7ep-27), C_(0x1.fc9a1f4f09858f536f1a575d9e29p-38), C_(0x1.89a8b7b9d28d1d71597812aa68c7p-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a35157d8dba56b3359c55dbb3245p+1), C_(-0x1.5a1bc35a1cc0dbb69c71add31e17p+4), C_(0x1.fa0a0878d9a933860f511fa37af4p+5), C_(-0x1.a68f6523a82701663e04e3ed3779p+6), C_(0x1.98403a971e63162a02dd92c33da9p+6), C_(-0x1.03810e60e02049d57e6cc9d05d6p+5), C_(-0x1.14faaec76846550eede58601f0cdp+6), C_(0x1.3d735b94c105436aa6c6accd08c9p+7), C_(-0x1.cdbd7de801407d716cbc38649987p+7), C_(0x1.20043470ad456af43bde8d7a0984p+8), C_(-0x1.2591e882d85cd18b0dca9775a589p+8), C_(0x1.b621996a63c17e6687cb0aeb2864p+7), C_(-0x1.a875ba068d8449d487f82d8f98a2p+6), C_(0x1.85c7d166f26b7783d793e4b535e5p+4), C_(0x1.1c0e0d6b929f95b9e528987efc33p+2), C_(-0x1.36efc345fd87e7f12a7cd8cf55f7p+2), C_(0x1.3e3f5c2c93c347939cad28d35ff2p+0), C_(-0x1.bffc3922a312894449dea079023bp-5), C_(-0x1.75f52c4bce3944c6d40bd8c68e83p-6), C_(0x1.dea5b49d2b299f2f3407a959506bp-10), C_(0x1.10aa3eff5f8aac0902d8bf4b6addp-15), C_(-0x1.ea6ed6c321e753c1b3e92351b813p-21), C_(0x1.089ab261bfe1c8b7f19aebdff953p-30), C_(0x1.9990a3735f2b8137827c03e7b5fp-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5d159c98a090a206b1f5a487328bp+2), C_(-0x1.54873e7e1b3d210625d277e6898dp+5), C_(0x1.2c245e185ac8b14c7baac4033f4ap+7), C_(-0x1.416f5cc6c22c1fc04eeda9dfb493p+8), C_(0x1.e67e2b7f933044475571e632011ap+8), C_(-0x1.298ee57db6ed5fd4bacad0de9695p+9), C_(0x1.48ee3d90a4e34a8f4d18f98b7344p+9), C_(-0x1.4e6b4521eb7a56c1ef75797e43fdp+9), C_(0x1.2782e95d7bf9f5fc360d37ee013bp+9), C_(-0x1.bb493883e544d446bc2b8bcc693p+8), C_(0x1.25dfd4b9fa45afe8f2d50abdb77ep+8), C_(-0x1.575e0c206b7ee6818931b6231d56p+7), C_(0x1.1c028f2725fce675841ea5e425e4p+6), C_(-0x1.08a1fe0ac6819f96e8258a0368bp+2), C_(-0x1.12ed1d6ca77301d9871c862435c4p+4), C_(0x1.66791e904ad3b41e47b43fe289f8p+3), C_(-0x1.7aa9733036515afd48134b03fe32p+1), C_(0x1.41600caa02955d88aadf08f58823p-3), C_(0x1.275514f436a31e564b7d019a87cbp-4), C_(-0x1.29373f56ac1095884f483f83febcp-7), C_(-0x1.51ea7d9f345040b9bbf67fd2c9c4p-13), C_(0x1.deb156b08b87ef0592d66bd4c9c7p-18), C_(-0x1.6e30fae8c34ed8366ddfb0cc8561p-27), C_(-0x1.1b57abb7d7f1ba81ca336dd9e4d6p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d4fe27a0835ae1a04e0830be24cp+2), C_(-0x1.ecb0f32ca76fb494d571b0a3e338p+5), C_(0x1.c6da62a20cd0a85f32742b3dd231p+7), C_(-0x1.e3622dd5ba05d80a963a5e3e0d7dp+8), C_(0x1.49508717a90e836846bfe76665d8p+9), C_(-0x1.3d934aacf56d0a27027f03a0039p+9), C_(0x1.068600d74e1c90df9e5939a69755p+9), C_(-0x1.bb4eb52dbc23c8aa9dac0b1ae5b9p+8), C_(0x1.2c2d3c048caae8b4e7ebc3a10a9fp+8), C_(-0x1.6a6f07f5d07dd28cc71310327c39p+5), C_(-0x1.48c0f7b3bed9dd4e2bcfc6df9159p+7), C_(0x1.bce28601020e5546efe49f4f2facp+7), C_(-0x1.9e035ea535c3aebdf12735df11cep+7), C_(0x1.737017c34f7deef2722c9d811907p+7), C_(-0x1.15bd065f2789c251ed52867c6e81p+7), C_(0x1.1609d2e86de1f46bc02dc6e0a8fcp+6), C_(-0x1.30b382548235fc08ce2a6ea99e65p+4), C_(0x1.34c266d274d020226722064f6a4ap+0), C_(0x1.56d14dbd1c0ef8dc071f1d5be26fp-1), C_(-0x1.f82518456ddfa0a1ea7fb11fa704p-4), C_(-0x1.1d5d333a03734067f69cdf063e2dp-9), C_(0x1.599f88826e1df7529e25322303e3p-13), C_(-0x1.742b04eba227022dc2784e1aeb19p-22), C_(-0x1.1fd835e2f3ac373e68a1719919f7p-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6f91b1fb16e463903f2417b8bc33p+2), C_(-0x1.8fef11e8059ceda062deb12c9387p+5), C_(0x1.809c444472a8d8415a2c7a9afbefp+7), C_(-0x1.b10bf090c92b5336357cfbd2f863p+8), C_(0x1.45258188f71468e863f92b55998cp+9), C_(-0x1.7231afc08bd276307932b219a0cfp+9), C_(0x1.7af82162ac359965f69e6fcab693p+9), C_(-0x1.823e9f8992b59fc66e1876f1aa68p+9), C_(0x1.6f4bc124eb7dc2e04c11a11579edp+9), C_(-0x1.32f291524b4fc819caccc41f919dp+9), C_(0x1.d856007cb8fa074ef0836c00fb93p+8), C_(-0x1.59b2f057a74e4aae3ebb4a35f68fp+8), C_(0x1.c4898ffe6b603cfd7a5fa627ad77p+7), C_(-0x1.01b04bb5c7e4ece20624945e7d4ap+7), C_(0x1.0ee550f2b46fb0067dbfbe5f34b2p+6), C_(-0x1.f149829700499105abd07323449cp+4), C_(0x1.21413698e7cf1b5b76cf50d81657p+3), C_(-0x1.1e358290df39caefe5b52d405e07p-2), C_(-0x1.54f12799790c9591a372397a1538p-1), C_(0x1.1dedd290f907f8d2a852f01bdfd7p-3), C_(0x1.2b8db385d6eeb017f64738645db6p-10), C_(-0x1.7cd67d6099898e46f355480e2303p-12), C_(0x1.c1758243d6f68f11163695671c33p-21), C_(0x1.5b5402fbe8db7e6e4a3332e846cap-33), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e00f201ca9b47bec13b3bceeec35p+1), C_(-0x1.09aad588fc6e1d2e5e320a1b6965p+5), C_(0x1.0083b1ed3add1dfc189ab7aaac2p+7), C_(-0x1.1b01639f15a47195db844f5df4eap+8), C_(0x1.8e74c5b415b4c982c62a28306ab1p+8), C_(-0x1.907a858da198db5b4a86eef21cd8p+8), C_(0x1.68e4a68143eb6280f78231820634p+8), C_(-0x1.685dfe59eb94f38e35f487b91dc1p+8), C_(0x1.592f39b72049a36e7924f8b1defp+8), C_(-0x1.09589acf597f567d3772f2b218afp+8), C_(0x1.658b66c44d2d9f09118af69ddd27p+7), C_(-0x1.f90c71880a91658c0d9a38574dffp+6), C_(0x1.49a9a7009f2b267b39bab54a8a34p+6), C_(-0x1.441338caa52cfa0e2a27d488fb3dp+5), C_(0x1.0b7b2a297fde14bc6faf3e06bf71p+4), C_(-0x1.d98372b1c68d3f52be82670d6ee1p+2), C_(0x1.f43ec1f2a32806088746ff9dc715p+0), C_(0x1.6165b77555fca80d9c5c14948139p-1), C_(-0x1.4f8a8171bb08fcb9ccd7f4688dddp-1), C_(0x1.267683e93d2b771765dfc5bfe73cp-3), C_(-0x1.8ddc624d415c8d8d9889292068a5p-9), C_(-0x1.979cae945ae1031f8b5a56752269p-11), C_(0x1.95627b187fdb196e7b60fd3122a7p-20), C_(0x1.38bcd286c35de60d5fb4c84a2f35p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ddc9914b8fce26e89a34c64d6d6p+0), C_(-0x1.0aa6a6fe4749ff9a53419e5cb74fp+4), C_(0x1.ffd30a30f104e3ad2ade2b583021p+5), C_(-0x1.1076bbdb4cf7527cd039bd2ee863p+7), C_(0x1.5b314fd5bd8427278ea0f14850c8p+7), C_(-0x1.15e629a2f07ab3b285fb28d62142p+7), C_(0x1.73ecdaa7dbcd11927e445f4fc04ap+6), C_(-0x1.7ea4991281a803e96d951a02ad23p+6), C_(0x1.92fe5087093b614dba0f2e58af18p+6), C_(-0x1.e50ce86c3eca30ad8c357a5bc172p+5), C_(0x1.23fe36ce5250d05c3006a508171cp+4), C_(-0x1.1183a5ac74636a4f4f8077863f2cp+3), C_(0x1.325da71616787b1a97cd6b487bbp+2), C_(0x1.b5b93d37eb78f2e235cc59568f84p+2), C_(-0x1.6174cc292a977e8769fcc13572c1p+3), C_(0x1.b8e78e1a9ada492b4dd6fe85e7f5p+2), C_(-0x1.ffc6e54f09b8a6376ab9c26e41bp+1), C_(0x1.807b43d233e13293cd8f6f610b94p+1), C_(-0x1.949effe4fd5f10b6f0bb69f9fc41p+0), C_(0x1.99c706ee33d33292c4de755a9043p-2), C_(-0x1.8b4255eb2ab52df50469eaf1f575p-6), C_(-0x1.25fbde4ae0e29153ac78daabb6bap-8), C_(0x1.a2ffd5a58a3e625ad5baf547df1dp-17), C_(0x1.4225e5d67d6a903058f380dcef3ap-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.82555f0fca681c9ced300bba3465p-2), C_(-0x1.b108ac4bd9d5de90a612fa91bba4p+1), C_(0x1.a3af9f5e28533d44a218819eab18p+3), C_(-0x1.c92e2a69bebea1255ad98910de81p+4), C_(0x1.336156f19a3eab19184560490c7ep+5), C_(-0x1.154d20c532d37d99d550b554251fp+5), C_(0x1.af95c6a7f034f7267500247c3a39p+4), C_(-0x1.a382ed435f8ed2216764cb0a372p+4), C_(0x1.a5a57db59b67be50825ea51ac179p+4), C_(-0x1.48587bdb4781058d9836884c3b74p+4), C_(0x1.c6519b1cdb292e6d292e4f1f9c11p+3), C_(-0x1.64406dc5dece20ec3c4c58b87407p+3), C_(0x1.05a0da2a87dafe77cb9a54ec8326p+3), C_(-0x1.34062a3bf7c109c05654bbca487fp+2), C_(0x1.65a3327bcf1ac1cee14ebea4c8b6p+1), C_(-0x1.b27cf7ab49be37cde0f46679310bp+0), C_(0x1.a5bdc7192b9c3a20ece9060c1ba9p-1), C_(-0x1.571ac2983f85e3a6dc62f13fd384p-2), C_(0x1.31767817c6adec541d6996364d3fp-3), C_(-0x1.904f3491bf69c7251d1b40c4f69ep-5), C_(0x1.0ee4f3163f55f45905e2ddfb93a4p-8), C_(0x1.2584f1f36b43e7bbd83744e7e8bep-10), C_(-0x1.373cf584c03ee906a072cfcde9b5p-17), C_(-0x1.db60a068c3377c744925f382f6d8p-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8dbb03fad2c2ff4e565f682fc387p-5), C_(-0x1.bebdc5d3b23911ed145126163ba8p-2), C_(0x1.aeb7a5ea21052a1c43ba381385e3p+0), C_(-0x1.cb9851522d20abcc6f87f331e722p+1), C_(0x1.240bf59871b997fc41c935dfbef9p+2), C_(-0x1.cab7cf1ed537e0d17c393ba768f6p+1), C_(0x1.1fd4543a5fd8cb1e3fd209bf00ffp+1), C_(-0x1.1ce9744c1c9756de9b809c9cc5acp+1), C_(0x1.3bab08bd76344b447fe47382a836p+1), C_(-0x1.c40e7b4e77556f5ef8447dfa81f7p+0), C_(0x1.feadc8c7ce87a8fc67e2732ba34ap-1), C_(-0x1.a643a47d84b4da70d0fb0b9b5ca8p-1), C_(0x1.543b964e0f03a3a71ec489e8760ap-1), C_(-0x1.577aa576ffa64efb7d0e9a7c6b39p-2), C_(0x1.499f6f7a97a22bd1178c8279f046p-3), C_(-0x1.d5a15151b901635be5a327439552p-4), C_(0x1.d4c5badb46707713b03f6550ccfep-5), C_(-0x1.094f5215690db085443c42ab246bp-6), C_(0x1.cd0926fb9e142792dd84020c8a8bp-8), C_(-0x1.b2091c2c73dd02f84cb3796bc045p-9), C_(0x1.fdc7350edfadd24f5fb7a32829d8p-13), C_(0x1.4af17513fc3a876960b7cf51425ap-13), C_(-0x1.fd199a3cefa31b76bcac261239c5p-19), C_(-0x1.7fa406e41ed65db974ed315201c3p-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2e3c0bb3f3ad4d49ee7e86ec562p-10), C_(0x1.d73cdc4f17147d4ff78a1eaebc89p-4), C_(0x1.980f074dbd462038712882b2223p-1), C_(0x1.0b8da7807c2738b0ef8a21bd41d9p-2), C_(-0x1.381b88314120b0755faac9b6a208p-2), C_(0x1.a64053bd4da4144d5c6645aafa5p-3), C_(-0x1.be6cb26620f84322f5bc9ad124p-4), C_(0x1.5369f32b472a8bf80c2615157588p-5), C_(-0x1.e553bfb83c481ee1c85b1021810cp-8), C_(-0x1.5b97376b07916025b5f5ed690f77p-9), C_(0x1.3ad93e070eb79f317793c09c0451p-9), C_(-0x1.6c8658d1b206dd40e11227faae77p-11), C_(0x1.421437e7b839d2e408af08229906p-16), C_(0x1.359cb55b7d335b5bc8ff9070d38p-15), C_(-0x1.16b1cde08937e6520514fc007dd3p-18), C_(-0x1.1e470298289ae452c29404b9c746p-19), C_(0x1.16b7d7c52ecb6bf5c9c270fe3977p-21), C_(-0x1.2a9017a9058ec8631bfea23cf0f2p-27), C_(-0x1.e6603a12c62203e481a6f751bb0fp-29), C_(0x1.ad635a5532ad9d7f9b990f3258b1p-33), C_(-0x1.0b7166f3d598041c11f82d418c5ep-37), C_(-0x1.2dcc8d3c8b0cf63074ab4d9fba6ep-43), C_(0x1.994c7452dcd30c07dade8e0a0b5bp-50), C_(0x1.d3e7db27a70ee63bd0dc60e06dc1p-60), C_(-0x1.ad34c0383fa643c903234154af78p-72), C_(0x1.c6fd0b1a8d6a2b5f9f47659e9cb5p-94), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ffe6a833f41d1e41c335a1d66225p-8), C_(0x1.6878956519ce3162ba29291a8504p-2), C_(0x1.4f6222726462315c1311b1bd0b69p-1), C_(-0x1.9d7a4f00f9dc035ff30a13b3dd54p+0), C_(0x1.ee1a7236f71e3afe8c9241dc280bp-1), C_(-0x1.3a4c3d150c11dd01e59680a43c1ap-1), C_(0x1.a5124e1ab47a907fdd8a56cf5fd2p-2), C_(-0x1.fd47140509eb33a71307cdb49b3fp-3), C_(0x1.efeb8355fd2f814144fb4db02bdbp-4), C_(-0x1.695e5e5e49cf847101e5144b6fefp-5), C_(0x1.73cae05387f642ba0d652b2dbcabp-7), C_(-0x1.fa774911ba2d3bb25d61e69c8c8ep-10), C_(0x1.13b07ddddb3b836ee57d12843693p-13), C_(0x1.7cb11c0b4280a9d8a95e4eb20e72p-14), C_(-0x1.d2cbfff6e2a582bd1061aa2f380bp-15), C_(0x1.74388c9fd28e69e7d9f0c5af3fddp-17), C_(0x1.21ff895bfb5f2915922793fd222dp-21), C_(-0x1.156307b5c128c175f7e3a71477b9p-22), C_(-0x1.19b91bff8bef4f88f1ed76cce8eap-25), C_(0x1.f7d83e4d41c76f94d46210e4d1f2p-31), C_(0x1.5090626b206a430059df75028168p-34), C_(-0x1.405683426ad010e44f0a98cc929p-40), C_(0x1.6ac079eed130df81302e2b26c482p-46), C_(-0x1.9a49f0637a3b64a9eb35bd52aa23p-55), C_(-0x1.88bc66cc087f1d558950f224d6c9p-67), C_(0x1.a0541eb1bdceab613773d4dc3dd7p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.70e38d13c6dccf6333417be4b4fbp-5), C_(0x1.98429094e12d1953c234a36b137bp-1), C_(-0x1.5a23aee5cfcf330386719e085aa1p+0), C_(-0x1.ca3a85e30ebf60ba5eccc5b7b84bp-2), C_(0x1.f2911f6caea6ac421bc7b6d2ce04p+0), C_(-0x1.902df5acb98563fb6c85941263b7p+0), C_(0x1.6e5d8a32fe3ae7b3c23b4e6e9c7ap-1), C_(-0x1.7cd7499a11b87c3bc4909e0bdb58p-5), C_(-0x1.cb51389df1436d54630b5c4050fbp-3), C_(0x1.8970fdea96db48b13c52294d029p-3), C_(-0x1.2e3ba43116d4ee1d14ccd7ef1eb6p-4), C_(0x1.a437288ed51ab324c667ecc7c439p-9), C_(0x1.5d8afaeb5ec2a57500ea441b58aap-7), C_(-0x1.3f213a25a4c39a4ee9f8ca7fc5f5p-8), C_(0x1.438df66495fed0569b1e6607263bp-11), C_(0x1.92aacb344e1aac45946a6dd95b1dp-13), C_(-0x1.4a2a2b6937dca67c2fb96409eaabp-14), C_(0x1.061494c076ea4c2b5c794f2371b4p-17), C_(0x1.1c61500cd5ff603bf7260846f007p-21), C_(-0x1.fed404b96c72e77fac42699e644dp-24), C_(0x1.9900fa8d5cb81723cdb543a2521ap-29), C_(0x1.4b71c6cbb7be353ab93ac21700e3p-33), C_(-0x1.f4e20f23251aa513b13eb0ad0eafp-40), C_(-0x1.ae764159a5bb5c8d340066c07578p-50), C_(0x1.0753e4c918ed6b59ce15c4a9365bp-59), C_(-0x1.1725d8c4676c38ff70e1cc359512p-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.b6406454732d4d440405d44a6a49p-3), C_(0x1.b949541f458cd808c01c6f4442bcp-1), C_(-0x1.49bc84198d8eee0e1769477dd34dp+2), C_(0x1.255157167a5528a3714c438e2bbbp+3), C_(-0x1.254591e8b6e06babda61e0b5bd92p+3), C_(0x1.bfdd01aa9e6916b30d7fb866cb4dp+2), C_(-0x1.258cb0e12f407e788c8d24c043p+2), C_(0x1.244b687910817f75269b9b13d0aap+1), C_(-0x1.76e9c86768fd81ae0140e512f91dp-1), C_(0x1.2db90e1b7e223907d65e1858ad53p-3), C_(-0x1.adc00aab7f786622c376bd60c25fp-4), C_(0x1.077b01cdc29a9bffc55813096431p-3), C_(-0x1.4e1bd3d7c8106ffe51d90e297c64p-4), C_(0x1.a8b1719f76969f8051acdf38ae9p-6), C_(-0x1.1b67a8fdd5d395a5e1003bc2df39p-9), C_(-0x1.5aa2219e8b072017d97056f432f5p-10), C_(0x1.0c296ebe05b6e9c7cf2917908081p-11), C_(-0x1.315112d6e2648d659715640aac77p-14), C_(-0x1.aa34a64782e3fdc563417212e36cp-23), C_(0x1.718ac2125512de66d6a9b5d79809p-20), C_(-0x1.4ed202350e6d4103a23efe811aep-25), C_(-0x1.6a2c3e7b115c942fffc924e2aa83p-29), C_(0x1.03cb1bd946e2daf6230de1902b89p-35), C_(0x1.d2ce73e99c2943d672b79f3df3dfp-46), C_(-0x1.110d7f1b0bfbfc4b48ffe175513cp-54), C_(0x1.2175be08d4af39d29c43830b5338p-73), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9bd3bc24739608dd1ea0727f797p-1), C_(-0x1.218b20c923a72ab49d783c3c2182p+1), C_(-0x1.8f073ee2485429a822c3456748ddp-2), C_(0x1.10368c3ad14ec0121ffa10beccc4p+3), C_(-0x1.6e5fd027a16b3fa71b0c68881f6dp+3), C_(-0x1.fee6b19288528fc99125553bcb88p-2), C_(0x1.5dae0c64ec100c07cb64acfb530ap+4), C_(-0x1.253938fa65f9cdca9dcd99a2d96bp+5), C_(0x1.0846ca351ee337bf1cde15f6a892p+5), C_(-0x1.d3379cfd6d392ab0067070d38b2ap+3), C_(-0x1.bc1cbd5de053b1b3e6030cd2eb44p+1), C_(0x1.49e86d68d4cf8c86d82167732746p+3), C_(-0x1.e4ade08c4a6c2c8507d0731ef456p+2), C_(0x1.651f390634956dee37faca7ade61p+1), C_(-0x1.14e32e1f9b6bac3d6ef9b665a8dep-2), C_(-0x1.c20b1d287136abbd5724af54edd7p-3), C_(0x1.9dc73570ee73f3a5d7e75adc1efap-4), C_(-0x1.dbb9ebdd9c09deccb1020147719ep-7), C_(-0x1.c7f5c1ec60f696f9a40d5c2f13dep-11), C_(0x1.a5fc856e52fad70c72c88b43b17bp-12), C_(-0x1.07f65daa0049b089e54b5e492044p-16), C_(-0x1.0e378f07aff0a4003d557ea13ebap-20), C_(0x1.69bc58d5ec0ccbef38bec2915824p-26), C_(0x1.872aa1bcf368769fc21e287db36p-36), C_(-0x1.7b84969608016d06bfce8c098437p-44), C_(0x1.92548cc9b5b71c86f11e26fc3a07p-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.29b15e8e05f4922e7d4e47048a9cp+1), C_(-0x1.cfd365d6145278198eca9c82d9f8p+3), C_(0x1.440caad9c12360807dafb3bad1d1p+5), C_(-0x1.116de9d813b38a3407c462c9c8afp+6), C_(0x1.3b639c503b3cf7fe4e226236b434p+6), C_(-0x1.0040f57e975e1a258b9875fe1f17p+6), C_(0x1.e6fde6a95ce32902224ee9a0f717p+4), C_(0x1.5c1e9e155aab7b67b6f0684e8054p+3), C_(-0x1.b1e5da7957b3c8fabda1cfa1992fp+5), C_(0x1.7d1f138d16b9d31aa28298c6d585p+6), C_(-0x1.d6f4cad7bdd82bc575e84a0ae447p+6), C_(0x1.9fd808c31038fd9d9f9820868c69p+6), C_(-0x1.ecec6e1a57ab3b47a08d37ee9238p+5), C_(0x1.43fff7220eba3de58880aab6571cp+4), C_(0x1.5e941cd01c024910420637b6b61bp-2), C_(-0x1.d2a0789936f63c584facf37b3e67p+1), C_(0x1.940e89f9fbe3b90fa47d360fd472p+0), C_(-0x1.f62a7689777aabb4ab21abcf7e27p-3), C_(-0x1.2b3b3b35a204159ed02721cadaafp-6), C_(0x1.3de2ba1c1b05528a92ffeeb8fc2ep-7), C_(-0x1.21cbeea2dd955597cbff120c27ccp-11), C_(-0x1.2150f65158193f62d7d7f8ca1f69p-15), C_(0x1.159bf889454c6b38325ea0bd0aa7p-20), C_(0x1.b00f4f96ce85167dd0220db19d66p-30), C_(-0x1.21e8e13c855c01e5c446a0ad86p-37), C_(0x1.33590911079747fc32e0ebbb9924p-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3069c9b572d786eb96d929d90cddp+2), C_(-0x1.2e376983f6cb6b3abd68459b0db9p+5), C_(0x1.1366d92966ea16320047794482afp+7), C_(-0x1.37b9852173f06f1765e1fe9f84p+8), C_(0x1.ff3f2db6a15a3d87e9d7df5b42f3p+8), C_(-0x1.57d9383606e506f39f38563cb6bep+9), C_(0x1.9e8b97533b1eae6eef5ccc2c8b76p+9), C_(-0x1.c556790a27e1d4367bdf86d03f05p+9), C_(0x1.af9eb47abc08e08daae8af537da6p+9), C_(-0x1.5e3047bf51b54c2759154839c7dbp+9), C_(0x1.efd9329bb40ff6440883f8a40f82p+8), C_(-0x1.337ec090261a5db68ef9839a3fcp+8), C_(0x1.1dd7e09a266914bfb2df7819245bp+7), C_(-0x1.34f8d53391e95dda3b7a36e1f269p+4), C_(-0x1.1b6423ffa4134de5e81b13aa374dp+5), C_(0x1.038ecbdebefe39ca7724b2c5d6b5p+5), C_(-0x1.9f2073b507553852ed1a7122dc5cp+3), C_(0x1.0d3b2378aacf1f56c9dbd6033ed8p+1), C_(0x1.b93ffbdcbcfbcafb2828e4f8a1e6p-3), C_(-0x1.00284db90f95b583e4f9723dea4p-3), C_(0x1.5202609236b6be9cf16ae5695042p-7), C_(0x1.4b9320a57f2323116dd63291deebp-11), C_(-0x1.d3b085775602aad7427a1a128489p-16), C_(-0x1.e975304f420640f339ac1f2721b2p-25), C_(0x1.e5cecfa6ab7bb5421ef8c106f4f7p-32), C_(-0x1.0188e4a2f5a9df06f6875fecaac5p-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f579b17074e36836eacdf20b2124p+2), C_(-0x1.13b9cbe766166f25c9dace3616b1p+6), C_(0x1.0d0d0432bec134cd566f5783ca25p+8), C_(-0x1.309a86e68bfe9899fc0e86f2260fp+9), C_(0x1.b8e26231ea03e8ec859843dc6ce9p+9), C_(-0x1.b08b284517ec42e68106ca8a8bc1p+9), C_(0x1.3c7d2b26245024778e76cf716fbfp+9), C_(-0x1.7e7def0dd6c17f062ac5f280847p+8), C_(0x1.9c880448390e60397d83aacda54p+5), C_(0x1.dc1752cc2f2f84356ce375550f21p+8), C_(-0x1.e54a03fbbc2fa46a8399b07d254cp+9), C_(0x1.1a42e1dae56904bbcf3f8f7fa5c7p+10), C_(-0x1.f903f4a18c30e32dc6c260029f14p+9), C_(0x1.9d8db919083864fcc4e1ce713df3p+9), C_(-0x1.34173ffb143e1d9eed0dd73c6925p+9), C_(0x1.64eb3c27db564d469eb11c515c5dp+8), C_(-0x1.0b0c43171fee5929daa55b569994p+7), C_(0x1.5f0a5375d11c72dc55988338ff36p+4), C_(0x1.d8f6b9f1522f2e96a9e46aa5caf8p+1), C_(-0x1.1c75896d6d598c65080bd27d32aap+1), C_(0x1.f38ac1a749daef77915c1d44f9d7p-3), C_(0x1.f82700b4dc7274aa9bd956d7234cp-7), C_(-0x1.1306135d4672f12980f36c25a44ep-10), C_(-0x1.2dc514d6999140dbb2a21c1d56f1p-19), C_(0x1.1d494ae1d331f410d68f7a178351p-25), C_(-0x1.2e8464bcec8d40ffd77ac9bbd77ap-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e32cc25ea4da498425dfec2497a6p+2), C_(-0x1.1692ca6458ea9e38b45000f9e974p+6), C_(0x1.1fa09c1316dfb4b439ad2e78bb59p+8), C_(-0x1.615e67f0c1ccc897da6f2d005018p+9), C_(0x1.265c8c1b4b1aa4b3e36b99e4a1a9p+10), C_(-0x1.7569ed1c8210ca209e47f9d0511cp+10), C_(0x1.9e96bde5063d41cf09da3c270b93p+10), C_(-0x1.bbbe167a38d63287ecfeda29fbbep+10), C_(0x1.be080201e737d36f7e79bffa876fp+10), C_(-0x1.8f099bdabb21898e359857d34007p+10), C_(0x1.43b83815e15a62b284f0ee906572p+10), C_(-0x1.ee6ad68b3bda4ee4ba8bf16f4fabp+9), C_(0x1.58d561cb84d267ecaf633fb5a5d5p+9), C_(-0x1.a3b282a8407a310226d833dadcd5p+8), C_(0x1.c79d620ffafc0589079eea90279ap+7), C_(-0x1.bc78cb9447aa124d62b31a0a7f54p+6), C_(0x1.418e35902e32cdd0c2f21fb873ep+5), C_(-0x1.3abf360acc2f742d879127375bb2p+2), C_(-0x1.ad7bb3867b3c2b046f80e1cb0482p+1), C_(0x1.a655024ebf2fd4378622021ee814p+0), C_(-0x1.affdcd4718ba7f1a965455b89c8ep-3), C_(-0x1.8341cd6c6b0a9d48905a1ecfc91fp-7), C_(0x1.b55710d3ebf552b754ea432b16e1p-10), C_(0x1.e321738ab144873b6e4379081333p-19), C_(-0x1.c53c1373c88584f948dc39838bd8p-24), C_(0x1.e0c270acb15c5fb50466c4df9e1p-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8d1f8a32797636f661365be0e3e6p+2), C_(-0x1.d4881995a0c1ea2393ff422e453fp+5), C_(0x1.e86d414a78e33b3180b306c7fb52p+7), C_(-0x1.280027c9b087591ad85db337ae83p+9), C_(0x1.d3eb5f0b0594c2750ef02a700404p+9), C_(-0x1.0b82a55c2799ede8dec1e33e1dcdp+10), C_(0x1.07ce9f70ddb2869a658274b505f1p+10), C_(-0x1.0d7822536789d9033e70cbead7bap+10), C_(0x1.0df61d2a506b1f8fcfe72d1ca4cdp+10), C_(-0x1.c6893ac6cda6b55a4941f5e57261p+9), C_(0x1.45ac9e808978822ff4ad1899b3b8p+9), C_(-0x1.c9d686e237043dec7c04f88fd885p+8), C_(0x1.35c4c3819b30f9b6fdd5c67ec132p+8), C_(-0x1.4a58be360f4f421d89e83ecf3267p+7), C_(0x1.017559c35f7610aa1b72e5e5a83p+6), C_(-0x1.5d1ba7f13474232b92fdf4e5cb84p+4), C_(0x1.dadd49a935c8394385d3a3bdf6d5p+1), C_(0x1.87b01fd4326a3668ccbb1eed227dp+2), C_(-0x1.9ab15d247f90f9fe7c9b6b3dd567p+2), C_(0x1.46cd6a0d33a48aafbbc221eb1f48p+1), C_(-0x1.8955d7defe0d5217296739d07f07p-2), C_(-0x1.85244f4e65bbc4ccef7883bc8ba1p-7), C_(0x1.6f86d3c43106164aba39dbfe0b2fp-8), C_(0x1.1b4e3c12a74dff21568f59de83f3p-16), C_(-0x1.7914d82d3193f580c3335f167104p-21), C_(0x1.903b4b44dd8c7c0a4e702124dc3fp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.041a0a897aa28eb3a0ccade17e3cp+1), C_(-0x1.3658b5d77609e7977d3641db3a11p+4), C_(0x1.5194af04e2f848c21930873e900ap+6), C_(-0x1.c3df81f0aaf28bccb5fed61687cfp+7), C_(0x1.ad183e8db3dabe867a1b1e1d7e93p+8), C_(-0x1.3d9c782d7007715e1144e807f092p+9), C_(0x1.852da35362a6d4101e229e2b5077p+9), C_(-0x1.9cca18f6947dd0d5bed4aff692d8p+9), C_(0x1.9a6efa498935e2e3d82e1fd52122p+9), C_(-0x1.a300c2ebdd39d26204b2e2ccd8bdp+9), C_(0x1.a735477cbff1b966c8a20eaae97p+9), C_(-0x1.7a384b1c312fbe2a2f45b3550037p+9), C_(0x1.2afd886ee72d716fc638e75f48b8p+9), C_(-0x1.d0f63946d275b18c0f5c2756f025p+8), C_(0x1.6384c4a13f54dc153d90136891aap+8), C_(-0x1.d6c269ce8bf34e1953164b65a3d5p+7), C_(0x1.08982647617ff8ae60bccefbfe0fp+7), C_(-0x1.1f7e83a0711235a83bc8e025bd62p+6), C_(0x1.2a5701b5bea0dde347ec02073e97p+5), C_(-0x1.c18aa4ec1159b6d22d740e4f35cdp+3), C_(0x1.4dc13861658a8dd406eb1a845d5ap+1), C_(0x1.bd5ac19033244ca1c006b305a421p-5), C_(-0x1.1aa94170fffad7174e8899965ff8p-4), C_(-0x1.97678bd8dc9fa54b7e4c01f3ba2ap-14), C_(0x1.25b3fc23ddcf5fe31ea2281e4301p-16), C_(-0x1.381fef501218e9cc3e0863bb3cadp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.456a1d2a45d0d4e9e18e4013bda3p+0), C_(-0x1.86731e38f2c9e9bd245a6d7f6e86p+3), C_(0x1.99ddae9b5957da8932fc9013b15ep+5), C_(-0x1.ebccc1d5d759a0cf4adc92beb271p+6), C_(0x1.74f85dd906948af50c229b89c98dp+7), C_(-0x1.8426225b26443b4ef3c972f9489bp+7), C_(0x1.4fbcc1bdf3f1963c49a88c06aa08p+7), C_(-0x1.4776c0e99319f61e68a41fbe42b3p+7), C_(0x1.573bef3fda7eadeaaa4191468e3p+7), C_(-0x1.2b0c271bd883e242fdd8d9725e0bp+7), C_(0x1.bb5bca80b624fa5bb278816db9f3p+6), C_(-0x1.5808025c93fa4e6af5a7ad436556p+6), C_(0x1.0c1df40cf5e4c4ea4441c80693a5p+6), C_(-0x1.5dea01151a3e197eb05317c268edp+5), C_(0x1.997fc95198573b5277250e908707p+4), C_(-0x1.f5c4140f2a03e036d15c57dbb36p+3), C_(0x1.1578f4041624b0e3ebbbb44abecfp+3), C_(-0x1.e11a4c47848258b137f885157e3p+1), C_(0x1.8c2f5a8cae553e89ef1e861ef5b3p+0), C_(-0x1.42cdddde9b71e8354b8c2fb7c09ep-1), C_(0x1.1b37523680cd9a16c0e5dc3ebd03p-3), C_(0x1.61bca3fd3effb1c3f5807afcb9adp-7), C_(-0x1.eeca78cc1dd9a8d407a9b1f6577bp-8), C_(0x1.427b3775515b64598a140f609c8fp-14), C_(0x1.1c6c30fb5472c91c3ee2a25808b3p-18), C_(-0x1.2f056506ce5e619914ce605b0524p-29), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.45a484f799a722e4cd950a09d5fbp-2), C_(-0x1.87cf9eab4f40073db99e6a0fb481p+1), C_(0x1.99aecd437634b1af52fbd40a01bcp+3), C_(-0x1.e335dd2c6e9de306d05cc358c6bp+4), C_(0x1.5e3841e2195098fae8b77b691b21p+5), C_(-0x1.48839e048b83d3127ebe74020885p+5), C_(0x1.e11a7f30735e301f0eb2ede8063fp+4), C_(-0x1.bff27724d4103b12e92a64b54c9dp+4), C_(0x1.f68b6fe2ccc3168c1a15db6eeebdp+4), C_(-0x1.a9c89c30bca221a764ae454bfb09p+4), C_(0x1.147ddad811d2b11feabea5bba8adp+4), C_(-0x1.a10ee0eb1ccb64a80033704ddb98p+3), C_(0x1.5d8b9ffe3cdb891325e9bfc9fb55p+3), C_(-0x1.b0eebf69279efaf954dd166c21dep+2), C_(0x1.b180929e1a69b7ef5328a0cfd4a4p+1), C_(-0x1.11a2d370771ca7d9ba7c7444df33p+1), C_(0x1.45b0d998cab377e10ef3a92e12dfp+0), C_(-0x1.d74083eaced416102c8dd2af61fp-2), C_(0x1.27c1113b5bdb7975242772f43479p-3), C_(-0x1.2ee6a8512694e4da2e5b07f1c606p-4), C_(0x1.0ad11030da22955532f0e66e0c83p-6), C_(0x1.b719ad4ae715fb13a424d63fb241p-8), C_(-0x1.7b5726cd7507b577ab874fe8a876p-9), C_(0x1.efe0e7fbce7f41797c67293a0937p-14), C_(0x1.116839f7247ae044e8dfdefe7163p-18), C_(-0x1.24c158fd367df5563093507c0edcp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.439a95b32a47eb5722e3cd7fe3cap-5), C_(-0x1.85e5f8ce20b701780e2029b7ff55p-2), C_(0x1.959ab595a2ea47cca93fdec47d03p+0), C_(-0x1.d591277dff53d8dcf59277336155p+1), C_(0x1.43a6564933b3f0805a5a899c5bb9p+2), C_(-0x1.0a2c05cc597aaccc032de2cc831fp+2), C_(0x1.273950f6ffd17ee92b32456caf9bp+1), C_(-0x1.050c8b9cb84b7c5048bc5cd2f92ep+1), C_(0x1.600ea820111d062fdf2a6acf661cp+1), C_(-0x1.21f61a844a104f06b392bde6725p+1), C_(0x1.19f0e6ef31a0d26707b436c0ada9p+0), C_(-0x1.8e2103144a726110a565e981ea79p-1), C_(0x1.a07f2894f970eb1bd26c4012674ap-1), C_(-0x1.ccce8527cee5c45450edf8973a9cp-2), C_(0x1.e56137866a8254327c313c62b4d6p-4), C_(-0x1.5df48c0c87cd72cb9ba6c6b9ceadp-4), C_(0x1.19d3f039c46cde096e59d4adaef2p-4), C_(-0x1.9e6cd0f61f4caa9b0d4bb0b897fp-9), C_(-0x1.b966bdf45728a5a5bb304f91c5cp-7), C_(0x1.8240771a20727b5953c676de8a9p-9), C_(-0x1.1b05a2f57f924748a24f50e9e6eep-9), C_(0x1.7f8554959f4a532982e2ba397a2fp-9), C_(-0x1.23710df832eb1845bb5316dc1abfp-10), C_(0x1.cc575afdf3f3ce7d0de6ac81f14p-14), C_(0x1.1f238196ae22e33d86876e9e195ep-18), C_(-0x1.3697e9bf43069ef0c328d37a1aebp-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d99d611c0465d7fca87092137394p-12), C_(0x1.0d2f985427a1dc1f62afa99d998fp-4), C_(0x1.4a539266aac6de6ff0ee136fe6aap-1), C_(0x1.1fc50d04f7f07a49e55f06b78355p-1), C_(-0x1.d497750272bfa28f3f1990b740bdp-2), C_(0x1.3575a87d9c1633de9f0ee95125a2p-2), C_(-0x1.7e644ab11888684db8a7b8d90489p-3), C_(0x1.a1785765bb948d52e0838b0df196p-4), C_(-0x1.7135a6ada8b52155f89869cf22c7p-5), C_(0x1.d8cfdcbb1618899a1617de65e071p-7), C_(-0x1.57e157b5bcea7fac037e4b9b62aap-9), C_(-0x1.5f633204e959fc32c151ba987165p-15), C_(0x1.10a4589d9f87d6dc51e36837ed0bp-13), C_(-0x1.592264d16e621b5275bdd9d12d3ep-16), C_(0x1.89979784d7185338d2badb26cabcp-18), C_(-0x1.4f841169a1bad189406e2832bc2dp-18), C_(0x1.74953d3967ccd8cc322dbf252946p-20), C_(-0x1.f7cb1acefcf435a3d287cb8094c6p-26), C_(-0x1.c92be21aef0c9ac0fb550ddd5f87p-26), C_(-0x1.3b9a57c4ce7e7a8e7b0e1df188abp-35), C_(-0x1.6a58cec0fa224ca49741d5041713p-35), C_(0x1.4bf1eb8cd4c9c2273508a8b73f46p-37), C_(0x1.697067f1715a141417bb7553b3a7p-44), C_(-0x1.513d790bd242fdd412e02eaf3fd9p-49), C_(-0x1.b3943c02986a6636aaf05d95d84p-57), C_(0x1.54d330be5783db7123cd1333ac9cp-67), C_(-0x1.3f6e1e631364c64c65f6b5a7fe23p-80), C_(-0x1.d0d882f8587b498d8efb759e05fp-104), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.af673717274af370272903c1fa7cp-9), C_(0x1.c7ad45d086ea4c5ed9ed7e340defp-3), C_(0x1.9756cb092ee06f6ac1eb577b96f6p-1), C_(-0x1.51916657c183447d0774789d6344p+0), C_(0x1.6cc6e8f0624052b2c0fdcc8950d3p-2), C_(-0x1.8cf37d6182ca0b170d0a042e4192p-4), C_(0x1.9a3fa2f41d4953051b0c6d4a1b03p-4), C_(-0x1.0a50be22f2b86dd755f1bb101decp-3), C_(0x1.df3f4f6c19d45193b61450be39f8p-4), C_(-0x1.2d4b7e715db6bf84cb93e1a16129p-4), C_(0x1.0681e4c20b9fce41d5b4e56756a7p-5), C_(-0x1.1b50d689cbed8df146901e68b6b4p-7), C_(0x1.49acd134a254ba0136bf2c9ddd8p-11), C_(0x1.16651955943e391787562b852142p-11), C_(-0x1.c26d1f2c70c86f0644644cef75b6p-13), C_(0x1.3002118e762a111c6bcee4aaae9bp-16), C_(0x1.49fbecfd7d9c6cba55cd30ac067dp-17), C_(-0x1.8781a4a6a5f7c8daadd9ede249c3p-19), C_(0x1.5ed0ad164acd249f0f9d827483fep-24), C_(0x1.da4a7558674addd03b35614f7a6dp-25), C_(-0x1.7e23c7237f3f9358779e22d38d23p-29), C_(-0x1.bd8f2cef8c9f03d137232e9e498bp-35), C_(0x1.1c61501fa10480730673344e3608p-37), C_(-0x1.c1b8b33989e0245e7c861b898f54p-44), C_(-0x1.95156f39cb33a3cd95db28e3bb11p-52), C_(0x1.d1f8ddb7d01989509bfbf0327d67p-60), C_(-0x1.34635de67ce8bb9a35ccd2f4bcc3p-74), C_(-0x1.c0c6d283f741e5d8d9e1ced44ca2p-97), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.52aa167437ed3a97a2d16e2e7e71p-6), C_(0x1.2f386450cd3603452775e405daacp-1), C_(-0x1.92da3e0f4795f52ddad307073cb1p-2), C_(-0x1.010e6c23362c2f5a0189ea0fe7f3p+1), C_(0x1.ba5e5707337cefc73943a8303bc5p+1), C_(-0x1.6efa1a351e68942304e8e68b7bacp+1), C_(0x1.e2efff792ca6cd2456dfdb721f76p+0), C_(-0x1.e9e84815ce29a5578b4bc0477acbp-1), C_(0x1.3e7bcfc83dd34f0d929299013451p-2), C_(-0x1.3f21e5e83db9b76a1e6a21ec3442p-6), C_(-0x1.00e091b8310d7c425038e08dacbfp-5), C_(0x1.93252ea5d40edb85ff0ddad301dp-8), C_(0x1.0cb53bda124f4c4d4c0ae3af4779p-7), C_(-0x1.6ecc6596fdeb97786cd08cbbbaedp-8), C_(0x1.1da3c88de4593a0d10cc249b83cep-10), C_(0x1.0f705c9109b88bc792c8e251c3f5p-12), C_(-0x1.687f176415b5a1410c9f394cb959p-13), C_(0x1.03bf749271ea0dc9bfa9a81f4245p-15), C_(-0x1.0a570c997b8f6bb3aa2b6fc454e1p-20), C_(-0x1.b60c856b75c6f8f8db3b0f76f67dp-22), C_(0x1.2f36c8024d47853b1fc5abd2c569p-24), C_(-0x1.ab6b4d2a0c9eb0fb78406697468ap-30), C_(-0x1.b77dbd4d624bb182ce2a8088a4c2p-33), C_(0x1.02e06a0b5252899742121667393ep-39), C_(0x1.f900db818405bc4cfc19c190531fp-46), C_(-0x1.5cc6aba4a366fbfbcb9e7e9b2b91p-54), C_(0x1.79a9be1badaf05e53c8d4ae211e7p-67), C_(0x1.12cb1c6610cf5a5ca8d9bf45819bp-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bde47de89537efcc2943722b907bp-4), C_(0x1.ff6e39e05bc1960ac6a7468afb9ep-1), C_(-0x1.0edf7812c7e6f7d06a00b362ef27p+2), C_(0x1.788eafbfef56fcdc50a685d1f90ep+2), C_(-0x1.0b9e58d049e2b1cb9469b014878dp+2), C_(0x1.57d72a54d9b7d9046e3ca22b5dccp+1), C_(-0x1.5aec59993d64c03ae451f5fb822ap+1), C_(0x1.66be004fbc25830ff3a497ea74efp+1), C_(-0x1.257b730e2148d4f4b3feb863502dp+1), C_(0x1.61e6a248fa765db41939b126fafep+0), C_(-0x1.1d661708485736ce63b6c04b417fp-1), C_(0x1.7634ae9385e7d28433590ede5d72p-4), C_(0x1.aae5eb36cf2339bb1da3727f92c7p-5), C_(-0x1.66a2dd81189a5724bb1062f0dfebp-5), C_(0x1.9ee5c38dff3c5ada29575f743d87p-7), C_(0x1.cee452b55c630166e1f1c650af12p-12), C_(-0x1.7d0e63753adf810a13b7946ecd6fp-10), C_(0x1.95a9bb14ccec080a6175688009ap-12), C_(-0x1.ac68b8496deea7093d3eaa37178ap-17), C_(-0x1.4a3e531dccd5a7c88df667aa9928p-17), C_(0x1.45a5b2adacfee470f99a3f9acab4p-20), C_(-0x1.a0585e72874e51a270db9477829dp-28), C_(-0x1.4a4aaf36fdaec2c3a3e857f50877p-28), C_(0x1.818dc3c36642c77c4040a75f3899p-34), C_(0x1.bc8ec635290e455c58f05f4aae9ap-41), C_(-0x1.1c50f4adb4d48c39b492719c193cp-48), C_(0x1.541ee5efeba27ec1d6332fa4f538p-61), C_(0x1.eef3c669427ba33d298eab6d070cp-82), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.da9efb84cd101b891a55bf085a33p-2), C_(-0x1.0a963523c780f95520ba62e1635dp-2), C_(-0x1.6ead78b2a7f870bae850968c013ap+2), C_(0x1.1fb0b7ee7fe9b42077abdaf556e2p+4), C_(-0x1.a26b20f9bdeeff0cd0b5e878c8cap+4), C_(0x1.5a362701692b5d54a80faabe0329p+4), C_(-0x1.c3b93743ed5e1f4aae7ff96667ep+2), C_(-0x1.0393f54066e2a86d4f5766fcec98p+3), C_(0x1.ce0e335b9b5cfd8737f6de07dc86p+3), C_(-0x1.3371f4378fc25cdcbf584ed9698fp+3), C_(0x1.04744c732a8970957ba707eb759dp-2), C_(0x1.5d5bbaac2d3dd399541ae8c8527cp+2), C_(-0x1.56903abc9d372d08f72cf8f9b7f6p+2), C_(0x1.4f367450bb0294accf5c9a7e742cp+1), C_(-0x1.16f1bf1e47dd7b33b29f107a7717p-1), C_(-0x1.0ca6089fc41ee660907b2bb584cap-3), C_(0x1.fd1e6437298de912355a40f30818p-4), C_(-0x1.127569c6d3d201e096a74c3e92a3p-5), C_(0x1.031ce43d6f2a9b28afac205ca3a5p-9), C_(0x1.dbc5a12350173dc4ceb0edd40202p-11), C_(-0x1.6e57586c99db2a8af6576e5d9fc9p-13), C_(0x1.338c12c9a95b47e57d454a7c66e9p-19), C_(0x1.ec833bdc8d6ab1cf492647696452p-21), C_(-0x1.31ee1e222a82fe6e397b0f1ab0a7p-26), C_(-0x1.068cce25031d061c7d5229b85c51p-32), C_(0x1.ab486d191520d8a9aefca6d39becp-40), C_(-0x1.971ac61147c4bd5f21d58d94dd2bp-52), C_(-0x1.28365b5992261cb91d89a4a61c9dp-71), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a28bf1f4baf0256370de9e50cdfp+0), C_(-0x1.0b8ecb513e670e46e8b61ff5e5a2p+3), C_(0x1.301d17ac5e1c6daeb2bb903493bbp+4), C_(-0x1.80a5fd5ebbea4cbe232c3d8a57f1p+4), C_(0x1.4a39e3e1048d62539834148e9e34p+4), C_(-0x1.1148278e9d9a1304c4d27a6289e7p+4), C_(0x1.18e244d79a0328c7ff6eaa1380dep+4), C_(-0x1.3908669ba07796469d9944fd1af2p+4), C_(0x1.80446c71adb1488769cf4e603a7ap+4), C_(-0x1.0a40794798e411ebd23986dcd959p+5), C_(0x1.52509dd04c4f6aeb9cbf4fd2a65ep+5), C_(-0x1.4b468531c5b19f58ba9821140c9p+5), C_(0x1.c80f1430e334a07768f1a5bc676fp+4), C_(-0x1.82ded3c89e7e9fa329e76277e5cep+3), C_(0x1.7610a167089f1959ecdad2bfe856p+0), C_(0x1.b0a89a8818c0677d48d7304191d3p+0), C_(-0x1.2b516da5d080fbac57ead9c2cab4p+0), C_(0x1.488189c0e63233e310386fe21bdep-2), C_(-0x1.16dd91fce8d2f3a24746d48a1c72p-6), C_(-0x1.957d5757f4d581e1eb81397c4cedp-7), C_(0x1.613bcf2c2fc6a53ed2c91b207503p-9), C_(-0x1.0adbc024da55152d1e362e31540ap-14), C_(-0x1.44905597a89087a3899ef1de6ff1p-16), C_(0x1.238bd55115863b967f9591633549p-21), C_(0x1.0b863bc593a1d515b8c451bf0e45p-27), C_(-0x1.2dac52b5d35bb8e11505ea96f44p-34), C_(0x1.a8ab5a61388b1db01ad925c31a8cp-46), C_(0x1.34fcf88bcfb3fdd3eace81ef29a8p-64), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e156f58145aba7d0b30fa35cff6p+1), C_(-0x1.d9350b2238c2b904f5fdfc3f59d8p+4), C_(0x1.b03e3957ecd6a002d130922f2289p+6), C_(-0x1.f51dfa789d878832ad001b3c3bbap+7), C_(0x1.b1d9ee3321d942364cb8258ac548p+8), C_(-0x1.3c90b7e3ca1db82e1a61d1d6988cp+9), C_(0x1.a1025f9df5665ef6d6390bf76e1p+9), C_(-0x1.ee82dbab6ab103949b52c0e24238p+9), C_(0x1.fcf169933904c38827bff6f06e1ap+9), C_(-0x1.beee0dc0c8ddb1ba16139309e6dap+9), C_(0x1.545f49e00f495f369a9c2bc574c5p+9), C_(-0x1.c39ca355bd5d296f37962bd729eep+8), C_(0x1.d17e6e268802ca2d8ab4ba84d645p+7), C_(-0x1.8d05e2b81cf726b84ae7be04d2f8p+5), C_(-0x1.a57ddae4deced8b3bcbf57c78c0cp+5), C_(0x1.065bfb9cfed103880a47e8cebd5dp+6), C_(-0x1.1a783beefce87b0115cd7f827bd2p+5), C_(0x1.2e9f2c1581a696ea729509934246p+3), C_(-0x1.3cad9a2427051e071bf1f9b27c09p-2), C_(-0x1.1b4b3a7aa70e82673e69d678de04p-1), C_(0x1.15a31469a9ce01c4f9e606bc0537p-3), C_(-0x1.5c66a63c9347469ce6f66ff5c6a6p-8), C_(-0x1.5db560cc8a8d9420c2df7533732ep-10), C_(0x1.c57be52a95f9a3c03fb08957c434p-15), C_(0x1.c9738067c5909d91761fe08abd47p-21), C_(-0x1.63f652c47225898a139ddd320614p-27), C_(0x1.769767db4423b6439ddbe400214ap-38), C_(0x1.108b386e39e95695575892a5277bp-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d870debcc05c458cb431fd983345p+2), C_(-0x1.0c2b8b0b28193dcd228c0a0c405bp+6), C_(0x1.10bd374d63550b983999c56c677ap+8), C_(-0x1.4441daef321d4016bb9b2c10ec43p+9), C_(0x1.eaed48222cc9b9253ebb102b9831p+9), C_(-0x1.dea055aad4ecaefb97c3b4138e1fp+9), C_(0x1.0ea6de87556ea6a2de81d408b23ep+9), C_(0x1.3bb921604519d1ae88e6a7fa3786p+5), C_(-0x1.7c03d4dcf551472cf7483533c9dbp+9), C_(0x1.b77df6c77230b9a06a324d910941p+10), C_(-0x1.59dd45c186fb11c5ad121467058cp+11), C_(0x1.92ad5ee85458cf75ddc7493a06c7p+11), C_(-0x1.7716e9b298971ca51bace1729b0ap+11), C_(0x1.34cd942cd473a5a7100d811101f7p+11), C_(-0x1.d2108687fa36ec88dd6bfb56d5c3p+10), C_(0x1.27e2041912517aaa65b2132e4553p+10), C_(-0x1.0ee0131c1b04ee634d1b07d2c971p+9), C_(0x1.13ffc016f56ca3a3bb78dd1c64f4p+7), C_(0x1.9021a9dd4e12af18897a92604f62p+1), C_(-0x1.cb9505a70965b7f9ec7314ae6da2p+3), C_(0x1.f11cd618c3358a67a8f728986e77p+1), C_(-0x1.a3fefe1a942d41c95d66abeb0178p-3), C_(-0x1.a953da883746e1eb5fc521fbad44p-5), C_(0x1.9718bee3af728b9e4c2d8088bafdp-9), C_(0x1.ad4249f39958d903ac018ed0138fp-15), C_(-0x1.eb70cd1aa40511f5c12a3ada0131p-21), C_(0x1.72006a07a097f617e889edbdb056p-31), C_(0x1.0d30627e6a2ad3489cda0318f0edp-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.155158ac6ea984ad1f3ad98465a9p+3), C_(-0x1.4fec3a6a32c1ef2818fdbca7bd5fp+6), C_(0x1.70dec41eaf97d263c2e4504b0b21p+8), C_(-0x1.e94cfecb1efa1478b22094cf32b8p+9), C_(0x1.bf0b100d34d0405ff7a1094810ecp+10), C_(-0x1.39291803fcf47b5c26824c7c465ep+11), C_(0x1.79ccf50afb46dbd4b77400a63149p+11), C_(-0x1.ab6c90991611b280fa6243394583p+11), C_(0x1.c47ed9a17b9cc8042e779917f5f2p+11), C_(-0x1.af1005783c9c08a75d46ca645f35p+11), C_(0x1.72a859cabb471f7e1c8ba7bd2a6cp+11), C_(-0x1.2846e6b9b14f481005e402049827p+11), C_(0x1.b3d87dff6a954876ee30a3fd1e1p+10), C_(-0x1.1ae10527ae49437f7880589e6393p+10), C_(0x1.41e16e9c43532c08707a85b672ep+9), C_(-0x1.460030c5bf206e4d0618004a8fep+8), C_(0x1.0818e6dd9acdc76d8ca94db3b3b3p+7), C_(-0x1.8ef0b66c7662c653e53071c7fb7ep+4), C_(-0x1.6eb8ec2d2fcf0443ad7c1412d0d4p+3), C_(0x1.3aba0303f01c424453fb561d43b2p+3), C_(-0x1.588d6d239648dcf73cdacc19a23ap+1), C_(0x1.5ca063a2897a34772f3d9594be58p-3), C_(0x1.72c884e06d399a8e64ff05cdd7a2p-5), C_(-0x1.2b7b99da7239a8d08435e37194cp-8), C_(-0x1.359ad5ec914c5a48afa1ae580694p-14), C_(0x1.0cff089d4d592f01775a150c05eep-19), C_(-0x1.207535755ab2ee6fe496486e6edap-29), C_(-0x1.a3ad9d559345b904814003502ba2p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.174fb1d6730638307d1e4b445fc7p+3), C_(-0x1.5cf63b4072a084fdeb886ad661e9p+6), C_(0x1.859702b93091fc7e65868db7a8fbp+8), C_(-0x1.008e38c64d4049e94bd38a5f00e3p+10), C_(0x1.c03c1b8df613f180675faa2c200ap+10), C_(-0x1.1e0d30516cd0d5b6c1126d4bf14cp+11), C_(0x1.33504e2e62ab9029d44ee63bfb62p+11), C_(-0x1.4498a39b45dd2d15e6ecc8905aabp+11), C_(0x1.500c422b7e4d651447cfcdfc454bp+11), C_(-0x1.2d6f916f2f063d6cac6b467c2932p+11), C_(0x1.c5bd8b8beccdb3ef655c28cdfe75p+10), C_(-0x1.3b7208dc1850750db50ab0ef592ep+10), C_(0x1.a4b1819107c720e54775d3b0e2c4p+9), C_(-0x1.c03583e49298125db8e2fdf27d4ep+8), C_(0x1.1254d5dd1a3c865791d5348ec394p+7), C_(0x1.be19509979c252700bdddf4796f4p+2), C_(-0x1.6abf524121ea45d75b1ac598d945p+5), C_(0x1.bdfa9494723d3641f8f4e66eff1ap+5), C_(-0x1.7a9c102bdb495114d11be11a8205p+5), C_(0x1.86920d3d07ed23a9933ffc257d69p+4), C_(-0x1.a9adfb25c4f27469db3fea5dd201p+2), C_(0x1.1337641b89dbbf1427d95e0cc537p-1), C_(0x1.191c64622c1b13245bafd3429ab6p-3), C_(-0x1.88d18423866c243d7190f3f8f03dp-6), C_(-0x1.aee4f466bb96965b6a34b6c35598p-12), C_(0x1.15e5e9747fe1bbdbc08f26b48b4cp-16), C_(-0x1.bc4491eee0fdcc0c5c6a94682339p-26), C_(-0x1.431c03e754cd8a35cd8981f0bf35p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.57dd202e5e84ab856980df8a0abap+2), C_(-0x1.b426b94987908d499f3bffafa19ep+5), C_(0x1.ef50af36bc949ed3fa7cc19e8e96p+7), C_(-0x1.4da8e644667e6ac3b7b19c4c383dp+9), C_(0x1.2d889ab089910f7ad4219226878ep+10), C_(-0x1.9456ec86efc743d502abdf76eae3p+10), C_(0x1.ca1f75d29c1784a6a7a3af88a28cp+10), C_(-0x1.f2eaf24b48be90f886d98564f553p+10), C_(0x1.0a60e2fdcea779a991419059c46dp+11), C_(-0x1.07fe75c2d85392f12125b660934dp+11), C_(0x1.e2b37ed5f446198c3a6ab7d8b74fp+10), C_(-0x1.a28fcff6e684b5cca8e0268f1e92p+10), C_(0x1.5596d2be7c1f83852a4b17681f79p+10), C_(-0x1.02761175eccb4a7f32feddc56feep+10), C_(0x1.70f45a3e9b6c87dda520903f4aafp+9), C_(-0x1.edf5a5b354e128a66fada7d4bcf3p+8), C_(0x1.27b1e13298bb3ef65c7ced26ff2fp+8), C_(-0x1.3be69243ef2c31f0230131660198p+7), C_(0x1.3b71f0120f2a47ab2f14bf7b7d89p+6), C_(-0x1.11985d9404f45378f95059bc551ep+5), C_(0x1.3b5a9762f053ae040918d7979484p+3), C_(-0x1.c32c18767db723614ce78e339586p-1), C_(-0x1.5d8e89b8ba2f46a3386878a383e3p-2), C_(0x1.3b1b46a97c2fa9eb1545e9c9486p-4), C_(0x1.23706d03f6f7466fb42dcd72c19fp-10), C_(-0x1.9c26fc84f3ff5e0f45e88806fbbbp-14), C_(0x1.962939a138e2b376295550104948p-23), C_(0x1.27428a5934f9dbd8cb77b8eb93d8p-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.82ba18a2815549dbb583ba20e3a4p+1), C_(-0x1.ee321ac782e8103dfda5e2a50005p+4), C_(0x1.174e5f65a44a587e2370d6742aeep+7), C_(-0x1.6e81d57c4c979417ab1a67acd69dp+8), C_(0x1.368de3361fae4ae909df52a5836ap+9), C_(-0x1.7106731d7c870bc083e5fa51f617p+9), C_(0x1.661d220cefa0ffe013a28a70693fp+9), C_(-0x1.6833b778e773ab42be55fb8d5e31p+9), C_(0x1.833c1b7a24cc4442e638654d7d43p+9), C_(-0x1.704d0cf5b403f737ee51433c941bp+9), C_(0x1.2a287b4a8744be736369f360e45fp+9), C_(-0x1.d795731af32d4e2789960ef06165p+8), C_(0x1.7a6623bbe9af7bf6c822bfb77cd2p+8), C_(-0x1.0ddd9fa1ad021e162c6d71d17f6ap+8), C_(0x1.4f824182bb440977dbde7b407e9p+7), C_(-0x1.9b8d6efd833c3f31fdcf2bc0b9fap+6), C_(0x1.e6b9bfc912a60c385c4952c1112ep+5), C_(-0x1.d872a65489bc6c3914d51095ebc1p+4), C_(0x1.82e4e50171640b22bb8023c09d2ep+3), C_(-0x1.3c81b080d7c589f42c4b3bd2cdd6p+2), C_(0x1.87117e04fd822595de3e0b568ccp+0), C_(-0x1.f2d1dbd395098c995334374fed2ep-6), C_(-0x1.327c0d249413fa2745cbbd687d3ep-3), C_(0x1.13b8c9585145f7834dc70fb2de56p-5), C_(-0x1.094893076dab22e2cc6f5a93ce22p-13), C_(-0x1.784719262e6d99b5739a61a4981ap-14), C_(0x1.31d26875ab45ebb06f0484706cp-23), C_(0x1.bc3aef2e9698a9624f45add91d4dp-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.229017de89888d3b45e2c184d9bp+0), C_(-0x1.74b098d7b294230e1965426f3612p+3), C_(0x1.a3d6fe58853c1e5c5b0a3a09e40cp+5), C_(-0x1.0ee9fe2c639a74c7c045b3701c38p+7), C_(0x1.b7ec28edec4542d27f9646062fefp+7), C_(-0x1.dcbffedb3a507fa5c4f4218a69c2p+7), C_(0x1.8f9512e48d1c46e9aca0a2a1ffcap+7), C_(-0x1.7421b1a8804595d4b26746d9ca32p+7), C_(0x1.a17e1d21e73d1b2881053890e718p+7), C_(-0x1.8b13badbca1d886a8838c2c2e2e8p+7), C_(0x1.210062e92f4896d0f00a29c58cfbp+7), C_(-0x1.a9798d44da6c2035da535dfbec27p+6), C_(0x1.62f521d1972a85eb2c6f26f231b9p+6), C_(-0x1.f0d14679f69c06584d1c30d18738p+5), C_(0x1.0b0540b21cf0924f5546e5194d02p+5), C_(-0x1.2e7f81d7237507956599c3ca61c1p+4), C_(0x1.776b19bc1de7ac2a6f830edb0d24p+3), C_(-0x1.390aaca35a348d0447af0cac40bp+2), C_(0x1.0e68e9445701769efc7a68d035e5p+0), C_(-0x1.1d9e671612a45bff7deef6e6cc44p-2), C_(0x1.1e141f6f8381b1b9942811bfdb96p-5), C_(0x1.626281f06a565209b56968645fb1p-3), C_(-0x1.00510e27c6af9fccce7dab2661cp-3), C_(0x1.dda065aa933f3a25232d375fa99bp-6), C_(-0x1.397e42b4cc1c25443933189b9067p-10), C_(-0x1.5e2780fee3a224f5cbc2e8463206p-13), C_(0x1.93d63eaebefb797682d434c6108cp-23), C_(0x1.24c485651202d28a48b67967bbebp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2dba81606cdf44cd9f04d2f8bc14p-3), C_(-0x1.83ba9062dc10a95420ae8251630ap+0), C_(0x1.bc6ce42e9d3a21102e4fdf0d4671p+2), C_(-0x1.2c97bd817af94b6452b764a95107p+4), C_(0x1.0e06914d9315537516f107f294e6p+5), C_(-0x1.5f4706680d4ada71d3fe8928e941p+5), C_(0x1.6ea3fbf492340b1a8746b11d0c42p+5), C_(-0x1.5a777ed4931f215f8e0a373e4b9fp+5), C_(0x1.424978021982d2d37f62990dfb19p+5), C_(-0x1.3090ff3d7fed662537bbff91030bp+5), C_(0x1.23e4419ddb640edbe25a71aaad29p+5), C_(-0x1.07fd356f7673b92c13a9d66edf4fp+5), C_(0x1.a8f488a3b6e4b2eef60c68cd2c1fp+4), C_(-0x1.49932384ed8b4cc7bb541dede413p+4), C_(0x1.0a96d421140fecc2982baba8b026p+4), C_(-0x1.8f60cd9c056028206308e7df4429p+3), C_(0x1.003bcbf26a5db032107ad008618cp+3), C_(-0x1.433ef046d9ed13921cc6b579a83ap+2), C_(0x1.a65b7dff9352096da27547ffc3e7p+1), C_(-0x1.d36032adf2dbd6f014bd3f02cf6dp+0), C_(0x1.a4a1ad470bd0ddc88c1710fd49dcp-1), C_(-0x1.88e9f63513ce060ad42735911b82p-2), C_(0x1.6764f965c95116ec3ca5a4be4d2fp-3), C_(-0x1.91c36b23af1d7e93ac71caa65612p-5), C_(0x1.07d03d7a1adc182d361556de1e4bp-8), C_(0x1.362d3e37ff6cd230a2a77cad24c8p-11), C_(-0x1.92dbfdbfa8197afc834aaea734e3p-20), C_(-0x1.22ff804507dbe78851ce06e1d7fp-30), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8dd6e1684e11d5d1ba3be6ea3c1dp-6), C_(-0x1.ffb4de00653d36e2054de2d9b35cp-3), C_(0x1.1f8df89dea983b6a6839c59e1daap+0), C_(-0x1.6eae32a3a790681f248ae47d8bf4p+1), C_(0x1.200cfdab0a8887ae485a3302d7acp+2), C_(-0x1.1f287662480ab738cbe219de6228p+2), C_(0x1.90990b7ee9dd1f94866d2e2c98f7p+1), C_(-0x1.3d166b62b6085e29fb936a0976f7p+1), C_(0x1.74d60ae1a8ceaa71b4a74664e6fcp+1), C_(-0x1.68026579c2213b7f75e6c5dc86c1p+1), C_(0x1.e76ba8ae988d51e5857ecafcf58dp+0), C_(-0x1.60830949d4c82da954f5df283712p+0), C_(0x1.48f2a8ad7050c9588f35978df03dp+0), C_(-0x1.e7d09d1d5c76d8ae64a80dc22b4p-1), C_(0x1.1252ee85de9250052c51460801d2p-1), C_(-0x1.6e9d007e3ce50ac7539c0411656fp-2), C_(0x1.0a88fbec92db255ff329ff3310a4p-2), C_(-0x1.16ea71f276b00e5a14dad4f88487p-3), C_(0x1.018afa9348367b971e98c4cc0c2cp-4), C_(-0x1.2fa053de7510dd5de40051b25ee8p-5), C_(0x1.2375ee2696f86cd08bc27b41fb5bp-6), C_(-0x1.73b10c938e4b6609ab6cf8acbfb8p-8), C_(0x1.1decc8370b2354d839f55dfbd7ebp-9), C_(-0x1.b8713a4dd74a971b693427cc738fp-11), C_(0x1.732711f764c017456161af308333p-14), C_(0x1.5deb76c540b6c1414e8c8011ad5bp-16), C_(-0x1.9271259f104138f720ca0ebaa72bp-23), C_(-0x1.2099915b9335422a7d16c948a51bp-32), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.674708c20fd278e13cb308fbf6b6p-13), C_(0x1.27cdb30a789a9a4cba57381b80dfp-5), C_(0x1.f3f9a4213a58e15fea805c6fce03p-2), C_(0x1.8a1b0e63e768effc8742d136ac6ep-1), C_(-0x1.d0008134e7b24ce7a0bdb2d5e177p-2), C_(0x1.06c9817f611e98379b152a389fafp-2), C_(-0x1.4ec109006f3ab5eb9ef4b4145d24p-3), C_(0x1.b93c322324f48f0734b615fc9893p-4), C_(-0x1.09f5f4083e296fb6c1df50020f51p-4), C_(0x1.0b6a75dfa25cd5d117e10197333bp-5), C_(-0x1.a17eb803ff745c2b927f4b56bb55p-7), C_(0x1.cda18d3f662aa65f684ad290727fp-9), C_(-0x1.1815693b1e509dbfebb4547eb7c2p-11), C_(-0x1.547c4d557ee7eea60970ca463eb3p-15), C_(0x1.a1d518779619a935a6506c218d6ap-15), C_(-0x1.fb90c559a340a6d74429771a650ap-17), C_(0x1.085bbb58c3dc5e159337591d11c5p-19), C_(0x1.4a16ea18a78a9255137a36b6eeb6p-22), C_(-0x1.3b0f83cef7c9cd6e4992ef7a8e0ap-23), C_(0x1.426950d9b6bca7a253eba2c282ddp-28), C_(0x1.acf5cc83787c76964322f9b1343dp-29), C_(0x1.c7dfc1cbcd560059e1fa3bbb0da4p-37), C_(-0x1.99a4987142751268f68b0c6ed2ep-37), C_(0x1.0c54f6dbbd52aba64c70d9892a56p-42), C_(0x1.60b6215484a1c96af7151c51425dp-49), C_(-0x1.6360709f9f94bbe775bd0ffbeceep-54), C_(0x1.f308a7934d0993ea019328882821p-62), C_(-0x1.dcd83ccd7b40e72afa7a2bb7cfap-74), C_(-0x1.f4c81d09055a8112f9a8f0e29d58p-87), C_(0x1.f541a7bafa4019158f37f50aca47p-112), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5e2be3ffc02e5cb63d505e4d42d9p-10), C_(0x1.115596e3350ec9cfc7fd8b282c15p-3), C_(0x1.8e066ec21fc6a13efd57c0a1a8d5p-1), C_(-0x1.9a3ae9a2a692b7d6fe0312f42fd2p-1), C_(-0x1.b4e823397cf87b829664fcfb615p-2), C_(0x1.24d79baf908bbde12d97a94a7f11p-1), C_(-0x1.96ff08990aa1ff2b3a6156b3a6f7p-2), C_(0x1.7cff079859d44a97134acb0b3815p-3), C_(-0x1.3b2f6fbc125eff4f9e00971a8041p-5), C_(-0x1.8c439625af31faef37a9ac49e57fp-6), C_(0x1.d82f61038e0e00ad9adf7940901dp-6), C_(-0x1.d308486caa607d54998083598bc8p-7), C_(0x1.b8ca6f1e525d8fc1aecc191249d8p-9), C_(0x1.4ea26d28d30874cd6f1bece4d0cdp-13), C_(-0x1.4455094b3efac9d3c28631c94fc4p-12), C_(0x1.116fb5095b299dc0400b6814e296p-15), C_(0x1.e6f46905743cf29b32a5a94efd0bp-16), C_(-0x1.73244b56511394e5623a6c13b582p-17), C_(0x1.105e30d7ecb45c8d929e54615ad8p-20), C_(0x1.85ee598e5c772af7b4423f5e4908p-23), C_(-0x1.5ac9f1c76ae72306c6963aa9eb6ap-25), C_(0x1.d789f3d703adce6fceeb7470ebe2p-30), C_(0x1.8d5e3e20027e865e92d2141a2b73p-35), C_(-0x1.c8b3833c3b76938050c849f3c902p-37), C_(0x1.38fe40b99904e82fbd88d14cb331p-43), C_(0x1.f524d19d8420a05a730c8d14369dp-49), C_(-0x1.a73b7d5e557e750b97979bfe8e3ep-57), C_(-0x1.c5320460bba019effc9564690ea4p-68), C_(0x1.a5354de9b5e4be0a26cfffd8bdbp-81), C_(-0x1.a59b918cf087f7e28a66eadc80bbp-105), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.295efeac152d79633d42d6d916dap-7), C_(0x1.9d61cc47e5de2628b18136c91ea6p-2), C_(0x1.161d416b67637e8de5329814dbadp-2), C_(-0x1.5b7a45663376a9aa5f95ed877064p+1), C_(0x1.d1174d09edd0e5a9b8dec824cf43p+1), C_(-0x1.64fd520a66219e33ceb19171c931p+1), C_(0x1.05168da96484602e8bf4113ac4e7p+1), C_(-0x1.6575089c4586c8407b43149ab11bp+0), C_(0x1.a38bf0b53f437316576c7b5f77a6p-1), C_(-0x1.889b16ed752f17512574ee20842fp-2), C_(0x1.152c76b8c5aa61f7d1f86545cf96p-3), C_(-0x1.1b4c99876d201e8bbadda8305eebp-5), C_(0x1.907f1e8b42628bd87c6dfaa42428p-8), C_(-0x1.48b152205d27ec7322d3d940da05p-13), C_(-0x1.a3276d4b1b41ee0d43115b5aa81dp-11), C_(0x1.19008ab2bad0e78321ce13187a8p-11), C_(-0x1.4a0f2fc3a3fe6743d3250b9f0687p-13), C_(0x1.b16d8531bcd974ffcfcfb275888ap-17), C_(0x1.3c9bc919e0e49ac8c1ec9b7c72d7p-19), C_(0x1.899254d74191895a0ee7c7e368dfp-24), C_(-0x1.e003adff466a6871b6189e153009p-24), C_(-0x1.b118f867cd64dc8214de14f22a3dp-27), C_(0x1.a8e81cf9b2bf4ed6a7f80b7fee49p-30), C_(0x1.472047d4ce812177c28860710d42p-36), C_(0x1.0bc546f1206b056c51ef6c4e3c73p-41), C_(-0x1.5b78778ec812c1a8126f0f855511p-47), C_(-0x1.75c5773026aebf48665648526e47p-53), C_(-0x1.4450e0ff79233cb66d7ae0406fdfp-64), C_(0x1.74639b34e9729d879c349c60a705p-76), C_(-0x1.74be14820bd545c3f1e6ecce41eap-99), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ade0c67a6df62bfb0e80195f4993p-5), C_(0x1.c28b430a75f298c1d73bb81e4353p-1), C_(-0x1.5f4ccfba427cea15c66f4a5c12bbp+1), C_(0x1.cdb8f607de72e596ea568a034c8fp+0), C_(0x1.f77743196657a78ad5bf74425543p+0), C_(-0x1.dd879ba809267a9d7904ab437cc5p+1), C_(0x1.37053c10bce28d1022d31ac1246dp+1), C_(-0x1.1bfa76c0a943a24b6df5bb2abebdp-2), C_(-0x1.2b5034c5e7cec27aa44e7ea3a878p+0), C_(0x1.63e2260baa9fdeb5f048ba37a04bp+0), C_(-0x1.a29913a0c0f2ddeebb2bd3c275b3p-1), C_(0x1.852867c8ceb35a88f788b40857cap-3), C_(0x1.9a9664fc9e678ca180654356c297p-4), C_(-0x1.c29f78e2de8f527b7cd8a08d24efp-4), C_(0x1.54d634445fcf6eedbc5dccf04eadp-5), C_(-0x1.41b2a5a54a66286808252915b865p-9), C_(-0x1.225d9fec5c6e8c447caf2b42ced4p-8), C_(0x1.f9019974a7ddb631ebee782869d1p-10), C_(-0x1.2c283714217e754b55528b628588p-12), C_(-0x1.8e8742bbbfb2111f9226dbaea15fp-16), C_(0x1.c9f58c62dd5d38676514b49c9e2ep-17), C_(-0x1.61f6495ed1b8ece209fc78f1d085p-20), C_(-0x1.96b8b0f8a15e32028c8ee0076679p-25), C_(0x1.71f48c99d030adfe377a7056701dp-27), C_(-0x1.b5fc8d66ab6cfd5a83337a0cc9b9p-34), C_(-0x1.c5963ee2273d2d13e0940bb125cdp-38), C_(0x1.6b4e6ce52480a98b4ad64082a237p-45), C_(0x1.e67135f42b49adad00310559fa39p-58), C_(-0x1.6aff40a6dd5b409b62d44964fcf6p-67), C_(0x1.6b5790e714dd812f487575d04214p-89), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.002833198203bf56e8fbb6905c21p-2), C_(0x1.74f145f5180b48bf2521976daf68p-1), C_(-0x1.d40722c67b8b2c63d49b5a9b6cadp+2), C_(0x1.2af6f0f464bc571c8b763a8383eap+4), C_(-0x1.a43135145799a27dfd1fadf6761p+4), C_(0x1.9a15ae0412710439a9b40c2dd4dbp+4), C_(-0x1.38d1bd49e9af291f59c9f34bcde4p+4), C_(0x1.6c6cdb14d7fe107edc16c4953b35p+3), C_(-0x1.13619aaa119f97b37d6d1c2c4585p+2), C_(0x1.d56ce1ec874a0c5dd634fb59d6d1p-1), C_(-0x1.e42907ae7a26468d6ecb1d9e3f24p-1), C_(0x1.e52911f9f656640a2404f83a2b4fp+0), C_(-0x1.ee224ef8eb13d4b961d19b7d1c3bp+0), C_(0x1.1f26d6223d44cb481a2910c6eba2p+0), C_(-0x1.5888435f5783628967f9baa03f79p-2), C_(-0x1.9e45fc4e6f7c960ebee0a7c398e8p-7), C_(0x1.dcd2d2ebfb6e400bbcf752c0bf7fp-5), C_(-0x1.93116bc1ac6b7200b82ddbf8d638p-6), C_(0x1.0e01783e342a4693e98c9edbf33cp-8), C_(0x1.31f3faa90de9ede16d914789626ap-12), C_(-0x1.f6b0df77a54401ad9bab438557ddp-13), C_(0x1.f05077a02c3aba8741da9769ad4ep-16), C_(0x1.2ec5b9d224e6bceb5db9ee6cff1dp-20), C_(-0x1.47f2b0eb68eda8ce48926b156c9bp-22), C_(0x1.bcb021bf883a1f92a78fc9df6525p-29), C_(0x1.1bcefd6cfba520ba047378483637p-32), C_(-0x1.34d97adc52a38a676a55a692601cp-39), C_(-0x1.6f2c8c9ca394fbdec6dda2487026p-53), C_(0x1.34e43d9253e6e8975e6c8e7aefefp-60), C_(-0x1.352f98f0f2e48db2a203fb32a0f2p-81), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e5d8b15d3664d52108fae09a8e52p-1), C_(-0x1.e7e4ae8313c9841f6b4ba59501e9p+1), C_(0x1.643947f56174ee22b35084254df8p+1), C_(0x1.8bf77730624fb34f058dbb215e6ap+3), C_(-0x1.39575fcf961c0f3da45ce2cb7fb1p+5), C_(0x1.f6657cd6c7e299b7cc89d7d3daa3p+5), C_(-0x1.2981aaa66ca36b3a94f8297750dp+6), C_(0x1.0cf300079688d85d6be476057064p+6), C_(-0x1.71528cd9cab137a39829bbec9ca2p+4), C_(-0x1.13658826409b41720bd51a0f2d32p+6), C_(0x1.5ecf135e336b7c201cd13f9f1c7bp+7), C_(-0x1.ca8fbd8754dc1920d78e0ace3c5ep+7), C_(0x1.83a96558c6c07294f0fd718cdf26p+7), C_(-0x1.9d91182e0786a78e2338c8bf2ff2p+6), C_(0x1.818f5ca05f023837d630b257f2ffp+4), C_(0x1.4e782cc994094deb153537dfc8d9p+3), C_(-0x1.7fba734a377970e0ae8d82bc8b81p+3), C_(0x1.361d7d826bb5b3b3a1616de586bdp+2), C_(-0x1.85fee8307d590ead49f8c992534dp-1), C_(-0x1.fcc3205624ce56be678cf9a5a7bcp-4), C_(0x1.30d54b861144b0080c77fb2ef955p-4), C_(-0x1.4236c7ccc62df6904f1792b21926p-7), C_(-0x1.6b6d4bcc089eed67f90762e3bff2p-12), C_(0x1.251cb75a77a65027fa18c49d6fe7p-13), C_(-0x1.7df627db3ed37f55c551bdd12823p-19), C_(-0x1.6d7ba0319a17f9c5347fd4ebc07ap-23), C_(0x1.047350b843565161f3ac671e5f76p-29), C_(0x1.ecabd0f857c5126fafed07e8e831p-41), C_(-0x1.035ef08b1273d485ae68801933a9p-49), C_(0x1.039e900e7fa12bdd9aa0b500dd5fp-69), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5c435b4994699430de1f0bf0f96ep+1), C_(-0x1.45ad88073e6251792d84638c28d6p+4), C_(0x1.1ac643e9c99f8dff42b4b5f9e976p+6), C_(-0x1.3bcd24e1c22f08a7330d952db5cp+7), C_(0x1.1132bead650e64e0cc6250fd5a4cp+8), C_(-0x1.a3321607e359615c22640184890cp+8), C_(0x1.2bec4ce73b524de840d2af975fb7p+9), C_(-0x1.83ddd4224b9abfb64ecabd8660acp+9), C_(0x1.b1ad4241d86bedd378c0238858cbp+9), C_(-0x1.9d7a3218170b28b67328a4e4a6f8p+9), C_(0x1.5526f87e8214f36e89fc59fbe6b5p+9), C_(-0x1.e996857ebd3fd865f8b8b57715d2p+8), C_(0x1.186a9a24f3387e74b22113290d4ap+8), C_(-0x1.4f804f76b6d5b86a618f6e232bp+6), C_(-0x1.84954fc1821007c0fd22bc06ae8ep+5), C_(0x1.59efa11d2ec6f964630b6fd432d3p+6), C_(-0x1.dac7ad3b33c95d5f07d90297e68ap+5), C_(0x1.62078796373e73b5598b78c1554p+4), C_(-0x1.88bb023e9f2f98b9b7a5caf3d0d1p+1), C_(-0x1.04b9160269b89d57d0a515a32ad5p+0), C_(0x1.18c6982acbd2cd140bf32d2822bbp-1), C_(-0x1.508ddc9d3ccb43c37b8bf661b39ap-4), C_(-0x1.539386e1415cf5772194fa5cb789p-9), C_(0x1.9eab992a4b9ab37998a4782656d7p-10), C_(-0x1.980b92ff814cc556c4aeda05445fp-15), C_(-0x1.761c29381edd29e5680cf5367b41p-19), C_(0x1.64e7e2ec4af2d5325d3b1ebf7038p-25), C_(0x1.1823b743e4c412fe2e1a1caf98aep-35), C_(-0x1.623923d3ddbaeed10b04fa360d62p-44), C_(0x1.6290fa803758e40f0b825bbc6f28p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.891443770e9f5b58ca0bdbd939d6p+2), C_(-0x1.c4b28f7dbecf38e874d3b242d4fbp+5), C_(0x1.d994c46f08417c9c24a3de260d39p+7), C_(-0x1.26defe09eb9e312242e62017ceb2p+9), C_(0x1.ddf577c4250f78c0132ae5d7d1cep+9), C_(-0x1.fd2079b0f3ddb297d557ffac7fap+9), C_(0x1.36152a2e286cfeac434a875affb8p+9), C_(0x1.d8616a51db368c3df9bbb5de82cep+6), C_(-0x1.190b42892374c709dd8c148043fep+10), C_(0x1.36219b396179567cea600ef5a5e7p+11), C_(-0x1.eed74001662f7e761e907ef9b166p+11), C_(0x1.31c149450a5e9832b2fbd7c32f38p+12), C_(-0x1.31807a4d8f7d8b9ec23e94e23c9ap+12), C_(0x1.07e37f0875c28ba98c5df12ea151p+12), C_(-0x1.9ca0e06fa4e40e6ba9a2f070a627p+11), C_(0x1.192392a49659f5be4afa683922a3p+11), C_(-0x1.28f7ef65a911c2242d4a04d3586cp+10), C_(0x1.8ef1182eeb70c3b810afe07ad9aep+8), C_(-0x1.076216da5c43b27292cd22bcb978p+5), C_(-0x1.3734a9c9c5014b6b42b155a6abedp+5), C_(0x1.2e313dce4fbf11c25ec52c766e83p+4), C_(-0x1.913ecda1e3436af7caac068805f8p+1), C_(-0x1.aba4e0591b35ef78388396d8949ap-4), C_(0x1.5578ca229685f75ec4dbb7fb72b6p-4), C_(-0x1.f3ff47839e58d032a1a624c1f604p-9), C_(-0x1.bd3a12076a4f509f06e99bb28599p-13), C_(0x1.29ffe91412a29d368ce7b0895443p-18), C_(0x1.5e7711914b058b73ae8c4ed370dp-28), C_(-0x1.267e3f1ece05182094aa29382cf7p-36), C_(0x1.26c8d9be624c3d09b42c989d403cp-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1c06072fbf26f358c9f078f98565p+3), C_(-0x1.65d998749f19f3f52787d2ac7bd1p+6), C_(0x1.9d8978b96f57f154ef9ce52c7bdfp+8), C_(-0x1.24c8d76a7f36d7089e3f4940c827p+10), C_(0x1.21d479bc00697b14d91a6dd4bcabp+11), C_(-0x1.bbc006c9393532c76b5d7283eb2fp+11), C_(0x1.2211c4425df9c2e46c401315e702p+12), C_(-0x1.5c64ff1d8bf677ab09ac8c8005b4p+12), C_(0x1.845a35a3158347c96beac73413ep+12), C_(-0x1.87e6df0fbf8ef42fd538df2c44e6p+12), C_(0x1.6504110de640c4682cba264cf46ap+12), C_(-0x1.2b9aa02be2b35409ccae86a8991fp+12), C_(0x1.cebcfb329a57eadc95a6866f02e1p+11), C_(-0x1.3e375c669dabfd4de916796f2023p+11), C_(0x1.7d70c67fe8973e080c2a8eb7f182p+10), C_(-0x1.8fd6874952e8a903dace07633bccp+9), C_(0x1.57b6f4096f1cf0152662dc88de7ap+8), C_(-0x1.3e2c004c73161017d1fe47d49586p+6), C_(-0x1.f1e0f66437531ffa287a43716481p+4), C_(0x1.39f676c7227564daf7244ac826e7p+5), C_(-0x1.07f7de36ead717df75674d143f33p+4), C_(0x1.6eaf02b444bc4ce4684168c04e9ap+1), C_(0x1.f8896c7b27aea8a0c13b638bec5cp-4), C_(-0x1.b78e4a3636f77d36045fd051d0a7p-4), C_(0x1.faf293c65fc88bb39eaf07f0c833p-8), C_(0x1.a6b604defe6a94f42a0056ad171bp-12), C_(-0x1.9886be2865e4c650159b7d4d95b1p-17), C_(-0x1.7c0bde2d4dd50659d8e873b48d0ap-26), C_(0x1.90aca39ea2e8ac3870ca13b1a564p-34), C_(-0x1.91166efa6d0a92bc7a2e9704d452p-51), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.58e7df6732419db59e9ac42f9ab1p+3), C_(-0x1.c53a29616fa380817d7f5e347aefp+6), C_(0x1.0cc18d57a1a1fb48e108cac3a066p+9), C_(-0x1.7c92fc1b6ca3895680c38212861fp+10), C_(0x1.6a1945d20b68d8baff4381a817e2p+11), C_(-0x1.fab771c0e1baf24e2c8f95c4199fp+11), C_(0x1.254298acbb2d449a7b3bb526f729p+12), C_(-0x1.407f9dc95f9b1203f980178aa4a8p+12), C_(0x1.53233c63dd8a7f18f0a2b3af5ccep+12), C_(-0x1.3b528b34539979362d8c0e80e80ep+12), C_(0x1.e2ea2797d25e54507eb78c335f71p+11), C_(-0x1.3d6169dd11c9bca3212058149b0bp+11), C_(0x1.75fce5d641404560c1229131d8bdp+10), C_(-0x1.2b5b50127f9f56d44ea4f01f61c9p+9), C_(-0x1.18e0518b142ec5c99d05ce213217p+7), C_(0x1.ed1ee257a974ab35fe81e878de48p+8), C_(-0x1.f5a5a8d8a9b3c073ca67ee8615b8p+8), C_(0x1.920c943e9e1a266133bfad52e46dp+8), C_(-0x1.22c1385412c45fef72454e0ef403p+8), C_(0x1.4b1ba13f6628b1dd44be57f24352p+7), C_(-0x1.ec876f34dee07503da6a5d0e4af4p+5), C_(0x1.641261f15a2bc3d54eada0d94bc5p+3), C_(0x1.3bac7fcb6881fd2d747aef7d1cc5p-1), C_(-0x1.3ae0db5ff49e0fda9ef09cfb9b34p-1), C_(0x1.0ba445bef297ba3c0905b698e9c6p-4), C_(0x1.c3804abda5b0efa9daece8d22468p-9), C_(-0x1.3c78fba89f7e4dd2da5d2b0f1ab2p-13), C_(-0x1.6e90a45b17e11834e30d4035587ep-22), C_(0x1.34c398a5dd4857b9fcc2b9b3ec09p-29), C_(-0x1.351bbccd566d5b56e0d110fac029p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0cfd9304e9d0e9e89a508d967352p+3), C_(-0x1.68c00ea69764cc01a573447ef7eep+6), C_(0x1.b4a63a85c6a121d6db6758f94115p+8), C_(-0x1.3c4fcf304828edf08897e340df25p+10), C_(0x1.35efe9ab816f6ad2ce3b95243287p+11), C_(-0x1.c3872b5b6dcd2512d759e390543cp+11), C_(0x1.1261ac83f506bff0f38c31198cefp+12), C_(-0x1.39e1fa3f00833a2dd6c432f2edcep+12), C_(0x1.5e4c9d364466ef749b8d0d88979bp+12), C_(-0x1.6b72e41a84905cceda3e7fc6c066p+12), C_(0x1.578fd4c404248dabc968b7c529b9p+12), C_(-0x1.30faf3648505cdf5f671e0ae34fdp+12), C_(0x1.0174ad7c898217c903f8f07741efp+12), C_(-0x1.942bc49f2f52a22fa3eae80252dcp+11), C_(0x1.25cbc7992fd63cf31740b115daf5p+11), C_(-0x1.914caac5676309ecc6f6c550d8ebp+10), C_(0x1.f93f030387c4d019b6838cf24389p+9), C_(-0x1.1b4f5dfc787bbc32262ca3f167bep+9), C_(0x1.1df01b8a36a8b0e740af0c5b60a7p+8), C_(-0x1.048db6f3ab7c1cc8ce49930b812dp+7), C_(0x1.730bcb9c58bfc20d60bef0471523p+5), C_(-0x1.09b56b87c1c7fb7baeed74ce6cdbp+3), C_(-0x1.4fb833b30fa7eeef6a7358348b92p+0), C_(0x1.e38e1048601a60cbceead8c786b8p-1), C_(-0x1.ee07e572041f738c256c5953b0d7p-4), C_(-0x1.913ced3c0164b56d323de7f36c57p-8), C_(0x1.0726b83c4032bf81b9ad0141e709p-11), C_(0x1.2751c6763466bbc5b359801c4ca6p-20), C_(-0x1.00ceb77e39cabc22cbab1770a0b7p-26), C_(0x1.0123085a8910152fac9990b7a672p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6ddd33f198eb3c96ba1c54f670fdp+2), C_(-0x1.ef9ef6f596ce44132c5dde1777d4p+5), C_(0x1.2bec86422c72fb4a905555a96936p+8), C_(-0x1.ab3138ae63b3c1e29f1c692c8b8ep+9), C_(0x1.90171accf1ae92cfd9c146fd2557p+10), C_(-0x1.0b8279e6381aa2b741cb2d9796cbp+11), C_(0x1.21c7cbc3a51f50320f21aa56334ap+11), C_(-0x1.3291c6bd3630cafeef14937244cfp+11), C_(0x1.52187d4f278255d90661622e17d1p+11), C_(-0x1.5764b21031af003ebeca03a2b0b9p+11), C_(0x1.2d82b77758b7aad296e73eef7d7bp+11), C_(-0x1.efcf6fd97e7509c927b7122c5c13p+10), C_(0x1.96b834131566dc9e06167e63c7d4p+10), C_(-0x1.34d67cf0a39ad9453edbb75a25c5p+10), C_(0x1.9aafba6f0ff85ebebfb694ebd422p+9), C_(-0x1.002f1ef9723b265f846b3c2332f6p+9), C_(0x1.378956144d5be0ceae60b1a0aa28p+8), C_(-0x1.48f6827b3eeb52ea5b3fa287d164p+7), C_(0x1.17de886be7cb3ac887cff35422aap+6), C_(-0x1.abd1c377daaf4123bc47a29397f4p+4), C_(0x1.18836fa0aedf116ff47c167f808p+3), C_(-0x1.72b11631904f6bd3fd5a823e34cp-2), C_(-0x1.93c736e0c44c0da3f45cfa30760fp+0), C_(0x1.74105b4ecfea6c16423bc348f8fp-1), C_(-0x1.a9382883de207a4dbe62c7de34c2p-4), C_(-0x1.8ee02bc822713114de66688f8544p-9), C_(0x1.b89c5ecf7a7b773088c639b3a53ap-11), C_(0x1.5051009d42a4549b60dc1a4ffdc1p-19), C_(-0x1.a9ba33acc416babe2777385baddfp-25), C_(0x1.aa6a7d0ba81031b3c9971794d3cep-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7e688b7526a774b76724ba13a96cp+1), C_(-0x1.044f66dd0bb355e9e82c72d5eaffp+5), C_(0x1.39d2780b0ad2f5c130250e42d893p+7), C_(-0x1.b63bb8898df0968b0e5291c5adf1p+8), C_(0x1.86b367123a2139a59288ccfca3dfp+9), C_(-0x1.d8001c1817ddf23795b1149354dfp+9), C_(0x1.b397f071da3115c284e47fbefa66p+9), C_(-0x1.9ca191acc971e01d76f080b3e85ap+9), C_(0x1.d28d7edb2db091286a502e3d1491p+9), C_(-0x1.daeab5bf793f0a5db198f7c1b01p+9), C_(0x1.738e37d47cc21d48d3f57dfe7cfep+9), C_(-0x1.0785a3e74df59d20286619983999p+9), C_(0x1.a556a97ba734840eab5a765f294cp+8), C_(-0x1.320671c41025d2eac683ee371196p+8), C_(0x1.33661041ead74be914f62376ca64p+7), C_(-0x1.d86506577d5080199e51f7260b6fp+5), C_(0x1.9ebe0657238551a24ab6c6c0e20bp+4), C_(-0x1.ec9ee904293324442bcbed481925p-1), C_(-0x1.1034340999c868fff5238312a8aap+4), C_(0x1.04d7524f6a9fff23ceab9523e19cp+4), C_(-0x1.2fcc89fd04e88d59c75667d7c4bbp+3), C_(0x1.7c24bc012bffc7d1e21de0348c52p+2), C_(-0x1.c84c145900f77b34a4876818624fp+1), C_(0x1.57bccbd9e4fcea0faae4ccf7a2f9p+0), C_(-0x1.d81daf1af068d1091e32e8f2fcc9p-3), C_(-0x1.20f9f72def1de8f22a005f73e8a4p-13), C_(0x1.c2f2ad7e016f5272ff115101365p-9), C_(0x1.baf6705e59cac3284164d29d2adfp-17), C_(-0x1.ae94eeab2dbd4d40eac4360abe26p-22), C_(0x1.af91281d9938911a63573a1c8a3ap-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a308ef1d16805759614e47ced45fp-1), C_(-0x1.1df37cb20ef6cd526bae886688ccp+3), C_(0x1.5a47cc2daffcb2cf20f8cbe23f9dp+5), C_(-0x1.e7cc32d4c7f05cc178a92423af38p+6), C_(0x1.ba5aa6f58d154790fde87c08c1abp+7), C_(-0x1.137ebe2556bb5c31390bfbcc3555p+8), C_(0x1.07f96c27b79ba1c76a48900fad0dp+8), C_(-0x1.f176d6c3151d8ca65c2069cc8ba9p+7), C_(0x1.0c09a0e0bcb9ff8d7d5ef1548dd1p+8), C_(-0x1.12bf0f34a9a5500b54ae9f341239p+8), C_(0x1.de16d55d65d2bb62ec7f100c7235p+7), C_(-0x1.8c7b496d3d3fd8274eb146a1b265p+7), C_(0x1.56592506626bc28d37aec7a2a08bp+7), C_(-0x1.13d919c9693b2e85ee4209bf711ep+7), C_(0x1.8b69de5718a09e2e84e51d955579p+6), C_(-0x1.15b78c90e783729339c94d803f63p+6), C_(0x1.8188b8db550fea38899d2489ef66p+5), C_(-0x1.e03c011f666ac66011b7609652a9p+4), C_(0x1.12ed8b36e986458009c8fb08c63dp+4), C_(-0x1.36a5b057bc26ecf6312ef4c8aa89p+3), C_(0x1.3d2641cf67e8fbde6d24a0c08316p+2), C_(-0x1.11ef148707dfa11f55a9bad8158fp+1), C_(0x1.c294da23fe29fd37f9c13ab439f3p-1), C_(-0x1.4f57e7e05e818e7ff02709327119p-2), C_(0x1.1ebd9964081cf6e9a360b8a8d058p-4), C_(0x1.367917f76eee2f0773ffda2dee7cp-14), C_(-0x1.fdd37749c94d91b95e5811e014fcp-10), C_(-0x1.0fc0733cbc7d657bb2812f3ed59dp-22), C_(0x1.f945fb653cfda9182e6054d0438ep-22), C_(-0x1.fb1bcfae6e46d13bafafa99aa27p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.74ef139ad4e11f00f65daa8820cdp-3), C_(-0x1.fd9d32fdef73fc52b4caeb648516p+0), C_(0x1.3320f17be8b7073381e865362afep+3), C_(-0x1.a9e31dbd98dd09635b0d379485c8p+4), C_(0x1.73dbdd38a87f5064433a350c721dp+5), C_(-0x1.aa50f206f25c72a99cb7b1dfa7d2p+5), C_(0x1.5e48ac9c2f1f1eff350b14cb6a0cp+5), C_(-0x1.20d7a78e95ecf57e7add31db3fd2p+5), C_(0x1.4350b94e5aa2da50e61a74e27b2cp+5), C_(-0x1.5499ff05228ddd2807c95d8259cp+5), C_(0x1.0d8c7214ffee0a1235b3874b3a3ap+5), C_(-0x1.8fe88996cfa9a55157f19af30b98p+4), C_(0x1.63da6bffb7322ee61e908c187b83p+4), C_(-0x1.24223f5c1b9d9506d6b401adee8dp+4), C_(0x1.7851e19176715ec2bb3ef2e77d74p+3), C_(-0x1.e4fd178fcd0ef2f7354c8299da37p+2), C_(0x1.610a439acb28979c58f2b0d330cdp+2), C_(-0x1.ae4c3e147b71c294863ea12a0857p+1), C_(0x1.a6fe28ab7ffa991086c47e322a6dp+0), C_(-0x1.ccc920f98175dd5797f1c22d8029p-1), C_(0x1.f9389387bff6b354c93278385205p-2), C_(-0x1.8612de961fd0228a7f5532d1edd2p-3), C_(0x1.fd43fc0e7883ee43ba7f30ad9465p-5), C_(-0x1.aafa1e0c4a86f88db60d4f1fa17bp-6), C_(0x1.b638737fa8e8eebd498a75e7c49cp-8), C_(0x1.071682a1f5057e2143b4d72fc7c5p-11), C_(-0x1.a84c3f530239b63f7da26929d4ffp-12), C_(0x1.a20c2374a0f6700016084886c2a8p-18), C_(0x1.e7f1c0adda0f62adb67917e7d654p-23), C_(-0x1.eb089a4058efe658e6efa5db9e34p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.31c729360063e0149d619e7c5659p-6), C_(-0x1.a21aa8a66a6833da5818bdb00dc4p-3), C_(0x1.f656a46fa2a9169e56e0e1915e67p-1), C_(-0x1.589b4fca92a9f10523379245a6fbp+1), C_(0x1.25049558932c1a7bf94dfb345bd9p+2), C_(-0x1.3b0f087615a26809432e1d6e01c8p+2), C_(0x1.bed87f332745bf792baa46fb22d3p+1), C_(-0x1.37fe75fa2aa3b693bb533ebc90ap+1), C_(0x1.75c34ae38a11fc31440e21813692p+1), C_(-0x1.9f32b219f201f09e83858382dcccp+1), C_(0x1.2a50b5ebe798e437ef2503085768p+1), C_(-0x1.80aff2523d4b3342a833db6031p+0), C_(0x1.71f9af43c19f0952a4e07472578p+0), C_(-0x1.40d21595459cbd897728656ded6bp+0), C_(0x1.6edc3b8de7cbccef39ac5c5b8452p-1), C_(-0x1.abb5cf29e076b1f30f36686df3b2p-2), C_(0x1.5fdcb9c5e1f87c285b04c2fd8053p-2), C_(-0x1.af4e9b9242255620df4c3ab9bf57p-3), C_(0x1.57b33e4d63cb5298c7100384e3b2p-4), C_(-0x1.736294d370dec79efb4014a700a8p-5), C_(0x1.e1a61d7964668ec603cb9aadd499p-6), C_(-0x1.38138139d6cd8275f0059b0302fbp-7), C_(0x1.a99b874715d59140bd445bce9797p-10), C_(-0x1.191ada841d111d8ae1875d5194c5p-10), C_(0x1.44a23a1750afa85a30082caf581dp-12), C_(0x1.4db128e094987961ef4278d6a462p-13), C_(-0x1.2cad37f3dbf9e7a235442f3e067dp-14), C_(0x1.f38c667f694821291da674a42ae8p-19), C_(0x1.c870773604d02f72b6568dfdd8eep-24), C_(-0x1.cdd01a024c710ef11bdc57da89cfp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.086b758f2eb28fd921eab56a11edp-14), C_(0x1.39d1d9b6240962e535ae21b2376ap-6), C_(0x1.6586cdc7bb445ac141a0312b8103p-2), C_(0x1.b9d577601dcdb0dcb740f8b98373p-1), C_(-0x1.29ed86125a029803c293e63e1f67p-2), C_(0x1.35228579cf169af0c995d4c52ae4p-4), C_(-0x1.d940ea5a753eace5078cc210d381p-6), C_(0x1.eb66212482f668b8fcf8d3b919cbp-6), C_(-0x1.11e395c55e411390d39b33c12486p-5), C_(0x1.cac8225b45414be4173b8eab4ac8p-6), C_(-0x1.1c2e36898d63a7284aba1b17de4dp-6), C_(0x1.01459f9607ee130b7061d5eb1498p-7), C_(-0x1.3f705b6c01172b34ae01036bd601p-9), C_(0x1.aa4226008e468554c7236a5aa13dp-12), C_(0x1.a227b89277165ccd7a008b2025e9p-16), C_(-0x1.df4876fdde2706ccc1065c683114p-16), C_(0x1.a3348c487531e3e6d511223fa2f3p-19), C_(0x1.bc3886b839cf7c209eee289f6c48p-20), C_(-0x1.3c3d3ef190e94974e0b46a471d0ep-21), C_(0x1.fe10f39c7db3f74fc941d5c89993p-26), C_(0x1.28b87cd51d74b7827dcb3f76ba15p-26), C_(-0x1.5145c4e025139affe8138cf7767p-29), C_(-0x1.c7ef81e91e695e468ea8a5c582b5p-34), C_(0x1.74462d4702c982a79ea8a83c2f8bp-37), C_(-0x1.2eb21459dd6235173db20b5350d7p-41), C_(-0x1.802cada0cd8903e4e2cc5b09958dp-49), C_(0x1.f4dc3c81c07b2740f80e7509651ap-52), C_(-0x1.790641c0d0b7b530c5f3ea46fd8ap-59), C_(-0x1.7be9575142225928d5569ad8cee9p-68), C_(0x1.70d851342e8d54c091b220a3045ap-78), C_(-0x1.08ea9c21a48ad423ef299cf99255p-94), C_(-0x1.6d7121dda4d1a467dfa9e3b22e7bp-121), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1287f0812571ced1e1d4f218f2e4p-11), C_(0x1.3963c1ea0712ddb1fe38bd9c9b8p-4), C_(0x1.56352993b88d1ab506ab53972cdp-1), C_(-0x1.f6edcab194e1f1b63bcde69f40efp-3), C_(-0x1.17b7ccfaac21f6709bae8571c345p+0), C_(0x1.0e886b0af5f1b1856a755304e662p+0), C_(-0x1.8ecc3f557378e15602e7822e181ep-1), C_(0x1.fc587a34e0e0edbbd49047b2d639p-2), C_(-0x1.0d307d8a24ec475046eaa126ebfbp-2), C_(0x1.aea667b7c25e2cfd5f86bd0180b7p-4), C_(-0x1.9d42bc92105fbc1675af424ec92cp-6), C_(-0x1.84840a8e18b0614ca4eaeb216151p-11), C_(0x1.a3a969f351753a208cd3e5a8f168p-9), C_(-0x1.2b9d22453328eaf6cc00ab2ce255p-10), C_(0x1.95e4d7f634c66f1127081eca4c12p-13), C_(-0x1.348b4478275cac4e09ed00491749p-14), C_(0x1.d3098c771ac4dfa090c0edef58f9p-15), C_(-0x1.49cdbb7d5d852bdcaa3c1cea09bfp-16), C_(0x1.12cb123d22d84321bf94a9d64f4p-19), C_(0x1.ee369d60388e0cdc7a4cb2173367p-22), C_(-0x1.fe1ef00c018375d62e92ff3458b4p-24), C_(0x1.a7341d99c255c94d652d9d8f033dp-28), C_(-0x1.530b27430376f235ffb52485dd26p-31), C_(0x1.baba95d77648bbe90c5142dc80f9p-36), C_(0x1.4f068520e819c6ced35b43d3471ap-37), C_(-0x1.57c84bc8729954adbcf1854852e1p-43), C_(-0x1.4644a16a824bfa62197420e08c45p-48), C_(-0x1.8db806597a9c3e694cd52ef5d34cp-57), C_(0x1.0d894936ca76f0f900d3760154afp-62), C_(-0x1.b4baf18dcac141cf35421e01ae8ap-74), C_(0x1.758520ee5d32f0284861059680c8p-88), C_(0x1.01a0cdf0066867c0900e21808ebp-113), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f55ef3437afefacc7be18bbe98cep-9), C_(0x1.0777b4e7fcce2c0e40744ca54978p-2), C_(0x1.3f1d6fcf2ecbd47e40d3c1703896p-1), C_(-0x1.504b43d516f52267cd7e5fe7d16dp+1), C_(0x1.4eaade935c6e2740942fa58ebd6dp+1), C_(-0x1.5ad808042149f417dbd58af6b00dp+0), C_(0x1.cab544fbb7d4b4c60e5f5aaacf98p-1), C_(-0x1.9ef87caf9226b19c3d44c512bce3p-1), C_(0x1.71fed5bcb893256d48b5662cb1dbp-1), C_(-0x1.0f0d57adf520b2ff7dc518f39f1bp-1), C_(0x1.30c75d43e61143b20925258c8b83p-2), C_(-0x1.e86b0f7372ef580e2a548027c15bp-4), C_(0x1.b73425fd2a98ccd833576427e8eep-6), C_(0x1.4682acb561a50d1c8642601cd7d1p-9), C_(-0x1.2eacc75c57cd93079a89b775a2e9p-8), C_(0x1.a21a6f510bbe181a8681692c18eap-10), C_(-0x1.147cb459e63791d570da7fd30181p-14), C_(-0x1.28e19a4afa00bfea3a7c1b8c9b43p-13), C_(0x1.931858e53ca4936f19114cad31b8p-15), C_(-0x1.62eadbc9e95863c36c22bbc42279p-19), C_(-0x1.de496f2e6fedcba7342c1d21ed73p-20), C_(0x1.70387d4ff6ccbebda63c71a99d37p-22), C_(-0x1.75a0d535dc76533ec0cb363c4ecp-32), C_(-0x1.a0b3effc1d4a9bf1824673d2a6ap-29), C_(0x1.b9e3fb75297f14c235645de65301p-33), C_(0x1.a8bed9eb35249e37507da13a3226p-41), C_(-0x1.16b3429b615b32018d7a07c98618p-42), C_(0x1.ff8673e3757ca4761f1167047725p-50), C_(0x1.145878dae073bba8c6a0fb3960bap-57), C_(-0x1.9feee550a5c8e58e5b4245c07331p-67), C_(0x1.83b415f1b1f54454e6745eb4b4d9p-82), C_(0x1.0b692b789332c1658c8a24d9733ap-106), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8aac090c80a048b0460ec2d7badbp-6), C_(0x1.5750bdc83f394eb3b8faccf4d05p-1), C_(-0x1.50c8f6f54e2cc9e3e11af9656bf6p+0), C_(-0x1.8a451969aae1b985b829fad06526p+0), C_(0x1.a2b7eb3937eee939c776f8d31095p+2), C_(-0x1.118e064b4695a7f92c4b4501fcb4p+3), C_(0x1.c7bf87fc63cf93f68f74e5e7c825p+2), C_(-0x1.1d8d78044ee8ee6d6d812a1942fep+2), C_(0x1.e73d8bee7689f31a0590abd75fdap+0), C_(-0x1.2add7b6319082ca3c2efcadae5afp-2), C_(-0x1.d3adb45266b9c9f4635ae6e3441ap-3), C_(0x1.033a83600934f9863377b693a726p-3), C_(0x1.b5451b19e5929d480505b5a86b0ep-5), C_(-0x1.7b8dd6246eb29127a889717ed76ep-4), C_(0x1.791fa45e84d145e6dc4c1510b4b6p-5), C_(-0x1.7c0beae24c83b65b5de7467eb78fp-8), C_(-0x1.5782b21d6af61f4f7dba20838e5fp-8), C_(0x1.a840c3e83eb503c78b20b8a28b62p-9), C_(-0x1.986e55de09433017be901893ecf5p-11), C_(0x1.26705b8c8ad65b55b61c41f75588p-15), C_(0x1.d3d83a9fdf1319302a3787bdd6a4p-16), C_(-0x1.d82fd865aa4582e2885f825ad846p-18), C_(0x1.f5b54c9c1896a94bf7ab1ebbd585p-22), C_(0x1.fdc61d80cbe3fa72384c0df210aep-25), C_(-0x1.0fd59d78e582bd5f0e263192f5d2p-27), C_(-0x1.b2380e734b4f9e20f629d35cee8ep-35), C_(0x1.88e8ce1bbad67bfa806d6889ad1bp-37), C_(-0x1.9888eae4a10ce8dbd9f3a51b6ca7p-45), C_(-0x1.466525261ac31d726b6464754be8p-51), C_(0x1.1b33afe3275e0f5266344c60d67dp-60), C_(-0x1.cb1864e2c62c6b93f97126fa2abep-75), C_(-0x1.3ca6dac99711dbeeb8df3656a48ap-98), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0491b50257a217948037c313c632p-3), C_(0x1.088e085a415b940e86ec5f53c805p+0), C_(-0x1.9cc2273fe20fe221de7ca14dc50ap+2), C_(0x1.b3ef626d8f7b0512e777dbab2038p+3), C_(-0x1.fbdaa71ed3446ae9d3eb57fb2edp+3), C_(0x1.ba80f6fc4d07a16a8240d21d3427p+3), C_(-0x1.97b8947186ea82517ff8170fe92bp+3), C_(0x1.9ec07cc028783871c266a993e177p+3), C_(-0x1.7db26c06ff96156fee69f60a32a6p+3), C_(0x1.1910e3936c71e0698749e0100bd9p+3), C_(-0x1.2af49c29492fb4bebe4ea4c0492ep+2), C_(0x1.4fef94a557c4567b7c45f05c21cdp+0), C_(0x1.8759880e99b2b3b19fcf3cb856f9p-2), C_(-0x1.52e5ecb25ff9114988afe0915415p-1), C_(0x1.5f17262b3d7f451babb3a37c2f6bp-2), C_(-0x1.a7f494de47ba1f8ccefd1a48b767p-5), C_(-0x1.5dc2bf7dbd1d10649dd1efeed2ebp-5), C_(0x1.fa52c9fe27d631a55490bc5d6453p-6), C_(-0x1.0edbce8cbb631c85810ceb7afb83p-7), C_(0x1.51bdedea6ecf9aa291d741d5449p-13), C_(0x1.03e8c53050207786cbf7a98773ebp-11), C_(-0x1.fbae0e996b24eb9e7412c53365a6p-14), C_(0x1.a5405fbd60ce14b0ebcc8751154bp-18), C_(0x1.8401a133e3997a7f15f86f10443dp-20), C_(-0x1.9620d8180585bbc8bcc656387216p-23), C_(0x1.59175b5517be80fcdb2badddc5c9p-32), C_(0x1.a5d4ddd28a790634117b9f52ee98p-32), C_(-0x1.a9e2125d31a3c8bd4449e4b094e8p-39), C_(-0x1.068a399565e004f3cf609f3513f9p-45), C_(0x1.3ca73a6f9a6a05c209544433b8c6p-54), C_(-0x1.740e2252efb089d1ae6c93a1b5fp-68), C_(-0x1.009e0cb9ab19e5360f5dcaede516p-90), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.12eabbc13ae4184543451253a593p-1), C_(-0x1.dcd48a30309a985e66770059ddf6p-1), C_(-0x1.61bd6ca0b74ea8c2e61c8e522049p+2), C_(0x1.4b16a330057a9a464e1afd029265p+4), C_(-0x1.6645126fb9e4a4d9cdaf8add299bp+3), C_(-0x1.746a9ef1dde16ed58e0b432bfa77p+6), C_(0x1.49df58a6d0bb202b69c6e445a50dp+8), C_(-0x1.2844a2ebcc53c8df614ae3957cc5p+9), C_(0x1.2e42267f64054a81e12f7b2ff462p+9), C_(-0x1.0225a1d4c62f4d7b402b42538ffp+7), C_(-0x1.601645627c56a1dba4f1a59caa2dp+9), C_(0x1.58f8de6f258472f30e4dedd3b403p+10), C_(-0x1.693ca7a1da62866e49185596166ep+10), C_(0x1.d8c8ec24a42109f71622d8b3d887p+9), C_(-0x1.46d08ddd7ae2544339cc13f918fp+8), C_(-0x1.3b3b035293fc39a231fe7419868fp+5), C_(0x1.d12d6fce626a721298fd94ab886ap+6), C_(-0x1.06b1d4ca392cd5c4bed1c5482646p+6), C_(0x1.11a1d31e54e9ef311bda0933730cp+4), C_(-0x1.40c7309469440a4e5541e2e4c29cp-4), C_(-0x1.5ca50bfd4e3e4aa86ac8722ac5aep+0), C_(0x1.83af684fffb5b293cdc91cda7503p-2), C_(-0x1.9e6da0de05c76e1cd2d553753824p-6), C_(-0x1.7858ef153620d7c30fc31cf56a03p-8), C_(0x1.dbde29a936a150c27f696a66c4f8p-11), C_(-0x1.7bcec5a7e8c292f303bfbe3660adp-19), C_(-0x1.4f2043d7bc5e1f3a3aca5e8c6039p-19), C_(0x1.c2215a9e7432391b90e0fdc7be76p-26), C_(0x1.2faa97edde49cab9c4399ff18db1p-32), C_(-0x1.023988307e2875f374e798bb263p-40), C_(0x1.b307ce337f9f1788bff0e23a47f6p-54), C_(0x1.2c0d7e12bcbb5186b064f5495d76p-75), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d53d20f76b4eb49c1b6330a595f1p+0), C_(-0x1.86cf243ed21bd08659834822cd59p+3), C_(0x1.17b81677ed649599a4d3595e967cp+5), C_(-0x1.abb0b3868d1ea2ff8d47921a5292p+5), C_(0x1.f121a0540b3049d09ec7e5551764p+4), C_(0x1.17380aa83335c1ea7599d28ad525p+6), C_(-0x1.0c95dd1e4ca7caa2bd6deac65cdcp+8), C_(0x1.0b7efc300b3c27dde71e697ba35dp+9), C_(-0x1.826ec4b2204db57bfd19486982e8p+9), C_(0x1.b8a41eb5a39bd8486cfb324fe223p+9), C_(-0x1.a1f5e828547f7c5b2bcb67af2fb7p+9), C_(0x1.5201c70981a0b03733b9e6dd6e09p+9), C_(-0x1.b80f281da59c5918dfb2c054585bp+8), C_(0x1.5562f5403383fa55297b9a337231p+7), C_(0x1.90f51962a56d70bb1b983c1ee4e5p+5), C_(-0x1.24ca65a640b01ad09d88f66dbd3cp+7), C_(0x1.f2553461b931355eaf34d3576431p+6), C_(-0x1.dd44638d13da936b6e3a63722e62p+5), C_(0x1.c0ad57b9e59f4a68dc33ce587da3p+3), C_(0x1.4256b15254b23391d079094819dbp+0), C_(-0x1.fef8071c6ce2bcb3957ad8d4d2e8p+0), C_(0x1.22e6dade4ecd5ba17bba3803612ep-1), C_(-0x1.5b42b69e978a5317df9091ce52d4p-5), C_(-0x1.642c165a0dc2d5830f0c68cef691p-7), C_(0x1.1410f766f54ec568508253190fd5p-9), C_(-0x1.866a34dd716a310ea2f7f87ada3fp-16), C_(-0x1.0b5a3f31f6ca3105091deb1b111dp-17), C_(0x1.e9e690f2d2cdcc9f8d2e274aa38ap-24), C_(0x1.73aa86e33bd9c22c0a03f2815f8fp-30), C_(-0x1.ab771b8e4149cc3a675cc4898a01p-38), C_(0x1.0db4d80a1d5dee01c7237b2562edp-50), C_(0x1.740bf5a4533bf10d9f87491f9f4bp-71), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.295ff3e65734f855f39c88490c77p+2), C_(-0x1.53451cd19bffc6de5e35716507fdp+5), C_(0x1.6528da0fe333f438d196bece2469p+7), C_(-0x1.cbdb85c1ecbc284c645d00a79bf9p+8), C_(0x1.932ea82ba595876f9e544cf675e8p+9), C_(-0x1.f84307101d81872f84fc73fbdae3p+9), C_(0x1.bf6854697aae94bb46e7b0542bd4p+9), C_(-0x1.bf12de658509da0b644cd695e0b7p+8), C_(-0x1.4368651bd726f170cb68d94b4efp+8), C_(0x1.6e6644c0e40c6d361a9bc94d8ca8p+10), C_(-0x1.63936602c4e494fb5778af823485p+11), C_(0x1.effe4a55a204acd95799b1a3ca8fp+11), C_(-0x1.113fec7086061d5415319b0c5f72p+12), C_(0x1.fcb0d58a8410175cda764e2c75f6p+11), C_(-0x1.a4bb9f060dab410fe3bd526fda39p+11), C_(0x1.329610ee0fa8084fbb618f8b1294p+11), C_(-0x1.6a3f2ab2a8a1738b723263aa7f2ap+10), C_(0x1.28b90043770072e85c55c758b4e2p+9), C_(-0x1.98095b9a0fe58b99d4dbb49d1d1ep+6), C_(-0x1.7e9c13fb873c76fdf7051d8da9ep+5), C_(0x1.38a8e96bcb8fab70b383bca5ab41p+5), C_(-0x1.67764003f2db50e6202ef878e23p+3), C_(0x1.be87d29fcd9eaf1da18ad636de29p-1), C_(0x1.281bdec2a7f8db103e09703f13fp-2), C_(-0x1.0bb48c6ffbbe8bdda51c03bcdddep-4), C_(0x1.77235116b4238df6f725d274e118p-10), C_(0x1.6675983c9f507c163e6782c7703ap-12), C_(-0x1.d3d6efe237ab3413c9e890035877p-18), C_(-0x1.81b8689afa6e0c7916f7a3885678p-24), C_(0x1.2f0e5249c6fc36ea9c04c196c326p-31), C_(-0x1.1cfcb984a013a5a7bc95cb9320e8p-43), C_(-0x1.891f706028ea406f88faa50dd1c9p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.06fc2ba8e79eb72495307bac6ae7p+3), C_(-0x1.5489cef9cc78f65236603d4cf5b6p+6), C_(0x1.9903c6b2ba02d6090a910755f61cp+8), C_(-0x1.312486b078b78cd8f1a70419307dp+10), C_(0x1.4302b86058a5a1292888fa9ca885p+11), C_(-0x1.0b2ccf4526b8c244af343cdb508bp+12), C_(0x1.789932548bf931d92c8e1c8fdaeap+12), C_(-0x1.e12b9567cda5d69eb9d09a4087d7p+12), C_(0x1.1abf23f09fbf8f276f484c29af9dp+13), C_(-0x1.2d5cd803da680fe5c48016ca91a5p+13), C_(0x1.2251ae99e408a20ab182f4722d14p+13), C_(-0x1.003d36dfd5a7feaa6fd4657cd76ep+13), C_(0x1.9f286327797df00b01373e3a21a7p+12), C_(-0x1.2d0f0d917a1ccdeca67d314f4298p+12), C_(0x1.7c4b637f2390259cb36649bf5cadp+11), C_(-0x1.9dc666df2eb31fd9d525e80a61c4p+10), C_(0x1.706ff6209d6f31fbb17a3cac3d1cp+9), C_(-0x1.76b515afa4c5f086db4f0c0e11f9p+7), C_(-0x1.24480d16a6ef2cbf187e850a3c68p+6), C_(0x1.d48700b685d23247b608b5cfdb9bp+6), C_(-0x1.05a23476b2f21c52a72aaf8a7e1cp+6), C_(0x1.24935371deb2ec43e23d888eb93dp+4), C_(-0x1.4ca6dde02f223d08bbf5ac28bf78p+0), C_(-0x1.58615b018cee75761c906455ba3p-1), C_(0x1.608c7993e060e80a3ede46931d7cp-3), C_(-0x1.b69ce98ab84f025bb8e299cdad9p-8), C_(-0x1.4823967168edf829557ae3a04f84p-10), C_(0x1.35d91ac6fb610d89a9ca12ef88e9p-15), C_(0x1.1a7bfc97dc33f6885878a1ae185cp-21), C_(-0x1.2be69d6aba0faabdfc72f4f8d745p-28), C_(0x1.ab2f7726c736fed01e244eeb7278p-40), C_(0x1.26a24576b891cedff10c341592ecp-58), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7d326037dd59f04b93695dea64a2p+3), C_(-0x1.057b7f9e150cfea8b7f60a37452p+7), C_(0x1.46966635c034e3d077a23a34c32dp+9), C_(-0x1.ebce82ab1e29c2e7e1d24be27a9dp+10), C_(0x1.f63288a008a00b0de93e3b52ce8cp+11), C_(-0x1.7a1dba3b5d1c5c524569d9d8ab6fp+12), C_(0x1.cf6c2665a1ce80b761f29f92f584p+12), C_(-0x1.02e9d9c7c198539a0401a9ab1cc4p+13), C_(0x1.126ddfd818acd4152500102b2dd1p+13), C_(-0x1.fbbfeeed9e84aef44a32d1cdc74ep+12), C_(0x1.6dd45600e62e38c3d8b7dfec1df4p+12), C_(-0x1.70d3cf8b17a54f73f23ea7c9008bp+11), C_(0x1.116e22f7a2135c32a071c68e4c4bp+9), C_(0x1.45e19d7a9f76f8d3600c21c7d961p+10), C_(-0x1.541801f00ec703cee53ee38cf9d1p+11), C_(0x1.9d27adde86cc9d38961105f8f3abp+11), C_(-0x1.718955043c8aaad595f50f39f434p+11), C_(0x1.13d222dd6eb22f7f0b910b51dfcbp+11), C_(-0x1.75dd9fab7780dd812eb2ca0b6548p+10), C_(0x1.b95889cd4ba403f3d771bad22aefp+9), C_(-0x1.880fb1002a98d978d68c5c6d01b8p+8), C_(0x1.a3c6bfae2048432d988090525bccp+6), C_(-0x1.6af0f7c1089720fadea20b94dfd9p+2), C_(-0x1.7dda27580f4d6fe605e5e2098125p+2), C_(0x1.bb56918206273622bbbf209a8389p+0), C_(-0x1.95410e4d3fa90c79d49021063b4ep-4), C_(-0x1.1e3dcf4406fb03d054399893d4cp-6), C_(0x1.863de856b0c02544096765b7d0aap-11), C_(0x1.82e7abd79b3d018087088704fa41p-17), C_(-0x1.21b01c6eb2b87dca0186448dc932p-23), C_(0x1.2f1ce1bb4e63e9b48ca04ddd06b5p-34), C_(0x1.a21b5c9a00d44d929d9e41311f24p-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6636de936afdb6694c4ffaed6a31p+3), C_(-0x1.f93a40edfceae00ae68e29b08ccap+6), C_(0x1.446da371d76c83e79d3a084840a1p+9), C_(-0x1.f81b7969b6241ca8af219aea83e3p+10), C_(0x1.0bf59cc8ab3644f7ca5bdfe6f82cp+12), C_(-0x1.aac9a227eb351b4f5d24fbc72641p+12), C_(0x1.1995306c55b12646bead2c38ad5ep+13), C_(-0x1.558e777f304785d9e9d3bf74bb24p+13), C_(0x1.8e256f3ea2d2e1b7bb373067b872p+13), C_(-0x1.b16f217fc65b857f8f6c9d68eed5p+13), C_(0x1.ae7e2aa7eb75bb88db9f2bedf708p+13), C_(-0x1.8d7f6b89b7d82de8cbcb8a91aep+13), C_(0x1.5bc0c9e9bcdde01e3a5bcbdf7ae2p+13), C_(-0x1.1c9a0c6fad5ae4a6fdea1b4bf6cap+13), C_(0x1.ae2f95c3b0ec2e40af37580cdc26p+12), C_(-0x1.2f129053ebc24ed7fe6fd750dd19p+12), C_(0x1.8d5b23e080443674d13b71f54d14p+11), C_(-0x1.d627dd21f8491dafe966ff60514ap+10), C_(0x1.ed8f9f756f065170266103952acap+9), C_(-0x1.cf7165a4ea829414cafd158d5c4ep+8), C_(0x1.6d33ddb7ad7e8017c0cb0ef30276p+7), C_(-0x1.65b4962a79c56602e9794ee156bdp+5), C_(-0x1.4d3b8e7db26f275e39c95bf13c09p+1), C_(0x1.950dbe3d7aca2e2a683f470bff22p+2), C_(-0x1.dbafbd443f803e2caf8c9757690fp+0), C_(0x1.04861e6b2202e3d3d031b9ec9cb4p-3), C_(0x1.7fe12c9629eace47e413a0b6403dp-6), C_(-0x1.c081b52017ebd837349a62b66ef9p-10), C_(-0x1.adbded066f7794fda23e0774673bp-16), C_(0x1.dd5025fbe71cc3a7e8141de53daap-22), C_(-0x1.642f3973aefae4a4f6422168ecd6p-32), C_(-0x1.eb48617a106cce90559379e40303p-49), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.24754790ab93df0d2355b8c8a1d6p+3), C_(-0x1.a21d6a4e4d9eb295ee53b44586fdp+6), C_(0x1.0d7a54376cc0558116461ff0ad85p+9), C_(-0x1.9dbd2fa0800f2f31e9998fd08c87p+10), C_(0x1.a81b276d71be81d44423e8d7940ap+11), C_(-0x1.3af0559f33f06e14389580e81a29p+12), C_(0x1.79904c76e9a060ec8e465cd0f64ep+12), C_(-0x1.a8514199bacb20e9109b77f293abp+12), C_(0x1.e26f534b2b2fd591e9ff3ecf4696p+12), C_(-0x1.01e02902687a04ca65f96e6a8b68p+13), C_(0x1.e5294c43a413c0653234e7f1aa09p+12), C_(-0x1.a1b883ef12d1d5472469dd56bc1fp+12), C_(0x1.5e76af85cca307f1a26352596c69p+12), C_(-0x1.15aa3e69a2aa9b29daeedbfe44dep+12), C_(0x1.86a5a2358b24b67c01514a96d3ebp+11), C_(-0x1.f3289b5523f3f49f9c93e10ff537p+10), C_(0x1.313866068b105f8069b31bb16bf3p+10), C_(-0x1.4f6a48ce8e3698f8a03194833bbfp+9), C_(0x1.23a63c6ead8e0e6aa15fe6f45702p+8), C_(-0x1.8310a2cf199a480eca2c2b3394c8p+6), C_(0x1.66b7a5ffb79e9dc036820a3ad358p+4), C_(0x1.9e1737848ca25244943790e11b0ap+2), C_(-0x1.b5673299d6c08937871359b74265p+3), C_(0x1.06e8de128ea18c685f5f56cec9c2p+3), C_(-0x1.231b2877825a92418fa8440891fep+1), C_(0x1.8ab9028a51e09357bf81bd620a6dp-3), C_(0x1.fe0af766377cd4e6799421dcabc8p-6), C_(-0x1.2be854453bc6da5ab705ba515333p-8), C_(-0x1.2ae4048d20f92820dcdbdae1afdp-14), C_(0x1.cba1e05e755f67b92b6effedbc08p-20), C_(-0x1.07cc113fc2e535393592fd575de3p-29), C_(-0x1.6bcf254ca2da0ef6aaa6b7f61e81p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6734f40a39a9f749d116c99eb0b2p+3), C_(-0x1.02800bdef42eee8e9cbe8c5b799cp+7), C_(0x1.46b9a7fb0659b383f2e6ccc2bfdp+9), C_(-0x1.d4653513846d8b632e3ab00ec6aep+10), C_(0x1.960cff14f27e9f5b5c924a5e31a6p+11), C_(-0x1.978ccec6aa50557b75045abb874cp+11), C_(0x1.65f6a7cb1b6c9a8b6c858f9858eap+10), C_(0x1.c444279391a3fe3940190e9b0d42p+7), C_(-0x1.743641ef137ce3dda68a9d7a6a5ep+7), C_(0x1.b0d221397077b61aaac6990656bfp+8), C_(-0x1.789f01238bd736d3d165c526de34p+11), C_(0x1.78076d93e8b2a21b1e57f1d51e32p+12), C_(-0x1.b80f30dfff7c8968576fe93ef454p+12), C_(0x1.bb7e92e14a551f987f2cb928af9ep+12), C_(-0x1.d7e88c840d9e4cc3ea2da57543cp+12), C_(0x1.d2485f20f81231778ef5c3fde98cp+12), C_(-0x1.8196b31f2aea3e18b21270e4dab8p+12), C_(0x1.2207d34a8263912f9c133abdb819p+12), C_(-0x1.b1c880d8d5a9e0a75d42bdbef999p+11), C_(0x1.2ab917d5ba30fbe55897a0ecf4f1p+11), C_(-0x1.5bfb47d78d5c9aa6b7b3ea1583e5p+10), C_(0x1.6b044d9f20d2a049f5f6d532822ap+9), C_(-0x1.6ef48eab0e23a150ac4817c103f4p+8), C_(0x1.3c86344d962287236a63845979d3p+7), C_(-0x1.62bb42947746334cf9768602ee2bp+5), C_(0x1.302845e71cb15c4d9c86c4ce6c69p+2), C_(0x1.8f631724d133592549dc9efdce6cp-1), C_(-0x1.82b35bd32ad297d37e7e03fdd8d4p-3), C_(-0x1.957cf95e09e20118e411d55e99c2p-9), C_(0x1.f6dae900f0dfcd786a2b2d830063p-14), C_(-0x1.960194a81c1ce1e7d634227c61f3p-23), C_(-0x1.17e5f78c653c49cc8a92fdb4f4c1p-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.206cbb79429c2414ff0c64aec8d3p+1), C_(-0x1.a083553e4e5a13a3aa202924b202p+4), C_(0x1.0cf208fc3d0318bce33d11bbf4eep+7), C_(-0x1.98490e95032010181534884dfc77p+8), C_(0x1.94a218c65bbc9e721912af119136p+9), C_(-0x1.17c83af6fa175ec696cff584b399p+10), C_(0x1.2a2038ecd41ce99e3b7c57bb1465p+10), C_(-0x1.2a77ab7e6edd3ce02f308ffb22c9p+10), C_(0x1.48a4ad0a80d290f172a8699dd903p+10), C_(-0x1.63c7a0fcade974b2571bdc4dbe83p+10), C_(0x1.4db14cb7e55e4fa2d6df561d81b8p+10), C_(-0x1.1f7d1042db45f9c24caed3674305p+10), C_(0x1.f7c955767cdfe40b013173464e47p+9), C_(-0x1.aa68a77f455100ba1716b7e81665p+9), C_(0x1.42df44997682f8bbd8705c8237fap+9), C_(-0x1.cc3c8a0b1406c4cb1854f7f475a5p+8), C_(0x1.4691261a687538ac5d74074129f3p+8), C_(-0x1.af8b6d718425edc744dded4be2d2p+7), C_(0x1.fddec0373e9c198b0187bcd05338p+6), C_(-0x1.206dca918e07679e17977c9e643dp+6), C_(0x1.394f1079b1d1bab9757ca4be3df6p+5), C_(-0x1.259c4ffdb02b3840be66495f597dp+4), C_(0x1.dbd0529d14d06481a401f7d28924p+2), C_(-0x1.6f7d774b2017e6812c50c53f3953p+1), C_(0x1.bf296d0152554d98043114f06ab7p-1), C_(-0x1.7c872eb94aac4434f1f1ee90200cp-4), C_(-0x1.14b95c5b19212b4fc03cbfb78471p-5), C_(0x1.194e2e645655459aae5fe3cd821dp-7), C_(0x1.3531940b1823b632efb391ef6f52p-14), C_(-0x1.7166e830bc1e3944c924058c6f08p-17), C_(0x1.2436b817dcb001ed9c4696c6c208p-26), C_(0x1.92b45b9b9529b7ad46fa43bf2077p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.74cc6314dd173590f359217811bfp-1), C_(-0x1.0da07c63bf5b57427067a74fa654p+3), C_(0x1.5af5b4b6a40764cc3bad47672c18p+5), C_(-0x1.03fb3e545cdf8287d11ea7aeca93p+7), C_(0x1.f3ca921092c121957e2f18e268fcp+7), C_(-0x1.44047871dcef9850bbedf1b419e5p+8), C_(0x1.3358182c099a552dc3876c2274b9p+8), C_(-0x1.10bd53f78b9c50f9a6e08d98e9a7p+8), C_(0x1.29eb9e1a3472cf232a6709ddfbd2p+8), C_(-0x1.4a2468b639e365dc0b3fd125eb7cp+8), C_(0x1.26dfa9c8f6c029f4753dc36c664p+8), C_(-0x1.d2f1acef4b4ba3b7e608497ba6a3p+7), C_(0x1.9597a28faf38ab1c2b429a5dd79dp+7), C_(-0x1.5e8348f17beed687dbbf25dfed75p+7), C_(0x1.f9613319a9e146e700ffce02e1bbp+6), C_(-0x1.4ea47fc45e78dfd9cd4f69ce75a7p+6), C_(0x1.dde07d45fce1683ab6993808e07bp+5), C_(-0x1.3e0ca7abd11c2d7cf0bb1fa5493p+5), C_(0x1.599232ab9283f8d2a3c47d198eb2p+4), C_(-0x1.6ac8188fba9f38deb15c420eb1d6p+3), C_(0x1.96eff61828d979e9be81958fbf3p+2), C_(-0x1.7071f5cc1d4694972d2c2c65d04cp+1), C_(0x1.e12484c6688efee796e8769de364p-1), C_(-0x1.4f89eb4be752a44a4402c23fb27ep-2), C_(0x1.c393c8a6167f5e45bd4990217d8dp-4), C_(0x1.7dd147fa057e0b50125bcfcb63a2p-9), C_(-0x1.13f7fd7ac3a280d730a2c002774bp-6), C_(0x1.03548ce92b6649d84ccad32bfb61p-8), C_(-0x1.2341881399bbc4b237f436539e91p-14), C_(-0x1.74f214490ba0ea1723d42cc72a56p-17), C_(0x1.5a01bfbda2f04b0c7709f4c8e447p-27), C_(0x1.dc5f89a7304e8e2e4721be65411cp-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3c25010b60fb3674740b05f24332p-3), C_(-0x1.c9af2c3ccca23c68e09fc2f7dc65p+0), C_(0x1.254de8cf13856aa803ccd66fd125p+3), C_(-0x1.b1e5eadb5abe7e897564be3e19b7p+4), C_(0x1.9450c60bf67cdef9bb4416994ee8p+5), C_(-0x1.e89b5b0fb80bdea3060e89b3c3b1p+5), C_(0x1.8f3eff015290335d6c5ba8db3ba6p+5), C_(-0x1.26718b161a212a6473dfb26ae75ep+5), C_(0x1.4a6ff4d30582a729b53c09473635p+5), C_(-0x1.8a12303f1194f457265cb9c94d2ap+5), C_(0x1.48e1a80801a27ea5d6b8c09eef2ap+5), C_(-0x1.bb6e89adbb91b4400c7c8bacc9f2p+4), C_(0x1.826bb857299c08edd527360dc4c6p+4), C_(-0x1.66d59bbc1beb521a1822adef1e5ap+4), C_(0x1.d762d94bf79addacd550a56af00dp+3), C_(-0x1.017df19c95ab47cf0b3801bfa83ep+3), C_(0x1.7ce4baf9290af712ae0b872e1a1ap+2), C_(-0x1.076985c84651e1c5e5388d3ed212p+2), C_(0x1.a91f1aca1f4d85453f0f9c33299ap+0), C_(-0x1.19588e1d9e17bce2cb6d81a29cf5p-1), C_(0x1.70b50254db487528bd3d29d3be35p-2), C_(-0x1.a1a5a33d385d5b812d62c1b7093dp-4), C_(-0x1.4244fca3bc21ee34636ecc1caae2p-4), C_(0x1.e957c08844afbfd050ce104aed32p-5), C_(-0x1.7d54f6f8e016b5cc4d2c805b197dp-6), C_(0x1.293a2e4267dc81d9d07b602eb6d4p-6), C_(-0x1.5d4d2a8021a073e46a46ee79612ap-7), C_(0x1.5b4fecdba5f9087fe95645ea7106p-9), C_(-0x1.4ed9a3f4a9afdf2f3236e61b6585p-13), C_(-0x1.125ce08dc9b661014740f9362c84p-16), C_(0x1.5ea5b19f4ff29c7baf0a16f9257p-27), C_(0x1.e1d2c8108c65a8cd4dea742f8f7p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.78f50d65c4a16421841e3f303dcap-7), C_(-0x1.10f9973c2a07331ce0ccac35cccap-3), C_(0x1.5ea80ed1cf2f2dbfa0cb00aff04ep-1), C_(-0x1.04e32caec7824fdd8feada2c4721p+1), C_(0x1.ec7b02aa786ba97d52a304f12e4cp+1), C_(-0x1.3174e658f8076784a24459fccb68p+2), C_(0x1.04af0495e940fb1a0934ba937e55p+2), C_(-0x1.82d9ce4c80e7862d53bd54f737b2p+1), C_(0x1.8562e843b948818ab7543f47aa8ep+1), C_(-0x1.b4475da1bb05033056b650854fbcp+1), C_(0x1.773ee8a0b6e167fb7d5268d067eep+1), C_(-0x1.162bbf2e87d9ef969863945cc2b1p+1), C_(0x1.ed70fea486a4beb02761cf722ef7p+0), C_(-0x1.be0a12832787fdeed784930ccda8p+0), C_(0x1.43344776804460a755e69c9fe27dp+0), C_(-0x1.bc193640146ea4b82ef2e3c4b7fp-1), C_(0x1.59f9f9e4cd9a370cf83a45b3405fp-1), C_(-0x1.ea19fd7c2dc2c5db9794b9225413p-2), C_(0x1.24cb1e377b41a9dc8bcbafd5c9e4p-2), C_(-0x1.6d1685ae383191436a11192a6015p-3), C_(0x1.ce23289a0d5c025951ea09936714p-4), C_(-0x1.e968908c7474ea2a6b493052c12ep-5), C_(0x1.e76f4d23e3441d0b7efbafd90df3p-6), C_(-0x1.fe92310a812ac1b17c748db28b34p-7), C_(0x1.bcfa77e534eadd2bde270b26117bp-8), C_(-0x1.3fde2d0e55306e2cc04a5e77181ep-9), C_(0x1.f9933c512b48e3277e9a4bb4b19p-11), C_(-0x1.3cde4b0a8d6703babab6ae1d57aep-12), C_(0x1.055b9666e46160de479c93713a7fp-15), C_(0x1.0afdd4a80e426c9edced22de6763p-18), C_(-0x1.63fa7644baff156719997e19782bp-27), C_(-0x1.e7410ee7b8c80f0f9fbb1245ff4ep-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7a4ce6ed992bb75d1922e250e291p-16), C_(0x1.42671fb0211a4a998d3a999cbba9p-7), C_(0x1.e6ee175fb834c8b714c01feffa11p-3), C_(0x1.b4d3dfe055a7b7209d9d957ea39fp-1), C_(-0x1.7d14720c62ef81c88eaa2934ef9ap-6), C_(-0x1.5a94efaefa077beed21f8e31afdfp-3), C_(0x1.42098eebb591e34e8dce26f5d9fdp-3), C_(-0x1.9b7dc4f9c2feaee194cc6094b673p-4), C_(0x1.80316f876ff22302ae3ab2cc5942p-5), C_(-0x1.8b13757e5a833cb7be38d086bf07p-7), C_(-0x1.9d8e278701564e508cebafcfb133p-9), C_(0x1.712f899035a27c983c908b6bba6cp-8), C_(-0x1.bedf3b9dd86feef8439cad4de336p-9), C_(0x1.4240f2118e493251bd8d9317b7d6p-10), C_(-0x1.0ae82fa70b020b05eaa57d2e86fcp-12), C_(0x1.5d87bb3a4b0411a199a2bbfb04acp-16), C_(-0x1.2d8c3a0a0933f834dfa752e731e6p-19), C_(0x1.e1643353d40db172275bb94c8db6p-19), C_(-0x1.66348482b32035f68245e91af884p-20), C_(0x1.38acac17e89fa0162b376bbd5bb2p-24), C_(0x1.00e7697e09dd627363f277ae5d0cp-24), C_(-0x1.a8f56e9d3a1cc00e461420464983p-27), C_(0x1.5a1ead033f0e454a9963da3438ap-33), C_(0x1.d4875150adea6366dba9b099b588p-34), C_(-0x1.cfdee2a4d421dce1ed3eb1824eb8p-39), C_(0x1.4ba806282cb55638c336fa42513ap-41), C_(-0x1.af632a71f0a85982bb61e8403dafp-51), C_(-0x1.cbdd4d28c6b8d8568783fc7a0356p-51), C_(0x1.4fd0be68bf175912b8e24547698ep-58), C_(0x1.61ffe57672ff2f1dc3af03a0658ep-65), C_(-0x1.3c884f70db98bc38107c463d9e95p-75), C_(-0x1.1f64d25df3ed3d5bb564497f042ep-86), C_(0x1.2bba4936fe9662bf3eb13c8582ep-103), C_(-0x1.1d5cf90ee87504b468831a41ae1ep-131), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a0c37edf06a8f94f636662aa39bbp-13), C_(0x1.5938ebddd04e210d6e15ff1b97b9p-5), C_(0x1.0ce81716630c1f9cc4b07a770d1bp-1), C_(0x1.bad54d5c0a788c931739cae743bdp-3), C_(-0x1.734c9748f4ffbe66b4e75bb9c043p+0), C_(0x1.219848201b9a0b52ec9b8191e5b3p+0), C_(-0x1.967b651c15d3ab20c349ccf7a27fp-1), C_(0x1.1dd39ecf7d040d13482ae3416703p-1), C_(-0x1.7d233595983848fd2834ed2571cap-2), C_(0x1.bdf22d0e95afab2bb96e5bd19c6ep-3), C_(-0x1.ab4ab3ea2f36e1559b9c3420ec0fp-4), C_(0x1.361512fce1c67582139ca256de4fp-5), C_(-0x1.2052c9fd431d75170cd08f266eddp-7), C_(0x1.0fc840c4a9b1a2b7d29c508eb6d3p-12), C_(0x1.b1c90fbb8951feffd58470c9d80ep-11), C_(-0x1.c8b87ff5be380a38841f22318f52p-12), C_(0x1.11b72f5c2ab5d1894363c9e7ab05p-13), C_(-0x1.44fd9e718f23deb8dfb254ca9d3p-16), C_(-0x1.801763632cca8db4265fd9b7171p-19), C_(0x1.09096d92c04b504ace3e77b64297p-19), C_(-0x1.d590c9308d6d05c5021dabbaa32ep-23), C_(-0x1.b408b4e946eb9006560416ae94d7p-25), C_(0x1.26b8d9536f33f7963391a473b488p-27), C_(0x1.21ba41de7becb667214c3ca5d913p-30), C_(-0x1.005e15e86c4a56785a4a0f6ab3f1p-33), C_(-0x1.892c108c5e8de79fc1617882908ap-39), C_(0x1.5e2035f63580023798eda85d3d21p-42), C_(-0x1.d491970f7aaa6c617e7d1c311941p-48), C_(0x1.4a6b89912129028f7fea4136c808p-54), C_(0x1.1d009ad5392248132b10cca6afdep-61), C_(-0x1.a642a25e87ebcab18086a8e2fc06p-69), C_(-0x1.2011c2ce8690d9b9656d986e92cap-81), C_(0x1.9134326520639372add0f822994cp-96), C_(-0x1.7df9e44e24a4ebd5669f58093dafp-123), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.971a55e8255470a8e87397205afep-10), C_(0x1.3dc2c8dbfcf7f93df2e2e770167bp-3), C_(0x1.7546e57d9721df0ee0f4226116f4p-1), C_(-0x1.037adcec0657ef37e8f5501826c9p+1), C_(0x1.f0f2562cfec47ba3b00526650a7ep-1), C_(0x1.6c9838c4962e4af4c25ecbc468b7p-1), C_(-0x1.ebd5569ff73f2f877d55e4233979p-1), C_(0x1.2915d00cfaaa51da1d3b22bc1b91p-1), C_(-0x1.e34c46891f72dbbcd8a73f99bdap-4), C_(-0x1.5072010dc85e733fe3c06054204ap-3), C_(0x1.c67306010de8b6a212c8a67869b3p-3), C_(-0x1.2fa98054a2107feaebe98c8fc435p-3), C_(0x1.df7d703c2f7ab707c9106e495b0fp-5), C_(-0x1.28e5dcad2172c449a1b7dca486f3p-7), C_(-0x1.dc7a4c4cd9eeea5517aa806e57aap-9), C_(0x1.18e996b43138b67ddc3e006638c8p-9), C_(0x1.b32438920580e922f03409f3eb6p-18), C_(-0x1.9037acbcd4ec345580dcc6ddb006p-12), C_(0x1.44eb457dfe491144a6a8147f8c33p-13), C_(-0x1.4321ac67acfe448897274bc08792p-16), C_(-0x1.256fe0790910edb7d614dee4ba24p-18), C_(0x1.ed8efd908e26dfcaf46a03ca2c55p-20), C_(-0x1.a7d2bd14ff6144489ccdef55f7a8p-23), C_(-0x1.037133591bd1adccd684e0184c22p-27), C_(0x1.ab74edd3244b37270e37d649fe31p-29), C_(-0x1.fc9e38e19ebe258bd42cc39b8e13p-33), C_(-0x1.8084026dbca3fcd810e0eb658b42p-38), C_(0x1.368fe30917847fa68db0002b6cdap-41), C_(-0x1.39e30293b3af2c4949eb4a178d03p-51), C_(-0x1.7503d7779e458b1aa1fdddbe3326p-54), C_(0x1.9a1da2379c2a990ef23e5cbc6726p-63), C_(-0x1.f1aa7d24b3e7cf365e425fbf9856p-78), C_(-0x1.86a335fc44a9a2d537ec8158da4p-89), C_(0x1.73ea8d0ad818e245ff5b1e9884a2p-115), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5a9454bfce16a0a0dcc504f76122p-7), C_(0x1.dac670f07b3810cfe0200e30b836p-2), C_(-0x1.07048222529da273b75a32ca582bp-2), C_(-0x1.b83c3b0926524121fff53826cc44p+1), C_(0x1.0676df488b1e4ed89c22050c7595p+3), C_(-0x1.30179a3f4da7316ca0c075836a81p+3), C_(0x1.05ba4eee5e31141776d12d72864ep+3), C_(-0x1.93e9c8737c9db916fd3aeb9dbbf9p+2), C_(0x1.11f35b97811e1392b7e5f33b18aep+2), C_(-0x1.34f47b568e89b7ecbfe83a3f3f92p+1), C_(0x1.13cb0f11e8118c8728dc07b4f30bp+0), C_(-0x1.7b2819c00008e638df3a1f667154p-2), C_(0x1.a1284251ac1c9a380e6762cf2045p-4), C_(-0x1.9462a198000c99e2d17bdaf7509fp-6), C_(0x1.98cbd04cf38d0b88fffaebdc2248p-10), C_(0x1.790fb9b4e1079fdb7c7f3de53909p-8), C_(-0x1.44467a122c6f0b3c619500e4be8cp-8), C_(0x1.0c81b81e9a914d549de9a5603fbfp-9), C_(-0x1.cac8f340d2aa3b68b219b85c015dp-12), C_(0x1.056344fb5f7fa4c5bdacd495990dp-15), C_(0x1.64dbcddfce7247b526ac9d7e0ccfp-18), C_(-0x1.2ea8218d9b8d1d441244fcd4b66ap-19), C_(0x1.ae941e74a568c6bb01832f906cd8p-21), C_(-0x1.1e524786cf0a95db795410244806p-23), C_(-0x1.2a97ea36eab85a08d496990ea5bdp-28), C_(0x1.91a720541503c3aab6c0537ffaf4p-30), C_(0x1.61eee7e526616835f0ba9666b29dp-35), C_(-0x1.1df0b9e54c56a105bc6728365e2fp-39), C_(-0x1.1ea73fd30a1b3871739285e4eb76p-44), C_(0x1.4cef49ba65ab3a484daa2106a09ap-51), C_(-0x1.042acc29aba7ca20f707f59b4985p-59), C_(0x1.2f927288a9fec8bba637277e07b5p-69), C_(0x1.f64dd565d432a80474f09d7042aap-85), C_(-0x1.de3b2de560b19ad42b01407d7ddfp-110), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f65b07bf823cec483c39d5a11448p-5), C_(0x1.f0133093951f37f6a896ead34da4p-1), C_(-0x1.2157210d40dee8bdad6501ac0ec8p+2), C_(0x1.a490d9720df43c568fadfc931407p+2), C_(-0x1.0a37608588b0a4119bc76eb25c95p+1), C_(-0x1.166e49a8a0cc2b9e02e97716b213p+2), C_(0x1.47f9043ce81ccaeaa7b51a7192a1p+2), C_(-0x1.51650f8f0f7bc2a8e1c87a310a8ep-2), C_(-0x1.4a651a2d2c8b208523a548f223d3p+2), C_(0x1.daa4090446b0d279d1861aa53d55p+2), C_(-0x1.69495e8e6d87591bdc3892f6f8c5p+2), C_(0x1.0277af1839af3f779c7cdb3ae641p+1), C_(0x1.6b6419616b5982af3302995b743bp-1), C_(-0x1.731cf8395e4c8d5b88b93305475p+0), C_(0x1.d1e75297f2041df9c5f5bf256a3fp-1), C_(-0x1.d49cf0590577e4f277c27934579cp-3), C_(-0x1.397f17a4194e8ce372c9e426fbfbp-4), C_(0x1.7a21cbbedfbe11f0454df42e4775p-4), C_(-0x1.2988578b3adabc4b1512d4cbb6abp-5), C_(0x1.545144ccc581a21bd7cff42729e5p-8), C_(0x1.55e4a8c66e27b9cd3f291e5b6a18p-10), C_(-0x1.82c0f91d9bec49c90d6f1f27054cp-11), C_(0x1.ed2cd19280a89d42a9f703b9d37bp-14), C_(0x1.348863e0c3862c00204ef5c290d7p-19), C_(-0x1.8699ea90dfea228ea4870e9888cp-19), C_(0x1.03f81160244ea4e0561d2796396ap-22), C_(0x1.2dc9e87ced5d3e0075d1b0f48214p-27), C_(-0x1.1e0055531ecb5b5480ebd74d3d13p-30), C_(0x1.78b61664e5a70e15a0ed3d839b88p-39), C_(0x1.5f0c636dbd6bd39cd760ce07545p-42), C_(-0x1.6221e33afdbcbb6531e539a33b88p-50), C_(0x1.408f5ecc984b11ae43df9f32fee6p-64), C_(0x1.516335d80f8b3330068bd15b7661p-74), C_(-0x1.4137e85d31ab926f05f01bb46b99p-98), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2c1ae6823399b2cb435cac91e1b4p-2), C_(0x1.0b5a4c7a50e393bc298a68b8c54ep-1), C_(-0x1.35e6d8721b448f3219c2ebf797cep+3), C_(0x1.08056d18cc3abfd158e32f385712p+5), C_(-0x1.e443d0b2f1917ce5a7864d3c4f97p+5), C_(0x1.26e95184621c1fe6c94f3f1e55c1p+6), C_(-0x1.027c3db720fc8465d08ef051f852p+6), C_(0x1.39b53e5c17e2d98c6d1b6a224a1p+5), C_(-0x1.a2ef9908e5f3063d5f6a67d79ad9p+3), C_(0x1.3c1856843b6ed43e69173ec9beb8p+2), C_(-0x1.50a61279deff7a9f95e9f5b1ffb7p+4), C_(0x1.7005437ea7f364b02fc7783b2745p+5), C_(-0x1.c35972d3e17999223e53468e37e1p+5), C_(0x1.5e3ef093f504f098160dfa010bc8p+5), C_(-0x1.3ec57fe40125d739e37516f7731fp+4), C_(0x1.8f87e8ce4ea1f97c1a2b6959d92ap+0), C_(0x1.3ebb2932b57e51e04c3ab524c19ep+2), C_(-0x1.f8f19a2160e20da38a2d0ba656dp+1), C_(0x1.767cc5a51bc973a84dbcca58047p+0), C_(-0x1.713b4eb249abff794f2872f24925p-3), C_(-0x1.57f96e30ddfd9bc4477fb05a13ecp-4), C_(0x1.6d3c7dfd75dd9d13bacd85402f0bp-5), C_(-0x1.f364307632fcaaf5a516d1734575p-8), C_(-0x1.a69b8516a1ae027062e6cc44b942p-13), C_(0x1.037145bb4087ace803c84d0a5bfcp-12), C_(-0x1.900324bb445222e2af610e0c858ap-16), C_(-0x1.c39b875e9ce90c4599df73f3cdd4p-21), C_(0x1.257ca20db0247e060d265d852efcp-23), C_(-0x1.94fc591b19bf8737ee11ebdb8608p-31), C_(-0x1.f784210bc45a0c13791f8d01e395p-35), C_(0x1.45da31c732197dc55fbe5cc58e5bp-42), C_(0x1.7b22a9fcf8e8894af17ff0c96d4ap-59), C_(-0x1.36334f22553eac1c5efc112842bap-65), C_(0x1.27559bf46283fc4563833952d7p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1b6522cefc386094703a1b940b9dp+0), C_(-0x1.725aa82bb56b65b988671eeb4df9p+2), C_(0x1.352392d274a5a82ecc23fa33228p+3), C_(0x1.0932fb369d6b1d42ff49967acb97p-1), C_(-0x1.879358a7154c8fe38abb0596bfcdp+3), C_(-0x1.7bc58b3667a9b25269bdd7a77a0cp+5), C_(0x1.0b13ecb8bf57a95468d44bdf0495p+8), C_(-0x1.43c9c4bcfe445dc8af77035b453p+9), C_(0x1.09ee5b9c8e5bb60028ced9f338a6p+10), C_(-0x1.51e18f7652afc8e422b14381c4bfp+10), C_(0x1.644767119a752b7a9c6636fe4ba3p+10), C_(-0x1.410473daba291fd610d9e089e60fp+10), C_(0x1.da130c42857b78f659a1d6303558p+9), C_(-0x1.d701d7e9133134b0f0d4fc7eec0bp+8), C_(0x1.63319398a8ba44714204cc51ebfap+1), C_(0x1.103c991a3daa09809634b6cd54c5p+8), C_(-0x1.27d3d6e7fd9bf2dd1ee7850f5b25p+8), C_(0x1.603f483ab97e5aeba0d81de20a75p+7), C_(-0x1.d0777f2eb89143bc896dcbff61bbp+5), C_(0x1.7a787d5d8610ba8dcf36333d8bcdp+1), C_(0x1.ac67a9959292f75e5874c7846e26p+2), C_(-0x1.90d4180a252c7e521492da4437e6p+1), C_(0x1.1a35f9399ae687cbbdc99928434bp-1), C_(0x1.6227b50ba315edc16940995bb21fp-6), C_(-0x1.88f3b956f9d0dbc770c981dd72f9p-6), C_(0x1.6aef03d1b7b80f64bb2a7833284p-9), C_(0x1.578d75e3a79566687a46c7635dbbp-14), C_(-0x1.6111d8865be635c9573ceef437cap-16), C_(0x1.98ae70f64468f801509511411944p-23), C_(0x1.ab515975e313ab940af4e8bf9f79p-27), C_(-0x1.5c32c92bf479e396733399534bacp-34), C_(-0x1.1971da66bec91c38c535f903a2a2p-47), C_(0x1.4b1b6c4a0c92ce2876a63b480607p-56), C_(-0x1.3b3d574a043e2a3cf8b53ffa3decp-78), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a2b24d1ab719647b6a1c2ecf4af6p+1), C_(-0x1.c90129239b0561ac21474fdc1f01p+4), C_(0x1.cf2e00eaf4f0becc29975ebbb3d9p+6), C_(-0x1.2500bd3d88164480cc94fa086f38p+8), C_(0x1.077598d26b6930fe825f3677222p+9), C_(-0x1.6c0faa52dddafef24a3684f97c95p+9), C_(0x1.958eaac6820db16ee26374b84f58p+9), C_(-0x1.6c2fe2006b51236b8cd28d2a3376p+9), C_(0x1.b8f7517f01d05ad3f5b4ba6c9b6ap+8), C_(0x1.7e41eac4aec61876fb9933392dbp+6), C_(-0x1.a414506f1749a1c58305f0247915p+9), C_(0x1.8a42dc8d7e0c984036d44acf6da6p+10), C_(-0x1.fc70c5eb750631dda8bffa5c2966p+10), C_(0x1.078cc6f7751312b231c8496978c6p+11), C_(-0x1.d83a569460166e52313ff6ef2cdap+10), C_(0x1.72db6cb15cd72ceb44fc1391ca0ap+10), C_(-0x1.e3a6df319fa13f73a1becc99c1bp+9), C_(0x1.cf3b0d7df18f715bb39783adf96p+8), C_(-0x1.d51428e901c215eaaca0f201c961p+6), C_(-0x1.8c56c880ec38034e39c62c6aaf1ep+4), C_(0x1.2c380f5e865da81b223aaf9ba893p+5), C_(-0x1.fc04081d34cedd56a87f6a93c47p+3), C_(0x1.67cfd3a1ef5c6955d5156ad19fdfp+1), C_(0x1.9005cc81fa0dd8ddcb0ef2e368cap-3), C_(-0x1.6895dc001e228c4142a65a949d43p-3), C_(0x1.82652a80425786d395286ed1c874p-6), C_(0x1.2598eb52540c582b66a388a574c1p-11), C_(-0x1.f931a276c55e6702f13f4d2ec79cp-13), C_(0x1.dc668b4d899394715f65f547aa0ap-19), C_(0x1.b4c7dcafec63006d515f9533babdp-23), C_(-0x1.cb6cdde84a22b96a4fc307092c49p-30), C_(-0x1.f612f7790e7dfcfca6facf9edd4ep-42), C_(0x1.b3f84ae9c3a1d3983026d3d5d97bp-51), C_(-0x1.9f1407c19decc2d85cd5ba63de83p-72), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bc1bbb932352fd4db217186d8038p+2), C_(-0x1.230220e94a6286e3ccf38d4bfcecp+6), C_(0x1.65729881a37a4e3a6ec39c0b03abp+8), C_(-0x1.146d11d32151befbe03f1861632dp+10), C_(0x1.34072da363b055ea4712dedb9e79p+11), C_(-0x1.0fba655ec8815d599296c7fe289ep+12), C_(0x1.9a1825ab277513bb221db58c408ep+12), C_(-0x1.16b4a3d0368f557cee02ea790ba7p+13), C_(0x1.59fb20e260f209444967e6c1a575p+13), C_(-0x1.8532af6245b8a37a5135bb9a8819p+13), C_(0x1.8c055ef648911dec2e20ac309451p+13), C_(-0x1.70169a3124976f7442e92622f30cp+13), C_(0x1.392792bc1a4318354c951213b5c5p+13), C_(-0x1.de2062219056d64d01622237bf5fp+12), C_(0x1.3e37823e9c9169638076f5c7aaebp+12), C_(-0x1.691be2f943c22d4422f81e97a65cp+11), C_(0x1.4b463c6bd400a0ecfedd95ba90c8p+10), C_(-0x1.5fc2af1919c21f21f19a7f30b116p+8), C_(-0x1.286e81ad3c5d4bb15d987b1d1575p+7), C_(0x1.11137fdb9735b4b7b7c77d4bdac5p+8), C_(-0x1.749f8e79c1414c37972b9280e062p+7), C_(0x1.1b06a540d8bf3d4241ae8a187538p+6), C_(-0x1.7a50c04170b90bf05ecb290f9376p+3), C_(-0x1.b0c80bbf87c7b0afb3614e48c05fp+0), C_(0x1.32db8166dd6bf259ffbc02129a89p+0), C_(-0x1.78bbab19bbfce1e222ea4ae4ebc1p-3), C_(-0x1.6be3931ec3a0a0f934055bd32184p-9), C_(0x1.4cb7ceaf89c2bc6ca23b4de198adp-9), C_(-0x1.ec1ff5f12b99a0b5484713b8896bp-15), C_(-0x1.a28eed0313308b4187f5c957721p-19), C_(0x1.1e4d1afc4f213777086c26ac990fp-25), C_(0x1.2e933ece77f3d4f12785b9380e9bp-36), C_(-0x1.0ed8efcca12869c8a8420946c2ebp-45), C_(0x1.01deae8b7334485f38756e42ddc9p-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7d01eebdfe55fe3c6ed21587d92p+3), C_(-0x1.0e862c8ffe7ff18db1f4d0d89561p+7), C_(0x1.6068e5f78cc3a3034b49cf000d6fp+9), C_(-0x1.16e27e80bfe67c3ab640b5e1ecffp+11), C_(0x1.2cfcdcdcf07c3d87dcfc36a512dcp+12), C_(-0x1.de03a2d7212d303b5f3943016437p+12), C_(0x1.2ec8864cafb19603887a2d7c4703p+13), C_(-0x1.500683f99e667a964beb950c1258p+13), C_(0x1.545745c7955e4cdf07cc034c2854p+13), C_(-0x1.1c5400071f26b6f894c12a7b3f37p+13), C_(0x1.16dc653d8bc1d4bb36f214e1e20ep+12), C_(0x1.b4ea0cf6f0a6b2f781cf9163eadfp+10), C_(-0x1.c11dd36c4cf2a48e63345a744925p+12), C_(0x1.5827531f986387c8025c0b0f20cep+13), C_(-0x1.a3de245f7e97f4c57daf304b115p+13), C_(0x1.b4f7e9a0a0606952656f83a68277p+13), C_(-0x1.7f2cf0b4269dd38dde070b5f0cdep+13), C_(0x1.2042e1dec45f6d9e8ecdde4d30dp+13), C_(-0x1.84b7d120c9be3df99a52bbd8cee1p+12), C_(0x1.d5a3bb45a7db2c787108d4dd50f2p+11), C_(-0x1.d06f9035faa5ec088975f115cd7bp+10), C_(0x1.3bba5a0006ab829f47d96569222bp+9), C_(-0x1.633fc40d33ceb334ddc3416213edp+6), C_(-0x1.ea064cf26a80ac52af3e7edffe55p+4), C_(0x1.228bc38d7faa44c44536bc6e393bp+4), C_(-0x1.94763b8fc894319c6a4baa13397fp+1), C_(-0x1.d3df039dfc19a1e9d51d6ee6175fp-6), C_(0x1.e63bf96d77b58d48a45fb3200bfap-5), C_(-0x1.0df6f4a0b44ee3edfa91f00b193cp-9), C_(-0x1.be80af96687fddc94510e8ade719p-14), C_(0x1.a12b7b548061ec0aec1afee7ffb3p-20), C_(0x1.557c0a8693ccc679320f886d948dp-30), C_(-0x1.894221980c4b8d10bc7e6d5fc51ap-39), C_(0x1.766b6e3ec237c8c757492e2c2a6dp-58), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a6f23ff482d2a8534d18ee2bd813p+3), C_(-0x1.37e1afb1392b3f40934da3d558f9p+7), C_(0x1.a686ad1a0ba3db778ce2719b5c95p+9), C_(-0x1.5df1b3980b353a49181f807fa276p+11), C_(0x1.912604b6b386163aa8a2a506984fp+12), C_(-0x1.5b61ddc6ff3217136a743b9c2999p+13), C_(0x1.f0e6d62d6c3adad4499f950bdba8p+13), C_(-0x1.40b6eb16bb3fcf7bbb403448e39fp+14), C_(0x1.87585fcb881fe424c96217849318p+14), C_(-0x1.be1e3f54a4c6e6b54ffcceb8221cp+14), C_(0x1.d1d8cfaa9552876a45180bcc50b2p+14), C_(-0x1.c1cad55e0d499c75b90a8681896dp+14), C_(0x1.98c3ae43fe1125e958f8e677c61fp+14), C_(-0x1.5c4d34f8b772415210663ccb0834p+14), C_(0x1.12a3aa37e5fd016d4163c33ef0a7p+14), C_(-0x1.9192f9cf12c8db367f3be99603f7p+13), C_(0x1.1122d052f1ea79533169d18075p+13), C_(-0x1.52bae1043f73d75aa63286049566p+12), C_(0x1.74a03155cefa742f49e86547448dp+11), C_(-0x1.690be5335ae783047d5d4ded6084p+10), C_(0x1.2aa92592f4ea4eab6ee72559722bp+9), C_(-0x1.54e703590f43bf9834fd6d7c3fcp+7), C_(-0x1.eedaac4f8962ad088ff79f7ab717p-1), C_(0x1.de050411f7cd568eda13f525f9dap+4), C_(-0x1.c148def3b49e232ee4958ee9fafep+3), C_(0x1.48e1be6a547f7c0d38d3ce51af9ep+1), C_(0x1.ccb6f2024dedfd3e23939d6e234ep-6), C_(-0x1.0b11a0ddf9bc2847e1d232a914d5p-4), C_(0x1.f0397fd92ef550872efcf8d934adp-9), C_(0x1.723cd3b01432ce7970852fde484dp-13), C_(-0x1.ed12536f5e4f2788058dfbdeb7b6p-19), C_(-0x1.6aaf317d39b56dc9439410fb90dbp-28), C_(0x1.cd1c2594785771509fd29eba3b57p-37), C_(-0x1.b707d969a42cbded13543076b42ap-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9908fd0ce831f3487747d933d748p+3), C_(-0x1.3339176496abd2cc6f353a6e44a9p+7), C_(0x1.a399ad0400dbc9e71dafc101d1e1p+9), C_(-0x1.58f242d223982437163d99490d3fp+11), C_(0x1.7f8e29aa27ab125f24d2fcb7cf63p+12), C_(-0x1.38a61979e2b2ffe2ae4d4e65fc71p+13), C_(0x1.9add7b4a18f5c8300bd029e80d54p+13), C_(-0x1.ebee387c8e0aff52186a751f53cp+13), C_(0x1.219cbd1b2da3c7319d2594cddc32p+14), C_(-0x1.42ee71a32a848700929a8801a23fp+14), C_(0x1.4162f4284633fd1e7fba1bb3800ep+14), C_(-0x1.21467722a3c16c9f70c4e0f39397p+14), C_(0x1.f02472a8506fd3b8d32f77a4b8f9p+13), C_(-0x1.93ab7dcd5a6c14300ddac86b8dd8p+13), C_(0x1.26e6ca1326b3694ec43b05b1dfbbp+13), C_(-0x1.7e6f2ae54bf7f66077fef1175708p+12), C_(0x1.ca344102205561eaf28babf9b0b3p+11), C_(-0x1.ec7742f47fb3351081ba5a5968b7p+10), C_(0x1.8bd38bdf87a320af9a5418399e9fp+9), C_(-0x1.1acd500cc5943718da806ac7add3p+7), C_(-0x1.4d85442446456020706cd509b723p+6), C_(0x1.ed6ad17e0f78e02531c1a4770ad4p+6), C_(-0x1.b2f4089457d680f06bec3c3dd972p+6), C_(0x1.0c247d783695e3ffa9b901ecf60ap+6), C_(-0x1.9870dc8b45a9f4e303e8e8311b4ap+4), C_(0x1.3338d9a06d3fea3c6e122fc7de4bp+2), C_(0x1.0f6ca08ad5fae6b6177d3fc4323bp-5), C_(-0x1.4c4e08354cb7e3eae0ddb198440bp-3), C_(0x1.02d3a75dac8a719338fdc8517e15p-6), C_(0x1.7509581763d127e7d21fa4b754b1p-11), C_(-0x1.54ad634865cc13ff2aa8e2b2e8acp-16), C_(-0x1.7ef1d65121e030d70caf398558e9p-25), C_(0x1.3b877c4e5003312e2d376dc10e97p-33), C_(-0x1.2c6f23660e48f98694d796524bep-50), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e6c2b226df78c279af13845051c3p+2), C_(-0x1.70ef0a94afa59b1a6aa8d2343645p+6), C_(0x1.fe115e7fdadc37c38b9e6da89457p+8), C_(-0x1.ab2ae85d8df6a5fa4cff025ed87bp+10), C_(0x1.e9076c74293a400016225b9ca839p+11), C_(-0x1.9fe839f33e758faf5bf246ffdc45p+12), C_(0x1.1ec83a83d597d7f150637077f9b7p+13), C_(-0x1.61f4e1f4fcae3d0d387b625dac79p+13), C_(0x1.a34037eb93edf57ca17d98f692cbp+13), C_(-0x1.df1d808eb7eddd0fc723f047f0e5p+13), C_(0x1.03261bb811b49bff52d5b3bd37b4p+14), C_(-0x1.08bec2cb9bb5325c84c6514f4d44p+14), C_(0x1.000c9dcb7996cb96b43e3d1c9772p+14), C_(-0x1.d42c4b6e482399636855cedb1712p+13), C_(0x1.9723de14cea5319a6860bbd3c799p+13), C_(-0x1.524bda96018d06eb97a9a94efd6ep+13), C_(0x1.08b8d63f8a5e0d7a39871bf89f73p+13), C_(-0x1.81d1060b61d0d3635b17f5b8f829p+12), C_(0x1.09630f3565a574b943c123a6bfa7p+12), C_(-0x1.59ea297354d075bf6b0a4b01f032p+11), C_(0x1.9c7ad6ace2b3cf85fb948aa7bdadp+10), C_(-0x1.b6b7705751739945f7c51d7dcccap+9), C_(0x1.aa6416006d3250b9dcdb9d2790c7p+8), C_(-0x1.7918296878e4f9853df6b6e8ae14p+7), C_(0x1.07145b6ad1daf57366d1625ece2dp+6), C_(-0x1.a108d75d6bbaf0652587e828bd3cp+3), C_(-0x1.33d485acc9655e7d88b74e802f9ap-2), C_(0x1.6d6fa9e91b92d2703b87421f247fp-1), C_(-0x1.78a5b635c316b5bfc318d4eea976p-4), C_(-0x1.16db8d9d41de38829032ed627d9fp-8), C_(0x1.9ed47b91da7177bda1e64cfb1175p-13), C_(0x1.dd448a5da4eed2af5748439dae43p-22), C_(-0x1.7fd3f33da284c2945eb532e858d6p-29), C_(0x1.6d7f73f5c3ea6d60bfb8d1a80ec8p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.34875227fc78d9ef7ed7ac6e0f82p+2), C_(-0x1.d5cd5efb52a9ef14597d82d198bcp+5), C_(0x1.425dfad9b492e41845300927f3b1p+8), C_(-0x1.06c373fbafad1222f880762e04cp+10), C_(0x1.1b9bff7a51e187819c73161a78e1p+11), C_(-0x1.b244eac1fdcf0d5091a23ea449c8p+11), C_(0x1.01eb21ca101f022e5418621b2a9ep+12), C_(-0x1.166548c799cafbaa88fc763d8453p+12), C_(0x1.3b0ce98f7e34e32ea84135429657p+12), C_(-0x1.6362301a242eb8214208b870faaep+12), C_(0x1.65cf7c0d7f65c5008737a94a5fecp+12), C_(-0x1.4657f8cbcbde3d6a4e18c8e9c05ep+12), C_(0x1.24d7d2cdfa25a491f828221544bcp+12), C_(-0x1.010708097c75d2ac6e322278d08bp+12), C_(0x1.9d020a4459bdeb50b979470ee77dp+11), C_(-0x1.328cca6ef194279a5bb009ec9338p+11), C_(0x1.bc083519c657836208142c7eb836p+10), C_(-0x1.32ef111f54699b431e478036157dp+10), C_(0x1.7f8dca23d339c29569ea2ec801c2p+9), C_(-0x1.bc6a63cb2fc0846b3e6af0f884aep+8), C_(0x1.f09b702a78c4dd679fe395dd6a7dp+7), C_(-0x1.f532dbb546bbac5b183e2380610fp+6), C_(0x1.ab4ca1b61588ca9a0a6f9d915ea4p+5), C_(-0x1.463ffdaa1065322e64ac74f7fa8bp+4), C_(0x1.ba4ea70cee33c38b2b0e8b20a1aap+2), C_(-0x1.3f8f23678b563eb9630f6042805dp+0), C_(-0x1.2f5a76f330866b9d02c88ed42bb5p-2), C_(0x1.a0cbd7080604e3774928fed42dbdp-3), C_(-0x1.d523cae4ae400c2fe3e190e83e84p-6), C_(-0x1.01b8eb0a5cba7579162a23c9063cp-10), C_(0x1.02b9e23339b17453717d89dae4c9p-13), C_(0x1.5122002fcd3e4c50886af50f4453p-22), C_(-0x1.dca9566b2b5e33d63760b950eda2p-29), C_(0x1.c5fa90ac19cdbed6fcc50c677b98p-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.095a4630f25b345edb3a033429c7p+1), C_(-0x1.94f72d60a79651db24efb743df14p+4), C_(0x1.14fec0291d4b12e7113f25067be9p+7), C_(-0x1.bdfa0b6be593ce00570a7078fca5p+8), C_(0x1.d39577b7cad7e7c4fd5dbf90540fp+9), C_(-0x1.5193ad0b12f066b4cb0fcaacb204p+10), C_(0x1.6a2e0f056a38f1473da552dd4715p+10), C_(-0x1.5d0e503eeaf62b38a4d6937112eep+10), C_(0x1.7e6b7f3178684900694f3b8c2fp+10), C_(-0x1.b6360679ec82c511bf5718cad79ep+10), C_(0x1.ac545c0c739641a55bb4e4c80843p+10), C_(-0x1.6be3874eef6d1f1a32235a12525ap+10), C_(0x1.3c4c888cb63122525397dd653d36p+10), C_(-0x1.1879194795ebee18032f4a91a091p+10), C_(0x1.b5e083426b3c7c6a910b26a6198p+9), C_(-0x1.2f24fbf8b03f0944b0e6672a17c2p+9), C_(0x1.aab5115e884dc181977e8353a09cp+8), C_(-0x1.2726385d133e4a16d05b604abddfp+8), C_(0x1.59979df7b75e1cc96562d4bd910ep+7), C_(-0x1.65732078d27eb27f5ae5d7879665p+6), C_(0x1.7f6def467b5364cd233fba2c5a55p+5), C_(-0x1.704ee2b3997739837bc58d39a41p+4), C_(0x1.cc5ee35ab0ad93a46168320cb92ep+2), C_(-0x1.50976171160a6dd2e2a17268b2e6p+0), C_(0x1.f9c57fa6a287f2b26fe11e313d13p-4), C_(0x1.64b2a171f9a1261fcd30fc5b5dfep-2), C_(-0x1.998a031a0009070455c3c0080416p-2), C_(0x1.57c1f71aec6cd09bc7ae16b02e75p-3), C_(-0x1.b25ef4a8ceef29ad7df2d5db7234p-6), C_(-0x1.808f4aaa023730c43464ce0d9251p-14), C_(0x1.d605bd7dd6adec51bc920eb90a32p-13), C_(0x1.cf1c89541af51d642527681f35ep-21), C_(-0x1.a94329286bdc4b6164f134153d1ap-27), C_(0x1.952b6e764f688e496b665b4266b4p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.42660039f1e4ab1b56c2e8881a0bp-6), C_(0x1.ec93c1aa5b61c9b6d5696151fd09p-3), C_(-0x1.97ce26c5b170acf42f1f93361a05p-2), C_(-0x1.c01099aa543ca8b825e143b557bap+2), C_(0x1.a4014de9af920ed4c9ee54928ddep+5), C_(-0x1.6ded0cd4cc8b853b87bfbfacc025p+7), C_(0x1.8330f0dbb0c28dbf63333311ac1cp+8), C_(-0x1.0c893c9ed1485a74e7f7800e12b6p+9), C_(0x1.052ccc4345d2df5a1dbe6873e028p+9), C_(-0x1.c1974852375e5b099cd67d213452p+8), C_(0x1.fad23c454fb6519a66669891ce2dp+8), C_(-0x1.3ffe274228465c9afdc401f4f0f8p+9), C_(0x1.4635deb84c3cfd97dc985dd6672ep+9), C_(-0x1.19ba20aba1a1dc6b33ade2534e4dp+9), C_(0x1.065bcb209e9694669a116f8f1c4fp+9), C_(-0x1.015ece212696c91b2da16a54aabdp+9), C_(0x1.b4c17c7bd409b3d1eb496cf9d8c2p+8), C_(-0x1.48c8d9ca7f31bb244453a83bed84p+8), C_(0x1.008b40131779b22fe5ee591e5e55p+8), C_(-0x1.8c6185bde00310328e2d72cc1f71p+7), C_(0x1.08d51505255015c001174081c04ap+7), C_(-0x1.42df3db9c4b2e8aa91c152e2460ep+6), C_(0x1.93d8682a099131f2e30d1893505ep+5), C_(-0x1.d72aacc75787dddd2538f4cd11fbp+4), C_(0x1.c56cd8c23773878de5456aa0988fp+3), C_(-0x1.8c843e6f10e078b693975b9ceec3p+2), C_(0x1.620f8bdb46e5d416d1abe187fae9p+1), C_(-0x1.ff5dc9ffbca3cebcb086bd21ec14p-1), C_(0x1.8dbab0e6a8c888a4a8c14551861fp-3), C_(-0x1.14fd9c124f34ee1806a1877b89eep-8), C_(-0x1.8d698e7a70351fb6b69fe98cc8ecp-9), C_(-0x1.922f4b831ef6074ab73b0f88d222p-17), C_(0x1.661caab697dee3a1ab3a4d24609cp-22), C_(-0x1.556f58a6ea91cacbb7f565948433p-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a102d4874492bf0c3f8abe5216a6p-4), C_(-0x1.3ebe78df84aaa4d0f4b794efc132p+0), C_(0x1.b2f7cb5502cda6c9d230fef5216p+2), C_(-0x1.5ac9e38bb117840228ea5f0969e6p+4), C_(0x1.63176aeb8932d6ab994905b6314fp+5), C_(-0x1.e61b7010df60cf6c4ad892eedae1p+5), C_(0x1.d104bdea5563bcce7c191c344f3p+5), C_(-0x1.7544f2a572dd637b67c83e625741p+5), C_(0x1.737d5aa77938e2318fbe4c3f84c8p+5), C_(-0x1.b1c6edf1bb3236287638385af6a1p+5), C_(0x1.9f0c5397c3faff6479945ec39ad4p+5), C_(-0x1.47ca4941183ccf73d74cc2ab091p+5), C_(0x1.1a93e6543e9f9a411108443c7824p+5), C_(-0x1.0927206f45006f2abe266610514dp+5), C_(0x1.a5f0e2f2d0b54c0cfa24d939192fp+4), C_(-0x1.2685107a4162e669c1fad19a69ebp+4), C_(0x1.bed6d3109a358fcb040f5e21b4d9p+3), C_(-0x1.52c12c07acc0e1d274e7d45ba9eap+3), C_(0x1.af31110ee1468e10bf21a15fab4p+2), C_(-0x1.02817ffcabad7fa52399e99ae606p+2), C_(0x1.4e0f916d4e048c57bf43251d9d88p+1), C_(-0x1.864c4e83e1764ac0ffdca7b484d8p+0), C_(0x1.7f1784ea638898f647b4e2787299p-1), C_(-0x1.8002ee89d7986397c24beb3e4ecfp-2), C_(0x1.7fc7499a09e8924504cfc808759p-3), C_(-0x1.2bfa08732bf79ef113f03ba38535p-4), C_(0x1.957da4e89baa41a793f6e28cc5c7p-6), C_(-0x1.2aec3447b7aecf379d17702dfbdp-7), C_(0x1.266385cc4f62510ab31310cb9e9ep-9), C_(-0x1.c0dfb99a8ea4dbba7703d245fd43p-16), C_(-0x1.1928369b116813aa42a010ac694dp-14), C_(0x1.2017f1a37d1405b50e30d1eabd65p-23), C_(0x1.0f4800b7b0a184fe6ec7608004b6p-26), C_(-0x1.03044a0f4ec3952e4f859c26c44fp-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.302549bcac16a07480ffb58950a4p-7), C_(-0x1.d1147836a22995451a237d2c571ep-4), C_(0x1.3c7951e94efea5a01e74ac179967p-1), C_(-0x1.f485b5137068e2de7e3ecadb998fp+0), C_(0x1.f6c9c4f20d2e109d726d9bfa2ad3p+1), C_(-0x1.498acbc4ea72d090f910303e1e3ap+2), C_(0x1.1d9755d014c869b79bc13e22f12fp+2), C_(-0x1.81525835d067c01df39c6d7268f2p+1), C_(0x1.6d720e347fb567a21392b49f69f3p+1), C_(-0x1.cedd19de5af2aa41ce8142ac49bdp+1), C_(0x1.b162c910bfde4ce0f673ec48bfa7p+1), C_(-0x1.2aa74c52348af8100314f0e62e0cp+1), C_(0x1.eda3d295893e868bfb35ec305bap+0), C_(-0x1.f7973b0f803ffd6ba7bc4f61d739p+0), C_(0x1.87d55f9f1654529cea30f503f524p+0), C_(-0x1.e3314a61cec2d1ec8852d0dbcec9p-1), C_(0x1.712067be057e009feff90d8198e8p-1), C_(-0x1.2d407bbb0b0ac1aee45b8cabc16p-1), C_(0x1.675f9e5eb7de518e9bb7430a57b9p-2), C_(-0x1.80b747814ba27c7cd05f743f5455p-3), C_(0x1.0a57b0f3cb83001cac6acade9288p-3), C_(-0x1.43510035a93ea4e9f4f0330f9b63p-4), C_(0x1.135c54f340512b998224396e7637p-5), C_(-0x1.042576d3101c9bfa2c3ee11498b6p-6), C_(0x1.28e7b29b5a905feb407256a997a8p-7), C_(-0x1.b45ff7bd1d15c0d666ce33e8722ep-9), C_(0x1.b09f4241d30f170ec83bd736891ep-11), C_(-0x1.7633994bcb363452031c0be60442p-12), C_(0x1.d2f415013436fa877d9f51f3a238p-14), C_(0x1.16fcce8bf9664ffcec318d033322p-17), C_(-0x1.f9a19b157868fe73cb52d3d8f794p-18), C_(0x1.555633d592e52d8c981188aedf8fp-23), C_(0x1.285fe2167b5b4b96d89f7083a8a9p-28), C_(-0x1.1bc8f87104551fb246bfa29e3c89p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.bd717b66e1d1d4d95ba3c08947dep-7), C_(-0x1.7b9fec6bb92af42e63e2e68ecca4p+2), C_(-0x1.1ead339bb1d44833388375e63d59p+7), C_(-0x1.012ddbc7bca1e6101aa1cf5d564ep+9), C_(0x1.c0b75070f83e37ada47fd8928c98p+3), C_(0x1.981856bff215b594a8e4e5f86ceep+6), C_(-0x1.7b31c06193f3e30ac8e863c6933ap+6), C_(0x1.e4866be11fb72b736fa85f578e21p+5), C_(-0x1.c461c239dff802f2348bdb864e24p+4), C_(0x1.d13242d9fb5ff5fac5479a566994p+2), C_(0x1.e6f4964d6a03d0f8158833051b6ap+0), C_(-0x1.b2b5fa84ed5bf72597a5eb232c95p+1), C_(0x1.0717ba30154525a4b9eaa944e41bp+1), C_(-0x1.7b72f81fcc526babbc7b68ad5d28p-1), C_(0x1.3a477558616d24c10f1dd99cb0c4p-3), C_(-0x1.9b911968d13ed312bc38bac2906ep-7), C_(0x1.631172e87e301114011b41a3b8a9p-10), C_(-0x1.1b6a6db603dde402c2223c4221d9p-9), C_(0x1.a5c80b0f2bc5bc3b3f1a94740a37p-11), C_(-0x1.702b73dc1bf286d5e095a7a0f5a4p-15), C_(-0x1.2e802f058eb73ef9b14848780ecp-15), C_(0x1.f461fea3bf76e5a0a5716d49933cp-18), C_(-0x1.978d16c26c68ef616764f83e76c8p-24), C_(-0x1.13d7c474d8cbc6770c364afcd753p-24), C_(0x1.1119bb3fe775e15526c923b289ap-29), C_(-0x1.8685450351316156519237add64dp-32), C_(0x1.fbf3d2901e1ab81addb9d152dd5p-42), C_(0x1.0ebded1ffbce50e958913e490b72p-41), C_(-0x1.8b6af637a9f31fc837c7aa02d1f6p-49), C_(-0x1.a0d4564bf2dc66611a174850c89ep-56), C_(0x1.74b661da2714cde7309e3860bc9fp-66), C_(0x1.5266f1077241c8b5ce693870559cp-77), C_(-0x1.60eccf731ce43024be7a209a4a5bp-94), C_(0x1.5002d3b2c3d4cf65f716a68d3eb6p-122), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.640d0cbfb34edc433e3c265970b3p-9), C_(-0x1.26ee7a9fef2f3cd66764d9f94d81p-1), C_(-0x1.cb77692ba61f4bed97023b434896p+2), C_(-0x1.7a52a3b4a77c5125cf118ae57d54p+1), C_(0x1.3d35a908c4d29476ad845269a92ap+4), C_(-0x1.eed0bb7ffc728b5021c0dd7f402dp+3), C_(0x1.5b446269f85399ef36e0a8f67578p+3), C_(-0x1.e860777819bbb58c5f71ba40875fp+2), C_(0x1.459d6005ddfc2d02a2fae3fd310dp+2), C_(-0x1.7cfb6d6fe6c7981796f3f294d796p+1), C_(0x1.6d0ba0eba8694d88a64c51b8f50ap+0), C_(-0x1.08e91d938b8389f5f0add295cdbap-1), C_(0x1.eca4948d0008e456bc9d67c81d75p-4), C_(-0x1.d06140d0577a1b263782da58dca4p-9), C_(-0x1.7297d215124a9ff8bc7627391918p-7), C_(0x1.862feda5c0e0ac9dd17f1152635dp-8), C_(-0x1.d3aeeacfe9c70326d1fac582acbcp-10), C_(0x1.15a5ade831e782a4ffc3bed5638p-12), C_(0x1.48236580a81473ae0d83a7ad5bf2p-15), C_(-0x1.c4dab80b872dfd428813332137cfp-16), C_(0x1.912930341a4fc5b6071d5bc9b09dp-19), C_(0x1.74839b9d5596fba97dd8392c7187p-21), C_(-0x1.f7937244a115a288dc7cde59188p-24), C_(-0x1.ef0ac8df8a590687cfdcc193b466p-27), C_(0x1.b60aa56de0f8813393124e0f539p-30), C_(0x1.4fe56c11057c7023ec8d56f2bd84p-35), C_(-0x1.2b1ee6f947a6f09f111f53e08b99p-38), C_(0x1.904f2b23e480ded5004c9a3b2081p-44), C_(-0x1.1a491e89e84c1ae1ad605792ed65p-50), C_(-0x1.e6f7ea660d39c7595d9913c47738p-58), C_(0x1.68bf338efe90278676de17896db9p-65), C_(0x1.ec3578649519ba8d72287ee8e375p-78), C_(-0x1.56c2062f8a091fe577e9571b2417p-92), C_(0x1.4654c88c71974e3c9f8fffc52861p-119), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.07725ffa38e9ced625cca68f3f21p-17), C_(0x1.418c13eff61cbb3a021569097a1cp-8), C_(0x1.3da46890dd9a0a4b666b663d4aa3p-3), C_(0x1.8a2b52a78c79acb029ea1b6db9aep-1), C_(0x1.1a351fcd80743de548c177ab2074p-2), C_(-0x1.854589d6ffe0f67b9ae39f8edb13p-2), C_(0x1.33e4c9737dbaaadf26763db4b5edp-2), C_(-0x1.aa815b6478cdd9f02d23c8d18fc1p-3), C_(0x1.087553137f3f92720c562745af4bp-3), C_(-0x1.1923520d0b86878b50e3a0765033p-4), C_(0x1.dbed9e8e6653062b736fe52ecb07p-6), C_(-0x1.13641cf1379f43fd1c7ac3bc71edp-7), C_(0x1.6875bc1af4453d3d4e0df0f5de38p-11), C_(0x1.a947dfa3688a3625b782cb79509ep-11), C_(-0x1.10b3493092979555022e5756e4f3p-11), C_(0x1.739af28e775c2a9c036cd7599ca6p-13), C_(-0x1.6cbb4a08c7eb5fe8237038a25da7p-15), C_(0x1.409e1bccbf4ef7d2793c14591929p-17), C_(-0x1.b4b5ec00d923dbc2091331f8dd78p-20), C_(-0x1.0bf29985eecde4627b6e6f4c0369p-23), C_(0x1.687a642b13ec01d769b15bc617e8p-23), C_(-0x1.137b64e3f44e9fdac7b535f30d85p-25), C_(-0x1.07f0606fa0dbad766d3197dd19cap-30), C_(0x1.6c85ed37d47e7b904cfd46760581p-31), C_(0x1.e0b71b0ad278ef564d1fcf1e88a3p-37), C_(-0x1.c7f3c451c06bde44cba8b0964cfp-39), C_(-0x1.3e734cfafd184d570a4dc2808fb9p-41), C_(0x1.ce28f04bbb94c603b91b46462315p-47), C_(0x1.70c276923dc2ecdd8f158e1477f7p-51), C_(-0x1.79a58db93f5236bb350459a10815p-57), C_(0x1.1f5027aac86b8e122cbfaf41ee62p-65), C_(-0x1.02276c5db8038c6bd4e95867d18dp-70), C_(0x1.254876c157537023d202fc646803p-80), C_(0x1.01c1badc280ce855150f875fe27fp-94), C_(0x1.81b6379c836e2bab36a7efba81e2p-110), C_(0x1.fb9eccd49ecd0870d19d3ffd447bp-140), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.32ea938ba90f99b6837f5af63be2p-14), C_(0x1.6ee1bf4cf707539d522967930e11p-6), C_(0x1.8a481c471691e9b156b25ff57636p-2), C_(0x1.0b4f5688ae00b19fc1e160cf6648p-1), C_(-0x1.73e1ddbd7901f6383d61c3a6ac0ap+0), C_(0x1.8b33bb402f96e0732af30db90eddp-1), C_(-0x1.9843e3061a5286745b1a22aa34f6p-2), C_(0x1.174b1b1b9671399a52d81cce6671p-2), C_(-0x1.d5ed9bfb0b3eacb0609851530eccp-3), C_(0x1.7f42427dbd66dd7c640694ddac63p-3), C_(-0x1.08eb5567536606f98b744fb38775p-3), C_(0x1.23d363b3776e341b922f685a5527p-4), C_(-0x1.e3311fba2b6786652a72b9017675p-6), C_(0x1.080310d541cbc7b415408ff9e9e9p-7), C_(-0x1.70478a76493e219892885c932ab3p-11), C_(-0x1.0307c808a4ebd5856963c5fffbdfp-11), C_(0x1.dee4ac1d99b73074451ae5f38c64p-13), C_(-0x1.44f6514c266093c947d073730317p-16), C_(-0x1.25e4b5de72eb99eebb1451b05b03p-16), C_(0x1.d4b5838001d90ed04674ba339f05p-18), C_(-0x1.0c63aca94f3b9788d5e3d0094dfdp-21), C_(-0x1.5d75636e21f07d7a3381c79d0362p-22), C_(0x1.731d5b5d003f55b6876fe0044ec6p-24), C_(-0x1.0c3e8c9e77afbdab5c815392ec9ep-29), C_(-0x1.add3791299db3c378e9de40e8a64p-30), C_(0x1.06fadabb3956eae25696a4f51f5cp-33), C_(-0x1.f4ce18079dfc9d6929b9dda1612cp-42), C_(-0x1.2eaa27d46e548153d91731a7ee6ap-41), C_(0x1.ae2bef5a0c85a05297e337e77b0ep-46), C_(0x1.4bfd5bd67de9ea53ad7c40089635p-54), C_(-0x1.1d671c704d7fca69eb029e029b5ap-57), C_(0x1.67963d56e9a972fedce141425dcep-66), C_(0x1.0b2bba52e426ee86c81ee87efd7fp-74), C_(-0x1.835ebfbafcc994f81e5e17cf300cp-86), C_(0x1.613768a516da5440f559a8b7229fp-103), C_(0x1.d0dabcbcf214e8044829d82792bcp-132), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3f4897070d099352fef182a2ce17p-11), C_(0x1.6d998ddc083bb79599bbcdbf5aabp-4), C_(0x1.5cdfd95e7a29056f595ea6b04d0dp-1), C_(-0x1.3be70bab67dce74ec0a3fcb7068ep+0), C_(-0x1.4f0043bcb070f4a9035f0cb75f46p-1), C_(0x1.3f5cc039811e2b5b41e1339ce191p+1), C_(-0x1.435a201615b7649bde7e6bdcd35cp+1), C_(0x1.edddf036bb21e05065a4314b8003p+0), C_(-0x1.339bd26a01d7b24e4a113345801p+0), C_(0x1.26ea186703fa7b37f25c2df1ffcep-1), C_(-0x1.62a5bd05e71620f3397b8b55cadcp-3), C_(-0x1.8157fc40373b6ffb1b755d5d64ddp-9), C_(0x1.2626bd14128e3600ff5e4ef117ddp-5), C_(-0x1.458d354bc66bca085d03a73908bp-6), C_(0x1.60eb38bd6dcb5883ff977a13b631p-8), C_(-0x1.11a579a9f60ad1f4e34335fca023p-10), C_(0x1.8521f25159bae6c124f05e0aa6c8p-11), C_(-0x1.2e7cbaa1495260ee131d264b7fcbp-11), C_(0x1.d8a73116e5170bf766c62902d5cp-13), C_(-0x1.14baffbb5f3fc7cd4417451de38p-15), C_(-0x1.bc76b1b7765f460d127ed8109cb6p-18), C_(0x1.eb62162b875e74ac3ffbad741aedp-19), C_(-0x1.3ec5df1234a119b292d63f400f4fp-21), C_(0x1.0bd69df0fe817c3f4ec6f9220c7ep-25), C_(0x1.06532665f4ae126a371a91623062p-28), C_(-0x1.7b6b83afc0194421f9c689981f49p-30), C_(0x1.34507b73be114caacaacc09786fp-33), C_(0x1.3e99e3a60acfbc311476e151da98p-38), C_(-0x1.f151e40b836b8f8aaa3a3f0ced37p-42), C_(-0x1.448cc1196d194e9baa30923d08e2p-48), C_(0x1.4daf1830022e2a424c8ef6ce75a5p-53), C_(0x1.5011fa2f598d1104ecc45344c209p-62), C_(-0x1.1686e4fad9ced67d1bdbae1c9b3ep-69), C_(0x1.abb8cbb5d77c3d36c138309edcb2p-81), C_(-0x1.70542f5b2fe975bfb256d1ce4e9dp-97), C_(-0x1.e4be478d2f9719b08915aab446a4p-125), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2434b5ba872d4c5808e71daa73f5p-8), C_(0x1.3130229eb7f3605b9b1b32cb9f97p-2), C_(0x1.7ae2dc23075619726157a440b0afp-2), C_(-0x1.f582a7e51625005d91ec63b814bap+1), C_(0x1.c7d08bb60552f4ce0a1dfeaea923p+2), C_(-0x1.a91c524d7a54ea689caba9ffde39p+2), C_(0x1.3c2342a582cf3f8debfc54cc85bap+2), C_(-0x1.088cd569576045a61a631e97afdcp+2), C_(0x1.d4e6f8f27b14576971c750ec5e9dp+1), C_(-0x1.7aa23dd152a396e3b62ff372d1d7p+1), C_(0x1.fadab4daf8f0e58f8d9d4ef01e97p+0), C_(-0x1.060b8820123e5eec7823aad8401ap+0), C_(0x1.6f3fb0d6ae2f90f1c572f1f9292fp-2), C_(-0x1.4c612316c2d6c3d361a3a87a8a95p-5), C_(-0x1.59b5936f0b00d23a57c7cb83dad9p-5), C_(0x1.f1cd6ac34748038c9618e97f54p-6), C_(-0x1.0815866d993d299c542a96e619ccp-7), C_(-0x1.33db5d2125a2859a2040c40794b8p-10), C_(0x1.bff774c7101082d480ffa7afad95p-10), C_(-0x1.14d1461893fe65443154fdd9ff78p-11), C_(0x1.60ee19b0b8b54d2e9cf10559c07ap-18), C_(0x1.6481008914d42c490ce92b7a443fp-15), C_(-0x1.79e8548e2225181445126279e5f6p-17), C_(0x1.0000883a713c85d37bfa6cb29923p-21), C_(0x1.0c4a52b19c7af0f6d1d88d405597p-22), C_(-0x1.51bfdb03a0cb4dfbccfaca10a1e4p-25), C_(0x1.2786225b5270b4ae5ce680be0a2p-30), C_(0x1.c2f3c31efae819fc824fc14e81e3p-33), C_(-0x1.e485fc83c20815b41344b0b5ebd8p-37), C_(-0x1.cdcc8478ab5ca320820b2bdaf727p-45), C_(0x1.248fa48f37bd758b38759e29a62cp-47), C_(-0x1.a1ed7efc74f0ddd5c3e7a26568ffp-56), C_(-0x1.257d232551abd9af4093fdff2e93p-63), C_(0x1.8e8d04aa5ac8d2663570e52c4402p-74), C_(-0x1.858c6aec0ddcc911f17d17aad5aap-90), C_(-0x1.0055b5f34554e57cc908df0fdeeep-116), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cd2d34d1a42efd10b55402f678dcp-6), C_(0x1.84d83b63c2112e72eadf0e175b4dp-1), C_(-0x1.432ceae809a5e8ac576108008797p+1), C_(0x1.a0b9d38c7e490414c924ee603181p-2), C_(0x1.201a5e729e35c6b52d82081c697bp+3), C_(-0x1.2e113a8c2f74baddd86814ec6249p+4), C_(0x1.552ffbcbb449884fbffcd2fa1903p+4), C_(-0x1.094e929e449b6445010b66a63f08p+4), C_(0x1.1c13ef7eb64aa8ee0175687d62ffp+3), C_(-0x1.1af822f546327a2297be45973a7cp+1), C_(-0x1.f9d0cabdd71723c2b35a33ecead9p-1), C_(0x1.ddb0b49cb2203c31df0981557b5ep-1), C_(0x1.5318acd89fe65697aea31294c66ep-2), C_(-0x1.05b05a50c615d71587f066c9936dp+0), C_(0x1.9b5ab34637cfef44bfcb0657ebfap-1), C_(-0x1.1af795bed4913c5d4d0b7000d26bp-2), C_(-0x1.67451e2d12b8b1dce42c001cf264p-5), C_(0x1.99b155175f94ba8d3e0e29b8e60fp-4), C_(-0x1.ac7539c2e19ebed9f65c60048ba4p-5), C_(0x1.9ca72681ec9ea8c760a8f2a71fa1p-7), C_(0x1.34e3b1c23cb7d1aa00f8b981d763p-12), C_(-0x1.3a24c6f5381cdc3e9a0a2312b097p-10), C_(0x1.74fb460ba6a3c91ca053d755b7f7p-12), C_(-0x1.0b246714f1ffd71ceaf84df8a2f5p-15), C_(-0x1.ab7c59cb5e81411290eca69a51b1p-18), C_(0x1.dce3bc922f58f0b17196be55c2d5p-20), C_(-0x1.67697e8054a806243dffdcb105dap-24), C_(-0x1.9e416c1fd1c36255ecb5eed76efap-27), C_(0x1.c8b3d9029a8aec4464e3c0dd17ap-31), C_(0x1.5aaa4a43abfd9a111ae71704a9d5p-37), C_(-0x1.7db632c817eaeaef04d7671c292bp-41), C_(0x1.4a05d041f84f4639b3fa535ffbc5p-49), C_(0x1.e2fed86a51ad69aa2e1cca0d7a0cp-57), C_(-0x1.05d887c98f164a6efe9f254828cp-66), C_(0x1.42293c268faac3b8f9cecd0a784ap-82), C_(0x1.a7fbcc57e37f33cf909b7d2d16cep-108), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.31422db2538bc0a87b308ffa37p-3), C_(0x1.0d01250c1b0d06e5278d6357ef2dp+0), C_(-0x1.24921c6c7a3e4123721458dbf25dp+3), C_(0x1.a227c85b5e55bd2048d352a6c652p+4), C_(-0x1.524f50b139534832a4ee54d2fbecp+5), C_(0x1.8738d759012c36786ab70fb57053p+5), C_(-0x1.9323ab467eb529dc5b829fba165cp+5), C_(0x1.a42ab8b3ebb45f1751552cca4226p+5), C_(-0x1.a0b31f7eb9e57c7f0585d5e9fdbfp+5), C_(0x1.5b572ee0532df8736514c7068d41p+5), C_(-0x1.a65ce687fe55f007c4de98a4572ep+4), C_(0x1.d054e5f3566481470f5818319872p+2), C_(0x1.85d591edfc333f35ee49a560ad36p+2), C_(-0x1.3b9b5d3160df5b3c5b4fd29535fbp+3), C_(0x1.a0e3e2fe3af5aba2fa3cba939e51p+2), C_(-0x1.908502149e3126842af43ab5d7e1p+0), C_(-0x1.2fdcf4d1b74c11a7c8107dbf5a5dp+0), C_(0x1.71a344c5df788a37bb879332042cp+0), C_(-0x1.6f12d9a04f61757636a67705762bp-1), C_(0x1.40e9a8c631ed8f09035310ff998dp-3), C_(0x1.90c3dfa395147a7cc0c7676c3758p-6), C_(-0x1.cb2bc9edd20ef799e67ea0b4ad99p-6), C_(0x1.07343e2ee6832b57b8208a80d9e7p-7), C_(-0x1.49dfe7960ed68e24de4768224cf5p-11), C_(-0x1.b6e121c3001f0f7bec5598cab095p-13), C_(0x1.dcc996a9ecb3b5336d9759d46957p-15), C_(-0x1.a1bb03b6243b89e05627bbe8512bp-19), C_(-0x1.d9f622b803a645f37f52496ad03cp-22), C_(0x1.6819f189a7727ca3a62602f289abp-25), C_(0x1.4ca2954f6ae1a2e73667b4619ccfp-32), C_(-0x1.8c19531172f0aea0af3e91e143eep-35), C_(0x1.ad03ab6b6c0809d426ec9d64de28p-43), C_(0x1.92a5c80316f77784726d71e5f027p-50), C_(-0x1.126aebf2a41485b2605ffe0d6f2ep-59), C_(0x1.0d7f8030d9d60a694722396ad34fp-74), C_(0x1.62acfe05bfb1201e774235c1d27p-99), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.46ba9611fdf6c7a94d4f6d15ae64p-1), C_(-0x1.dc52978d552a4c87a8e0e11df878p+0), C_(-0x1.7fa540f99cfd7a53d485cc23b3dep+2), C_(0x1.5732b50df53b69d2559ff51a1e33p+5), C_(-0x1.b13b1bdb27ab101c396869bcc29bp+6), C_(0x1.33606cf67b649ff0c53d5daba4dp+7), C_(-0x1.bdcf241a98962a37ffef026534aep+6), C_(-0x1.6f03a4675ff5f681cbcdceb803f8p+5), C_(0x1.1808882b291db1c41b8c116f1fb3p+8), C_(-0x1.010ae854c8f06138d8c0149f09bcp+9), C_(0x1.53a4857a4441ea9cc9b274ab65a3p+9), C_(-0x1.6d4a26d83e33b0ac3dc870af21b4p+9), C_(0x1.3d6709439125c739fb2f5edfb5dcp+9), C_(-0x1.889b5e2f1c327048a556374f7da9p+8), C_(0x1.56fd4f6d97a60ae9928f3958a702p+6), C_(0x1.25b06390e20f015674e98cf0aeb5p+7), C_(-0x1.b399a1a2f22fe6161cb0e96be4a5p+7), C_(0x1.3df78e7e4d04373329461fc9ed72p+7), C_(-0x1.0ef9b79a3621238b48ca4f0954ap+6), C_(0x1.5f7982d2ac2abd1246025f08fe6fp+3), C_(0x1.6a625e6b6bab463f678abfc9f5a5p+2), C_(-0x1.198f31ed8cd901a93c9ab1bea14ep+2), C_(0x1.42ee7fc8a94768a05abd24f4f6ap+0), C_(-0x1.7d60037bbed413784256ebd48bcdp-4), C_(-0x1.6ff7a83ef962302af99cd8276389p-5), C_(0x1.ab35b35a042defdd50e378dee2cap-7), C_(-0x1.b332608ca1a847238ace5779c464p-11), C_(-0x1.021ab5a3bdbb30ee9a537ffac573p-13), C_(0x1.eac528756b7f5130df18318c4f94p-17), C_(0x1.0199b85d253f43e310c32a3ee23dp-24), C_(-0x1.6d0abfd965fbe6911b0989caac0cp-26), C_(0x1.0c61bef3e22c19990cf4042ba7e3p-33), C_(0x1.18cf50a4e4b4950ef758930ceb31p-40), C_(-0x1.0160d4507e328ccba58abe0174c2p-49), C_(0x1.7a161fd10bdebbba470322602b5ap-64), C_(0x1.f195998251a554e483f0c71a4471p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.13189db507a58f44b230b3686764p+1), C_(-0x1.0f9b17b47559884eb516506b8576p+4), C_(0x1.e2750024accc2d74cdaf0e777dc5p+5), C_(-0x1.02e9517352f36c7e1cca5cdce0a3p+7), C_(0x1.84ea97af0478dfed161742a65f15p+7), C_(-0x1.cff7ea5e103622b218e35556d5c2p+7), C_(0x1.edfef34bb4dfb6181091bc4e1283p+7), C_(-0x1.f2fc15391d50c27f5075a6c8ff4bp+7), C_(0x1.eb246356ef9387175566a1e68a13p+7), C_(-0x1.02127d08179f9b70803e08887c21p+8), C_(0x1.3a1511b48828ca00655918525c18p+8), C_(-0x1.91c784aea677bcaa4677a1d92317p+8), C_(0x1.d755a30a6335088a6e9e8a634a61p+8), C_(-0x1.e5c19797a7c13f73162c80019235p+8), C_(0x1.be09360d2ab5d983638f05e968dcp+8), C_(-0x1.6e80a047a6bc49df58dac888c978p+8), C_(0x1.017887f1e05fdfd52e459afc793dp+8), C_(-0x1.16d045efd9fc23449024f4ef5b58p+7), C_(0x1.6f3c5a5aa270e946f4f0452290a4p+5), C_(0x1.00a0bb4260f4b86b22991895dfc7p+1), C_(-0x1.883af181a30c4b69a77ebd74a0cbp+3), C_(0x1.ca6f2d6266dac24630d5b0215037p+2), C_(-0x1.fb9354caf7469830d8b743a50504p+0), C_(0x1.c12f9fd42c0cff788f8d8a32aaf7p-4), C_(0x1.aa753c061078e6073623671f0cd1p-4), C_(-0x1.0149c0900041728b5dc19008c617p-5), C_(0x1.320d29d0ed46573ee176d2f36b8fp-9), C_(0x1.7569a3a8ad03ea55263aad4cfdap-12), C_(-0x1.c7142f2922eef32fe70a3d54296ap-15), C_(0x1.46d93383351fcdeef5e2617523b5p-25), C_(0x1.cc32d5d77364e5410b711a5b1237p-24), C_(-0x1.c3faa80be31a417c7ff07c960f74p-31), C_(-0x1.0e8f2f249697649bebd486ba2aa7p-37), C_(0x1.4b97e65c483067d885e78eb825fep-46), C_(-0x1.6f0e0ef20e7a06716a4c8ec9fe8dp-60), C_(-0x1.e310d5b8794443399cdd6ece490ap-83), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.580f506a271ceefdaa3463cf1629p+2), C_(-0x1.bed7dad0110afcce89ace888e88p+5), C_(0x1.122d5f16217b3e9bf4e80fdc4373p+8), C_(-0x1.ad0c5fd2ce7d97e26b1b63596f32p+9), C_(0x1.ebebc475930229b2000cf737b101p+10), C_(-0x1.c66859645ad39ff322d2fa4b454fp+11), C_(0x1.6b3c821d2c08e770e244c3fd9b4bp+12), C_(-0x1.05ed443c98660df7e825b62de19bp+13), C_(0x1.57df9f8d58ae967ab62cd9351becp+13), C_(-0x1.988852a4ddb8e2394c97f0e9d30bp+13), C_(0x1.b718499032f53cfb6791a553f164p+13), C_(-0x1.ae72afe9b5f0ce3d7715181f289ep+13), C_(0x1.817de8fd200b93d2fe94ab51ad77p+13), C_(-0x1.361e5f944923d3d5bdf35a20adffp+13), C_(0x1.b3a6d661a5e954603cd076722514p+12), C_(-0x1.036ff3829f5795f4ec64398489e6p+12), C_(0x1.edf47d39280a4d357e9e1781a39bp+10), C_(-0x1.10c036b4236268a93be68873acb9p+9), C_(-0x1.e0b697df7f002ac2801a14873b67p+7), C_(0x1.ecbda44c262ae523cdc868e322e1p+8), C_(-0x1.86f5d451d505eacfde5511850305p+8), C_(0x1.725c7f3a52e97d8a78a3843dfb9p+7), C_(-0x1.79d4729613fc7b35a032158d6205p+5), C_(0x1.fd7ee793312f8451ca67d9e92df2p-4), C_(0x1.0d01b8a4bb031f49626bbfdc2049p+2), C_(-0x1.47046f0d13d0e9edd2f830615f89p+0), C_(0x1.be74b29e56e9e7adf67a6938c90ep-4), C_(0x1.1bce9460eaf5c685ea35565b6408p-6), C_(-0x1.bea1c36d184dadae8028a6e3e14cp-9), C_(0x1.c87dd9f0e82f03f1f618a5e508a2p-16), C_(0x1.3736896d21eebb32c780ad16f33cp-17), C_(-0x1.9904cb4c4529ea63892483302a3cp-24), C_(-0x1.1964fba513e306ae2fe86b385614p-30), C_(0x1.cd54969392f7573024faf58e36bap-39), C_(-0x1.819d1aa8bbcb7dddef905812ef85p-52), C_(-0x1.fb7d3a090e0ab46eb1271ed833e8p-74), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.58fd39e3ea473b9c365112f9e5fdp+3), C_(-0x1.f5c4ea84a3bdf86fabc78b7ccf87p+6), C_(0x1.5132162ce5f74a25ac418aed5521p+9), C_(-0x1.153d0f08884aedd476baf2e683p+11), C_(0x1.382a3e583a8c4c9f1dbe11c15209p+12), C_(-0x1.01662d4c3e81ce469818c40b609cp+13), C_(0x1.4a1e803e16c3f08b00f992a85132p+13), C_(-0x1.5e4f1aa3047031adaa3ecd9f7d51p+13), C_(0x1.34f8d319cfee8ccaed9905f9568p+13), C_(-0x1.5037b2099231e17c790011360049p+12), C_(-0x1.c9d4325924514ceeece20c92f62cp+11), C_(0x1.ef1c5da047ca3c6636907219e698p+13), C_(-0x1.aa6460f62329021cc0a31061d8ffp+14), C_(0x1.1493ffefe577c924223ee91be135p+15), C_(-0x1.378dc9a8516802b7004a42d17ea6p+15), C_(0x1.3a895ef60ca292cbe80e485690b9p+15), C_(-0x1.17d3cdfce981563e49f923d38dc9p+15), C_(0x1.b32449a2a05e7c53387e3b5eab6ap+14), C_(-0x1.2d005b15e1ac660d6c6de2ac5d77p+14), C_(0x1.762585d24bf9c7735f9898961b24p+13), C_(-0x1.8db35bc09fe7ee5140a582ff984ep+12), C_(0x1.3cd0860a0aa20c2aa3d4d395b99bp+11), C_(-0x1.0eb312cd7109b3879fc433d5f57fp+9), C_(-0x1.439f55d9eae59605a3c39a59b84ep+6), C_(0x1.991df190f9945d0054430f51818fp+6), C_(-0x1.f474551766f4044e9817e92e973ap+4), C_(0x1.7b90022b6c4e7f168ce752888458p+1), C_(0x1.1453a51ab81ae063df6727985433p-1), C_(-0x1.0919f3da668fc601223376349f5bp-3), C_(0x1.2552ca2a72c78998c9ac373b5bbap-9), C_(0x1.0101dfee94cc5d7f60f2678fd0b1p-11), C_(-0x1.dade9b27d08cb19be2ad380c75a3p-18), C_(-0x1.64097fcb6571f6185210c51bbb62p-24), C_(0x1.8e12f1e504e13d786036befb6f25p-32), C_(-0x1.eef1afe29fcfbef2c0d8edeb2fdcp-45), C_(-0x1.45af8bce131ab3ac470aded6347bp-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c2e57f37dba380a65ba9eda2079fp+3), C_(-0x1.59749d8525f12d8082256adb88ffp+7), C_(0x1.ea6ee085cc96e0d288f3be1b9ca2p+9), C_(-0x1.adf6c2874bed2b3f69d173f96a2fp+11), C_(0x1.07b4a22de335b119555a005db318p+13), C_(-0x1.ecd88a76ee3d3e922a5c04819366p+13), C_(0x1.7c29acad357038f41eb8b1dd0fc7p+14), C_(-0x1.052f5556b7e4a1a5c20ecd7e819fp+15), C_(0x1.4e46d551ac93ec5e56006a3de757p+15), C_(-0x1.8e77607cfd5ad57c6663b8875b37p+15), C_(0x1.b47447ef6b859ed13ace58a9a34dp+15), C_(-0x1.b911fbfaa77dec0071a250cc5fefp+15), C_(0x1.a115d6e8e14d04bc0db0286009bep+15), C_(-0x1.7187cfaf46cf0d5ed6f0095f890ep+15), C_(0x1.2fababdbdc3283e40c1d376f77f3p+15), C_(-0x1.cda4daf54c9cb2382843dcbe14cfp+14), C_(0x1.457825a36823f87f660fc5987cb3p+14), C_(-0x1.a46083210b99766804825ce7a718p+13), C_(0x1.e3885ee2753248f8df804c157d1cp+12), C_(-0x1.e49914e71496a8b65b2bc3b0a8d4p+11), C_(0x1.9ae829c152385eae9b1515bb5c36p+10), C_(-0x1.f191137e3badeb9e76f5cbed8cb2p+8), C_(0x1.57e65b068678833f27ed3ab74f4ep+1), C_(0x1.c2acc962d2fde80f4a40165a5fbdp+6), C_(-0x1.1b8eff5b124df721e99f0cb0e796p+6), C_(0x1.4ce0864f5bc843b2b9783951ecc5p+4), C_(-0x1.f98632e1903923d8655f653df191p+0), C_(-0x1.f614ca355bef0d83e7011b692c6bp-2), C_(0x1.105d05e210a04ac76f5004e82666p-3), C_(-0x1.2c35027764d106ecb7dcc0f035dp-8), C_(-0x1.76591805b151661a98c804b730dcp-11), C_(0x1.f83620ba68c2e3da4e964c603cc5p-17), C_(0x1.9ec84cf651d46727ce1b0a44d7ddp-23), C_(-0x1.358d783409c13e2404896fd5c7b4p-30), C_(0x1.257546b697ae8fd8394b22b0ae34p-42), C_(0x1.8233dd1d0686d57c137ec852b5d4p-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ffa03a8700da7856451e869e7b5ap+3), C_(-0x1.91f11c60f20f4732595d765621bcp+7), C_(0x1.215104c7061731e391acb03d0135p+10), C_(-0x1.fa2000694cbffa8b68970bca9b4p+11), C_(0x1.2ea66d9c1c1c36281a4f053280ccp+13), C_(-0x1.0bde0020ff0122097ceed958162p+14), C_(0x1.7dfdf722720076bd662023e14b8fp+14), C_(-0x1.e6475940e8f80e3e0662171bf565p+14), C_(0x1.28fcf546d66430029dc0ae7f105p+15), C_(-0x1.570d2d144c0d85d5f33951d38d4dp+15), C_(0x1.64b992f501b16328e29ed09c3ca4p+15), C_(-0x1.4cdaed031e2e4abf8359db4b1506p+15), C_(0x1.21c4ffd20e63be71df3b6f2245d3p+15), C_(-0x1.db78c1b913f3be9244561a56f2ecp+14), C_(0x1.5e8fb02e9949d4c003e971dc8526p+14), C_(-0x1.bcf51c1ea8f31b04ed5d992397bap+13), C_(0x1.e583e17ea627e00530e2cb6f7d39p+12), C_(-0x1.aa4e81eafaf451b39ea0ddb0f57dp+11), C_(0x1.13f68d6d4da0d49f20c5505cdf9ep+9), C_(0x1.eda1ba36110bbecc88ad9ef4ce8cp+9), C_(-0x1.4fff2b926b6f5e6bcd2243e80004p+10), C_(0x1.12bce3e2f7931f11964e6bc3f549p+10), C_(-0x1.798d627cec26e7e1e4f53d7bdf9cp+9), C_(0x1.be6fc86ae4a8be5d77f2a1e9d57ap+8), C_(-0x1.8da2d6faf8e64c22dc4a043ad99dp+7), C_(0x1.b66a3015a1c5a11c948aaaf7cab3p+5), C_(-0x1.44429d9883de74d9c60a876b939p+2), C_(-0x1.c3e96613b6e5e2ff71adfacfda7fp+0), C_(0x1.1e57998dcfcf5d1648e257f8bf08p-1), C_(-0x1.07010d4834a6e7a67ce43acbf39ep-5), C_(-0x1.1b562f148b2fb64632b98ead9b7fp-8), C_(0x1.0af79c08ad78f06aac625b45eb1p-13), C_(0x1.f410b3bf125a82ae4c43c7624696p-20), C_(-0x1.f9be8616ca648419dbd80373acd5p-27), C_(0x1.6a9909c4a9f6ffff9ad70512f7b1p-38), C_(0x1.dd2f7b7aa9b821698f859b9d1a0fp-57), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.87fb22468465fb8a2934ce18ef16p+3), C_(-0x1.37c2f683aab22684a06e79a101a1p+7), C_(0x1.c5fd83f053f82dac4273a062a48dp+9), C_(-0x1.91b1e12dd60d97ec2e841dbfca05p+11), C_(0x1.e68387666347c07a316a9422b5b6p+12), C_(-0x1.b4dea0e7d579f84f7fb9d6c16bdcp+13), C_(0x1.3c269a772fa78e428d8f5044caa8p+14), C_(-0x1.97127ecaa2ab1915c1aae5c6fc8ap+14), C_(0x1.f6af289cce31c29a6ec330fbe9e1p+14), C_(-0x1.2a9f5b6b03ca5e9eb10038f1c5dbp+15), C_(0x1.4b10d6718988db4dba24714139cp+15), C_(-0x1.55a31577d419bbaf6e8ea53fe90dp+15), C_(0x1.4e7cdd5d8ea4ad7bd94b50975a01p+15), C_(-0x1.38022f772c0b4cce7e7232f4f9bap+15), C_(0x1.12be31f5fe34faa8426124a140c7p+15), C_(-0x1.c90c6d590473b7e23f50a6ff90abp+14), C_(0x1.68be09036d4b8e25079ad44a0fb5p+14), C_(-0x1.0c494e2492cb7350d7dea324e249p+14), C_(0x1.758345ee1ea103707e4fc5726b69p+13), C_(-0x1.e8a773cd517e44f45076f71519e1p+12), C_(0x1.2a474ea41676fa5a62a310e63587p+12), C_(-0x1.4af3fdfe318309e19b15b68fb972p+11), C_(0x1.49733b39a1c4ced0b1d897e0d8ecp+10), C_(-0x1.28058c9d809d32e67b550b8feec3p+9), C_(0x1.c739fb1ca38e254565961e77d1e7p+7), C_(-0x1.e2ee0f774ec3af6a1c1e4f7b17bcp+5), C_(0x1.f584835c1818f23dc08b323d98e5p+1), C_(0x1.dc8e84cc4afe7a2fb01ea8367041p+1), C_(-0x1.3b3a53bf8d0a53e1e10973253b98p+0), C_(0x1.6a83343080c3f8b48adb7f8a0fc4p-4), C_(0x1.952a26a6e4af59b3b26bda8c8609p-7), C_(-0x1.3a135cf1b710ef334411ec10d2fbp-11), C_(-0x1.208be3b61fd62740fba383db12cep-17), C_(0x1.a71d1df2466b06f953d67915b744p-24), C_(-0x1.b3e65dd0b550b982df6eefc5304bp-35), C_(-0x1.1ed120d152ef3b5a4475e78c15bcp-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.14760cca8b142294e79588592265p+3), C_(-0x1.ba74df47bf664ee2547385285e06p+6), C_(0x1.41711dcfaf9ae33ef5a42497cdccp+9), C_(-0x1.1818fad342f755601ec00141bb62p+11), C_(0x1.474e1b48df1603e34e0f10a63ce8p+12), C_(-0x1.1344c928a46119ef7f83bdf82b73p+13), C_(0x1.69c3448f5e9dbd2d90d955490598p+13), C_(-0x1.a6933630b28804e5fdf1db79e516p+13), C_(0x1.f096b7533884b484daabf2ec386p+13), C_(-0x1.22623e57fb5283c6330ad006e50dp+14), C_(0x1.3656cdaada5ee9f54e572471e7bep+14), C_(-0x1.2c112510224741f5281f55b6dc46p+14), C_(0x1.1649895fe753bac480e018c717a8p+14), C_(-0x1.f7bb2384208e05c66ecac730535dp+13), C_(0x1.a9475e44156e584ae36a2ec50f02p+13), C_(-0x1.4a8f9de0fe8b863882cf98bdc30ep+13), C_(0x1.eb5875381b21b266553a6296e0a5p+12), C_(-0x1.5ee64eec32c02ba06ecbd76a11b3p+12), C_(0x1.ccfb4d9d3a3fd43202c9da414974p+11), C_(-0x1.14a05b02023d93595fe14dff5f3bp+11), C_(0x1.3a9e21e52de90e0e25e5cf4ca63ap+10), C_(-0x1.4bc3a327f05f291344a38f901a5dp+9), C_(0x1.2adbd2de6a50340d8168b2783c01p+8), C_(-0x1.c3c2f4b5f88c5c0995d28d11b9ebp+6), C_(0x1.277a18d79f69dcf96944e2b0fcf5p+5), C_(-0x1.c9f8833026d5a408341117a30a92p+2), C_(-0x1.454631d4223dc7af67ef97ef1099p+1), C_(0x1.43b3c20fabe24e5d14333b1e0567p+1), C_(-0x1.7e2b7474504f09a810523ca07f92p-1), C_(0x1.0161c2b653dc5e969cd9fbd6d0edp-4), C_(0x1.00c51140e71642a9a41e83368bbdp-7), C_(-0x1.ae184c969f7530c56af21ca3a7a8p-11), C_(-0x1.8063c15ef2a25ff6da3cad34895fp-17), C_(0x1.7fa9f24707d3d7cbfa3e9820acf4p-23), C_(-0x1.2feaa75fa15b4cbbde0dc3686d2fp-33), C_(-0x1.8febd0375e4aae5f4479ef67c215p-50), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.309432a44a63023cd5d74f5bea55p+2), C_(-0x1.e8f069c87232260c91fa71890f2bp+5), C_(0x1.620bb6edc4428b1d5f4fa47a5ecep+8), C_(-0x1.30502125aeb77e95c45d9e43464ep+10), C_(0x1.5897d2f743a96869b1eb0ca13247p+11), C_(-0x1.10925ae24fc57451105c29bc2a9fp+12), C_(0x1.4362e4b63cec61ff21aac6b7ac6ep+12), C_(-0x1.4ffdb02cc70cfe03dbf6d475eb63p+12), C_(0x1.779b03f599f05e82b08d8b48f758p+12), C_(-0x1.baec7e0e55169b8140b39b8fb14bp+12), C_(0x1.ce2ff743f88370d5e72cb7988fbcp+12), C_(-0x1.9f067ce3296956a187e74bb12383p+12), C_(0x1.6abb1f9cef609047d528387a0ad9p+12), C_(-0x1.4450d5aabf62ce501c4c7a9271c2p+12), C_(0x1.08545f0a3187b9a2ec020313e51cp+12), C_(-0x1.7530230cd216d38656dfbf0553dap+11), C_(0x1.f952b436845ca1bafccd87887abfp+10), C_(-0x1.560fff419d2c2e711437c4013006p+10), C_(0x1.8c0d255b6e233d3a2cb91681d042p+9), C_(-0x1.5fdc3ca1d5db02eaba158929c246p+8), C_(0x1.0a97d5984be8315545f375086dccp+7), C_(-0x1.20a6202d36bbe9ea7b9fe18176b3p+5), C_(-0x1.5a7221251a0809c48fe9776bbed6p+4), C_(0x1.3634e4081412bfd6aa7ecc784b01p+5), C_(-0x1.bdda94264568de640cdd8fb6a91bp+4), C_(0x1.feb750a84a74f7d5dc8417586506p+3), C_(-0x1.275477518f18aa31553de78414f5p+3), C_(0x1.12ebd04f5867e9e6cd551be469c5p+2), C_(-0x1.30dbe403419efe34f764090a038fp+0), C_(0x1.058d7af30daa34c20339630ccaeap-3), C_(0x1.916084cd62258d7ea8b1535e2f8ep-7), C_(-0x1.732dce99f11c6f7cee7cd02c7701p-9), C_(-0x1.7126e2b2a55e5160267b465d584cp-15), C_(0x1.f42158d77d0c28962287129d0e59p-21), C_(-0x1.357be619f66df06ada13476a9641p-30), C_(-0x1.9731ccc0ad49712bbc19913bd785p-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a04267542fb82b6511fb8f206b7p+0), C_(-0x1.3cbc4bff9713202eddfb257134f3p+4), C_(0x1.cbebed769f041b8ff3b3ff336b7ep+6), C_(-0x1.8d408dd48e3feaaa0b268282946dp+8), C_(0x1.c5c362fe59a680f0eae654ab9d42p+9), C_(-0x1.6befff94df0fd5c1ea5963474048p+10), C_(0x1.b68e6a376222daa009bfb53e28dp+10), C_(-0x1.c650372cae06a09b58e507b0871ep+10), C_(0x1.e7dc6f316434651b61d954241667p+10), C_(-0x1.15cc9fcbffbdadb34e9d61d6c6eep+11), C_(0x1.25d8da27ae488c61183e3d71ffbcp+11), C_(-0x1.17ff07a3bf7e3928a0bec71f80dbp+11), C_(0x1.0475b26522c32263166cf14a852ap+11), C_(-0x1.e40da504c90b0dabfc10981e655cp+10), C_(0x1.a69e253ca704fe5504b2c83ebfdbp+10), C_(-0x1.57f0b96fa56496dc384c41ebdb2p+10), C_(0x1.11486c0ca46dc3a169a7bf688364p+10), C_(-0x1.a51b5b4b4c6e9a002c8fc1ca65e6p+9), C_(0x1.2ee508d88648873a9042e781e817p+9), C_(-0x1.9d3a15a142fb235220e5bdb7d581p+8), C_(0x1.11494e2078a35defd9005276ea95p+8), C_(-0x1.535f44eb08e29df270d509de713ep+7), C_(0x1.85e2cd196a74cb82559b30f986fdp+6), C_(-0x1.ab69cc5e56727978f17d430c4129p+5), C_(0x1.b6235da40abe2f3f3eea8ec9a5f6p+4), C_(-0x1.8b55be10b7592b154b2ba9939157p+3), C_(0x1.414892cca85f8967c379d65c1761p+2), C_(-0x1.e63611dc23584e97ec62af26dc25p+0), C_(0x1.1a15ef6adced3df1c6c0346a88a1p-1), C_(-0x1.2481c80f712590a8d277e551e4fep-4), C_(-0x1.27449cc156e8a2b8d79cdb23e19p-7), C_(0x1.70c363a504f9eefb5323d6beb984p-9), C_(0x1.513124306018b235441513a840aep-15), C_(-0x1.d1034c80bf12bfc41e39ee6d8817p-20), C_(0x1.59ccd407dcf5a9a7533ca67a560ap-29), C_(0x1.c6dbd9b6fbf34f8784ef66a9534dp-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d374dc0cd29f78efae1c669adc98p-2), C_(-0x1.780e4d99b7126e1227fd8360470ep+2), C_(0x1.0fdf2439cdc107efd9b577f835a9p+5), C_(-0x1.cfa32c44d17cf6112a211a2ca37ap+6), C_(0x1.015959857901578ca504dacee669p+8), C_(-0x1.85bc6b66153fd1bea9b65cf18fa7p+8), C_(0x1.a64f0f8c995c4aa45de473272a55p+8), C_(-0x1.7a602a5238af6059f76503b7cbc2p+8), C_(0x1.7b654c5560678179ce7606e1eb5bp+8), C_(-0x1.bd48fca1124c5a0c87121a03cfe7p+8), C_(0x1.d04b583d66c5fddbbacf446d9c66p+8), C_(-0x1.9412225fd51522e93e47c93309f2p+8), C_(0x1.601c278c16ffe3bedc9949af1437p+8), C_(-0x1.4b7186886095601966984faa4acep+8), C_(0x1.1d01310f5613f772298e42534595p+8), C_(-0x1.abfcdefee09bf658999362e6f111p+7), C_(0x1.4372d34e52fa3409ae85e2a019f6p+7), C_(-0x1.f6105d4c84d999290c211733ed04p+6), C_(0x1.5bb1d872e66637325ce8f6aa17bep+6), C_(-0x1.b1d6456c69f76f04df5acebda739p+5), C_(0x1.15b4bfdbddb01fb2de3e2b574816p+5), C_(-0x1.5951b3080c61b9307228b6ed10bbp+4), C_(0x1.701e202aeccdeb8ac6b6b30bcacp+3), C_(-0x1.6ddc190753e3ea59a0862615508fp+2), C_(0x1.77099e572e056d9b063dba7e75c1p+1), C_(-0x1.4e4b25c08b76d3f35349a1737dcep+0), C_(0x1.d2b148f357c3f676caf89142fe6p-2), C_(-0x1.3f20a405e77bfa5f0c7b2c20c976p-3), C_(0x1.9e7b676edad2c438a7201cee715ap-5), C_(-0x1.868422c7d3c55e44cf7999291ce8p-8), C_(-0x1.3d8b8d9fd24906b21fe8a1d895d9p-9), C_(0x1.57f23d8a911c1c88e9f1808c31e4p-11), C_(0x1.21e64d9dcd8227de3458f3f5849cp-21), C_(-0x1.d450acc53a98cfc94056c9e9eb52p-21), C_(0x1.0524ac3af31035a21da55dd5b9a3p-30), C_(0x1.575344ae7025305d708f9f17a1a5p-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.515b9f63b7c8d9d621c7f83ca202p-4), C_(-0x1.0f7f6c187ccac0b76cfe6b463e44p+0), C_(0x1.8785c563b5897121211402b9f302p+2), C_(-0x1.4b2e4e52216e5851aba80d8bd8e5p+4), C_(0x1.6901cf579638d44ea9478cea01d4p+5), C_(-0x1.06c8002a381179d9f60f753114a4p+6), C_(0x1.05cb21187a0f4fd8449a14491a1ap+6), C_(-0x1.95b91f5bb17e01dfb0ac91c796f8p+5), C_(0x1.7701942190fc5f1e86a9d43b21f6p+5), C_(-0x1.ce78be0577929e543cbd7ad9b93bp+5), C_(0x1.e29898694f90f26ba0d29f50470ep+5), C_(-0x1.7f1203e71656f1392c2a5ed0ed1cp+5), C_(0x1.37e1b965edd32923f1ca90e8ee72p+5), C_(-0x1.32c7bde1b71fddd33a7396827f1p+5), C_(0x1.098dc7ef6c8b51bc5142e5eef069p+5), C_(-0x1.6fe8868cdb497ea274e3965b3923p+4), C_(0x1.0ba553b7e7f0be8b204b950f5ae8p+4), C_(-0x1.b42a38b735b9796714d4ff017726p+3), C_(0x1.28e9aca928974002f9a9710ee004p+3), C_(-0x1.515c3566a134d8fdf2749b107958p+2), C_(0x1.ae8a4319bcbc3c0849df1986eff8p+1), C_(-0x1.1895df589aea592ca4ae051262ecp+1), C_(0x1.14e9f7c12e2c99db92b3020068dbp+0), C_(-0x1.e47340b006f8809308435a5f94dcp-2), C_(0x1.062f736c8ea4db2c5025ce71eba6p-2), C_(-0x1.d4b69f6b077f6afaf5cbb7fe058ap-4), C_(0x1.ca34188e3ee232929967c28b9b2ep-6), C_(-0x1.abe68c068be60d047f0a28b8716cp-8), C_(0x1.690421cc61ef435baf7b95f1a52fp-9), C_(0x1.f0697cb773e3bc4b5c6f8da3552ap-12), C_(-0x1.c195d60892125cb3e4fc26494359p-11), C_(0x1.b812af9cf3a26f639a51b597d61cp-13), C_(-0x1.bff07c97b4e02892210bbfe57ccbp-18), C_(-0x1.52d29bd9004df24ead72772a383cp-21), C_(0x1.032cd4ca8cfc03e1481665c670fdp-32), C_(0x1.5462cc3c1b3950e1af932e243f9p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.19f56cbab95bde76557badc0f4cfp-7), C_(-0x1.c5e9cb7948f398db235b0497713cp-4), C_(0x1.45ccfe221c0e9033121b0a870c75p-1), C_(-0x1.0ff7774a4970235ef0d0d38e3503p+1), C_(0x1.1f8e85bb37dc52e0187eb7a98e68p+2), C_(-0x1.86af502d50caccee8ec1f8fa9cd2p+2), C_(0x1.49bbefd2893ed26dde1f31860f1dp+2), C_(-0x1.6128a473d02d185e7eb02c402e5cp+1), C_(0x1.1828041581a25f5b721c3a717f02p+1), C_(-0x1.d956f1ddda30a36e6132710c578ep+1), C_(0x1.038faca047549c3c3be2f3f91741p+2), C_(-0x1.37b3d4e72913f8a1a7f18bf41b92p+1), C_(0x1.7db8d08d07a3f9e23e72ca58a9d9p+0), C_(-0x1.e8024d590281c76397a14742f7fep+0), C_(0x1.bf0c126480d51b8dd799512a9bbcp+0), C_(-0x1.9a6e24093a6a2e038548f4c21568p-1), C_(0x1.9d414904073073148ca53b09a0c9p-2), C_(-0x1.e94579a438133caa5c0cf94e7bc6p-2), C_(0x1.1fe0d75be11ddab72d3817a1df79p-2), C_(-0x1.138ce466125db8659c96547c9ecbp-7), C_(-0x1.34e623ad04da0418dc894a3d03adp-6), C_(-0x1.2fc16b0c0aa7163aea99c6e062f3p-7), C_(-0x1.d550ce5b878423f79b2e760869bbp-6), C_(0x1.5e3d43af8f8ddb8e3580c4af5d78p-5), C_(-0x1.6c1ef7a1d6e428cbd81df1c34e95p-6), C_(0x1.8a7d31fc8c9aee233f27827d8acap-7), C_(-0x1.52a8406945db2a229ecbdd1d3a6ap-7), C_(0x1.7e48f37194da1a9d35aebc50ef39p-8), C_(-0x1.157ac29aabe3ff0003550e84e639p-9), C_(0x1.ef1519ddac57eba8aaaa2d2f321ap-11), C_(-0x1.e9152bfae3a36641e3acf97f58dcp-12), C_(0x1.063d5981a1db32ae377107926c9ep-13), C_(-0x1.4c0cd023430cc482bd47183c0ef3p-17), C_(-0x1.c41b70da67df95d6233d9591b513p-21), C_(0x1.5615a8cb6d771ab8987aa2645074p-32), C_(0x1.c05941495cbd662c96cb64517d6bp-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.94435eb9af5275885daf683a6d65p-11), C_(0x1.ed6b4c3fc563bad856b7ff679708p-2), C_(0x1.e76d4a24be344d37fa2f63572709p+3), C_(0x1.2e6decff81b60c629b716c5e755bp+6), C_(0x1.b10d4368bfb547486b053181a892p+4), C_(-0x1.2aabf32fc96a83423162d2c816bp+5), C_(0x1.d877b83c63dd7e5e4cc6dd5d03a9p+4), C_(-0x1.473d4fc793666a7b844c67c60bd8p+4), C_(0x1.95d0bb71b70ebdc02338882a3446p+3), C_(-0x1.af691b75d1d83460cd380f784013p+2), C_(0x1.6d28dba75e1d6e3724ad5b4f87b2p+1), C_(-0x1.a6978440cef93cfbe48ab54a4883p-1), C_(0x1.1490ceb2bb752e576e6ab7934d2ap-4), C_(0x1.464cc9ffc1d7e4d14789afa29b8ap-4), C_(-0x1.a276802b30603b547d67dda28d1bp-5), C_(0x1.1d1df4fc9211fc9b42905d09c47cp-6), C_(-0x1.17d7d8739a0a8aedb047da85632p-8), C_(0x1.ebfe215a7af3d07469844cb63084p-11), C_(-0x1.4f11d28267254fe725cc5344d47fp-13), C_(-0x1.9b2b7a111f74e448315a5acfceb6p-17), C_(0x1.14946151574b1cc87019ae7e5eccp-16), C_(-0x1.a6bb3de2d570ec48084b02756991p-19), C_(-0x1.9504b8c2dfd49dc16ebf73767df5p-24), C_(0x1.17aee7159c99baf232751bad6bd3p-24), C_(0x1.70d51f32a8d959f82b22d341a23bp-30), C_(-0x1.5dd5370ddab610b2e6c646e6c17ap-32), C_(-0x1.e8aac4dbdf4eaec509688435a8c6p-35), C_(0x1.629884f91c42aa4b289bcdb69f39p-40), C_(0x1.1aef0590aab3b2864498ba08a331p-44), C_(-0x1.21c09a3e7d5c59641f5b485f413p-50), C_(0x1.b8e2ec16d3130e2d4b06e1e5ebcbp-59), C_(-0x1.8c242cff56d3b852843f6ec978c7p-64), C_(0x1.c20c22cff32a0ee7b7221886273ep-74), C_(0x1.8b88202dbba79e3009dedbb574b1p-88), C_(0x1.27f0bb4febe21c10d76a7232b49p-103), C_(0x1.8579c244925048746514bf00ae6dp-133), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.263966f58e93453d04e057c51a09p-10), C_(0x1.5fb5bf5017c5cbd580114bdb418p-2), C_(0x1.79fa0aa0ef4b1e94ae76e603830ep+2), C_(0x1.0041752577d99920a4756cf6dfd7p+3), C_(-0x1.6480edc11cb316f0df4191286f79p+4), C_(0x1.7adbeb32519375a4e9fc4f3e6a5bp+3), C_(-0x1.8761c804c949b74e319f96893292p+2), C_(0x1.0bbe5cbfe7fbfd16a26214b40cadp+2), C_(-0x1.c27eb52ff5df81afb96ebb8be06ap+1), C_(0x1.6f68e268413d3fe6c3a7fa4919f1p+1), C_(-0x1.fbed86051f0cd090a4eeebb3ba08p+0), C_(0x1.17c1f8ccfdcb9142f7ebab0435b5p+0), C_(-0x1.cf35ce446b0dbe81a8d8224d1015p-2), C_(0x1.fa3032b16e2ec1aa83ca0e93a41cp-4), C_(-0x1.610cbeafdcc29a63e60dfb78086p-7), C_(-0x1.f0a31aba969e59e1d540df6c7f09p-8), C_(0x1.cb16dc9a66c8c832a40588853909p-9), C_(-0x1.378619c057d6f59580d9bc18beb2p-12), C_(-0x1.19bd674de47d6898c22e3b3237e3p-12), C_(0x1.c15384b637285af63775101117b6p-14), C_(-0x1.014a5dd580db7e757daab9ece5fdp-17), C_(-0x1.4f01d7193ba039b859fe936d4da5p-18), C_(0x1.63c48bb9daaef9ef37d87bcf220dp-20), C_(-0x1.0126c6d159333aa9ffefda4ce01fp-25), C_(-0x1.9c0d1ce2d6bcfc30df35efd50ccbp-26), C_(0x1.f835a0a4ec39a7abf277183bd5afp-30), C_(-0x1.e018504ab9e4668fd6a8d7855266p-38), C_(-0x1.2225fdd38424d963076e1b05254fp-37), C_(0x1.9c61eaa91cf12e3330e482deddd5p-42), C_(0x1.3e42beb720a117dd0b00b4bdbe96p-50), C_(-0x1.1199b0b74da5aecc08a2c6ccc14ep-53), C_(0x1.58b777bfe6b1520fc88066b839f4p-62), C_(0x1.001f51ec932dbb77f103a0f7564dp-70), C_(-0x1.7359d9741f8ec2aef5430062a9fap-82), C_(0x1.529c13dec223da6d213dd3aa18cap-99), C_(0x1.bda18c791fe6b89a60c075d9dac4p-128), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.55c2dd92705ef29dacf510df5483p-9), C_(-0x1.875690159b946a743f6031d71359p-2), C_(-0x1.756f6cbad17a45f8fdca57537e0cp+1), C_(0x1.522462f959194685a62f604b7373p+2), C_(0x1.6695cecd8b44feab641f1eb716abp+1), C_(-0x1.55d8721e5e38fe7f6b6b27b70f1ap+3), C_(0x1.5a1db9a981431612f8d678081919p+3), C_(-0x1.0851517441a6e04a55b896ef99e1p+3), C_(0x1.4943b00084361d8656967cf91ea6p+2), C_(-0x1.3bad2deaede17c67f605a6915c1cp+1), C_(0x1.7b9d5b96164de0ffe09e1ad56182p-1), C_(0x1.9c78d3c486af6a9c43cd6d82014p-7), C_(-0x1.3adc11c8d3555c352fd89192cfdp-3), C_(0x1.5c787302c6a0e308908c5a566d12p-4), C_(-0x1.79c3b00ffbead0016b7d6948b83ep-6), C_(0x1.24e941b9401cdd0859a58e2c60b8p-8), C_(-0x1.a08712ec476e0f62559aaf166efp-9), C_(0x1.43c84b18b6bc1f9bc1ed4ace622fp-9), C_(-0x1.f9ed905ce1a3fabec727edc27bfdp-11), C_(0x1.28365cf3c20b9931191c65e395d2p-13), C_(0x1.dbc105f0dcd19a43895a2c14219bp-16), C_(-0x1.06fd02a0249f9985362be2e45162p-16), C_(0x1.5536f1beba49f3fa62573cb3aefap-19), C_(-0x1.1eb1b927a2367b6b71d37a3a0b16p-23), C_(-0x1.18cae380af7c0fb2b2883f2e7a9fp-26), C_(0x1.962198a9fb4f49acf27837af9e55p-28), C_(-0x1.4a0510fbc2258e2b740de37281f1p-31), C_(-0x1.5507dda80e4462056671b4ed9443p-36), C_(0x1.0a2a68de8dc560166b8fa1f0e29fp-39), C_(0x1.5b65f0e23da86c0f9732111de5a7p-46), C_(-0x1.652ce69e3233a8cdb2d672d4de9fp-51), C_(-0x1.67baca3a273431e8c1471458d539p-60), C_(0x1.2a22a2a629f6431996d0904b53cbp-67), C_(-0x1.c9d5657e9bda6dc8a405fc5c3a28p-79), C_(0x1.8a4260a0edd15c6744f3a072dd9cp-95), C_(0x1.036f45f65701ff403784f02b67ep-122), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.bda79ab9326966a8373d34c403d5p-10), C_(-0x1.d1744a8423410c1cdbc92198fb2ep-4), C_(-0x1.20ed565d8344f24b447d5dad1a94p-3), C_(0x1.7e6fc4bdbfcb347e60be376cd8fcp+0), C_(-0x1.5b972509d68a9e778b59e41da454p+1), C_(0x1.442d2d17d149d7c8adb7128a4a5bp+1), C_(-0x1.e2277288714cc11d45fb77f46c4ap+0), C_(0x1.9379ce87585cf7e36c9df60dab88p+0), C_(-0x1.659214144828aeeba2e8c5e20a63p+0), C_(0x1.20bc0fb1d00715f9a829adb0ea43p+0), C_(-0x1.8283009ebbc1eb153c3ab896b77bp-1), C_(0x1.8fa7bb64ff9ab76d61906bd796f1p-2), C_(-0x1.180d836c3d15c7dc5dd02b639eccp-3), C_(0x1.faecc9e70faee2855b6fee69691fp-7), C_(0x1.07a09dde4a2beade229071da7cf2p-6), C_(-0x1.7b9be86674bb70da10cbd67f2dafp-7), C_(0x1.92c3d8394a5b35c0ac95d90e2cd5p-9), C_(0x1.d5864f4fa99910c57caa7bc9e471p-12), C_(-0x1.559b12ec6e892a72794bb66e37cep-11), C_(0x1.a62f6a612f39a18acf0803b47144p-13), C_(-0x1.0d223ecdbfff75a7fa9690777531p-19), C_(-0x1.0fdbebf048174e10984f842f14c4p-16), C_(0x1.202e4a843fcd49b1f3f621772e1ep-18), C_(-0x1.86705793870af2933b93c10e211p-23), C_(-0x1.992e1c88b7cd13dae9b8e491d4dap-24), C_(0x1.018eb6827a7049feef27c5ca32bcp-26), C_(-0x1.c2b71846e1645f5cc0f2480787d5p-32), C_(-0x1.57e1e9171e5bc5fcf45eafbaecf7p-34), C_(0x1.717b9ae9f68e605d4d193d54fc52p-38), C_(0x1.6027613ce51bde3efec97caba709p-46), C_(-0x1.be324a2f0323f8a5380cb0e8a1d4p-49), C_(0x1.3eb2f19289730e4086f2e07ef711p-57), C_(0x1.bf9c807f8fa727e8ceb75bf12aacp-65), C_(-0x1.2fec3bd7b3920aea071e434958e4p-75), C_(0x1.290ed0b71d4a892449c6c2ced6f5p-91), C_(0x1.86f240571d54c453fa3cc6af74bep-118), C_(0x0p+0) }; }; + + +template +constexpr inline std::array daubechies_scaling_integer_grid() +{ + static_assert(sizeof(Real) <= 16, "Integer grids only computed up to 128 bits of precision."); + static_assert(p <= 19, "Integer grids only implemented up to 19."); + static_assert(p > 1, "Integer grids only implemented for p >= 2."); + return daubechies_scaling_integer_grid_imp::value; +} + +} // namespaces +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/erf_inv.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/erf_inv.hpp new file mode 100644 index 0000000000000..cb65cffbc1073 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/erf_inv.hpp @@ -0,0 +1,559 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SF_ERF_INV_HPP +#define BOOST_MATH_SF_ERF_INV_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4127) // Conditional expression is constant +#pragma warning(disable:4702) // Unreachable code: optimization warning +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include + +namespace boost{ namespace math{ + +namespace detail{ +// +// The inverse erf and erfc functions share a common implementation, +// this version is for 80-bit long double's and smaller: +// +template +BOOST_MATH_GPU_ENABLED T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + T result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute error compared to |Y|. + // + // double: Max error found: 2.001849e-18 + // long double: Max error found: 1.017064e-20 + // Maximum Deviation Found (actual error term at infinite precision) 8.030e-21 + // + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.0891314744949340820313f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000508781949658280665617), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00836874819741736770379), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0334806625409744615033), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0126926147662974029034), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0365637971411762664006), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0219878681111168899165), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00822687874676915743155), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00538772965071242932965) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.970005043303290640362), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.56574558234175846809), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.56221558398423026363), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.662328840472002992063), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.71228902341542847553), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0527396382340099713954), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0795283687341571680018), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00233393759374190016776), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000886216390456424707504) + }; + // LCOV_EXCL_STOP + T g = p * (p + 10); + T r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute error compared to Y. + // + // double : Max error found: 7.403372e-17 + // long double : Max error found: 6.084616e-20 + // Maximum Deviation Found (error term) 4.811e-20 + // + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 2.249481201171875f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.202433508355938759655), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.105264680699391713268), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.37050328343119927838), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.6447298408374015486), + BOOST_MATH_BIG_CONSTANT(T, 64, -18.8510648058714251895), + BOOST_MATH_BIG_CONSTANT(T, 64, -44.6382324441786960818), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.445385985570866523), + BOOST_MATH_BIG_CONSTANT(T, 64, 21.1294655448340526258), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.67192254707729348546) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.24264124854247537712), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.9713437953343869095), + BOOST_MATH_BIG_CONSTANT(T, 64, -28.6608180499800029974), + BOOST_MATH_BIG_CONSTANT(T, 64, -20.1432634680485188801), + BOOST_MATH_BIG_CONSTANT(T, 64, 48.5609213108739935468), + BOOST_MATH_BIG_CONSTANT(T, 64, 10.8268667355460159008), + BOOST_MATH_BIG_CONSTANT(T, 64, -22.6436933413139721736), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.72114765761200282724) + }; + // LCOV_EXCL_STOP + T g = sqrt(-2 * log(q)); + T xs = q - 0.25f; + T r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute error compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + T x = sqrt(-log(q)); + if(x < 3) + { + // LCOV_EXCL_START + // Max error found: 1.089051e-20 + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.807220458984375f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.131102781679951906451), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.163794047193317060787), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.117030156341995252019), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.387079738972604337464), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.337785538912035898924), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142869534408157156766), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0290157910005329060432), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00214558995388805277169), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.679465575181126350155e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.285225331782217055858e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.681149956853776992068e-9) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.46625407242567245975), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.38168345707006855425), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.77846592945843778382), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.59301921623620271374), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.848854343457902036425), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.152264338295331783612), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.01105924229346489121) + }; + // LCOV_EXCL_STOP + T xs = x - 1.125f; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // LCOV_EXCL_START + // Max error found: 8.389174e-21 + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.93995571136474609375f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0350353787183177984712), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00222426529213447927281), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0185573306514231072324), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00950804701325919603619), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00187123492819559223345), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000157544617424960554631), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.460469890584317994083e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.230404776911882601748e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.266339227425782031962e-11) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.3653349817554063097), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.762059164553623404043), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.220091105764131249824), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0341589143670947727934), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00263861676657015992959), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.764675292302794483503e-4) + }; + // LCOV_EXCL_STOP + T xs = x - 3; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // LCOV_EXCL_START + // Max error found: 1.481312e-19 + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.98362827301025390625f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0167431005076633737133), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00112951438745580278863), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00105628862152492910091), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000209386317487588078668), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.149624783758342370182e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.449696789927706453732e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.462596163522878599135e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.281128735628831791805e-13), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.99055709973310326855e-16) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.591429344886417493481), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.138151865749083321638), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0160746087093676504695), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000964011807005165528527), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.275335474764726041141e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.282243172016108031869e-6) + }; + // LCOV_EXCL_STOP + T xs = x - 6; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // LCOV_EXCL_START + // Max error found: 5.697761e-20 + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.99714565277099609375f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0024978212791898131227), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.779190719229053954292e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.254723037413027451751e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.162397777342510920873e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.396341011304801168516e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.411632831190944208473e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.145596286718675035587e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.116765012397184275695e-17) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.207123112214422517181), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0169410838120975906478), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000690538265622684595676), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.145007359818232637924e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.144437756628144157666e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.509761276599778486139e-9) + }; + // LCOV_EXCL_STOP + T xs = x - 18; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // LCOV_EXCL_START + // Max error found: 1.279746e-20 + BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0.99941349029541015625f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000539042911019078575891), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.28398759004727721098e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.899465114892291446442e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.229345859265920864296e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.225561444863500149219e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.947846627503022684216e-12), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.135880130108924861008e-14), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.348890393399948882918e-21) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0845746234001899436914), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00282092984726264681981), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.468292921940894236786e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.399968812193862100054e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.161809290887904476097e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.231558608310259605225e-11) + }; + // LCOV_EXCL_STOP + T xs = x - 44; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +template +struct erf_roots +{ + boost::math::tuple operator()(const T& guess) + { + BOOST_MATH_STD_USING + T derivative = sign * (2 / sqrt(constants::pi())) * exp(-(guess * guess)); + T derivative2 = -2 * guess * derivative; + return boost::math::make_tuple(((sign > 0) ? static_cast(boost::math::erf(guess, Policy()) - target) : static_cast(boost::math::erfc(guess, Policy())) - target), derivative, derivative2); + } + erf_roots(T z, int s) : target(z), sign(s) {} +private: + T target; + int sign; +}; + +template +T erf_inv_imp(const T& p, const T& q, const Policy& pol, const std::integral_constant&) +{ + // + // Generic version, get a guess that's accurate to 64-bits (10^-19) + // + using tag_type = std::integral_constant; + T guess = erf_inv_imp(p, q, pol, tag_type()); + T result; + // + // If T has more bit's than 64 in it's mantissa then we need to iterate, + // otherwise we can just return the result: + // + if(policies::digits() > 64) + { + std::uintmax_t max_iter = policies::get_max_root_iterations(); + if(p <= 0.5) + { + result = tools::halley_iterate(detail::erf_roots::type, Policy>(p, 1), guess, static_cast(0), tools::max_value(), (policies::digits() * 2) / 3, max_iter); + } + else + { + result = tools::halley_iterate(detail::erf_roots::type, Policy>(q, -1), guess, static_cast(0), tools::max_value(), (policies::digits() * 2) / 3, max_iter); + } + policies::check_root_iterations("boost::math::erf_inv<%1%>", max_iter, pol); + } + else + { + result = guess; + } + return result; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type erfc_inv(T z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + + // + // Begin by testing for domain errors, and other special cases: + // + constexpr auto function = "boost::math::erfc_inv<%1%>(%1%, %1%)"; + if((z < 0) || (z > 2)) + return policies::raise_domain_error(function, "Argument outside range [0,2] in inverse erfc function (got p=%1%).", z, pol); + if(z == 0) + return policies::raise_overflow_error(function, nullptr, pol); + if(z == 2) + return -policies::raise_overflow_error(function, nullptr, pol); + // + // Normalise the input, so it's in the range [0,1], we will + // negate the result if z is outside that range. This is a simple + // application of the erfc reflection formula: erfc(-z) = 2 - erfc(z) + // + result_type p, q, s; + if(z > 1) + { + q = 2 - z; + p = 1 - q; + s = -1; + } + else + { + p = 1 - z; + q = z; + s = 1; + } + // + // A bit of meta-programming to figure out which implementation + // to use, based on the number of bits in the mantissa of T: + // + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + // + // And get the result, negating where required: + // + return s * policies::checked_narrowing_cast( + detail::erf_inv_imp(static_cast(p), static_cast(q), forwarding_policy(), tag_type()), function); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type erf_inv(T z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + + // + // Begin by testing for domain errors, and other special cases: + // + constexpr auto function = "boost::math::erf_inv<%1%>(%1%, %1%)"; + if((z < -1) || (z > 1)) + return policies::raise_domain_error(function, "Argument outside range [-1, 1] in inverse erf function (got p=%1%).", z, pol); + if(z == 1) + return policies::raise_overflow_error(function, nullptr, pol); + if(z == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + if(z == 0) + return 0; + // + // Normalise the input, so it's in the range [0,1], we will + // negate the result if z is outside that range. This is a simple + // application of the erf reflection formula: erf(-z) = -erf(z) + // + result_type p, q, s; + if(z < 0) + { + p = -z; + q = 1 - p; + s = -1; + } + else + { + p = z; + q = 1 - z; + s = 1; + } + // + // A bit of meta-programming to figure out which implementation + // to use, based on the number of bits in the mantissa of T: + // + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + + // + // And get the result, negating where required: + // + return s * policies::checked_narrowing_cast( + detail::erf_inv_imp(static_cast(p), static_cast(q), forwarding_policy(), tag_type()), function); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erfc_inv(T z) +{ + return erfc_inv(z, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erf_inv(T z) +{ + return erf_inv(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#else // Special handling for NVRTC + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED auto erf_inv(T x) +{ + return ::erfinv(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto erf_inv(float x) +{ + return ::erfinvf(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erf_inv(T x, const Policy&) +{ + return ::erfinv(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erf_inv(float x, const Policy&) +{ + return ::erfinvf(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc_inv(T x) +{ + return ::erfcinv(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto erfc_inv(float x) +{ + return ::erfcinvf(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc_inv(T x, const Policy&) +{ + return ::erfcinv(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc_inv(float x, const Policy&) +{ + return ::erfcinvf(x); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTV + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_SF_ERF_INV_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/fp_traits.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/fp_traits.hpp new file mode 100644 index 0000000000000..015ea9cd35949 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/fp_traits.hpp @@ -0,0 +1,580 @@ +// fp_traits.hpp + +#ifndef BOOST_MATH_FP_TRAITS_HPP +#define BOOST_MATH_FP_TRAITS_HPP + +// Copyright (c) 2006 Johan Rade +// Copyright (c) 2024 Matt Borland + +// 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) + +/* +To support old compilers, care has been taken to avoid partial template +specialization and meta function forwarding. +With these techniques, the code could be simplified. +*/ + +#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT +// The VAX floating point formats are used (for float and double) +# define BOOST_FPCLASSIFY_VAX_FORMAT +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Determine endianness +#ifndef BOOST_MATH_STANDALONE + +#include +#define BOOST_MATH_ENDIAN_BIG_BYTE BOOST_ENDIAN_BIG_BYTE +#define BOOST_MATH_ENDIAN_LITTLE_BYTE BOOST_ENDIAN_LITTLE_BYTE + +#elif defined(_WIN32) + +#define BOOST_MATH_ENDIAN_BIG_BYTE 0 +#define BOOST_MATH_ENDIAN_LITTLE_BYTE 1 + +#elif defined(__BYTE_ORDER__) + +#define BOOST_MATH_ENDIAN_BIG_BYTE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BOOST_MATH_ENDIAN_LITTLE_BYTE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + +#else +#error Could not determine endian type. Please disable standalone mode, and file an issue at https://github.com/boostorg/math +#endif // Determine endianness + +static_assert((BOOST_MATH_ENDIAN_BIG_BYTE || BOOST_MATH_ENDIAN_LITTLE_BYTE) + && !(BOOST_MATH_ENDIAN_BIG_BYTE && BOOST_MATH_ENDIAN_LITTLE_BYTE), + "Inconsistent endianness detected. Please disable standalone mode, and file an issue at https://github.com/boostorg/math"); + +#ifdef BOOST_NO_STDC_NAMESPACE + namespace std{ using ::memcpy; } +#endif + +#ifndef FP_NORMAL + +#define FP_ZERO 0 +#define FP_NORMAL 1 +#define FP_INFINITE 2 +#define FP_NAN 3 +#define FP_SUBNORMAL 4 + +#else + +#define BOOST_HAS_FPCLASSIFY + +#ifndef fpclassify +# if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \ + && defined(_GLIBCXX_USE_C99_MATH) \ + && !(defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) \ + && (_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC != 0)) +# ifdef _STLP_VENDOR_CSTD +# if _STLPORT_VERSION >= 0x520 +# define BOOST_FPCLASSIFY_PREFIX ::__std_alias:: +# else +# define BOOST_FPCLASSIFY_PREFIX ::_STLP_VENDOR_CSTD:: +# endif +# else +# define BOOST_FPCLASSIFY_PREFIX ::std:: +# endif +# else +# undef BOOST_HAS_FPCLASSIFY +# define BOOST_FPCLASSIFY_PREFIX +# endif +#elif (defined(__HP_aCC) && !defined(__hppa)) +// aCC 6 appears to do "#define fpclassify fpclassify" which messes us up a bit! +# define BOOST_FPCLASSIFY_PREFIX :: +#else +# define BOOST_FPCLASSIFY_PREFIX +#endif + +#ifdef __MINGW32__ +# undef BOOST_HAS_FPCLASSIFY +#endif + +#endif + + +//------------------------------------------------------------------------------ + +namespace boost { +namespace math { +namespace detail { + +//------------------------------------------------------------------------------ + +/* +The following classes are used to tag the different methods that are used +for floating point classification +*/ + +struct native_tag {}; +template +struct generic_tag {}; +struct ieee_tag {}; +struct ieee_copy_all_bits_tag : public ieee_tag {}; +struct ieee_copy_leading_bits_tag : public ieee_tag {}; + +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// +// These helper functions are used only when numeric_limits<> +// members are not compile time constants: +// +inline bool is_generic_tag_false(const generic_tag*) +{ + return true; +} +inline bool is_generic_tag_false(const void*) +{ + return false; +} +#endif + +//------------------------------------------------------------------------------ + +/* +Most processors support three different floating point precisions: +single precision (32 bits), double precision (64 bits) +and extended double precision (80 - 128 bits, depending on the processor) + +Note that the C++ type long double can be implemented +both as double precision and extended double precision. +*/ + +struct unknown_precision{}; +struct single_precision {}; +struct double_precision {}; +struct extended_double_precision {}; + +// native_tag version -------------------------------------------------------------- + +template struct fp_traits_native +{ + typedef native_tag method; +}; + +// generic_tag version ------------------------------------------------------------- + +template struct fp_traits_non_native +{ +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + typedef generic_tag::is_specialized> method; +#else + typedef generic_tag method; +#endif +}; + +// ieee_tag versions --------------------------------------------------------------- + +/* +These specializations of fp_traits_non_native contain information needed +to "parse" the binary representation of a floating point number. + +Typedef members: + + bits -- the target type when copying the leading bytes of a floating + point number. It is a typedef for uint32_t or uint64_t. + + method -- tells us whether all bytes are copied or not. + It is a typedef for ieee_copy_all_bits_tag or ieee_copy_leading_bits_tag. + +Static data members: + + sign, exponent, flag, significand -- bit masks that give the meaning of the + bits in the leading bytes. + +Static function members: + + get_bits(), set_bits() -- provide access to the leading bytes. + +*/ + +// ieee_tag version, float (32 bits) ----------------------------------------------- + +#ifndef BOOST_FPCLASSIFY_VAX_FORMAT + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + BOOST_MATH_STATIC constexpr uint32_t sign = 0x80000000u; + BOOST_MATH_STATIC constexpr uint32_t exponent = 0x7f800000; + BOOST_MATH_STATIC constexpr uint32_t flag = 0x00000000; + BOOST_MATH_STATIC constexpr uint32_t significand = 0x007fffff; + + typedef uint32_t bits; + BOOST_MATH_GPU_ENABLED static void get_bits(float x, uint32_t& a) { std::memcpy(&a, &x, 4); } + BOOST_MATH_GPU_ENABLED static void set_bits(float& x, uint32_t a) { std::memcpy(&x, &a, 4); } +}; + +// ieee_tag version, double (64 bits) ---------------------------------------------- + +#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) \ + || defined(BOOST_BORLANDC) || defined(__CODEGEAR__) + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7ff00000; + static constexpr uint32_t flag = 0; + static constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 4; +}; + +//.............................................................................. + +#else + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + BOOST_MATH_STATIC constexpr uint64_t sign = static_cast(0x80000000u) << 32; + BOOST_MATH_STATIC constexpr uint64_t exponent = static_cast(0x7ff00000) << 32; + BOOST_MATH_STATIC constexpr uint64_t flag = 0; + BOOST_MATH_STATIC constexpr uint64_t significand + = (static_cast(0x000fffff) << 32) + static_cast(0xffffffffu); + + typedef uint64_t bits; + BOOST_MATH_GPU_ENABLED static void get_bits(double x, uint64_t& a) { std::memcpy(&a, &x, 8); } + BOOST_MATH_GPU_ENABLED static void set_bits(double& x, uint64_t a) { std::memcpy(&x, &a, 8); } +}; + +#endif + +#endif // #ifndef BOOST_FPCLASSIFY_VAX_FORMAT + +// long double (64 bits) ------------------------------------------------------- + +#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\ + || defined(BOOST_BORLANDC) || defined(__CODEGEAR__) + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7ff00000; + static constexpr uint32_t flag = 0; + static constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 4; +}; + +//.............................................................................. + +#else + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + static const uint64_t sign = static_cast(0x80000000u) << 32; + static const uint64_t exponent = static_cast(0x7ff00000) << 32; + static const uint64_t flag = 0; + static const uint64_t significand + = (static_cast(0x000fffff) << 32) + static_cast(0xffffffffu); + + typedef uint64_t bits; + static void get_bits(long double x, uint64_t& a) { std::memcpy(&a, &x, 8); } + static void set_bits(long double& x, uint64_t a) { std::memcpy(&x, &a, 8); } +}; + +#endif + + +// long double (>64 bits), x86 and x64 ----------------------------------------- + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \ + || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) + +// Intel extended double precision format (80 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + BOOST_MATH_STATIC constexpr uint32_t sign = 0x80000000u; + BOOST_MATH_STATIC constexpr uint32_t exponent = 0x7fff0000; + BOOST_MATH_STATIC constexpr uint32_t flag = 0x00008000; + BOOST_MATH_STATIC constexpr uint32_t significand = 0x00007fff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + 6, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + 6, &a, 4); + } +}; + + +// long double (>64 bits), Itanium --------------------------------------------- + +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + +// The floating point format is unknown at compile time +// No template specialization is provided. +// The generic_tag definition is used. + +// The Itanium supports both +// the Intel extended double precision format (80 bits) and +// the IEEE extended double precision format with 15 exponent bits (128 bits). + +#elif defined(__GNUC__) && (LDBL_MANT_DIG == 106) + +// +// Define nothing here and fall though to generic_tag: +// We have GCC's "double double" in effect, and any attempt +// to handle it via bit-fiddling is pretty much doomed to fail... +// + +// long double (>64 bits), PowerPC --------------------------------------------- + +#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \ + || defined(__ppc) || defined(__ppc__) || defined(__PPC__) + +// PowerPC extended double precision format (128 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + BOOST_MATH_STATIC constexpr uint32_t sign = 0x80000000u; + BOOST_MATH_STATIC constexpr uint32_t exponent = 0x7ff00000; + BOOST_MATH_STATIC constexpr uint32_t flag = 0x00000000; + BOOST_MATH_STATIC constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + BOOST_MATH_STATIC constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 12; +}; + + +// long double (>64 bits), Motorola 68K ---------------------------------------- + +#elif defined(__m68k) || defined(__m68k__) \ + || defined(__mc68000) || defined(__mc68000__) \ + +// Motorola extended double precision format (96 bits) + +// It is the same format as the Intel extended double precision format, +// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and +// 3) the flag bit is not set for infinity + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + BOOST_MATH_STATIC constexpr uint32_t sign = 0x80000000u; + BOOST_MATH_STATIC constexpr uint32_t exponent = 0x7fff0000; + BOOST_MATH_STATIC constexpr uint32_t flag = 0x00008000; + BOOST_MATH_STATIC constexpr uint32_t significand = 0x00007fff; + + // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding. + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, &x, 2); + std::memcpy(reinterpret_cast(&a) + 2, + reinterpret_cast(&x) + 4, 2); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(&x, &a, 2); + std::memcpy(reinterpret_cast(&x) + 4, + reinterpret_cast(&a) + 2, 2); + } +}; + + +// long double (>64 bits), All other processors -------------------------------- + +#else + +// IEEE extended double precision format with 15 exponent bits (128 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + BOOST_MATH_STATIC constexpr uint32_t sign = 0x80000000u; + BOOST_MATH_STATIC constexpr uint32_t exponent = 0x7fff0000; + BOOST_MATH_STATIC constexpr uint32_t flag = 0x00000000; + BOOST_MATH_STATIC constexpr uint32_t significand = 0x0000ffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + BOOST_MATH_STATIC constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 12; +}; + +#endif + +//------------------------------------------------------------------------------ + +// size_to_precision is a type switch for converting a C++ floating point type +// to the corresponding precision type. + +template struct size_to_precision +{ + typedef unknown_precision type; +}; + +template<> struct size_to_precision<4, true> +{ + typedef single_precision type; +}; + +template<> struct size_to_precision<8, true> +{ + typedef double_precision type; +}; + +template<> struct size_to_precision<10, true> +{ + typedef extended_double_precision type; +}; + +template<> struct size_to_precision<12, true> +{ + typedef extended_double_precision type; +}; + +template<> struct size_to_precision<16, true> +{ + typedef extended_double_precision type; +}; + +//------------------------------------------------------------------------------ +// +// Figure out whether to use native classification functions based on +// whether T is a built in floating point type or not: +// +template +struct select_native +{ + typedef typename size_to_precision::value>::type precision; + typedef fp_traits_non_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; + +//------------------------------------------------------------------------------ + +// fp_traits is a type switch that selects the right fp_traits_non_native + +#if (defined(BOOST_MATH_USE_C99) && !(defined(__GNUC__) && (__GNUC__ < 4))) \ + && !defined(__hpux) \ + && !defined(__DECCXX)\ + && !defined(__osf__) \ + && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)\ + && !defined(__FAST_MATH__)\ + && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)\ + && !defined(__INTEL_COMPILER)\ + && !defined(sun)\ + && !defined(__VXWORKS__)\ + && !defined(BOOST_MATH_HAS_GPU_SUPPORT) +# define BOOST_MATH_USE_STD_FPCLASSIFY +#endif + +template struct fp_traits +{ + typedef typename size_to_precision::value>::type precision; +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) + typedef typename select_native::type type; +#else + typedef fp_traits_non_native type; +#endif + typedef fp_traits_non_native sign_change_type; +}; + +//------------------------------------------------------------------------------ + +} // namespace detail +} // namespace math +} // namespace boost + +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/gamma_inva.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/gamma_inva.hpp new file mode 100644 index 0000000000000..8c3be8ef1aef7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/gamma_inva.hpp @@ -0,0 +1,241 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +// +// This is not a complete header file, it is included by gamma.hpp +// after it has defined it's definitions. This inverts the incomplete +// gamma functions P and Q on the first parameter "a" using a generic +// root finding algorithm (TOMS Algorithm 748). +// + +#ifndef BOOST_MATH_SP_DETAIL_GAMMA_INVA +#define BOOST_MATH_SP_DETAIL_GAMMA_INVA + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost{ namespace math{ + +#ifdef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED auto erfc_inv(T x, const Policy&); +#endif + +namespace detail{ + +template +struct gamma_inva_t +{ + BOOST_MATH_GPU_ENABLED gamma_inva_t(T z_, T p_, bool invert_) : z(z_), p(p_), invert(invert_) {} + BOOST_MATH_GPU_ENABLED T operator()(T a) + { + return invert ? p - boost::math::gamma_q(a, z, Policy()) : boost::math::gamma_p(a, z, Policy()) - p; + } +private: + T z, p; + bool invert; +}; + +template +BOOST_MATH_GPU_ENABLED T inverse_poisson_cornish_fisher(T lambda, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING + // mean: + T m = lambda; + // standard deviation: + T sigma = sqrt(lambda); + // skewness + T sk = 1 / sigma; + // kurtosis: + // T k = 1/lambda; + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + /* + // Add on correction due to kurtosis. + // Disabled for now, seems to make things worse? + // + if(lambda >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + */ + w = m + sigma * w; + return w > tools::min_value() ? w : tools::min_value(); +} + +template +BOOST_MATH_GPU_ENABLED T gamma_inva_imp(const T& z, const T& p, const T& q, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std lib math functions + // + // Special cases first: + // + if(p == 0) + { + return policies::raise_overflow_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + // + // Function object, this is the functor whose root + // we have to solve: + // + gamma_inva_t f(z, (p < q) ? p : q, (p < q) ? false : true); + // + // Tolerance: full precision. + // + tools::eps_tolerance tol(policies::digits()); + // + // Now figure out a starting guess for what a may be, + // we'll start out with a value that'll put p or q + // right bang in the middle of their range, the functions + // are quite sensitive so we should need too many steps + // to bracket the root from there: + // + T guess; + T factor = 8; + if(z >= 1) + { + // + // We can use the relationship between the incomplete + // gamma function and the poisson distribution to + // calculate an approximate inverse, for large z + // this is actually pretty accurate, but it fails badly + // when z is very small. Also set our step-factor according + // to how accurate we think the result is likely to be: + // + guess = 1 + inverse_poisson_cornish_fisher(z, q, p, pol); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + } + else if(z > 0.5) + { + guess = z * 1.2f; + } + else + { + guess = -0.4f / log(z); + } + // + // Max iterations permitted: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Use our generic derivative-free root finding procedure. + // We could use Newton steps here, taking the PDF of the + // Poisson distribution as our derivative, but that's + // even worse performance-wise than the generic method :-( + // + std::pair r = bracket_and_solve_root(f, guess, factor, false, tol, max_iter, pol); + if(max_iter >= policies::get_max_root_iterations()) + return policies::raise_evaluation_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol); + return (r.first + r.second) / 2; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_p_inva(T1 x, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(p == 0) + { + policies::raise_overflow_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(p == 1) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::gamma_inva_imp( + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + pol), "boost::math::gamma_p_inva<%1%>(%1%, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_q_inva(T1 x, T2 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(q == 1) + { + policies::raise_overflow_error("boost::math::gamma_q_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::gamma_inva_imp( + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + pol), "boost::math::gamma_q_inva<%1%>(%1%, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_p_inva(T1 x, T2 p) +{ + return boost::math::gamma_p_inva(x, p, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_q_inva(T1 x, T2 q) +{ + return boost::math::gamma_q_inva(x, q, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_DETAIL_GAMMA_INVA + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp new file mode 100644 index 0000000000000..be91d406c2ed6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_0F1_BESSEL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_0F1_BESSEL_HPP + +#include +#include + + namespace boost { namespace math { namespace detail { + + template + inline T hypergeometric_0F1_bessel(const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING + + //const bool is_z_nonpositive = z <= 0; + BOOST_MATH_ASSERT(z < 0); // condition used at call site + + const T sqrt_z = sqrt(-z); + const T bessel_mult = boost::math::cyl_bessel_j(b - 1, 2 * sqrt_z, pol); + + if (b > boost::math::max_factorial::value) + { + const T lsqrt_z = log(sqrt_z); + const T lsqrt_z_pow_b = (b - 1) * lsqrt_z; + T lg = (boost::math::lgamma(b, pol) - lsqrt_z_pow_b); + lg = exp(lg); + return lg * bessel_mult; + } + else + { + const T sqrt_z_pow_b = pow(sqrt_z, b - 1); + return (boost::math::tgamma(b, pol) / sqrt_z_pow_b) * bessel_mult; + } + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_0F1_BESSEL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp new file mode 100644 index 0000000000000..49f0fc0aacba7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp @@ -0,0 +1,293 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP + +#include + +// +// This file implements the addition theorems for 1F1 on z, specifically +// each function returns 1F1[a, b, z + k] for some integer k - there's +// no particular reason why k needs to be an integer, but no reason why +// it shouldn't be either. +// +// The functions are named hypergeometric_1f1_recurrence_on_z_[plus|minus|zero]_[plus|minus|zero] +// where a "plus" indicates forward recurrence, minus backwards recurrence, and zero no recurrence. +// So for example hypergeometric_1f1_recurrence_on_z_zero_plus uses forward recurrence on b and +// hypergeometric_1f1_recurrence_on_z_minus_minus uses backwards recurrence on both a and b. +// +// See https://dlmf.nist.gov/13.13 +// + + namespace boost { namespace math { namespace detail { + + // + // This works moderately well for a < 0, but has some very strange behaviour with + // strings of values of the same sign followed by a sign switch then another + // series all the same sign and so on.... doesn't converge smoothly either + // but rises and falls in wave-like behaviour.... very slow to converge... + // + template + struct hypergeometric_1f1_recurrence_on_z_minus_zero_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_minus_zero_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_minus_a_plus_n(b - a), a_(a), b_(b), z_(z), n(0), k(k_) + { + BOOST_MATH_STD_USING + long long scale1(0), scale2(0); + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol, scale1); + M_next = boost::math::detail::hypergeometric_1F1_imp(T(a - 1), b, z, pol, scale2); + if (scale1 != scale2) + M_next *= exp(T(scale2 - scale1)); + if (M > 1e10f) + { + // rescale: + long long rescale = lltrunc(log(fabs(M))); + M *= exp(T(-rescale)); + M_next *= exp(T(-rescale)); + scale1 += rescale; + } + scaling = scale1; + } + T operator()() + { + T result = term * M; + term *= b_minus_a_plus_n * k / ((z_ + k) * ++n); + b_minus_a_plus_n += 1; + T M2 = -((2 * (a_ - n) - b_ + z_) * M_next - (a_ - n) * M) / (b_ - (a_ - n)); + M = M_next; + M_next = M2; + + return result; + } + long long scale()const { return scaling; } + private: + T term, b_minus_a_plus_n, M, M_next, a_, b_, z_; + int n, k; + long long scaling; + }; + + template + T hypergeometric_1f1_recurrence_on_z_minus_zero(const T& a, const T& b, const T& z, int k, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT((z + k) / z > 0.5f); + hypergeometric_1f1_recurrence_on_z_minus_zero_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + log_scaling += s.scale(); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)) * pow(z / (z + k), b - a); + } + +#if 0 + + // + // These are commented out as they are currently unused, but may find use in the future: + // + + template + struct hypergeometric_1f1_recurrence_on_z_plus_plus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_plus_plus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), a_plus_n(a), b_plus_n(b), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a + 1, b + 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= a_plus_n * k / (b_plus_n * ++n); + a_plus_n += 1; + b_plus_n += 1; + // The a_plus_n == 0 case below isn't actually correct, but doesn't matter as that term will be zero + // anyway, we just need to not divide by zero and end up with a NaN in the result. + T M2 = (a_plus_n == -1) ? 1 : (a_plus_n == 0) ? 0 : (M_next * b_plus_n * (1 - b_plus_n + z_) + b_plus_n * (b_plus_n - 1) * M) / (a_plus_n * z_); + M = M_next; + M_next = M2; + return result; + } + T term, a_plus_n, b_plus_n, M, M_next, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_plus_plus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + hypergeometric_1f1_recurrence_on_z_plus_plus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result; + } + + template + struct hypergeometric_1f1_recurrence_on_z_zero_minus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_zero_minus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_pochhammer(1 - b), x_k_power(-k_ / z), b_minus_n(b), a_(a), z_(z), b_(b), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a, b - 1, z, pol); + } + T operator()() + { + BOOST_MATH_STD_USING + T result = term * M; + term *= b_pochhammer * x_k_power / ++n; + b_pochhammer += 1; + b_minus_n -= 1; + T M2 = (M_next * b_minus_n * (1 - b_minus_n - z_) + z_ * (b_minus_n - a_) * M) / (-b_minus_n * (b_minus_n - 1)); + M = M_next; + M_next = M2; + return result; + } + T term, b_pochhammer, x_k_power, M, M_next, b_minus_n, a_, z_, b_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_zero_minus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(abs(k) < fabs(z)); + hypergeometric_1f1_recurrence_on_z_zero_minus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * pow((z + k) / z, 1 - b); + } + + template + struct hypergeometric_1f1_recurrence_on_z_plus_zero_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_plus_zero_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), a_pochhammer(a), z_plus_k(z + k_), b_(b), a_(a), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a + 1, b, z, pol); + } + T operator()() + { + T result = term * M; + term *= a_pochhammer * k / (++n * z_plus_k); + a_pochhammer += 1; + T M2 = (a_pochhammer == -1) ? 1 : (a_pochhammer == 0) ? 0 : (M_next * (2 * a_pochhammer - b_ + z_) + (b_ - a_pochhammer) * M) / a_pochhammer; + M = M_next; + M_next = M2; + + return result; + } + T term, a_pochhammer, z_plus_k, M, M_next, b_minus_n, a_, b_, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_plus_zero(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(k / z > -0.5f); + //BOOST_MATH_ASSERT(floor(a) != a || a > 0); + hypergeometric_1f1_recurrence_on_z_plus_zero_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * pow(z / (z + k), a); + } + + template + struct hypergeometric_1f1_recurrence_on_z_zero_plus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_zero_plus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_minus_a_plus_n(b - a), b_plus_n(b), a_(a), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a, b + 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= b_minus_a_plus_n * -k / (b_plus_n * ++n); + b_minus_a_plus_n += 1; + b_plus_n += 1; + T M2 = (b_plus_n * (b_plus_n - 1) * M + b_plus_n * (1 - b_plus_n - z_) * M_next) / (-z_ * b_minus_a_plus_n); + M = M_next; + M_next = M2; + + return result; + } + T term, b_minus_a_plus_n, M, M_next, b_minus_n, a_, b_plus_n, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_zero_plus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + hypergeometric_1f1_recurrence_on_z_zero_plus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)); + } + // + // I'm unable to find any situation where this series isn't divergent and therefore + // is probably quite useless: + // + template + struct hypergeometric_1f1_recurrence_on_z_minus_minus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_minus_minus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), one_minus_b_plus_n(1 - b), a_(a), b_(b), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a - 1, b - 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= one_minus_b_plus_n * k / (z_ * ++n); + one_minus_b_plus_n += 1; + T M2 = -((b_ - n) * (1 - b_ + n + z_) * M_next - (a_ - n) * z_ * M) / ((b_ - n) * (b_ - n - 1)); + M = M_next; + M_next = M2; + + return result; + } + T term, one_minus_b_plus_n, M, M_next, a_, b_, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_minus_minus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + hypergeometric_1f1_recurrence_on_z_minus_minus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)) * pow((z + k) / z, 1 - b); + } +#endif + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp new file mode 100644 index 0000000000000..07d9dabf892c7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp @@ -0,0 +1,768 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP + +#include +#include +#include +#include +#include + + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_divergent_fallback(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + bool hypergeometric_1F1_is_tricomi_viable_positive_b(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if ((z < b) && (a > -50)) + return false; // might as well fall through to recursion + if (b <= 100) + return true; + // Even though we're in a reasonable domain for Tricomi's approximation, + // the arguments to the Bessel functions may be so large that we can't + // actually evaluate them: + T x = sqrt(fabs(2 * z * b - 4 * a * z)); + T v = b - 1; + return log(boost::math::constants::e() * x / (2 * v)) * v > tools::log_min_value(); + } + + // + // Returns an arbitrarily small value compared to "target" for use as a seed + // value for Bessel recurrences. Note that we'd better not make it too small + // or underflow may occur resulting in either one of the terms in the + // recurrence being zero, or else the result being zero. Using 1/epsilon + // as a safety factor ensures that if we do underflow to zero, all of the digits + // will have been cancelled out anyway: + // + template + T arbitrary_small_value(const T& target) + { + using std::fabs; + return (tools::min_value() / tools::epsilon()) * (fabs(target) > 1 ? target : 1); + } + + + template + struct hypergeometric_1F1_AS_13_3_7_tricomi_series + { + typedef T result_type; + + enum { cache_size = 64 }; + + hypergeometric_1F1_AS_13_3_7_tricomi_series(const T& a, const T& b, const T& z, const Policy& pol_) + : A_minus_2(1), A_minus_1(0), A(b / 2), mult(z / 2), term(1), b_minus_1_plus_n(b - 1), + bessel_arg((b / 2 - a) * z), + two_a_minus_b(2 * a - b), pol(pol_), n(2) + { + BOOST_MATH_STD_USING + term /= pow(fabs(bessel_arg), b_minus_1_plus_n / 2); + mult /= sqrt(fabs(bessel_arg)); + bessel_cache[cache_size - 1] = bessel_arg > 0 ? boost::math::cyl_bessel_j(b_minus_1_plus_n - 1, 2 * sqrt(bessel_arg), pol) : boost::math::cyl_bessel_i(b_minus_1_plus_n - 1, 2 * sqrt(-bessel_arg), pol); + if (fabs(bessel_cache[cache_size - 1]) < tools::min_value() / tools::epsilon()) + { + // We get very limited precision due to rapid denormalisation/underflow of the Bessel values, raise an exception and try something else: + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Underflow in Bessel functions", bessel_cache[cache_size - 1], pol); + // Exceptions are off if we get here, just fill the cache with NaN's and we'll let this method fail and fallback later: + std::fill(bessel_cache.begin(), bessel_cache.end(), std::numeric_limits::quiet_NaN()); + cache_offset = -cache_size; + return; + } + if ((fabs(term * bessel_cache[cache_size - 1]) < tools::min_value() / (tools::epsilon() * tools::epsilon())) || !(boost::math::isfinite)(term) || (!std::numeric_limits::has_infinity && (fabs(term) > tools::max_value()))) + { + term = -log(fabs(bessel_arg)) * b_minus_1_plus_n / 2; + log_scale = lltrunc(term); + term -= log_scale; + term = exp(term); + } + else + log_scale = 0; +#ifndef BOOST_MATH_NO_CXX17_IF_CONSTEXPR + if constexpr (std::numeric_limits::has_infinity) + { + if (!(boost::math::isfinite)(bessel_cache[cache_size - 1])) + { + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); + // Exceptions are off if we get here, just fill the cache with NaN's and we'll let this method fail and fallback later: + std::fill(bessel_cache.begin(), bessel_cache.end(), std::numeric_limits::quiet_NaN()); + } + } + else + if ((boost::math::isnan)(bessel_cache[cache_size - 1]) || (fabs(bessel_cache[cache_size - 1]) >= tools::max_value())) + { + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); + // Exceptions are off if we get here, just fill the cache with NaN's and we'll let this method fail and fallback later: + std::fill(bessel_cache.begin(), bessel_cache.end(), std::numeric_limits::quiet_NaN()); + } +#else + if ((std::numeric_limits::has_infinity && !(boost::math::isfinite)(bessel_cache[cache_size - 1])) + || (!std::numeric_limits::has_infinity && ((boost::math::isnan)(bessel_cache[cache_size - 1]) || (fabs(bessel_cache[cache_size - 1]) >= tools::max_value())))) + { + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); + // Exceptions are off if we get here, just fill the cache with NaN's and we'll let this method fail and fallback later: + std::fill(bessel_cache.begin(), bessel_cache.end(), std::numeric_limits::quiet_NaN()); + } +#endif + cache_offset = -cache_size; + refill_cache(); + } + T operator()() + { + // + // We return the n-2 term, and do 2 terms at once as every other term can be + // very small (or zero) when b == 2a: + // + BOOST_MATH_STD_USING + // + // Except in the multiprecision case, we have probably illiminated anything + // would need more than the default 64 Bessel Functions. Anything more + // than that risks becoming a divergent series anyway... + // + if(n - 2 - cache_offset >= cache_size) + refill_cache(); // LCOV_EXCL_LINE + T result = A_minus_2 * term * bessel_cache[n - 2 - cache_offset]; + term *= mult; + ++n; + T A_next = ((b_minus_1_plus_n + 2) * A_minus_1 + two_a_minus_b * A_minus_2) / n; + b_minus_1_plus_n += 1; + A_minus_2 = A_minus_1; + A_minus_1 = A; + A = A_next; + + if (A_minus_2 != 0) + { + if (n - 2 - cache_offset >= cache_size) + refill_cache(); // LCOV_EXCL_LINE + result += A_minus_2 * term * bessel_cache[n - 2 - cache_offset]; + } + term *= mult; + ++n; + A_next = ((b_minus_1_plus_n + 2) * A_minus_1 + two_a_minus_b * A_minus_2) / n; + b_minus_1_plus_n += 1; + A_minus_2 = A_minus_1; + A_minus_1 = A; + A = A_next; + + return result; + } + + long long scale()const + { + return log_scale; + } + + private: + T A_minus_2, A_minus_1, A, mult, term, b_minus_1_plus_n, bessel_arg, two_a_minus_b; + std::array bessel_cache; + const Policy& pol; + int n, cache_offset; + long long log_scale; + + hypergeometric_1F1_AS_13_3_7_tricomi_series operator=(const hypergeometric_1F1_AS_13_3_7_tricomi_series&) = delete; + + void refill_cache() + { + BOOST_MATH_STD_USING + // + // We don't calculate a new bessel I/J value: instead start our iterator off + // with an arbitrary small value, then when we get back to the last value in the previous cache + // calculate the ratio and use it to renormalise all the new values. This is more efficient, but + // also avoids problems with J_v(x) or I_v(x) underflowing to zero. + // + cache_offset += cache_size; + T last_value = bessel_cache.back(); + T ratio; + if (bessel_arg > 0) + { + // + // We will be calculating Bessel J. + // We need a different recurrence strategy for positive and negative orders: + // + if (b_minus_1_plus_n > 0) + { + bessel_j_backwards_iterator i(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(bessel_arg), arbitrary_small_value(last_value)); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_cache[j] = *i; + // + // Depending on the value of bessel_arg, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) + { + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), T(j + 1)) * 2); + if (!((boost::math::isfinite)(rescale))) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_cache[k] /= rescale; + bessel_j_backwards_iterator ti(b_minus_1_plus_n + j, 2 * sqrt(bessel_arg), bessel_cache[j + 1], bessel_cache[j]); + i = ti; + } + } + ratio = last_value / *i; + } + else + { + // + // Negative order is difficult: the J_v(x) recurrence relations are unstable + // *in both directions* for v < 0, except as v -> -INF when we have + // J_-v(x) ~= -sin(pi.v)Y_v(x). + // For small v what we can do is compute every other Bessel function and + // then fill in the gaps using the recurrence relation. This *is* stable + // provided that v is not so negative that the above approximation holds. + // + bessel_cache[1] = cyl_bessel_j(b_minus_1_plus_n + 1, 2 * sqrt(bessel_arg), pol); + bessel_cache[0] = (last_value + bessel_cache[1]) / (b_minus_1_plus_n / sqrt(bessel_arg)); + int pos = 2; + while ((pos < cache_size - 1) && (b_minus_1_plus_n + pos < 0)) + { + bessel_cache[pos + 1] = cyl_bessel_j(b_minus_1_plus_n + pos + 1, 2 * sqrt(bessel_arg), pol); + bessel_cache[pos] = (bessel_cache[pos-1] + bessel_cache[pos+1]) / ((b_minus_1_plus_n + pos) / sqrt(bessel_arg)); + pos += 2; + } + if (pos < cache_size) + { + // + // We have crossed over into the region where backward recursion is the stable direction + // start from arbitrary value and recurse down to "pos" and normalise: + // + bessel_j_backwards_iterator i2(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(bessel_arg), arbitrary_small_value(bessel_cache[pos-1])); + for (int loc = cache_size - 1; loc >= pos; --loc) + bessel_cache[loc] = *i2++; + ratio = bessel_cache[pos - 1] / *i2; + // + // Sanity check, if we normalised to an unusually small value then it was likely + // to be near a root and the calculated ratio is garbage, if so perform one + // more J_v(x) evaluation at position and normalise again: + // + if (fabs(bessel_cache[pos] * ratio / bessel_cache[pos - 1]) > 5) + ratio = cyl_bessel_j(b_minus_1_plus_n + pos, 2 * sqrt(bessel_arg), pol) / bessel_cache[pos]; + while (pos < cache_size) + bessel_cache[pos++] *= ratio; + } + ratio = 1; + } + } + else + { + // + // Bessel I. + // We need a different recurrence strategy for positive and negative orders: + // + if (b_minus_1_plus_n > 0) + { + bessel_i_backwards_iterator i(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(-bessel_arg), arbitrary_small_value(last_value)); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_cache[j] = *i; + // + // Depending on the value of bessel_arg, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) + { + T rescale = static_cast(pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), T(j + 1)) * 2); + if (!((boost::math::isfinite)(rescale))) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_cache[k] /= rescale; + i = bessel_i_backwards_iterator(b_minus_1_plus_n + j, 2 * sqrt(-bessel_arg), bessel_cache[j + 1], bessel_cache[j]); + } + } + ratio = last_value / *i; + } + else + { + // + // Forwards iteration is stable: + // + bessel_i_forwards_iterator i(b_minus_1_plus_n, 2 * sqrt(-bessel_arg)); + int pos = 0; + while ((pos < cache_size) && (b_minus_1_plus_n + pos < 0.5)) + { + bessel_cache[pos++] = *i++; + } + if (pos < cache_size) + { + // + // We have crossed over into the region where backward recursion is the stable direction + // start from arbitrary value and recurse down to "pos" and normalise: + // + bessel_i_backwards_iterator i2(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(-bessel_arg), arbitrary_small_value(last_value)); + for (int loc = cache_size - 1; loc >= pos; --loc) + bessel_cache[loc] = *i2++; + ratio = bessel_cache[pos - 1] / *i2; + while (pos < cache_size) + bessel_cache[pos++] *= ratio; + } + ratio = 1; + } + } + if(ratio != 1) + for (auto j = bessel_cache.begin(); j != bessel_cache.end(); ++j) + *j *= ratio; + // + // Very occasionally our normalisation fails because the normalisztion value + // is sitting right on top of a root (or very close to it). When that happens + // best to calculate a fresh Bessel evaluation and normalise again. + // + if (fabs(bessel_cache[0] / last_value) > 5) + { + ratio = (bessel_arg < 0 ? cyl_bessel_i(b_minus_1_plus_n, 2 * sqrt(-bessel_arg), pol) : cyl_bessel_j(b_minus_1_plus_n, 2 * sqrt(bessel_arg), pol)) / bessel_cache[0]; + if (ratio != 1) + for (auto j = bessel_cache.begin(); j != bessel_cache.end(); ++j) + *j *= ratio; + } + } + }; + + template + T hypergeometric_1F1_AS_13_3_7_tricomi(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scale) + { + BOOST_MATH_STD_USING + // + // Works for a < 0, b < 0, z > 0. + // + // For convergence we require A * term to be converging otherwise we get + // a divergent alternating series. It's actually really hard to analyse this + // and the best purely heuristic policy we've found is + // z < fabs((2 * a - b) / (sqrt(fabs(a)))) ; b > 0 or: + // z < fabs((2 * a - b) / (sqrt(fabs(ab)))) ; b < 0 + // + T prefix(0); + int prefix_sgn(0); + bool use_logs = false; + long long scale = 0; + // + // We can actually support the b == 2a case within here, but we haven't + // as we appear never to get here in practice. Which means this get out + // clause is a bit of defensive programming.... + // + if(b == 2 * a) + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + prefix = boost::math::tgamma(b, pol); + prefix *= exp(z / 2); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::runtime_error&) + { + use_logs = true; + } +#endif + if (use_logs || (prefix == 0) || !(boost::math::isfinite)(prefix) || (!std::numeric_limits::has_infinity && (fabs(prefix) >= tools::max_value()))) + { + use_logs = true; + prefix = boost::math::lgamma(b, &prefix_sgn, pol) + z / 2; + scale = lltrunc(prefix); + log_scale += scale; + prefix -= scale; + } + T result(0); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + bool retry = false; + long long series_scale = 0; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + hypergeometric_1F1_AS_13_3_7_tricomi_series s(a, b, z, pol); + series_scale = s.scale(); + log_scale += s.scale(); +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + T norm = 0; + result = 0; + if((a < 0) && (b < 0)) + result = boost::math::tools::checked_sum_series(s, boost::math::policies::get_epsilon(), max_iter, result, norm); + else + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, result); + if (!(boost::math::isfinite)(result) || (result == 0) || (!std::numeric_limits::has_infinity && (fabs(result) >= tools::max_value()))) + retry = true; + if (norm / fabs(result) > 1 / boost::math::tools::root_epsilon()) + retry = true; // fatal cancellation + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::overflow_error&) + { + retry = true; + } + catch (const boost::math::evaluation_error&) + { + retry = true; + } +#endif + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::overflow_error&) + { + log_scale -= scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } + catch (const boost::math::evaluation_error&) + { + log_scale -= scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } +#endif + if (retry) + { + log_scale -= scale; + log_scale -= series_scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_7<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (use_logs) + { + int sgn = boost::math::sign(result); + prefix += log(fabs(result)); + result = sgn * prefix_sgn * exp(prefix); + } + else + { + if ((fabs(result) > 1) && (fabs(prefix) > 1) && (tools::max_value() / fabs(result) < fabs(prefix))) + { + // Overflow: + scale = lltrunc(tools::log_max_value()) - 10; + log_scale += scale; + result /= exp(T(scale)); + } + result *= prefix; + } + return result; + } + + + template + struct cyl_bessel_i_large_x_sum + { + typedef T result_type; + + cyl_bessel_i_large_x_sum(const T& v, const T& x) : v(v), z(x), term(1), k(0) {} + + T operator()() + { + T result = term; + ++k; + term *= -(4 * v * v - (2 * k - 1) * (2 * k - 1)) / (8 * k * z); + return result; + } + T v, z, term; + int k; + }; + + template + T cyl_bessel_i_large_x_scaled(const T& v, const T& x, long long& log_scaling, const Policy& pol) + { + BOOST_MATH_STD_USING + cyl_bessel_i_large_x_sum s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::cyl_bessel_i_large_x<%1%>(%1%,%1%)", max_iter, pol); + long long scale = boost::math::lltrunc(x); + log_scaling += scale; + return result * exp(x - scale) / sqrt(boost::math::constants::two_pi() * x); + } + + + + template + struct hypergeometric_1F1_AS_13_3_6_series + { + typedef T result_type; + + enum { cache_size = 64 }; + // + // This series is only convergent/useful for a and b approximately equal + // (ideally |a-b| < 1). The series can also go divergent after a while + // when b < 0, which limits precision to around that of double. In that + // situation we return 0 to terminate the series as otherwise the divergent + // terms will destroy all the bits in our result before they do eventually + // converge again. One important use case for this series is for z < 0 + // and |a| << |b| so that either b-a == b or at least most of the digits in a + // are lost in the subtraction. Note that while you can easily convince yourself + // that the result should be unity when b-a == b, in fact this is not (quite) + // the case for large z. + // + hypergeometric_1F1_AS_13_3_6_series(const T& a, const T& b, const T& z, const T& b_minus_a, const Policy& pol_) + : b_minus_a(b_minus_a), half_z(z / 2), poch_1(2 * b_minus_a - 1), poch_2(b_minus_a - a), b_poch(b), term(1), last_result(1), sign(1), n(0), cache_offset(-cache_size), scale(0), pol(pol_) + { + bessel_i_cache[cache_size - 1] = half_z > tools::log_max_value() ? + cyl_bessel_i_large_x_scaled(T(b_minus_a - 1.5f), half_z, scale, pol) : boost::math::cyl_bessel_i(b_minus_a - 1.5f, half_z, pol); + refill_cache(); + } + T operator()() + { + BOOST_MATH_STD_USING + if(n - cache_offset >= cache_size) + refill_cache(); + + T result = term * (b_minus_a - 0.5f + n) * sign * bessel_i_cache[n - cache_offset]; + ++n; + term *= poch_1; + poch_1 = (n == 1) ? T(2 * b_minus_a) : T(poch_1 + 1); + term *= poch_2; + poch_2 += 1; + term /= n; + term /= b_poch; + b_poch += 1; + sign = -sign; + + if ((fabs(result) > fabs(last_result)) && (n > 100)) + return 0; // series has gone divergent! + + last_result = result; + + return result; + } + + long long scaling()const + { + return scale; + } + + private: + T b_minus_a, half_z, poch_1, poch_2, b_poch, term, last_result; + int sign; + int n, cache_offset; + long long scale; + const Policy& pol; + std::array bessel_i_cache; + + void refill_cache() + { + BOOST_MATH_STD_USING + // + // We don't calculate a new bessel I value: instead start our iterator off + // with an arbitrary small value, then when we get back to the last value in the previous cache + // calculate the ratio and use it to renormalise all the values. This is more efficient, but + // also avoids problems with I_v(x) underflowing to zero. + // + cache_offset += cache_size; + T last_value = bessel_i_cache.back(); + bessel_i_backwards_iterator i(b_minus_a + cache_offset + (int)cache_size - 1.5f, half_z, tools::min_value() * (fabs(last_value) > 1 ? last_value : 1) / tools::epsilon()); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_i_cache[j] = *i; + // + // Depending on the value of half_z, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if((j < cache_size - 2) && (bessel_i_cache[j + 1] != 0) && (tools::max_value() / fabs(64 * bessel_i_cache[j] / bessel_i_cache[j + 1]) < fabs(bessel_i_cache[j]))) + { + T rescale = static_cast(pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), T(j + 1)) * 2); + if (rescale > tools::max_value()) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_i_cache[k] /= rescale; + i = bessel_i_backwards_iterator(b_minus_a -0.5f + cache_offset + j, half_z, bessel_i_cache[j + 1], bessel_i_cache[j]); + } + } + T ratio = last_value / *i; + for (auto j = bessel_i_cache.begin(); j != bessel_i_cache.end(); ++j) + *j *= ratio; + } + + hypergeometric_1F1_AS_13_3_6_series() = delete; + hypergeometric_1F1_AS_13_3_6_series(const hypergeometric_1F1_AS_13_3_6_series&) = delete; + hypergeometric_1F1_AS_13_3_6_series& operator=(const hypergeometric_1F1_AS_13_3_6_series&) = delete; + }; + + template + T hypergeometric_1F1_AS_13_3_6(const T& a, const T& b, const T& z, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + if(b_minus_a == 0) + { + // special case: M(a,a,z) == exp(z) + long long scale = lltrunc(z, pol); + log_scaling += scale; + return exp(z - scale); + } + hypergeometric_1F1_AS_13_3_6_series s(a, b, z, b_minus_a, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_6<%1%>(%1%,%1%,%1%)", max_iter, pol); + result *= boost::math::tgamma(b_minus_a - 0.5f, pol) * pow(z / 4, -b_minus_a + T(0.5f)); + long long scale = lltrunc(z / 2); + log_scaling += scale; + log_scaling += s.scaling(); + result *= exp(z / 2 - scale); + return result; + } + + /****************************************************************************************************************/ + // + // The following are not used at present and are commented out for that reason: + // + /****************************************************************************************************************/ + +#if 0 + + template + struct hypergeometric_1F1_AS_13_3_8_series + { + // + // TODO: store and cache Bessel function evaluations via backwards recurrence. + // + // The C term grows by at least an order of magnitude with each iteration, and + // rate of growth is largely independent of the arguments. Free parameter h + // seems to give accurate results for small values (almost zero) or h=1. + // Convergence and accuracy, only when -a/z > 100, this appears to have no + // or little benefit over 13.3.7 as it generally requires more iterations? + // + hypergeometric_1F1_AS_13_3_8_series(const T& a, const T& b, const T& z, const T& h, const Policy& pol_) + : C_minus_2(1), C_minus_1(-b * h), C(b * (b + 1) * h * h / 2 - (2 * h - 1) * a / 2), + bessel_arg(2 * sqrt(-a * z)), bessel_order(b - 1), power_term(std::pow(-a * z, (1 - b) / 2)), mult(z / std::sqrt(-a * z)), + a_(a), b_(b), z_(z), h_(h), n(2), pol(pol_) + { + } + T operator()() + { + // we actually return the n-2 term: + T result = C_minus_2 * power_term * boost::math::cyl_bessel_j(bessel_order, bessel_arg, pol); + bessel_order += 1; + power_term *= mult; + ++n; + T C_next = ((1 - 2 * h_) * (n - 1) - b_ * h_) * C + + ((1 - 2 * h_) * a_ - h_ * (h_ - 1) *(b_ + n - 2)) * C_minus_1 + - h_ * (h_ - 1) * a_ * C_minus_2; + C_next /= n; + C_minus_2 = C_minus_1; + C_minus_1 = C; + C = C_next; + return result; + } + T C, C_minus_1, C_minus_2, bessel_arg, bessel_order, power_term, mult, a_, b_, z_, h_; + const Policy& pol; + int n; + + typedef T result_type; + }; + + template + T hypergeometric_1F1_AS_13_3_8(const T& a, const T& b, const T& z, const T& h, const Policy& pol) + { + BOOST_MATH_STD_USING + T prefix = exp(h * z) * boost::math::tgamma(b); + hypergeometric_1F1_AS_13_3_8_series s(a, b, z, h, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_8<%1%>(%1%,%1%,%1%)", max_iter, pol); + result *= prefix; + return result; + } + + // + // This is the series from https://dlmf.nist.gov/13.11 + // It appears to be unusable for a,z < 0, and for + // b < 0 appears to never be better than the defining series + // for 1F1. + // + template + struct hypergeometric_1f1_13_11_1_series + { + typedef T result_type; + + hypergeometric_1f1_13_11_1_series(const T& a, const T& b, const T& z, const Policy& pol_) + : term(1), two_a_minus_1_plus_s(2 * a - 1), two_a_minus_b_plus_s(2 * a - b), b_plus_s(b), a_minus_half_plus_s(a - 0.5f), half_z(z / 2), s(0), pol(pol_) + { + } + T operator()() + { + T result = term * a_minus_half_plus_s * boost::math::cyl_bessel_i(a_minus_half_plus_s, half_z, pol); + + term *= two_a_minus_1_plus_s * two_a_minus_b_plus_s / (b_plus_s * ++s); + two_a_minus_1_plus_s += 1; + a_minus_half_plus_s += 1; + two_a_minus_b_plus_s += 1; + b_plus_s += 1; + + return result; + } + T term, two_a_minus_1_plus_s, two_a_minus_b_plus_s, b_plus_s, a_minus_half_plus_s, half_z; + long long s; + const Policy& pol; + }; + + template + T hypergeometric_1f1_13_11_1(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + bool use_logs = false; + T prefix; + int prefix_sgn = 1; + if (true/*(a < boost::math::max_factorial::value) && (a > 0)*/) + prefix = boost::math::tgamma(a - 0.5f, pol); + else + { + prefix = boost::math::lgamma(a - 0.5f, &prefix_sgn, pol); + use_logs = true; + } + if (use_logs) + { + prefix += z / 2; + prefix += log(z / 4) * (0.5f - a); + } + else if (z > 0) + { + prefix *= pow(z / 4, 0.5f - a); + prefix *= exp(z / 2); + } + else + { + prefix *= exp(z / 2); + prefix *= pow(z / 4, 0.5f - a); + } + + hypergeometric_1f1_13_11_1_series s(a, b, z, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_13_11_1<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (use_logs) + { + long long scaling = lltrunc(prefix); + log_scaling += scaling; + prefix -= scaling; + result *= exp(prefix) * prefix_sgn; + } + else + result *= prefix; + + return result; + } + +#endif + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp new file mode 100644 index 0000000000000..ce2fe20eb7dec --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp @@ -0,0 +1,678 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) + +#ifndef BOOST_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ + +#include +#include + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + /* + Evaluation by method of ratios for domain b < 0 < a,z + + We first convert the recurrence relation into a ratio + of M(a+1, b+1, z) / M(a, b, z) using Shintan's equivalence + between solving a recurrence relation using Miller's method + and continued fractions. The continued fraction is VERY rapid + to converge (typically < 10 terms), but may converge to entirely + the wrong value if we're in a bad part of the domain. Strangely + it seems to matter not whether we use recurrence on a, b or a and b + they all work or not work about the same, so we might as well make + life easy for ourselves and use the a and b recurrence to avoid + having to apply one extra recurrence to convert from an a or b + recurrence to an a+b one. + + See: H. Shintan, Note on Miller's recurrence algorithm, J. Sci. Hiroshima Univ. Ser. A-I Math., 29 (1965), pp. 121-133. + Also: Computational Aspects of Three Term Recurrence Relations, SIAM Review, January 1967. + + The following table lists by experiment, how large z can be in order to + ensure the continued fraction converges to the correct value: + + a b max z + 13, -130, 22 + 13, -1300, 335 + 13, -13000, 3585 + 130, -130, 8 + 130, -1300, 263 + 130, - 13000, 3420 + 1300, -130, 1 + 1300, -1300, 90 + 1300, -13000, 2650 + 13000, -13, - + 13000, -130, - + 13000, -1300, 13 + 13000, -13000, 750 + + So try z_limit = -b / (4 - 5 * sqrt(log(a)) * a / b); + or z_limit = -b / (4 - 5 * (log(a)) * a / b) for a < 100 + + This still isn't quite right for both a and b small, but we'll be using a Bessel approximation + in that region anyway. + + Normalization using wronksian {1,2} from A&S 13.1.20 (also 13.1.12, 13.1.13): + + W{ M(a,b,z), z^(1-b)M(1+a-b, 2-b, z) } = (1-b)z^-b e^z + + = M(a,b,z) M2'(a,b,z) - M'(a,b,z) M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z)] - a/b M(a+1,b+1,z) z^(1-b)M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z)] - a/b R(a,b,z) M(a,b,z) z^(1-b)M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z) - a/b R(a,b,z) z^(1-b)M2(a,b,z) ] + so: + (1-b)e^z = M(a,b,z) [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z R(a,b,z) M2(a,b,z) ] + + */ + + template + inline bool is_in_hypergeometric_1F1_from_function_ratio_negative_b_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if (a < 100) + return z < -b / (4 - 5 * (log(a)) * a / b); + else + return z < -b / (4 - 5 * sqrt(log(a)) * a / b); + } + + template + T hypergeometric_1F1_from_function_ratio_negative_b(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling, const T& ratio) + { + BOOST_MATH_STD_USING + // + // Let M2 = M(1+a-b, 2-b, z) + // This is going to be a mighty big number: + // + long long local_scaling = 0; + T M2 = boost::math::detail::hypergeometric_1F1_imp(T(1 + a - b), T(2 - b), z, pol, local_scaling); + log_scaling -= local_scaling; // all the M2 terms are in the denominator + // + // Since a, b and z are all likely to be large we need the Wronksian + // calculation below to not overflow, so scale everything right down: + // + if (fabs(M2) > 1) + { + long long s = lltrunc(log(fabs(M2))); + log_scaling -= s; // M2 will be in the denominator, so subtract the scaling! + local_scaling += s; + M2 *= exp(T(-s)); + } + // + // Let M3 = M(1+a-b + 1, 2-b + 1, z) + // we can get to this from the ratio which is cheaper to calculate: + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef2(1 + a - b + 1, 2 - b + 1, z); + T M3 = boost::math::tools::function_ratio_from_backwards_recurrence(coef2, boost::math::policies::get_epsilon(), max_iter) * M2; + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Get the RHS of the Wronksian: + // + long long fz = lltrunc(z); + log_scaling += fz; + T rhs = (1 - b) * exp(z - fz); + // + // We need to divide that by: + // [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z^b R(a,b,z) M2(a,b,z) ] + // Note that at this stage, both M3 and M2 are scaled by exp(local_scaling). + // + T lhs = (a - b + 1) * z * M3 / (2 - b) + (1 - b) * M2 - a * z * ratio * M2 / b; + + return rhs / lhs; + } + + template + T hypergeometric_1F1_from_function_ratio_negative_b(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef(a + 1, b + 1, z); + T ratio = boost::math::tools::function_ratio_from_backwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + return hypergeometric_1F1_from_function_ratio_negative_b(a, b, z, pol, log_scaling, ratio); + } + // + // And over again, this time via forwards recurrence when z is large enough: + // + template + bool hypergeometric_1F1_is_in_forwards_recurence_for_negative_b_region(const T& a, const T& b, const T& z) + { + // + // There's no easy relation between a, b and z that tells us whether we're in the region + // where forwards recursion is stable, so use a lookup table, note that the minimum + // permissible z-value is decreasing with a, and increasing with |b|: + // + static const float data[][3] = { + {7.500e+00f, -7.500e+00f, 8.409e+00f }, + {7.500e+00f, -1.125e+01f, 8.409e+00f }, + {7.500e+00f, -1.688e+01f, 9.250e+00f }, + {7.500e+00f, -2.531e+01f, 1.119e+01f }, + {7.500e+00f, -3.797e+01f, 1.354e+01f }, + {7.500e+00f, -5.695e+01f, 1.983e+01f }, + {7.500e+00f, -8.543e+01f, 2.639e+01f }, + {7.500e+00f, -1.281e+02f, 3.864e+01f }, + {7.500e+00f, -1.922e+02f, 5.657e+01f }, + {7.500e+00f, -2.883e+02f, 8.283e+01f }, + {7.500e+00f, -4.325e+02f, 1.213e+02f }, + {7.500e+00f, -6.487e+02f, 1.953e+02f }, + {7.500e+00f, -9.731e+02f, 2.860e+02f }, + {7.500e+00f, -1.460e+03f, 4.187e+02f }, + {7.500e+00f, -2.189e+03f, 6.130e+02f }, + {7.500e+00f, -3.284e+03f, 9.872e+02f }, + {7.500e+00f, -4.926e+03f, 1.445e+03f }, + {7.500e+00f, -7.389e+03f, 2.116e+03f }, + {7.500e+00f, -1.108e+04f, 3.098e+03f }, + {7.500e+00f, -1.663e+04f, 4.990e+03f }, + {1.125e+01f, -7.500e+00f, 6.318e+00f }, + {1.125e+01f, -1.125e+01f, 6.950e+00f }, + {1.125e+01f, -1.688e+01f, 7.645e+00f }, + {1.125e+01f, -2.531e+01f, 9.250e+00f }, + {1.125e+01f, -3.797e+01f, 1.231e+01f }, + {1.125e+01f, -5.695e+01f, 1.639e+01f }, + {1.125e+01f, -8.543e+01f, 2.399e+01f }, + {1.125e+01f, -1.281e+02f, 3.513e+01f }, + {1.125e+01f, -1.922e+02f, 5.657e+01f }, + {1.125e+01f, -2.883e+02f, 8.283e+01f }, + {1.125e+01f, -4.325e+02f, 1.213e+02f }, + {1.125e+01f, -6.487e+02f, 1.776e+02f }, + {1.125e+01f, -9.731e+02f, 2.860e+02f }, + {1.125e+01f, -1.460e+03f, 4.187e+02f }, + {1.125e+01f, -2.189e+03f, 6.130e+02f }, + {1.125e+01f, -3.284e+03f, 9.872e+02f }, + {1.125e+01f, -4.926e+03f, 1.445e+03f }, + {1.125e+01f, -7.389e+03f, 2.116e+03f }, + {1.125e+01f, -1.108e+04f, 3.098e+03f }, + {1.125e+01f, -1.663e+04f, 4.990e+03f }, + {1.688e+01f, -7.500e+00f, 4.747e+00f }, + {1.688e+01f, -1.125e+01f, 5.222e+00f }, + {1.688e+01f, -1.688e+01f, 5.744e+00f }, + {1.688e+01f, -2.531e+01f, 7.645e+00f }, + {1.688e+01f, -3.797e+01f, 1.018e+01f }, + {1.688e+01f, -5.695e+01f, 1.490e+01f }, + {1.688e+01f, -8.543e+01f, 2.181e+01f }, + {1.688e+01f, -1.281e+02f, 3.193e+01f }, + {1.688e+01f, -1.922e+02f, 5.143e+01f }, + {1.688e+01f, -2.883e+02f, 7.530e+01f }, + {1.688e+01f, -4.325e+02f, 1.213e+02f }, + {1.688e+01f, -6.487e+02f, 1.776e+02f }, + {1.688e+01f, -9.731e+02f, 2.600e+02f }, + {1.688e+01f, -1.460e+03f, 4.187e+02f }, + {1.688e+01f, -2.189e+03f, 6.130e+02f }, + {1.688e+01f, -3.284e+03f, 9.872e+02f }, + {1.688e+01f, -4.926e+03f, 1.445e+03f }, + {1.688e+01f, -7.389e+03f, 2.116e+03f }, + {1.688e+01f, -1.108e+04f, 3.098e+03f }, + {1.688e+01f, -1.663e+04f, 4.990e+03f }, + {2.531e+01f, -7.500e+00f, 3.242e+00f }, + {2.531e+01f, -1.125e+01f, 3.566e+00f }, + {2.531e+01f, -1.688e+01f, 4.315e+00f }, + {2.531e+01f, -2.531e+01f, 5.744e+00f }, + {2.531e+01f, -3.797e+01f, 7.645e+00f }, + {2.531e+01f, -5.695e+01f, 1.231e+01f }, + {2.531e+01f, -8.543e+01f, 1.803e+01f }, + {2.531e+01f, -1.281e+02f, 2.903e+01f }, + {2.531e+01f, -1.922e+02f, 4.676e+01f }, + {2.531e+01f, -2.883e+02f, 6.845e+01f }, + {2.531e+01f, -4.325e+02f, 1.102e+02f }, + {2.531e+01f, -6.487e+02f, 1.776e+02f }, + {2.531e+01f, -9.731e+02f, 2.600e+02f }, + {2.531e+01f, -1.460e+03f, 4.187e+02f }, + {2.531e+01f, -2.189e+03f, 6.130e+02f }, + {2.531e+01f, -3.284e+03f, 8.974e+02f }, + {2.531e+01f, -4.926e+03f, 1.445e+03f }, + {2.531e+01f, -7.389e+03f, 2.116e+03f }, + {2.531e+01f, -1.108e+04f, 3.098e+03f }, + {2.531e+01f, -1.663e+04f, 4.990e+03f }, + {3.797e+01f, -7.500e+00f, 2.214e+00f }, + {3.797e+01f, -1.125e+01f, 2.679e+00f }, + {3.797e+01f, -1.688e+01f, 3.242e+00f }, + {3.797e+01f, -2.531e+01f, 4.315e+00f }, + {3.797e+01f, -3.797e+01f, 6.318e+00f }, + {3.797e+01f, -5.695e+01f, 9.250e+00f }, + {3.797e+01f, -8.543e+01f, 1.490e+01f }, + {3.797e+01f, -1.281e+02f, 2.399e+01f }, + {3.797e+01f, -1.922e+02f, 3.864e+01f }, + {3.797e+01f, -2.883e+02f, 6.223e+01f }, + {3.797e+01f, -4.325e+02f, 1.002e+02f }, + {3.797e+01f, -6.487e+02f, 1.614e+02f }, + {3.797e+01f, -9.731e+02f, 2.600e+02f }, + {3.797e+01f, -1.460e+03f, 3.806e+02f }, + {3.797e+01f, -2.189e+03f, 6.130e+02f }, + {3.797e+01f, -3.284e+03f, 8.974e+02f }, + {3.797e+01f, -4.926e+03f, 1.445e+03f }, + {3.797e+01f, -7.389e+03f, 2.116e+03f }, + {3.797e+01f, -1.108e+04f, 3.098e+03f }, + {3.797e+01f, -1.663e+04f, 4.990e+03f }, + {5.695e+01f, -7.500e+00f, 1.513e+00f }, + {5.695e+01f, -1.125e+01f, 1.830e+00f }, + {5.695e+01f, -1.688e+01f, 2.214e+00f }, + {5.695e+01f, -2.531e+01f, 3.242e+00f }, + {5.695e+01f, -3.797e+01f, 4.315e+00f }, + {5.695e+01f, -5.695e+01f, 7.645e+00f }, + {5.695e+01f, -8.543e+01f, 1.231e+01f }, + {5.695e+01f, -1.281e+02f, 1.983e+01f }, + {5.695e+01f, -1.922e+02f, 3.513e+01f }, + {5.695e+01f, -2.883e+02f, 5.657e+01f }, + {5.695e+01f, -4.325e+02f, 9.111e+01f }, + {5.695e+01f, -6.487e+02f, 1.467e+02f }, + {5.695e+01f, -9.731e+02f, 2.363e+02f }, + {5.695e+01f, -1.460e+03f, 3.806e+02f }, + {5.695e+01f, -2.189e+03f, 5.572e+02f }, + {5.695e+01f, -3.284e+03f, 8.974e+02f }, + {5.695e+01f, -4.926e+03f, 1.314e+03f }, + {5.695e+01f, -7.389e+03f, 2.116e+03f }, + {5.695e+01f, -1.108e+04f, 3.098e+03f }, + {5.695e+01f, -1.663e+04f, 4.990e+03f }, + {8.543e+01f, -7.500e+00f, 1.250e+00f }, + {8.543e+01f, -1.125e+01f, 1.250e+00f }, + {8.543e+01f, -1.688e+01f, 1.513e+00f }, + {8.543e+01f, -2.531e+01f, 2.214e+00f }, + {8.543e+01f, -3.797e+01f, 3.242e+00f }, + {8.543e+01f, -5.695e+01f, 5.222e+00f }, + {8.543e+01f, -8.543e+01f, 9.250e+00f }, + {8.543e+01f, -1.281e+02f, 1.639e+01f }, + {8.543e+01f, -1.922e+02f, 2.903e+01f }, + {8.543e+01f, -2.883e+02f, 5.143e+01f }, + {8.543e+01f, -4.325e+02f, 8.283e+01f }, + {8.543e+01f, -6.487e+02f, 1.334e+02f }, + {8.543e+01f, -9.731e+02f, 2.148e+02f }, + {8.543e+01f, -1.460e+03f, 3.460e+02f }, + {8.543e+01f, -2.189e+03f, 5.572e+02f }, + {8.543e+01f, -3.284e+03f, 8.974e+02f }, + {8.543e+01f, -4.926e+03f, 1.314e+03f }, + {8.543e+01f, -7.389e+03f, 2.116e+03f }, + {8.543e+01f, -1.108e+04f, 3.098e+03f }, + {8.543e+01f, -1.663e+04f, 4.536e+03f }, + {1.281e+02f, -7.500e+00f, 1.250e+00f }, + {1.281e+02f, -1.125e+01f, 1.250e+00f }, + {1.281e+02f, -1.688e+01f, 1.250e+00f }, + {1.281e+02f, -2.531e+01f, 1.513e+00f }, + {1.281e+02f, -3.797e+01f, 2.214e+00f }, + {1.281e+02f, -5.695e+01f, 3.923e+00f }, + {1.281e+02f, -8.543e+01f, 6.950e+00f }, + {1.281e+02f, -1.281e+02f, 1.231e+01f }, + {1.281e+02f, -1.922e+02f, 2.181e+01f }, + {1.281e+02f, -2.883e+02f, 4.250e+01f }, + {1.281e+02f, -4.325e+02f, 6.845e+01f }, + {1.281e+02f, -6.487e+02f, 1.213e+02f }, + {1.281e+02f, -9.731e+02f, 1.953e+02f }, + {1.281e+02f, -1.460e+03f, 3.460e+02f }, + {1.281e+02f, -2.189e+03f, 5.572e+02f }, + {1.281e+02f, -3.284e+03f, 8.159e+02f }, + {1.281e+02f, -4.926e+03f, 1.314e+03f }, + {1.281e+02f, -7.389e+03f, 1.924e+03f }, + {1.281e+02f, -1.108e+04f, 3.098e+03f }, + {1.281e+02f, -1.663e+04f, 4.536e+03f }, + {1.922e+02f, -7.500e+00f, 1.250e+00f }, + {1.922e+02f, -1.125e+01f, 1.250e+00f }, + {1.922e+02f, -1.688e+01f, 1.250e+00f }, + {1.922e+02f, -2.531e+01f, 1.250e+00f }, + {1.922e+02f, -3.797e+01f, 1.664e+00f }, + {1.922e+02f, -5.695e+01f, 2.679e+00f }, + {1.922e+02f, -8.543e+01f, 5.222e+00f }, + {1.922e+02f, -1.281e+02f, 9.250e+00f }, + {1.922e+02f, -1.922e+02f, 1.803e+01f }, + {1.922e+02f, -2.883e+02f, 3.193e+01f }, + {1.922e+02f, -4.325e+02f, 5.657e+01f }, + {1.922e+02f, -6.487e+02f, 1.002e+02f }, + {1.922e+02f, -9.731e+02f, 1.776e+02f }, + {1.922e+02f, -1.460e+03f, 3.145e+02f }, + {1.922e+02f, -2.189e+03f, 5.066e+02f }, + {1.922e+02f, -3.284e+03f, 8.159e+02f }, + {1.922e+02f, -4.926e+03f, 1.194e+03f }, + {1.922e+02f, -7.389e+03f, 1.924e+03f }, + {1.922e+02f, -1.108e+04f, 3.098e+03f }, + {1.922e+02f, -1.663e+04f, 4.536e+03f }, + {2.883e+02f, -7.500e+00f, 1.250e+00f }, + {2.883e+02f, -1.125e+01f, 1.250e+00f }, + {2.883e+02f, -1.688e+01f, 1.250e+00f }, + {2.883e+02f, -2.531e+01f, 1.250e+00f }, + {2.883e+02f, -3.797e+01f, 1.250e+00f }, + {2.883e+02f, -5.695e+01f, 2.013e+00f }, + {2.883e+02f, -8.543e+01f, 3.566e+00f }, + {2.883e+02f, -1.281e+02f, 6.950e+00f }, + {2.883e+02f, -1.922e+02f, 1.354e+01f }, + {2.883e+02f, -2.883e+02f, 2.399e+01f }, + {2.883e+02f, -4.325e+02f, 4.676e+01f }, + {2.883e+02f, -6.487e+02f, 8.283e+01f }, + {2.883e+02f, -9.731e+02f, 1.614e+02f }, + {2.883e+02f, -1.460e+03f, 2.600e+02f }, + {2.883e+02f, -2.189e+03f, 4.605e+02f }, + {2.883e+02f, -3.284e+03f, 7.417e+02f }, + {2.883e+02f, -4.926e+03f, 1.194e+03f }, + {2.883e+02f, -7.389e+03f, 1.924e+03f }, + {2.883e+02f, -1.108e+04f, 2.817e+03f }, + {2.883e+02f, -1.663e+04f, 4.536e+03f }, + {4.325e+02f, -7.500e+00f, 1.250e+00f }, + {4.325e+02f, -1.125e+01f, 1.250e+00f }, + {4.325e+02f, -1.688e+01f, 1.250e+00f }, + {4.325e+02f, -2.531e+01f, 1.250e+00f }, + {4.325e+02f, -3.797e+01f, 1.250e+00f }, + {4.325e+02f, -5.695e+01f, 1.375e+00f }, + {4.325e+02f, -8.543e+01f, 2.436e+00f }, + {4.325e+02f, -1.281e+02f, 4.747e+00f }, + {4.325e+02f, -1.922e+02f, 9.250e+00f }, + {4.325e+02f, -2.883e+02f, 1.803e+01f }, + {4.325e+02f, -4.325e+02f, 3.513e+01f }, + {4.325e+02f, -6.487e+02f, 6.845e+01f }, + {4.325e+02f, -9.731e+02f, 1.334e+02f }, + {4.325e+02f, -1.460e+03f, 2.363e+02f }, + {4.325e+02f, -2.189e+03f, 3.806e+02f }, + {4.325e+02f, -3.284e+03f, 6.743e+02f }, + {4.325e+02f, -4.926e+03f, 1.086e+03f }, + {4.325e+02f, -7.389e+03f, 1.749e+03f }, + {4.325e+02f, -1.108e+04f, 2.817e+03f }, + {4.325e+02f, -1.663e+04f, 4.536e+03f }, + {6.487e+02f, -7.500e+00f, 1.250e+00f }, + {6.487e+02f, -1.125e+01f, 1.250e+00f }, + {6.487e+02f, -1.688e+01f, 1.250e+00f }, + {6.487e+02f, -2.531e+01f, 1.250e+00f }, + {6.487e+02f, -3.797e+01f, 1.250e+00f }, + {6.487e+02f, -5.695e+01f, 1.250e+00f }, + {6.487e+02f, -8.543e+01f, 1.664e+00f }, + {6.487e+02f, -1.281e+02f, 3.242e+00f }, + {6.487e+02f, -1.922e+02f, 6.950e+00f }, + {6.487e+02f, -2.883e+02f, 1.354e+01f }, + {6.487e+02f, -4.325e+02f, 2.639e+01f }, + {6.487e+02f, -6.487e+02f, 5.143e+01f }, + {6.487e+02f, -9.731e+02f, 1.002e+02f }, + {6.487e+02f, -1.460e+03f, 1.953e+02f }, + {6.487e+02f, -2.189e+03f, 3.460e+02f }, + {6.487e+02f, -3.284e+03f, 6.130e+02f }, + {6.487e+02f, -4.926e+03f, 9.872e+02f }, + {6.487e+02f, -7.389e+03f, 1.590e+03f }, + {6.487e+02f, -1.108e+04f, 2.561e+03f }, + {6.487e+02f, -1.663e+04f, 4.124e+03f }, + {9.731e+02f, -7.500e+00f, 1.250e+00f }, + {9.731e+02f, -1.125e+01f, 1.250e+00f }, + {9.731e+02f, -1.688e+01f, 1.250e+00f }, + {9.731e+02f, -2.531e+01f, 1.250e+00f }, + {9.731e+02f, -3.797e+01f, 1.250e+00f }, + {9.731e+02f, -5.695e+01f, 1.250e+00f }, + {9.731e+02f, -8.543e+01f, 1.250e+00f }, + {9.731e+02f, -1.281e+02f, 2.214e+00f }, + {9.731e+02f, -1.922e+02f, 4.747e+00f }, + {9.731e+02f, -2.883e+02f, 9.250e+00f }, + {9.731e+02f, -4.325e+02f, 1.983e+01f }, + {9.731e+02f, -6.487e+02f, 3.864e+01f }, + {9.731e+02f, -9.731e+02f, 7.530e+01f }, + {9.731e+02f, -1.460e+03f, 1.467e+02f }, + {9.731e+02f, -2.189e+03f, 2.860e+02f }, + {9.731e+02f, -3.284e+03f, 5.066e+02f }, + {9.731e+02f, -4.926e+03f, 8.974e+02f }, + {9.731e+02f, -7.389e+03f, 1.445e+03f }, + {9.731e+02f, -1.108e+04f, 2.561e+03f }, + {9.731e+02f, -1.663e+04f, 4.124e+03f }, + {1.460e+03f, -7.500e+00f, 1.250e+00f }, + {1.460e+03f, -1.125e+01f, 1.250e+00f }, + {1.460e+03f, -1.688e+01f, 1.250e+00f }, + {1.460e+03f, -2.531e+01f, 1.250e+00f }, + {1.460e+03f, -3.797e+01f, 1.250e+00f }, + {1.460e+03f, -5.695e+01f, 1.250e+00f }, + {1.460e+03f, -8.543e+01f, 1.250e+00f }, + {1.460e+03f, -1.281e+02f, 1.513e+00f }, + {1.460e+03f, -1.922e+02f, 3.242e+00f }, + {1.460e+03f, -2.883e+02f, 6.950e+00f }, + {1.460e+03f, -4.325e+02f, 1.354e+01f }, + {1.460e+03f, -6.487e+02f, 2.903e+01f }, + {1.460e+03f, -9.731e+02f, 5.657e+01f }, + {1.460e+03f, -1.460e+03f, 1.213e+02f }, + {1.460e+03f, -2.189e+03f, 2.148e+02f }, + {1.460e+03f, -3.284e+03f, 4.187e+02f }, + {1.460e+03f, -4.926e+03f, 7.417e+02f }, + {1.460e+03f, -7.389e+03f, 1.314e+03f }, + {1.460e+03f, -1.108e+04f, 2.328e+03f }, + {1.460e+03f, -1.663e+04f, 3.749e+03f }, + {2.189e+03f, -7.500e+00f, 1.250e+00f }, + {2.189e+03f, -1.125e+01f, 1.250e+00f }, + {2.189e+03f, -1.688e+01f, 1.250e+00f }, + {2.189e+03f, -2.531e+01f, 1.250e+00f }, + {2.189e+03f, -3.797e+01f, 1.250e+00f }, + {2.189e+03f, -5.695e+01f, 1.250e+00f }, + {2.189e+03f, -8.543e+01f, 1.250e+00f }, + {2.189e+03f, -1.281e+02f, 1.250e+00f }, + {2.189e+03f, -1.922e+02f, 2.214e+00f }, + {2.189e+03f, -2.883e+02f, 4.747e+00f }, + {2.189e+03f, -4.325e+02f, 9.250e+00f }, + {2.189e+03f, -6.487e+02f, 1.983e+01f }, + {2.189e+03f, -9.731e+02f, 4.250e+01f }, + {2.189e+03f, -1.460e+03f, 8.283e+01f }, + {2.189e+03f, -2.189e+03f, 1.776e+02f }, + {2.189e+03f, -3.284e+03f, 3.460e+02f }, + {2.189e+03f, -4.926e+03f, 6.130e+02f }, + {2.189e+03f, -7.389e+03f, 1.086e+03f }, + {2.189e+03f, -1.108e+04f, 1.924e+03f }, + {2.189e+03f, -1.663e+04f, 3.408e+03f }, + {3.284e+03f, -7.500e+00f, 1.250e+00f }, + {3.284e+03f, -1.125e+01f, 1.250e+00f }, + {3.284e+03f, -1.688e+01f, 1.250e+00f }, + {3.284e+03f, -2.531e+01f, 1.250e+00f }, + {3.284e+03f, -3.797e+01f, 1.250e+00f }, + {3.284e+03f, -5.695e+01f, 1.250e+00f }, + {3.284e+03f, -8.543e+01f, 1.250e+00f }, + {3.284e+03f, -1.281e+02f, 1.250e+00f }, + {3.284e+03f, -1.922e+02f, 1.513e+00f }, + {3.284e+03f, -2.883e+02f, 3.242e+00f }, + {3.284e+03f, -4.325e+02f, 6.318e+00f }, + {3.284e+03f, -6.487e+02f, 1.354e+01f }, + {3.284e+03f, -9.731e+02f, 2.903e+01f }, + {3.284e+03f, -1.460e+03f, 6.223e+01f }, + {3.284e+03f, -2.189e+03f, 1.334e+02f }, + {3.284e+03f, -3.284e+03f, 2.600e+02f }, + {3.284e+03f, -4.926e+03f, 5.066e+02f }, + {3.284e+03f, -7.389e+03f, 9.872e+02f }, + {3.284e+03f, -1.108e+04f, 1.749e+03f }, + {3.284e+03f, -1.663e+04f, 3.098e+03f }, + {4.926e+03f, -7.500e+00f, 1.250e+00f }, + {4.926e+03f, -1.125e+01f, 1.250e+00f }, + {4.926e+03f, -1.688e+01f, 1.250e+00f }, + {4.926e+03f, -2.531e+01f, 1.250e+00f }, + {4.926e+03f, -3.797e+01f, 1.250e+00f }, + {4.926e+03f, -5.695e+01f, 1.250e+00f }, + {4.926e+03f, -8.543e+01f, 1.250e+00f }, + {4.926e+03f, -1.281e+02f, 1.250e+00f }, + {4.926e+03f, -1.922e+02f, 1.250e+00f }, + {4.926e+03f, -2.883e+02f, 2.013e+00f }, + {4.926e+03f, -4.325e+02f, 4.315e+00f }, + {4.926e+03f, -6.487e+02f, 9.250e+00f }, + {4.926e+03f, -9.731e+02f, 2.181e+01f }, + {4.926e+03f, -1.460e+03f, 4.250e+01f }, + {4.926e+03f, -2.189e+03f, 9.111e+01f }, + {4.926e+03f, -3.284e+03f, 1.953e+02f }, + {4.926e+03f, -4.926e+03f, 3.806e+02f }, + {4.926e+03f, -7.389e+03f, 7.417e+02f }, + {4.926e+03f, -1.108e+04f, 1.445e+03f }, + {4.926e+03f, -1.663e+04f, 2.561e+03f }, + {7.389e+03f, -7.500e+00f, 1.250e+00f }, + {7.389e+03f, -1.125e+01f, 1.250e+00f }, + {7.389e+03f, -1.688e+01f, 1.250e+00f }, + {7.389e+03f, -2.531e+01f, 1.250e+00f }, + {7.389e+03f, -3.797e+01f, 1.250e+00f }, + {7.389e+03f, -5.695e+01f, 1.250e+00f }, + {7.389e+03f, -8.543e+01f, 1.250e+00f }, + {7.389e+03f, -1.281e+02f, 1.250e+00f }, + {7.389e+03f, -1.922e+02f, 1.250e+00f }, + {7.389e+03f, -2.883e+02f, 1.375e+00f }, + {7.389e+03f, -4.325e+02f, 2.947e+00f }, + {7.389e+03f, -6.487e+02f, 6.318e+00f }, + {7.389e+03f, -9.731e+02f, 1.490e+01f }, + {7.389e+03f, -1.460e+03f, 3.193e+01f }, + {7.389e+03f, -2.189e+03f, 6.845e+01f }, + {7.389e+03f, -3.284e+03f, 1.334e+02f }, + {7.389e+03f, -4.926e+03f, 2.860e+02f }, + {7.389e+03f, -7.389e+03f, 5.572e+02f }, + {7.389e+03f, -1.108e+04f, 1.086e+03f }, + {7.389e+03f, -1.663e+04f, 2.116e+03f }, + {1.108e+04f, -7.500e+00f, 1.250e+00f }, + {1.108e+04f, -1.125e+01f, 1.250e+00f }, + {1.108e+04f, -1.688e+01f, 1.250e+00f }, + {1.108e+04f, -2.531e+01f, 1.250e+00f }, + {1.108e+04f, -3.797e+01f, 1.250e+00f }, + {1.108e+04f, -5.695e+01f, 1.250e+00f }, + {1.108e+04f, -8.543e+01f, 1.250e+00f }, + {1.108e+04f, -1.281e+02f, 1.250e+00f }, + {1.108e+04f, -1.922e+02f, 1.250e+00f }, + {1.108e+04f, -2.883e+02f, 1.250e+00f }, + {1.108e+04f, -4.325e+02f, 2.013e+00f }, + {1.108e+04f, -6.487e+02f, 4.315e+00f }, + {1.108e+04f, -9.731e+02f, 1.018e+01f }, + {1.108e+04f, -1.460e+03f, 2.181e+01f }, + {1.108e+04f, -2.189e+03f, 4.676e+01f }, + {1.108e+04f, -3.284e+03f, 1.002e+02f }, + {1.108e+04f, -4.926e+03f, 2.148e+02f }, + {1.108e+04f, -7.389e+03f, 4.187e+02f }, + {1.108e+04f, -1.108e+04f, 8.974e+02f }, + {1.108e+04f, -1.663e+04f, 1.749e+03f }, + {1.663e+04f, -7.500e+00f, 1.250e+00f }, + {1.663e+04f, -1.125e+01f, 1.250e+00f }, + {1.663e+04f, -1.688e+01f, 1.250e+00f }, + {1.663e+04f, -2.531e+01f, 1.250e+00f }, + {1.663e+04f, -3.797e+01f, 1.250e+00f }, + {1.663e+04f, -5.695e+01f, 1.250e+00f }, + {1.663e+04f, -8.543e+01f, 1.250e+00f }, + {1.663e+04f, -1.281e+02f, 1.250e+00f }, + {1.663e+04f, -1.922e+02f, 1.250e+00f }, + {1.663e+04f, -2.883e+02f, 1.250e+00f }, + {1.663e+04f, -4.325e+02f, 1.375e+00f }, + {1.663e+04f, -6.487e+02f, 2.947e+00f }, + {1.663e+04f, -9.731e+02f, 6.318e+00f }, + {1.663e+04f, -1.460e+03f, 1.490e+01f }, + {1.663e+04f, -2.189e+03f, 3.193e+01f }, + {1.663e+04f, -3.284e+03f, 6.845e+01f }, + {1.663e+04f, -4.926e+03f, 1.467e+02f }, + {1.663e+04f, -7.389e+03f, 3.145e+02f }, + {1.663e+04f, -1.108e+04f, 6.743e+02f }, + {1.663e+04f, -1.663e+04f, 1.314e+03f }, + }; + if ((a > 1.663e+04) || (-b > 1.663e+04)) + return z > -b; // Way overly conservative? + if (a < data[0][0]) + return false; + int index = 0; + while (data[index][0] < a) + ++index; + if(a != data[index][0]) + --index; + while ((data[index][1] < b) && (data[index][2] > 1.25)) + --index; + ++index; + BOOST_MATH_ASSERT(a > data[index][0]); + BOOST_MATH_ASSERT(-b < -data[index][1]); + return z > data[index][2]; + } + template + T hypergeometric_1F1_from_function_ratio_negative_b_forwards(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef(a, b, z); + T ratio = 1 / boost::math::tools::function_ratio_from_forwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // We can't normalise via the Wronksian as the subtraction in the Wronksian will suffer an exquisite amount of cancellation - + // potentially many hundreds of digits in this region. However, if forwards iteration is stable at this point + // it will also be stable for M(a, b+1, z) etc all the way up to the origin, and hopefully one step beyond. So + // use a reference value just over the origin to normalise: + // + long long scale = 0; + int steps = itrunc(ceil(-b)); + T reference_value = hypergeometric_1F1_imp(T(a + steps), T(b + steps), z, pol, log_scaling); + T found = boost::math::tools::apply_recurrence_relation_forward(boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients(a + 1, b + 1, z), steps - 1, T(1), ratio, &scale); + log_scaling -= scale; + if ((fabs(reference_value) < 1) && (fabs(reference_value) < tools::min_value() * fabs(found))) + { + // Possible underflow, rescale + long long s = lltrunc(tools::log_max_value()); + log_scaling -= s; + reference_value *= exp(T(s)); + } + else if ((fabs(found) < 1) && (fabs(reference_value) > tools::max_value() * fabs(found))) + { + // Overflow, rescale: + long long s = lltrunc(tools::log_max_value()); + log_scaling += s; + reference_value /= exp(T(s)); + } + return reference_value / found; + } + + + + // + // This next version is largely the same as above, but calculates the ratio for the b recurrence relation + // which has a larger area of stability than the ab recurrence when a,b < 0. We can then use a single + // recurrence step to convert this to the ratio for the ab recursion and proceed largely as before. + // The routine is quite insensitive to the size of z, but requires |a| < |5b| for accuracy. + // Fortunately the accuracy outside this domain falls off steadily rather than suddenly switching + // to a different behaviour. + // + template + T hypergeometric_1F1_from_function_ratio_negative_ab(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients coef(a, b + 1, z); + T ratio = boost::math::tools::function_ratio_from_backwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // We need to use A&S 13.4.3 to convert a ratio for M(a, b + 1, z) / M(a, b, z) + // to M(a+1, b+1, z) / M(a, b, z) + // + // We have: (a-b)M(a, b+1, z) - aM(a+1, b+1, z) + bM(a, b, z) = 0 + // and therefore: M(a + 1, b + 1, z) / M(a, b, z) = ((a - b)M(a, b + 1, z) / M(a, b, z) + b) / a + // + ratio = ((a - b) * ratio + b) / a; + // + // Let M2 = M(1+a-b, 2-b, z) + // This is going to be a mighty big number: + // + long long local_scaling = 0; + T M2 = boost::math::detail::hypergeometric_1F1_imp(T(1 + a - b), T(2 - b), z, pol, local_scaling); + log_scaling -= local_scaling; // all the M2 terms are in the denominator + // + // Let M3 = M(1+a-b + 1, 2-b + 1, z) + // We don't use the ratio to get this as it's not clear that it's reliable: + // + long long local_scaling2 = 0; + T M3 = boost::math::detail::hypergeometric_1F1_imp(T(2 + a - b), T(3 - b), z, pol, local_scaling2); + // + // M2 and M3 must be identically scaled: + // + if (local_scaling != local_scaling2) + { + M3 *= exp(T(local_scaling2 - local_scaling)); + } + // + // Get the RHS of the Wronksian: + // + long long fz = lltrunc(z); + log_scaling += fz; + T rhs = (1 - b) * exp(z - fz); + // + // We need to divide that by: + // [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z^b R(a,b,z) M2(a,b,z) ] + // Note that at this stage, both M3 and M2 are scaled by exp(local_scaling). + // + T lhs = (a - b + 1) * z * M3 / (2 - b) + (1 - b) * M2 - a * z * ratio * M2 / b; + + return rhs / lhs; + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp new file mode 100644 index 0000000000000..bc23d5f145308 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp @@ -0,0 +1,50 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP + +#include + +// +// Evaluation of 1F1 by continued fraction +// see http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/10/0002/ +// +// This is not terribly useful, as like the series we're adding a something to 1, +// so only really useful when we know that the result will be > 1. +// + + + namespace boost { namespace math { namespace detail { + + template + struct hypergeometric_1F1_cf_func + { + typedef std::pair result_type; + hypergeometric_1F1_cf_func(T a_, T b_, T z_) : a(a_), b(b_), z(z_), k(0) {} + std::pair operator()() + { + ++k; + return std::make_pair(-(((a + k) * z) / ((k + 1) * (b + k))), 1 + ((a + k) * z) / ((k + 1) * (b + k))); + } + T a, b, z; + unsigned k; + }; + + template + T hypergeometric_1F1_cf(const T& a, const T& b, const T& z, const Policy& pol, const char* function) + { + hypergeometric_1F1_cf_func func(a, b, z); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::continued_fraction_a(func, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations(function, max_iter, pol); + return 1 + a * z / (b * (1 + result)); + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp new file mode 100644 index 0000000000000..8b8bbc40dfee4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp @@ -0,0 +1,35 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP +// +// Evaluation of 1F1 by continued fraction +// by asymptotic approximation for large a, +// see https://dlmf.nist.gov/13.8#E9 +// +// This is not terribly useful, as it only gets a few digits correct even for very +// large a, also needs b and z small: +// + + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_large_neg_a_asymtotic_dlmf_13_8_9(T a, T b, T z, const Policy& pol) + { + T result = boost::math::cyl_bessel_j(b - 1, sqrt(2 * z * (b - 2 * a)), pol); + result *= boost::math::tgamma(b, pol) * exp(z / 2); + T p = pow((b / 2 - a) * z, (1 - b) / 4); + result *= p; + result *= p; + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp new file mode 100644 index 0000000000000..d072ec2b607fa --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp @@ -0,0 +1,492 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) + +#ifndef BOOST_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ + +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + template + inline bool is_negative_integer(const T& x) + { + using std::floor; + return (x <= 0) && (floor(x) == x); + } + + + template + struct hypergeometric_1F1_igamma_series + { + enum{ cache_size = 64 }; + + typedef T result_type; + hypergeometric_1F1_igamma_series(const T& alpha, const T& delta, const T& x, const Policy& pol) + : delta_poch(-delta), alpha_poch(alpha), x(x), k(0), cache_offset(0), pol(pol) + { + BOOST_MATH_STD_USING + T log_term = log(x) * -alpha; + log_scaling = lltrunc(log_term - 3 - boost::math::tools::log_min_value() / 50); + term = exp(log_term - log_scaling); + refill_cache(); + } + T operator()() + { + if (k - cache_offset >= cache_size) + { + cache_offset += cache_size; + refill_cache(); + } + T result = term * gamma_cache[k - cache_offset]; + term *= delta_poch * alpha_poch / (++k * x); + delta_poch += 1; + alpha_poch += 1; + return result; + } + void refill_cache() + { + typedef typename lanczos::lanczos::type lanczos_type; + + gamma_cache[cache_size - 1] = boost::math::gamma_p(alpha_poch + ((int)cache_size - 1), x, pol); + for (int i = cache_size - 1; i > 0; --i) + { + gamma_cache[i - 1] = gamma_cache[i] >= 1 ? T(1) : T(gamma_cache[i] + regularised_gamma_prefix(T(alpha_poch + (i - 1)), x, pol, lanczos_type()) / (alpha_poch + (i - 1))); + } + } + T delta_poch, alpha_poch, x, term; + T gamma_cache[cache_size]; + int k; + long long log_scaling; + int cache_offset; + Policy pol; + }; + + template + T hypergeometric_1F1_igamma(const T& a, const T& b, const T& x, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + if (b_minus_a == 0) + { + // special case: M(a,a,z) == exp(z) + long long scale = lltrunc(x, pol); + log_scaling += scale; + return exp(x - scale); + } + hypergeometric_1F1_igamma_series s(b_minus_a, a - 1, x, pol); + log_scaling += s.log_scaling; + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol); + T log_prefix = x + boost::math::lgamma(b, pol) - boost::math::lgamma(a, pol); + long long scale = lltrunc(log_prefix); + log_scaling += scale; + return result * exp(log_prefix - scale); + } + + template + T hypergeometric_1F1_shift_on_a(T h, const T& a_local, const T& b_local, const T& x, int a_shift, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + T a = a_local + a_shift; + if (a_shift == 0) + return h; + else if (a_shift > 0) + { + // + // Forward recursion on a is stable as long as 2a-b+z > 0. + // If 2a-b+z < 0 then backwards recursion is stable even though + // the function may be strictly increasing with a. Potentially + // we may need to split the recurrence in 2 sections - one using + // forward recursion, and one backwards. + // + // We will get the next seed value from the ratio + // on b as that's stable and quick to compute. + // + + T crossover_a = (b_local - x) / 2; + int crossover_shift = itrunc(crossover_a - a_local); + + if (crossover_shift > 1) + { + // + // Forwards recursion will start off unstable, but may switch to the stable direction later. + // Start in the middle and go in both directions: + // + if (crossover_shift > a_shift) + crossover_shift = a_shift; + crossover_a = a_local + crossover_shift; + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(crossover_a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = ((1+a-b) / a) M(a,b,z) + ((b-1) / a) M(a,b,z)/b_ratio + // + T first = 1; + T second = ((1 + crossover_a - b_local) / crossover_a) + ((b_local - 1) / crossover_a) / b_ratio; + // + // Recurse down to a_local, compare values and re-normalise first and second: + // + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(crossover_a, b_local, x); + long long backwards_scale = 0; + T comparitor = boost::math::tools::apply_recurrence_relation_backward(a_coef, crossover_shift, second, first, &backwards_scale); + log_scaling -= backwards_scale; + if ((h < 1) && (tools::max_value() * h > comparitor)) + { + // Need to rescale! + long long scale = lltrunc(log(h), pol) + 1; + h *= exp(T(-scale)); + log_scaling += scale; + } + comparitor /= h; + first /= comparitor; + second /= comparitor; + // + // Now we can recurse forwards for the rest of the range: + // + if (crossover_shift < a_shift) + { + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef_2(crossover_a + 1, b_local, x); + h = boost::math::tools::apply_recurrence_relation_forward(a_coef_2, a_shift - crossover_shift - 1, first, second, &log_scaling); + } + else + h = first; + } + else + { + // + // Regular case where forwards iteration is stable right from the start: + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a_local, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = ((1+a-b) / a) M(a,b,z) + ((b-1) / a) M(a,b,z)/b_ratio + // + T second = ((1 + a_local - b_local) / a_local) * h + ((b_local - 1) / a_local) * h / b_ratio; + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(a_local + 1, b_local, x); + h = boost::math::tools::apply_recurrence_relation_forward(a_coef, --a_shift, h, second, &log_scaling); + } + } + else + { + // + // We've calculated h for a larger value of a than we want, and need to recurse down. + // However, only forward iteration is stable, so calculate the ratio, compare values, + // and normalise. Note that we calculate the ratio on b and convert to a since the + // direction is the minimal solution for N->+INF. + // + // IMPORTANT: this is only currently called for a > b and therefore forwards iteration + // is the only stable direction as we will only iterate down until a ~ b, but we + // will check this with an assert: + // + BOOST_MATH_ASSERT(2 * a - b_local + x > 0); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = (1+a-b) / a M(a,b,z) + (b-1) / a M(a,b,z)/ (M(a,b,z)/M(a,b-1,z)) + // + T first = 1; // arbitrary value; + T second = ((1 + a - b_local) / a) + ((b_local - 1) / a) * (1 / b_ratio); + + if (a_shift == -1) + h = h / second; + else + { + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(a + 1, b_local, x); + T comparitor = boost::math::tools::apply_recurrence_relation_forward(a_coef, -(a_shift + 1), first, second); + if (boost::math::tools::min_value() * comparitor > h) + { + // Ooops, need to rescale h: + long long rescale = lltrunc(log(fabs(h))); + T scale = exp(T(-rescale)); + h *= scale; + log_scaling += rescale; + } + h = h / comparitor; + } + } + return h; + } + + template + T hypergeometric_1F1_shift_on_b(T h, const T& a, const T& b_local, const T& x, int b_shift, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + + T b = b_local + b_shift; + if (b_shift == 0) + return h; + else if (b_shift > 0) + { + // + // We get here for b_shift > 0 when b > z. We can't use forward recursion on b - it's unstable, + // so grab the ratio and work backwards to b - b_shift and normalise. + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T first = 1; // arbitrary value; + T second = 1 / boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (b_shift == 1) + h = h / second; + else + { + // + // Reset coefficients and recurse: + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef_2(a, b - 1, x); + long long local_scale = 0; + T comparitor = boost::math::tools::apply_recurrence_relation_backward(b_coef_2, --b_shift, first, second, &local_scale); + log_scaling -= local_scale; + if (boost::math::tools::min_value() * comparitor > h) + { + // Ooops, need to rescale h: + long long rescale = lltrunc(log(fabs(h))); + T scale = exp(T(-rescale)); + h *= scale; + log_scaling += rescale; + } + h = h / comparitor; + } + } + else + { + T second; + if (a == b_local) + { + // recurrence is trivial for a == b and method of ratios fails as the c-term goes to zero: + second = -b_local * (1 - b_local - x) * h / (b_local * (b_local - 1)); + } + else + { + BOOST_MATH_ASSERT(!is_negative_integer(b - a)); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + second = h / boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + } + if (b_shift == -1) + h = second; + else + { + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef_2(a, b_local - 1, x); + h = boost::math::tools::apply_recurrence_relation_backward(b_coef_2, -(++b_shift), h, second, &log_scaling); + } + } + return h; + } + + + template + T hypergeometric_1F1_large_igamma(const T& a, const T& b, const T& x, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We need a < b < z in order to ensure there's at least a chance of convergence, + // we can use recurrence relations to shift forwards on a+b or just a to achieve this, + // for decent accuracy, try to keep 2b - 1 < a < 2b < z + // + int b_shift = b * 2 < x ? 0 : itrunc(b - x / 2); + int a_shift = a > b - b_shift ? -itrunc(b - b_shift - a - 1) : -itrunc(b - b_shift - a); + + if (a_shift < 0) + { + // Might as well do all the shifting on b as scale a downwards: + b_shift -= a_shift; + a_shift = 0; + } + + T a_local = a - a_shift; + T b_local = b - b_shift; + T b_minus_a_local = (a_shift == 0) && (b_shift == 0) ? b_minus_a : b_local - a_local; + long long local_scaling = 0; + T h = hypergeometric_1F1_igamma(a_local, b_local, x, b_minus_a_local, pol, local_scaling); + log_scaling += local_scaling; + + // + // Apply shifts on a and b as required: + // + h = hypergeometric_1F1_shift_on_a(h, a_local, b_local, x, a_shift, pol, log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, x, b_shift, pol, log_scaling); + + return h; + } + + template + T hypergeometric_1F1_large_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We make a small, and b > z: + // + int a_shift(0), b_shift(0); + if (a * z > b) + { + a_shift = itrunc(a) - 5; + b_shift = b < z ? itrunc(b - z - 1) : 0; + } + // + // If a_shift is trivially small, there's really not much point in losing + // accuracy to save a couple of iterations: + // + if (a_shift < 5) + a_shift = 0; + T a_local = a - a_shift; + T b_local = b - b_shift; + T h = boost::math::detail::hypergeometric_1F1_generic_series(a_local, b_local, z, pol, log_scaling, "hypergeometric_1F1_large_series<%1%>(a,b,z)"); + // + // Apply shifts on a and b as required: + // + if (a_shift && (a_local == 0)) + { + // + // Shifting on a via method of ratios in hypergeometric_1F1_shift_on_a fails when + // a_local == 0. However, the value of h calculated was trivial (unity), so + // calculate a second 1F1 for a == 1 and recurse as normal: + // + long long scale = 0; + T h2 = boost::math::detail::hypergeometric_1F1_generic_series(T(a_local + 1), b_local, z, pol, scale, "hypergeometric_1F1_large_series<%1%>(a,b,z)"); + if (scale != log_scaling) + { + h2 *= exp(T(scale - log_scaling)); + } + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients coef(a_local + 1, b_local, z); + h = boost::math::tools::apply_recurrence_relation_forward(coef, a_shift - 1, h, h2, &log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + else + { + h = hypergeometric_1F1_shift_on_a(h, a_local, b_local, z, a_shift, pol, log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + return h; + } + + template + T hypergeometric_1F1_large_13_3_6_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // A&S 13.3.6 is good only when a ~ b, but isn't too fussy on the size of z. + // So shift b to match a (b shifting seems to be more stable via method of ratios). + // + int b_shift = itrunc(b - a); + if ((b_shift < 0) && (b - b_shift != a)) + b_shift -= 1; + T b_local = b - b_shift; + if ((b_local - a - 0.5 <= 0) && (b_local != a)) + { + // Make sure b_local - a - 0.5 > 0 + b_shift -= 1; + b_local += 1; + } + T h = boost::math::detail::hypergeometric_1F1_AS_13_3_6(a, b_local, z, T(b_local - a), pol, log_scaling); + return hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + + template + T hypergeometric_1F1_large_abz(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // This is the selection logic to pick the "best" method. + // We have a,b,z >> 0 and need to compute the approximate cost of each method + // and then select whichever wins out. + // + enum method + { + method_series = 0, + method_shifted_series, + method_gamma, + method_bessel + }; + // + // Cost of direct series, is the approx number of terms required until we hit convergence: + // + T current_cost = (sqrt(16 * z * (3 * a + z) + 9 * b * b - 24 * b * z) - 3 * b + 4 * z) / 6; + method current_method = method_series; + // + // Cost of shifted series, is the number of recurrences required to move to a zone where + // the series is convergent right from the start. + // Note that recurrence relations fail for very small b, and too many recurrences on a + // will completely destroy all our digits. + // Also note that the method fails when b-a is a negative integer unless b is already + // larger than z and thus does not need shifting. + // + T cost = a + ((b < z) ? T(z - b) : T(0)); + if((b > 1) && (cost < current_cost) && ((b > z) || !is_negative_integer(b-a))) + { + current_method = method_shifted_series; + current_cost = cost; + } + // + // Cost for gamma function method is the number of recurrences required to move it + // into a convergent zone, note that recurrence relations fail for very small b. + // Also add on a fudge factor to account for the fact that this method is both + // more expensive to compute (requires gamma functions), and less accurate than the + // methods above: + // + T b_shift = fabs(b * 2 < z ? T(0) : T(b - z / 2)); + T a_shift = fabs(a > b - b_shift ? T(-(b - b_shift - a - 1)) : T(-(b - b_shift - a))); + cost = 1000 + b_shift + a_shift; + if((b > 1) && (cost <= current_cost)) + { + current_method = method_gamma; + current_cost = cost; + } + // + // Cost for bessel approximation is the number of recurrences required to make a ~ b, + // Note that recurrence relations fail for very small b. We also have issue with large + // z: either overflow/numeric instability or else the series goes divergent. We seem to be + // OK for z smaller than log_max_value though, maybe we can stretch a little further + // but that's not clear... + // Also need to add on a fudge factor to the cost to account for the fact that we need + // to calculate the Bessel functions, this is not quite as high as the gamma function + // method above as this is generally more accurate and so preferred if the methods are close: + // + cost = 50 + fabs(b - a); + if((b > 1) && (cost <= current_cost) && (z < tools::log_max_value()) && (z < 11356) && (b - a != 0.5f)) + { + current_method = method_bessel; + current_cost = cost; + } + + switch (current_method) + { + case method_series: + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, "hypergeometric_1f1_large_abz<%1%>(a,b,z)"); + case method_shifted_series: + return detail::hypergeometric_1F1_large_series(a, b, z, pol, log_scaling); + case method_gamma: + return detail::hypergeometric_1F1_large_igamma(a, b, z, T(b - a), pol, log_scaling); + case method_bessel: + return detail::hypergeometric_1F1_large_13_3_6_series(a, b, z, pol, log_scaling); + } + return 0; // We don't get here! + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp new file mode 100644 index 0000000000000..3752fec15860c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp @@ -0,0 +1,521 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2019 John Maddock +// 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) + +#ifndef BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP +#define BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP + +namespace boost { + namespace math { + namespace detail { + // + // hypergeometric_1F1_negative_b_recurrence_region maps out the domains over which + // forward and backwards recurrences are stable when b < 0. + // Returns -1, 0, or 1: + // -1: Backwards recurrence is stable. + // +1: Forwards recurrence is stable. + // 0: Neither recurrence is stable. + // + template + int hypergeometric_1F1_negative_b_recurrence_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + static const double domain[][4] = { + { 1e-300, -1000000.1, 278609.88983674475, 465687}, + { 1e-300, -400000.03999999998, 111530.83622048119, 111544}, + { 1e-300, -160000.016, 44699.113858309654, 44712}, + { 1e-300, -64000.006399999998, 17966.035866477272, 17980}, + { 1e-300, -25600.002560000001, 7273.793013139204, 7287}, + { 1e-300, -10240.001024000001, 2998.0791015625, 3012}, + { 1e-300, -4096.0004096000002, 1291.0461647727273, 1306}, + { 1e-300, -1638.40016384, 619.421875, 636}, + { 1e-300, -655.36006553599998, 374.62926136363637, 397}, + { 1e-300, -262.14402621440001, 335.29958677685943, 370}, + { 1e-300, -104.85761048576001, 412.83057851239664, 462}, + { 1e-300, -41.943044194304001, 513.00603693181824, 570}, + { 1e-300, -16.777217677721602, 584.14449896694214, 644}, + { 1e-300, -6.7108870710886404, 623.30417097107443, 684}, + { 1e-300, -2.6843548284354561, 642.31960227272725, 704}, + { 1e-300, -1.0737419313741825, 650.20738636363626, 711}, + { 1.0000000000000001e-275, -1000000.1, 278597.3203069513, 448872}, + { 1.0000000000000001e-275, -400000.03999999998, 111518.14741654831, 111531}, + { 1.0000000000000001e-275, -160000.016, 44686.621781782669, 44700}, + { 1.0000000000000001e-275, -64000.006399999998, 17953.944740988994, 17967}, + { 1.0000000000000001e-275, -25600.002560000001, 7261.1431107954559, 7274}, + { 1.0000000000000001e-275, -10240.001024000001, 2985.014559659091, 2999}, + { 1.0000000000000001e-275, -4096.0004096000002, 1277.4573863636363, 1292}, + { 1.0000000000000001e-275, -1638.40016384, 603.88778409090912, 620}, + { 1.0000000000000001e-275, -655.36006553599998, 354.10653409090912, 376}, + { 1.0000000000000001e-275, -262.14402621440001, 303.91367510330571, 337}, + { 1.0000000000000001e-275, -104.85761048576001, 367.0454545454545, 416}, + { 1.0000000000000001e-275, -41.943044194304001, 460.06028861053716, 516}, + { 1.0000000000000001e-275, -16.777217677721602, 528.36389462809916, 588}, + { 1.0000000000000001e-275, -6.7108870710886404, 566.33555010330565, 627}, + { 1.0000000000000001e-275, -2.6843548284354561, 585.32541322314046, 646}, + { 1.0000000000000001e-275, -1.0737419313741825, 593.0082967458676, 654}, + { 1.0000000000000002e-250, -1000000.1, 278584.75303113955, 431059}, + { 1.0000000000000002e-250, -400000.03999999998, 111505.53022349965, 111519}, + { 1.0000000000000002e-250, -160000.016, 44674.060190374199, 44687}, + { 1.0000000000000002e-250, -64000.006399999998, 17941.25452769886, 17954}, + { 1.0000000000000002e-250, -25600.002560000001, 7248.2002840909081, 7262}, + { 1.0000000000000002e-250, -10240.001024000001, 2972.017267400568, 2985}, + { 1.0000000000000002e-250, -4096.0004096000002, 1263.6363636363637, 1278}, + { 1.0000000000000002e-250, -1638.40016384, 588.35369318181824, 604}, + { 1.0000000000000002e-250, -655.36006553599998, 334.18039772727275, 355}, + { 1.0000000000000002e-250, -262.14402621440001, 273.7357954545455, 306}, + { 1.0000000000000002e-250, -104.85761048576001, 323.05010330578506, 370}, + { 1.0000000000000002e-250, -41.943044194304001, 407.41541838842977, 463}, + { 1.0000000000000002e-250, -16.777217677721602, 472.78376807851242, 532}, + { 1.0000000000000002e-250, -6.7108870710886404, 509.47443181818176, 570}, + { 1.0000000000000002e-250, -2.6843548284354561, 528.11466942148763, 589}, + { 1.0000000000000002e-250, -1.0737419313741825, 535.52815082644634, 596}, + { 1.0000000000000003e-225, -1000000.1, 278572.12184906006, 278585}, + { 1.0000000000000003e-225, -400000.03999999998, 111493.21068649805, 551165}, + { 1.0000000000000003e-225, -160000.016, 44661.126509232956, 44674}, + { 1.0000000000000003e-225, -64000.006399999998, 17928.069602272728, 17942}, + { 1.0000000000000003e-225, -25600.002560000001, 7235.550426136364, 7249}, + { 1.0000000000000003e-225, -10240.001024000001, 2959.153053977273, 2973}, + { 1.0000000000000003e-225, -4096.0004096000002, 1250.2649147727275, 1264}, + { 1.0000000000000003e-225, -1638.40016384, 573.37073863636363, 589}, + { 1.0000000000000003e-225, -655.36006553599998, 315.21946022727275, 335}, + { 1.0000000000000003e-225, -262.14402621440001, 245.11137654958674, 275}, + { 1.0000000000000003e-225, -104.85761048576001, 280.71022727272725, 326}, + { 1.0000000000000003e-225, -41.943044194304001, 355.45519111570246, 411}, + { 1.0000000000000003e-225, -16.777217677721602, 417.41670971074382, 476}, + { 1.0000000000000003e-225, -6.7108870710886404, 452.71984762396687, 513}, + { 1.0000000000000003e-225, -2.6843548284354561, 470.45648243801656, 532}, + { 1.0000000000000003e-225, -1.0737419313741825, 478.06438855888422, 539}, + { 1.0000000000000004e-200, -1000000.1, 278559.54284667969, 278573}, + { 1.0000000000000004e-200, -400000.03999999998, 111480.15247691762, 111493}, + { 1.0000000000000004e-200, -160000.016, 44648.944635564636, 44662}, + { 1.0000000000000004e-200, -64000.006399999998, 17916.076071999294, 17929}, + { 1.0000000000000004e-200, -25600.002560000001, 7223.06005859375, 7236}, + { 1.0000000000000004e-200, -10240.001024000001, 2946.222301136364, 2960}, + { 1.0000000000000004e-200, -4096.0004096000002, 1236.0916193181818, 1251}, + { 1.0000000000000004e-200, -1638.40016384, 558.40909090909076, 574}, + { 1.0000000000000004e-200, -655.36006553599998, 297.05220170454544, 316}, + { 1.0000000000000004e-200, -262.14402621440001, 218.16438533057845, 247}, + { 1.0000000000000004e-200, -104.85761048576001, 239.76949896694211, 283}, + { 1.0000000000000004e-200, -41.943044194304001, 304.40728305785115, 359}, + { 1.0000000000000004e-200, -16.777217677721602, 362.01349431818181, 421}, + { 1.0000000000000004e-200, -6.7108870710886404, 396.18123708677683, 456}, + { 1.0000000000000004e-200, -2.6843548284354561, 413.36518595041321, 474}, + { 1.0000000000000004e-200, -1.0737419313741825, 420.31249999999994, 482}, + { 1.0000000000000006e-175, -1000000.1, 278547.12638697342, 465687}, + { 1.0000000000000006e-175, -400000.03999999998, 111468.15407492899, 111481}, + { 1.0000000000000006e-175, -160000.016, 44636.134832208802, 44649}, + { 1.0000000000000006e-175, -64000.006399999998, 17903.091796875, 17917}, + { 1.0000000000000006e-175, -25600.002560000001, 7210.247247869318, 7223}, + { 1.0000000000000006e-175, -10240.001024000001, 2933.2915482954545, 2947}, + { 1.0000000000000006e-175, -4096.0004096000002, 1223.600497159091, 1237}, + { 1.0000000000000006e-175, -1638.40016384, 544.06640625, 559}, + { 1.0000000000000006e-175, -655.36006553599998, 279.11931818181813, 298}, + { 1.0000000000000006e-175, -262.14402621440001, 192.94921875, 220}, + { 1.0000000000000006e-175, -104.85761048576001, 200.78641528925618, 242}, + { 1.0000000000000006e-175, -41.943044194304001, 254.19679752066114, 308}, + { 1.0000000000000006e-175, -16.777217677721602, 307.10227272727263, 366}, + { 1.0000000000000006e-175, -6.7108870710886404, 339.36918904958679, 400}, + { 1.0000000000000006e-175, -2.6843548284354561, 356.1554106404958, 417}, + { 1.0000000000000006e-175, -1.0737419313741825, 363.13694473140492, 424}, + { 1.0000000000000007e-150, -1000000.1, 278534.48812689661, 448872}, + { 1.0000000000000007e-150, -400000.03999999998, 111455.15580610794, 111468}, + { 1.0000000000000007e-150, -160000.016, 44623.643454811798, 44637}, + { 1.0000000000000007e-150, -64000.006399999998, 17891.00373493541, 17904}, + { 1.0000000000000007e-150, -25600.002560000001, 7197.631392045454, 7211}, + { 1.0000000000000007e-150, -10240.001024000001, 2920.3607954545455, 2934}, + { 1.0000000000000007e-150, -4096.0004096000002, 1210.3267045454545, 1224}, + { 1.0000000000000007e-150, -1638.40016384, 530.0033735795455, 545}, + { 1.0000000000000007e-150, -655.36006553599998, 262.37215909090907, 280}, + { 1.0000000000000007e-150, -262.14402621440001, 169.07024793388427, 194}, + { 1.0000000000000007e-150, -104.85761048576001, 164.12706611570246, 203}, + { 1.0000000000000007e-150, -41.943044194304001, 206.02079028925615, 258}, + { 1.0000000000000007e-150, -16.777217677721602, 253.0191115702479, 311}, + { 1.0000000000000007e-150, -6.7108870710886404, 283.23056559917353, 343}, + { 1.0000000000000007e-150, -2.6843548284354561, 299.29041838842977, 360}, + { 1.0000000000000007e-150, -1.0737419313741825, 305.7925490702479, 367}, + { 1.0000000000000008e-125, -1000000.1, 278522.04145396838, 285024}, + { 1.0000000000000008e-125, -400000.03999999998, 111443.00279374557, 111456}, + { 1.0000000000000008e-125, -160000.016, 44611.143155184654, 44624}, + { 1.0000000000000008e-125, -64000.006399999998, 17878.306263316765, 17891}, + { 1.0000000000000008e-125, -25600.002560000001, 7185.1384943181802, 7198}, + { 1.0000000000000008e-125, -10240.001024000001, 2907.430042613636, 2921}, + { 1.0000000000000008e-125, -4096.0004096000002, 1197.0621448863635, 1211}, + { 1.0000000000000008e-125, -1638.40016384, 516.05983664772725, 531}, + { 1.0000000000000008e-125, -655.36006553599998, 246.17897727272725, 263}, + { 1.0000000000000008e-125, -262.14402621440001, 147.2197830578512, 171}, + { 1.0000000000000008e-125, -104.85761048576001, 130.599173553719, 166}, + { 1.0000000000000008e-125, -41.943044194304001, 159.12190082644628, 209}, + { 1.0000000000000008e-125, -16.777217677721602, 199.5635330578512, 256}, + { 1.0000000000000008e-125, -6.7108870710886404, 227.1807205578512, 287}, + { 1.0000000000000008e-125, -2.6843548284354561, 242.41670971074376, 303}, + { 1.0000000000000008e-125, -1.0737419313741825, 248.39036673553716, 309}, + { 1.0000000000000009e-100, -1000000.1, 278509.36086203833, 278546}, + { 1.0000000000000009e-100, -400000.03999999998, 111430.10303574696, 551165}, + { 1.0000000000000009e-100, -160000.016, 44598.652055220169, 44612}, + { 1.0000000000000009e-100, -64000.006399999998, 17865.125532670456, 17879}, + { 1.0000000000000009e-100, -25600.002560000001, 7172.046519886364, 7186}, + { 1.0000000000000009e-100, -10240.001024000001, 2895.015980113636, 2908}, + { 1.0000000000000009e-100, -4096.0004096000002, 1184.2329545454545, 1198}, + { 1.0000000000000009e-100, -1638.40016384, 502.04403409090901, 517}, + { 1.0000000000000009e-100, -655.36006553599998, 231.13849431818178, 247}, + { 1.0000000000000009e-100, -262.14402621440001, 128.02290482954544, 149}, + { 1.0000000000000009e-100, -104.85761048576001, 100.76188016528923, 133}, + { 1.0000000000000009e-100, -41.943044194304001, 115.10072314049584, 162}, + { 1.0000000000000009e-100, -16.777217677721602, 147.05255681818178, 203}, + { 1.0000000000000009e-100, -6.7108870710886404, 171.19963842975204, 231}, + { 1.0000000000000009e-100, -2.6843548284354561, 185.58367768595039, 246}, + { 1.0000000000000009e-100, -1.0737419313741825, 191.0575929752066, 252}, + { 1.0000000000000009e-75, -1000000.1, 278497.00512279174, 278510}, + { 1.0000000000000009e-75, -400000.03999999998, 111417.96751369131, 111431}, + { 1.0000000000000009e-75, -160000.016, 44586.151478160507, 44599}, + { 1.0000000000000009e-75, -64000.006399999998, 17853.128506747154, 17866}, + { 1.0000000000000009e-75, -25600.002560000001, 7160.0009918212891, 7173}, + { 1.0000000000000009e-75, -10240.001024000001, 2882.563210227273, 2896}, + { 1.0000000000000009e-75, -4096.0004096000002, 1171.4037642045455, 1185}, + { 1.0000000000000009e-75, -1638.40016384, 489.03941761363637, 503}, + { 1.0000000000000009e-75, -655.36006553599998, 216.05113636363637, 232}, + { 1.0000000000000009e-75, -262.14402621440001, 110.08296745867767, 129}, + { 1.0000000000000009e-75, -104.85761048576001, 74.400826446280988, 102}, + { 1.0000000000000009e-75, -41.943044194304001, 75.619834710743788, 118}, + { 1.0000000000000009e-75, -16.777217677721602, 96.373966942148741, 150}, + { 1.0000000000000009e-75, -6.7108870710886404, 116.33910123966942, 175}, + { 1.0000000000000009e-75, -2.6843548284354561, 129.00947507747935, 189}, + { 1.0000000000000009e-75, -1.0737419313741825, 134.06379132231399, 195}, + { 1.0000000000000011e-50, -1000000.1, 278484.14271457132, 465687}, + { 1.0000000000000011e-50, -400000.03999999998, 111405.16246448863, 111418}, + { 1.0000000000000011e-50, -160000.016, 44573.165838068184, 44587}, + { 1.0000000000000011e-50, -64000.006399999998, 17840.147727272728, 17854}, + { 1.0000000000000011e-50, -25600.002560000001, 7147.375887784091, 7160}, + { 1.0000000000000011e-50, -10240.001024000001, 2869.888583096591, 2883}, + { 1.0000000000000011e-50, -4096.0004096000002, 1158.1576704545455, 1172}, + { 1.0000000000000011e-50, -1638.40016384, 476.00257457386363, 490}, + { 1.0000000000000011e-50, -655.36006553599998, 202.20170454545453, 217}, + { 1.0000000000000011e-50, -262.14402621440001, 94.02682722107437, 111}, + { 1.0000000000000011e-50, -104.85761048576001, 53.0810950413223, 76}, + { 1.0000000000000011e-50, -41.943044194304001, 42.355371900826441, 78}, + { 1.0000000000000011e-50, -16.777217677721602, 50.051652892561975, 100}, + { 1.0000000000000011e-50, -6.7108870710886404, 63.174070247933884, 120}, + { 1.0000000000000011e-50, -2.6843548284354561, 72.956805268595033, 132}, + { 1.0000000000000011e-50, -1.0737419313741825, 77.104855371900811, 138}, + { 1.0000000000000012e-25, -1000000.1, 278471.90274041548, 448844}, + { 1.0000000000000012e-25, -400000.03999999998, 111392.85056374289, 111423}, + { 1.0000000000000012e-25, -160000.016, 44561.0361328125, 44574}, + { 1.0000000000000012e-25, -64000.006399999998, 17828.149314186794, 17841}, + { 1.0000000000000012e-25, -25600.002560000001, 7134.765625, 7148}, + { 1.0000000000000012e-25, -10240.001024000001, 2857.211647727273, 2870}, + { 1.0000000000000012e-25, -4096.0004096000002, 1146.1576704545453, 1159}, + { 1.0000000000000012e-25, -1638.40016384, 463.0625, 476}, + { 1.0000000000000012e-25, -655.36006553599998, 189.27556818181819, 203}, + { 1.0000000000000012e-25, -262.14402621440001, 79.163223140495859, 95}, + { 1.0000000000000012e-25, -104.85761048576001, 36.15702479338843, 54}, + { 1.0000000000000012e-25, -41.943044194304001, 19.008264462809912, 44}, + { 1.0000000000000012e-25, -16.777217677721602, 14.220686983471072, 53}, + { 1.0000000000000012e-25, -6.7108870710886404, 15.207081141998497, 66}, + { 1.0000000000000012e-25, -2.6843548284354561, 19.000046957175051, 76}, + { 1.0000000000000012e-25, -1.0737419313741825, 21.00738364892468, 81}, + { 1, -1000000.1, 278455, 285026}, + { 1, -400000.03999999998, 111376, 111392}, + { 1, -160000.016, 44544, 44561}, + { 1, -64000.006399999998, 17812, 17828}, + { 1, -25600.002560000001, 7119, 7135}, + { 1, -10240.001024000001, 2841, 2858}, + { 1, -4096.0004096000002, 1130, 1147}, + { 1, -1638.40016384, 447, 464}, + { 1, -655.36006553599998, 174, 190}, + { 1, -262.14402621440001, 64, 81}, + { 1, -104.85761048576001, 21, 37}, + { 1, -41.943044194304001, 5, 20}, + { 1, -16.777217677721602, 0, 16}, + { 1, -6.7108870710886404, 0, 17}, + { 1, -2.6843548284354561, 0, 20}, + { 1, -1.0737419313741825, 0, 21}, + { 2.5, -1000000.1, 278450, 278466}, + { 2.5, -400000.03999999998, 111372, 111388}, + { 2.5, -160000.016, 44540, 44557}, + { 2.5, -64000.006399999998, 17808, 17824}, + { 2.5, -25600.002560000001, 7115, 7131}, + { 2.5, -10240.001024000001, 2838, 2854}, + { 2.5, -4096.0004096000002, 1127, 1144}, + { 2.5, -1638.40016384, 445, 461}, + { 2.5, -655.36006553599998, 172, 188}, + { 2.5, -262.14402621440001, 63, 79}, + { 2.5, -104.85761048576001, 20, 35}, + { 2.5, -41.943044194304001, 4, 19}, + { 2.5, -16.777217677721602, 0, 13}, + { 2.5, -6.7108870710886404, 0, 13}, + { 2.5, -2.6843548284354561, 0, 15}, + { 2.5, -1.0737419313741825, 2, 16}, + { 6.25, -1000000.1, 278440, 278456}, + { 6.25, -400000.03999999998, 111362, 111378}, + { 6.25, -160000.016, 44531, 44548}, + { 6.25, -64000.006399999998, 17800, 17816}, + { 6.25, -25600.002560000001, 7108, 7124}, + { 6.25, -10240.001024000001, 2831, 2848}, + { 6.25, -4096.0004096000002, 1121, 1138}, + { 6.25, -1638.40016384, 440, 456}, + { 6.25, -655.36006553599998, 167, 183}, + { 6.25, -262.14402621440001, 59, 75}, + { 6.25, -104.85761048576001, 18, 32}, + { 6.25, -41.943044194304001, 3, 16}, + { 6.25, -16.777217677721602, 0, 10}, + { 6.25, -6.7108870710886404, 0, 9}, + { 6.25, -2.6843548284354561, 0, 9}, + { 6.25, -1.0737419313741825, 4, 9}, + { 15.625, -1000000.1, 278415, 278432}, + { 15.625, -400000.03999999998, 111339, 111425}, + { 15.625, -160000.016, 44510, 44527}, + { 15.625, -64000.006399999998, 17781, 17797}, + { 15.625, -25600.002560000001, 7091, 7107}, + { 15.625, -10240.001024000001, 2816, 2833}, + { 15.625, -4096.0004096000002, 1108, 1125}, + { 15.625, -1638.40016384, 429, 445}, + { 15.625, -655.36006553599998, 159, 174}, + { 15.625, -262.14402621440001, 53, 67}, + { 15.625, -104.85761048576001, 14, 27}, + { 15.625, -41.943044194304001, 2, 11}, + { 15.625, -16.777217677721602, 0, 7}, + { 15.625, -6.7108870710886404, 0, 5}, + { 15.625, -2.6843548284354561, 5, 5}, + { 15.625, -1.0737419313741825, 5, 5}, + { 39.0625, -1000000.1, 278359, 431061}, + { 39.0625, -400000.03999999998, 111287, 111304}, + { 39.0625, -160000.016, 44463, 44480}, + { 39.0625, -64000.006399999998, 17738, 17755}, + { 39.0625, -25600.002560000001, 7053, 7069}, + { 39.0625, -10240.001024000001, 2784, 2800}, + { 39.0625, -4096.0004096000002, 1081, 1097}, + { 39.0625, -1638.40016384, 407, 422}, + { 39.0625, -655.36006553599998, 143, 157}, + { 39.0625, -262.14402621440001, 43, 56}, + { 39.0625, -104.85761048576001, 10, 19}, + { 39.0625, -41.943044194304001, 0, 7}, + { 39.0625, -16.777217677721602, 0, 4}, + { 39.0625, -6.7108870710886404, 0, 3}, + { 39.0625, -2.6843548284354561, 3, 3}, + { 39.0625, -1.0737419313741825, 3, 3}, + { 97.65625, -1000000.1, 278230, 278277}, + { 97.65625, -400000.03999999998, 111170, 111425}, + { 97.65625, -160000.016, 44358, 44374}, + { 97.65625, -64000.006399999998, 17645, 17661}, + { 97.65625, -25600.002560000001, 6972, 6988}, + { 97.65625, -10240.001024000001, 2715, 2731}, + { 97.65625, -4096.0004096000002, 1026, 1041}, + { 97.65625, -1638.40016384, 366, 380}, + { 97.65625, -655.36006553599998, 117, 129}, + { 97.65625, -262.14402621440001, 30, 40}, + { 97.65625, -104.85761048576001, 5, 12}, + { 97.65625, -41.943044194304001, 0, 4}, + { 97.65625, -16.777217677721602, 0, 3}, + { 97.65625, -6.7108870710886404, 0, 1}, + { 97.65625, -2.6843548284354561, 0, 1}, + { 97.65625, -1.0737419313741825, 0, 1}, + { 244.140625, -1000000.1, 277936, 796691}, + { 244.140625, -400000.03999999998, 110906, 110923}, + { 244.140625, -160000.016, 44124, 44141}, + { 244.140625, -64000.006399999998, 17442, 17458}, + { 244.140625, -25600.002560000001, 6801, 6816}, + { 244.140625, -10240.001024000001, 2577, 2593}, + { 244.140625, -4096.0004096000002, 924, 938}, + { 244.140625, -1638.40016384, 300, 312}, + { 244.140625, -655.36006553599998, 82, 92}, + { 244.140625, -262.14402621440001, 17, 24}, + { 244.140625, -104.85761048576001, 2, 7}, + { 244.140625, -41.943044194304001, 0, 3}, + { 244.140625, -16.777217677721602, 0, 1}, + { 244.140625, -6.7108870710886404, 0, 1}, + { 244.140625, -2.6843548284354561, 0, 1}, + { 244.140625, -1.0737419313741825, 0, 1}, + { 610.3515625, -1000000.1, 277277, 277294}, + { 610.3515625, -400000.03999999998, 110322, 111647}, + { 610.3515625, -160000.016, 43617, 43633}, + { 610.3515625, -64000.006399999998, 17014, 17030}, + { 610.3515625, -25600.002560000001, 6456, 6471}, + { 610.3515625, -10240.001024000001, 2321, 2335}, + { 610.3515625, -4096.0004096000002, 757, 769}, + { 610.3515625, -1638.40016384, 212, 221}, + { 610.3515625, -655.36006553599998, 48, 55}, + { 610.3515625, -262.14402621440001, 8, 13}, + { 610.3515625, -104.85761048576001, 0, 4}, + { 610.3515625, -41.943044194304001, 0, 1}, + { 610.3515625, -16.777217677721602, 0, 1}, + { 610.3515625, -6.7108870710886404, 0, 1}, + { 610.3515625, -2.6843548284354561, 0, 1}, + { 610.3515625, -1.0737419313741825, 0, 1}, + { 1525.87890625, -1000000.1, 275817, 431061}, + { 1525.87890625, -400000.03999999998, 109054, 109070}, + { 1525.87890625, -160000.016, 42546, 42562}, + { 1525.87890625, -64000.006399999998, 16151, 16167}, + { 1525.87890625, -25600.002560000001, 5814, 5828}, + { 1525.87890625, -10240.001024000001, 1902, 1914}, + { 1525.87890625, -4096.0004096000002, 535, 545}, + { 1525.87890625, -1638.40016384, 125, 131}, + { 1525.87890625, -655.36006553599998, 23, 28}, + { 1525.87890625, -262.14402621440001, 3, 7}, + { 1525.87890625, -104.85761048576001, 0, 1}, + { 1525.87890625, -41.943044194304001, 0, 1}, + { 1525.87890625, -16.777217677721602, 0, 1}, + { 1525.87890625, -6.7108870710886404, 0, 1}, + { 1525.87890625, -2.6843548284354561, 0, 1}, + { 1525.87890625, -1.0737419313741825, 0, 1}, + { 3814.697265625, -1000000.1, 272645, 272661}, + { 3814.697265625, -400000.03999999998, 106377, 106393}, + { 3814.697265625, -160000.016, 40390, 40406}, + { 3814.697265625, -64000.006399999998, 14545, 14560}, + { 3814.697265625, -25600.002560000001, 4765, 4777}, + { 3814.697265625, -10240.001024000001, 1346, 1356}, + { 3814.697265625, -4096.0004096000002, 316, 323}, + { 3814.697265625, -1638.40016384, 61, 66}, + { 3814.697265625, -655.36006553599998, 9, 13}, + { 3814.697265625, -262.14402621440001, 0, 4}, + { 3814.697265625, -104.85761048576001, 0, 1}, + { 3814.697265625, -41.943044194304001, 0, 1}, + { 3814.697265625, -16.777217677721602, 0, 1}, + { 3814.697265625, -6.7108870710886404, 0, 1}, + { 3814.697265625, -2.6843548284354561, 0, 1}, + { 3814.697265625, -1.0737419313741825, 0, 1}, + { 9536.7431640625, -1000000.1, 265953, 266155}, + { 9536.7431640625, -400000.03999999998, 100987, 101002}, + { 9536.7431640625, -160000.016, 36374, 36388}, + { 9536.7431640625, -64000.006399999998, 11921, 11934}, + { 9536.7431640625, -25600.002560000001, 3374, 3384}, + { 9536.7431640625, -10240.001024000001, 795, 802}, + { 9536.7431640625, -4096.0004096000002, 157, 162}, + { 9536.7431640625, -1638.40016384, 27, 30}, + { 9536.7431640625, -655.36006553599998, 3, 6}, + { 9536.7431640625, -262.14402621440001, 0, 1}, + { 9536.7431640625, -104.85761048576001, 0, 1}, + { 9536.7431640625, -41.943044194304001, 0, 1}, + { 9536.7431640625, -16.777217677721602, 0, 1}, + { 9536.7431640625, -6.7108870710886404, 0, 1}, + { 9536.7431640625, -2.6843548284354561, 0, 1}, + { 9536.7431640625, -1.0737419313741825, 0, 1}, + }; + static const unsigned total_elements = sizeof(domain) / sizeof(domain[0]); + static const unsigned stride = 16; + //static const unsigned a_elements = total_elements / stride; + BOOST_MATH_ASSERT(total_elements % stride == 0); + + static const double a_max = domain[total_elements - 1][0]; + static const double a_min = domain[0][0]; + static const double b_max = domain[stride - 1][1]; + static const double b_min = domain[0][1]; + + if (a < a_min) + return 0; // TODO: Use series? + if (b < b_min) + { + // + // This is a general heuristic that's more or less correct, + // but a bit too safe in most cases. Checked OK with + // random testing. + // + if (z > -b) + return 1; + if (a < 100) + return z < -b / (4 - 5 * (log(a)) * a / b) ? -1 : 0; + else + return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; + } + if (a > a_max) + { + // + // Crossover point is decreasing with increasing a + // upper limit is fine, lower limit is not: + // + if (b > b_max) + return 0; // TODO: don't know what else to do??? + unsigned index = total_elements - stride; + BOOST_MATH_ASSERT(domain[index][0] == a_max); + while (domain[index][1] < b) + ++index; + double b0 = domain[index - 1][1]; + double b1 = domain[index][1]; + double z0 = domain[index - 1][3]; + double z1 = domain[index][3]; + T upper_z_limit = static_cast((z0 * (b1 - b) + z1 * (b - b0)) / (b1 - b0)); + if (z > upper_z_limit) + return 1; + return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; + + } + if (b > b_max) + { + return 0; // TODO: is there a better way??? + } + // + // Bi-linear interpolation case: + // + unsigned index = 0; + while (domain[index][0] < a) + index += stride; + while (domain[index][1] < b) + ++index; + // + // We now have 4 corners: + // + double x1 = domain[index - stride - 1][0]; + double x2 = domain[index][0]; + double y1 = domain[index - 1][1]; + double y2 = domain[index][1]; + double f11 = domain[index - stride - 1][2]; + BOOST_MATH_ASSERT(domain[index - stride - 1][0] == x1); + BOOST_MATH_ASSERT(domain[index - stride - 1][1] == y1); + double f12 = domain[index - stride][2]; + BOOST_MATH_ASSERT(domain[index - stride][0] == x1); + BOOST_MATH_ASSERT(domain[index - stride][1] == y2); + double f21 = domain[index - 1][2]; + BOOST_MATH_ASSERT(domain[index - 1][0] == x2); + BOOST_MATH_ASSERT(domain[index - 1][1] == y1); + double f22 = domain[index][2]; + BOOST_MATH_ASSERT(domain[index][0] == x2); + BOOST_MATH_ASSERT(domain[index][1] == y2); + // + // Interpolation is a crude tool and our corners have quite tight bounds, + // and the "impossible region" is bounded by convex planes. For the upper + // bound this is fine - bilinear interpolation will be over-conservative + // but safe. For the lower limit though we may calculate that the "safe" + // zone is in an unsafe place. To work around this we move our coordinates + // closer to the lowest corner of our bounding box by an amount + // proportional to the distance from the nearest corner. This has the effect + // of making our lower bound smaller than it would otherwise be, and more so nearer + // the centre of the bounding box. + // + T effective_x = static_cast(a + (std::min)(T(a - x1), T(x2 - a)) * 0.25); + T effective_y = static_cast(b + (std::min)(T(b - y1), T(y2 - b)) * 0.25); + + T lower_limit = static_cast(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - effective_x) * (y2 - effective_y) + f21 * (effective_x - x1) * (y2 - effective_y) + f12 * (x2 - effective_x) * (effective_y - y1) + f22 * (effective_x - x1) * (effective_y - y1))); + + // + // If one f value was zero, take the whole box as zero: + // + double min_f = (std::min)((std::min)(f11, f12), (std::min)(f21, f22)); + if (min_f == 0) + lower_limit = 0; + // + // Now we can test! + // + if (z < lower_limit) + return -1; + + BOOST_MATH_ASSERT(f11 <= domain[index - stride - 1][3]); + f11 = domain[index - stride - 1][3]; + BOOST_MATH_ASSERT(f12 <= domain[index - stride][3]); + f12 = domain[index - stride][3]; + BOOST_MATH_ASSERT(f21 <= domain[index - 1][3]); + f21 = domain[index - 1][3]; + BOOST_MATH_ASSERT(f22 <= domain[index][3]); + f22 = domain[index][3]; + + T upper_limit = static_cast(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - a) * (y2 - b) + f21 * (a - x1) * (y2 - b) + f12 * (x2 - a) * (b - y1) + f22 * (a - x1) * (b - y1))); + if (z > upper_limit) + return 1; + return 0; + } + +} } } + + +#endif // BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp new file mode 100644 index 0000000000000..db5ea1da06205 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp @@ -0,0 +1,522 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) + +#ifndef BOOST_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ + +#include +#include + +#include +#include + + namespace boost { namespace math { namespace detail { + + // forward declaration for initial values + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol); + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + struct hypergeometric_1F1_recurrence_a_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_a_coefficients(const T& a, const T& b, const T& z): + a(a), b(b), z(z) + { + } + + hypergeometric_1F1_recurrence_a_coefficients(const hypergeometric_1F1_recurrence_a_coefficients&) = default; + + hypergeometric_1F1_recurrence_a_coefficients operator=(const hypergeometric_1F1_recurrence_a_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T ai = a + i; + + const T an = b - ai; + const T bn = (2 * ai - b + z); + const T cn = -ai; + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + }; + + template + struct hypergeometric_1F1_recurrence_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_b_coefficients(const T& a, const T& b, const T& z): + a(a), b(b), z(z) + { + } + + hypergeometric_1F1_recurrence_b_coefficients(const hypergeometric_1F1_recurrence_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_b_coefficients& operator=(const hypergeometric_1F1_recurrence_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T bi = b + i; + + const T an = bi * (bi - 1); + const T bn = bi * (1 - bi - z); + const T cn = z * (bi - a); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + }; + // + // for use when we're recursing to a small b: + // + template + struct hypergeometric_1F1_recurrence_small_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_small_b_coefficients(const T& a, const T& b, const T& z, int N) : + a(a), b(b), z(z), N(N) + { + } + + hypergeometric_1F1_recurrence_small_b_coefficients(const hypergeometric_1F1_recurrence_small_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_small_b_coefficients operator=(const hypergeometric_1F1_recurrence_small_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T bi = b + (i + N); + const T bi_minus_1 = b + (i + N - 1); + + const T an = bi * bi_minus_1; + const T bn = bi * (-bi_minus_1 - z); + const T cn = z * (bi - a); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + int N; + }; + + template + struct hypergeometric_1F1_recurrence_a_and_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_a_and_b_coefficients(const T& a, const T& b, const T& z, int offset = 0): + a(a), b(b), z(z), offset(offset) + { + } + + hypergeometric_1F1_recurrence_a_and_b_coefficients(const hypergeometric_1F1_recurrence_a_and_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_a_and_b_coefficients operator=(const hypergeometric_1F1_recurrence_a_and_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T ai = a + (offset + i); + const T bi = b + (offset + i); + + const T an = bi * (b + (offset + i - 1)); + const T bn = bi * (z - (b + (offset + i - 1))); + const T cn = -ai * z; + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + int offset; + }; +#if 0 + // + // These next few recurrence relations are archived for future reference, some of them are novel, though all + // are trivially derived from the existing well known relations: + // + // Recurrence relation for double-stepping on both a and b: + // - b(b-1)(b-2) / (2-b+z) M(a-2,b-2,z) + [b(a-1)z / (2-b+z) + b(1-b+z) + abz(b+1) /(b+1)(z-b)] M(a,b,z) - a(a+1)z^2 / (b+1)(z-b) M(a+2,b+2,z) + // + template + struct hypergeometric_1F1_recurrence_2a_and_2b_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2a_and_2b_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T ai = a + (offset + i); + const T bi = b + (offset + i); + + const T an = -bi * (b + (offset + i - 1)) * (b + (offset + i - 2)) / (-(b + (offset + i - 2)) + z); + const T bn = bi * (a + (offset + i - 1)) * z / (z - (b + (offset + i - 2))) + + bi * (z - (b + (offset + i - 1))) + + ai * bi * z * (b + (offset + i + 1)) / ((b + (offset + i + 1)) * (z - bi)); + const T cn = -ai * (a + (offset + i + 1)) * z * z / ((b + (offset + i + 1)) * (z - bi)); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2a_and_2b_coefficients operator=(const hypergeometric_1F1_recurrence_2a_and_2b_coefficients&); + }; + + // + // Recurrence relation for double-stepping on a: + // -(b-a)(1 + b - a)/(2a-2-b+z)M(a-2,b,z) + [(b-a)(a-1)/(2a-2-b+z) + (2a-b+z) + a(b-a-1)/(2a+2-b+z)]M(a,b,z) -a(a+1)/(2a+2-b+z)M(a+2,b,z) + // + template + struct hypergeometric_1F1_recurrence_2a_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2a_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T ai = a + (offset + i); + // -(b-a)(1 + b - a)/(2a-2-b+z) + const T an = -(b - ai) * (b - (a + (offset + i - 1))) / (2 * (a + (offset + i - 1)) - b + z); + const T bn = (b - ai) * (a + (offset + i - 1)) / (2 * (a + (offset + i - 1)) - b + z) + (2 * ai - b + z) + ai * (b - (a + (offset + i + 1))) / (2 * (a + (offset + i + 1)) - b + z); + const T cn = -ai * (a + (offset + i + 1)) / (2 * (a + (offset + i + 1)) - b + z); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2a_coefficients operator=(const hypergeometric_1F1_recurrence_2a_coefficients&); + }; + + // + // Recurrence relation for double-stepping on b: + // b(b-1)^2(b-2)/((1-b)(2-b-z)) M(a,b-2,z) + [zb(b-1)(b-1-a)/((1-b)(2-b-z)) + b(1-b-z) + z(b-a)(b+1)b/((b+1)(b+z)) ] M(a,b,z) + z^2(b-a)(b+1-a)/((b+1)(b+z)) M(a,b+2,z) + // + template + struct hypergeometric_1F1_recurrence_2b_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2b_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T bi = b + (offset + i); + const T bi_m1 = b + (offset + i - 1); + const T bi_p1 = b + (offset + i + 1); + const T bi_m2 = b + (offset + i - 2); + + const T an = bi * (bi_m1) * (bi_m1) * (bi_m2) / (-bi_m1 * (-bi_m2 - z)); + const T bn = z * bi * bi_m1 * (bi_m1 - a) / (-bi_m1 * (-bi_m2 - z)) + bi * (-bi_m1 - z) + z * (bi - a) * bi_p1 * bi / (bi_p1 * (bi + z)); + const T cn = z * z * (bi - a) * (bi_p1 - a) / (bi_p1 * (bi + z)); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2b_coefficients operator=(const hypergeometric_1F1_recurrence_2b_coefficients&); + }; + + // + // Recurrence relation for a+ b-: + // -z(b-a)(a-1-b)/(b(a-1+z)) M(a-1,b+1,z) + [(b-a)(a-1)b/(b(a-1+z)) + (2a-b+z) + a(b-a-1)/(a+z)] M(a,b,z) + a(1-b)/(a+z) M(a+1,b-1,z) + // + // This is potentially the most useful of these novel recurrences. + // - - + - + + template + struct hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + const T ai = a + (offset + i); + const T bi = b - (offset + i); + + const T an = -z * (bi - ai) * (ai - 1 - bi) / (bi * (ai - 1 + z)); + const T bn = z * ((-1 / (ai + z) - 1 / (ai + z - 1)) * (bi + z - 1) + 3) + bi - 1; + const T cn = ai * (1 - bi) / (ai + z); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients operator=(const hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients&); + }; +#endif + + template + inline T hypergeometric_1F1_backward_recurrence_for_negative_a(const T& a, const T& b, const T& z, const Policy& pol, const char* function, long long& log_scaling) + { + BOOST_MATH_STD_USING // modf, frexp, fabs, pow + + std::intmax_t integer_part = 0; + T ak = modf(a, &integer_part); + // + // We need ak-1 positive to avoid infinite recursion below: + // + if (0 != ak) + { + ak += 2; + integer_part -= 2; + } + if (ak - 1 == b) + { + // When ak - 1 == b are recursion coefficients disappear to zero and + // we end up with a NaN result. Reduce the recursion steps by 1 to + // avoid this. We rely on |b| small and therefore no infinite recursion. + ak -= 1; + integer_part += 1; + } + + if (-integer_part > static_cast(policies::get_max_series_iterations())) + return policies::raise_evaluation_error(function, "1F1 arguments sit in a range with a so negative that we have no evaluation method, got a = %1%", std::numeric_limits::quiet_NaN(), pol); + + T first {}; + T second {}; + if(ak == 0) + { + first = 1; + ak -= 1; + second = 1 - z / b; + if (fabs(second) < 0.5) + second = (b - z) / b; // cancellation avoidance + } + else + { + long long scaling1 {}; + long long scaling2 {}; + first = detail::hypergeometric_1F1_imp(ak, b, z, pol, scaling1); + ak -= 1; + second = detail::hypergeometric_1F1_imp(ak, b, z, pol, scaling2); + if (scaling1 != scaling2) + { + second *= exp(T(scaling2 - scaling1)); + } + log_scaling += scaling1; + } + ++integer_part; + + detail::hypergeometric_1F1_recurrence_a_coefficients s(ak, b, z); + + return tools::apply_recurrence_relation_backward(s, + static_cast(std::abs(integer_part)), + first, + second, &log_scaling); + } + + + template + T hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(const T& a, const T& b, const T& z, const Policy& pol, const char*, long long& log_scaling) + { + using std::swap; + BOOST_MATH_STD_USING // modf, frexp, fabs, pow + // + // We compute + // + // M[a + a_shift, b + b_shift; z] + // + // and recurse backwards on a and b down to + // + // M[a, b, z] + // + // With a + a_shift > 1 and b + b_shift > z + // + // There are 3 distinct regions to ensure stability during the recursions: + // + // a > 0 : stable for backwards on a + // a < 0, b > 0 : stable for backwards on a and b + // a < 0, b < 0 : stable for backwards on b (as long as |b| is small). + // + // We could simplify things by ignoring the middle region, but it's more efficient + // to recurse on a and b together when we can. + // + + BOOST_MATH_ASSERT(a < -1); // Not tested nor taken for -1 < a < 0 + + int b_shift = itrunc(z - b) + 2; + + int a_shift = itrunc(-a); + if (a + a_shift != 0) + { + a_shift += 2; + } + // + // If the shifts are so large that we would throw an evaluation_error, try the series instead, + // even though this will almost certainly throw as well: + // + if (b_shift > static_cast(boost::math::policies::get_max_series_iterations())) + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + if (a_shift > static_cast(boost::math::policies::get_max_series_iterations())) + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + int a_b_shift = b < 0 ? itrunc(b + b_shift) : b_shift; // The max we can shift on a and b together + int leading_a_shift = (std::min)(3, a_shift); // Just enough to make a negative + if (a_b_shift > a_shift - 3) + { + a_b_shift = a_shift < 3 ? 0 : a_shift - 3; + } + else + { + // Need to ensure that leading_a_shift is large enough that a will reach it's target + // after the first 2 phases (-,0) and (-,-) are over: + leading_a_shift = a_shift - a_b_shift; + } + int trailing_b_shift = b_shift - a_b_shift; + if (a_b_shift < 5) + { + // Might as well do things in two steps rather than 3: + if (a_b_shift > 0) + { + leading_a_shift += a_b_shift; + trailing_b_shift += a_b_shift; + } + a_b_shift = 0; + --leading_a_shift; + } + + BOOST_MATH_ASSERT(leading_a_shift > 1); + BOOST_MATH_ASSERT(a_b_shift + leading_a_shift + (a_b_shift == 0 ? 1 : 0) == a_shift); + BOOST_MATH_ASSERT(a_b_shift + trailing_b_shift == b_shift); + + if ((trailing_b_shift == 0) && (fabs(b) < 0.5) && a_b_shift) + { + // Better to have the final recursion on b alone, otherwise we lose precision when b is very small: + int diff = (std::min)(a_b_shift, 3); + a_b_shift -= diff; + leading_a_shift += diff; + trailing_b_shift += diff; + } + + T first {}; + T second {}; + long long scale1 {}; + long long scale2 {}; + first = boost::math::detail::hypergeometric_1F1_imp(T(a + a_shift), T(b + b_shift), z, pol, scale1); + // + // It would be good to compute "second" from first and the ratio - unfortunately we are right on the cusp + // recursion on a switching from stable backwards to stable forwards behaviour and so this is not possible here. + // + second = boost::math::detail::hypergeometric_1F1_imp(T(a + a_shift - 1), T(b + b_shift), z, pol, scale2); + if (scale1 != scale2) + second *= exp(T(scale2 - scale1)); + log_scaling += scale1; + + // + // Now we have [a + a_shift, b + b_shift, z] and [a + a_shift - 1, b + b_shift, z] + // and want to recurse until [a + a_shift - leading_a_shift, b + b_shift, z] and [a + a_shift - leadng_a_shift - 1, b + b_shift, z] + // which is leading_a_shift -1 steps. + // + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_a_coefficients(a + a_shift - 1, b + b_shift, z), + leading_a_shift, first, second, &log_scaling, &first); + + if (a_b_shift) + { + // + // Now we need to switch to an a+b shift so that we have: + // [a + a_shift - leading_a_shift, b + b_shift, z] and [a + a_shift - leadng_a_shift - 1, b + b_shift - 1, z] + // A&S 13.4.3 gives us what we need: + // + { + // local a's and b's: + T la = a + a_shift - leading_a_shift - 1; + T lb = b + b_shift; + second = ((1 + la - lb) * second - la * first) / (1 - lb); + } + // + // Now apply a_b_shift - 1 recursions to get down to + // [a + 1, b + trailing_b_shift + 1, z] and [a, b + trailing_b_shift, z] + // + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_a_and_b_coefficients(a, b + b_shift - a_b_shift, z, a_b_shift - 1), + a_b_shift - 1, first, second, &log_scaling, &first); + // + // Now we need to switch to a b shift, a different application of A&S 13.4.3 + // will get us there, we leave "second" where it is, and move "first" sideways: + // + { + T lb = b + trailing_b_shift + 1; + first = (second * (lb - 1) - a * first) / -(1 + a - lb); + } + } + else + { + // + // We have M[a+1, b+b_shift, z] and M[a, b+b_shift, z] and need M[a, b+b_shift-1, z] for + // recursion on b: A&S 13.4.3 gives us what we need. + // + T third = -(second * (1 + a - b - b_shift) - first * a) / (b + b_shift - 1); + swap(first, second); + swap(second, third); + --trailing_b_shift; + } + // + // Finish off by applying trailing_b_shift recursions: + // + if (trailing_b_shift) + { + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_small_b_coefficients(a, b, z, trailing_b_shift), + trailing_b_shift, first, second, &log_scaling); + } + return second; + } + + + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp new file mode 100644 index 0000000000000..e128e3d7ad698 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 John Maddock +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP + +#include +#include + + namespace boost{ namespace math{ namespace detail{ + + template + T hypergeometric_1F1_scaled_series(const T& a, const T& b, T z, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // + // Result is returned scaled by e^-z. + // Whenever the terms start becoming too large, we scale by some factor e^-n + // and keep track of the integer scaling factor n. At the end we can perform + // an exact subtraction of n from z and scale the result: + // + T sum(0), term(1), upper_limit(sqrt(boost::math::tools::max_value())), diff; + unsigned n = 0; + long long log_scaling_factor = 1 - lltrunc(boost::math::tools::log_max_value()); + T scaling_factor = exp(T(log_scaling_factor)); + std::intmax_t current_scaling = 0; + + do + { + sum += term; + if (sum >= upper_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + current_scaling += log_scaling_factor; + } + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + ++n; + diff = fabs(term / sum); + } while (diff > boost::math::policies::get_epsilon()); + + z = -z - current_scaling; + while (z < log_scaling_factor) + { + z -= log_scaling_factor; + sum *= scaling_factor; + } + return sum * exp(z); + } + + + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp new file mode 100644 index 0000000000000..4414a75d864f2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp @@ -0,0 +1,70 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP + +#include +#include + + namespace boost { namespace math { namespace detail { + + // forward declaration for initial values + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol); + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + T max_b_for_1F1_small_a_negative_b_by_ratio(const T& z) + { + if (z < -998) + return (z * 2) / 3; + float max_b[][2] = + { + { 0.0f, -47.3046f }, {-6.7275f, -52.0351f }, { -8.9543f, -57.2386f }, {-11.9182f, -62.9625f }, {-14.421f, -69.2587f }, {-19.1943f, -76.1846f }, {-23.2252f, -83.803f }, {-28.1024f, -92.1833f }, {-34.0039f, -101.402f }, {-37.4043f, -111.542f }, {-45.2593f, -122.696f }, {-54.7637f, -134.966f }, {-60.2401f, -148.462f }, {-72.8905f, -163.308f }, {-88.1975f, -179.639f }, {-88.1975f, -197.603f }, {-106.719f, -217.363f }, {-129.13f, -239.1f }, {-142.043f, -263.01f }, {-156.247f, -289.311f }, {-189.059f, -318.242f }, {-207.965f, -350.066f }, {-228.762f, -385.073f }, {-276.801f, -423.58f }, {-304.482f, -465.938f }, {-334.93f, -512.532f }, {-368.423f, -563.785f }, {-405.265f, -620.163f }, {-445.792f, -682.18f }, {-539.408f, -750.398f }, {-593.349f, -825.437f }, {-652.683f, -907.981f }, {-717.952f, -998.779f } + }; + auto p = std::lower_bound(max_b, max_b + sizeof(max_b) / sizeof(max_b[0]), z, [](const float (&a)[2], const T& z) { return a[1] > z; }); + T b = p - max_b ? (*--p)[0] : 0; + // + // We need approximately an extra 10 recurrences per 50 binary digits precision above that of double: + // + b += (std::max)(0, boost::math::tools::digits() - 53) / 5; + return b; + } + + template + T hypergeometric_1F1_small_a_negative_b_by_ratio(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We grab the ratio for M[a, b, z] / M[a, b+1, z] and use it to seed 2 initial values, + // then recurse until b > 0, compute a reference value and normalize (Millers method). + // + int iterations = itrunc(-b, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T ratio = boost::math::tools::function_ratio_from_forwards_recurrence(boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients(a, b, z), boost::math::tools::epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_small_a_negative_b_by_ratio<%1%>(%1%,%1%,%1%)", max_iter, pol); + T first = 1; + T second = 1 / ratio; + long long scaling1 = 0; + BOOST_MATH_ASSERT(b + iterations != a); + second = boost::math::tools::apply_recurrence_relation_forward(boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients(a, b + 1, z), iterations, first, second, &scaling1); + long long scaling2 = 0; + first = hypergeometric_1F1_imp(a, T(b + iterations + 1), z, pol, scaling2); + // + // Result is now first/second * e^(scaling2 - scaling1) + // + log_scaling += scaling2 - scaling1; + return first / second; + } + + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_asym.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_asym.hpp new file mode 100644 index 0000000000000..e603957180c0d --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_asym.hpp @@ -0,0 +1,179 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_ASYM_HPP +#define BOOST_MATH_HYPERGEOMETRIC_ASYM_HPP + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + + namespace boost { namespace math { + + namespace detail { + + // + // Asymptotic series based on https://dlmf.nist.gov/13.7#E1 + // + // Note that a and b must not be negative integers, in addition + // we require z > 0 and so apply Kummer's relation for z < 0. + // + template + inline T hypergeometric_1F1_asym_large_z_series(T a, const T& b, T z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::hypergeometric_1F1_asym_large_z_series<%1%>(%1%, %1%, %1%)"; + T prefix; + long long e; + int s; + if (z < 0) + { + a = b - a; + z = -z; + prefix = 1; + } + else + { + e = z > static_cast((std::numeric_limits::max)()) ? (std::numeric_limits::max)() : lltrunc(z, pol); + log_scaling += e; + prefix = exp(z - e); + } + if ((fabs(a) < 10) && (fabs(b) < 10)) + { + prefix *= pow(z, a) * pow(z, -b) * boost::math::tgamma(b, pol) / boost::math::tgamma(a, pol); + } + else + { + T t = log(z) * (a - b); + e = lltrunc(t, pol); + log_scaling += e; + prefix *= exp(t - e); + + t = boost::math::lgamma(b, &s, pol); + e = lltrunc(t, pol); + log_scaling += e; + prefix *= s * exp(t - e); + + t = boost::math::lgamma(a, &s, pol); + e = lltrunc(t, pol); + log_scaling -= e; + prefix /= s * exp(t - e); + } + // + // Checked 2F0: + // + unsigned k = 0; + T a1_poch(1 - a); + T a2_poch(b - a); + T z_mult(1 / z); + T sum = 0; + T abs_sum = 0; + T term = 1; + T last_term = 0; + do + { + sum += term; + last_term = term; + abs_sum += fabs(sum); + term *= a1_poch * a2_poch * z_mult; + term /= ++k; + a1_poch += 1; + a2_poch += 1; + if (fabs(sum) * boost::math::policies::get_epsilon() > fabs(term)) + break; + if(fabs(sum) / abs_sum < boost::math::policies::get_epsilon()) + return boost::math::policies::raise_evaluation_error(function, "Large-z asymptotic approximation to 1F1 has destroyed all the digits in the result due to cancellation. Current best guess is %1%", + prefix * sum, Policy()); + if(k > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "1F1: Unable to locate solution in a reasonable time:" + " large-z asymptotic approximation. Current best guess is %1%", prefix * sum, Policy()); + if((k > 10) && (fabs(term) > fabs(last_term))) + return boost::math::policies::raise_evaluation_error(function, "Large-z asymptotic approximation to 1F1 is divergent. Current best guess is %1%", prefix * sum, Policy()); + } while (true); + + return prefix * sum; + } + + + // experimental range + template + inline bool hypergeometric_1F1_asym_region(const T& a, const T& b, const T& z, const Policy&) + { + BOOST_MATH_STD_USING + int half_digits = policies::digits() / 2; + bool in_region = false; + + if (fabs(a) < 0.001f) + return false; // Haven't been able to make this work, why not? TODO! + + // + // We use the following heuristic, if after we have had half_digits terms + // of the 2F0 series, we require terms to be decreasing in size by a factor + // of at least 0.7. Assuming the earlier terms were converging much faster + // than this, then this should be enough to achieve convergence before the + // series shoots off to infinity. + // + if (z > 0) + { + T one_minus_a = 1 - a; + T b_minus_a = b - a; + if (fabs((one_minus_a + half_digits) * (b_minus_a + half_digits) / (half_digits * z)) < 0.7) + { + in_region = true; + // + // double check that we are not divergent at the start if a,b < 0: + // + if ((one_minus_a < 0) || (b_minus_a < 0)) + { + if (fabs(one_minus_a * b_minus_a / z) > 0.5) + in_region = false; + } + } + } + else if (fabs((1 - (b - a) + half_digits) * (a + half_digits) / (half_digits * z)) < 0.7) + { + if ((floor(b - a) == (b - a)) && (b - a < 0)) + return false; // Can't have a negative integer b-a. + in_region = true; + // + // double check that we are not divergent at the start if a,b < 0: + // + T a1 = 1 - (b - a); + if ((a1 < 0) || (a < 0)) + { + if (fabs(a1 * a / z) > 0.5) + in_region = false; + } + } + // + // Check for a and b negative integers as these aren't supported by the approximation: + // + if (in_region) + { + if ((a < 0) && (floor(a) == a)) + in_region = false; + if ((b < 0) && (floor(b) == b)) + in_region = false; + if (fabs(z) < 40) + in_region = false; + } + return in_region; + } + + } } } // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_HYPERGEOMETRIC_ASYM_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_cf.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_cf.hpp new file mode 100644 index 0000000000000..236cc551a6dd7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_cf.hpp @@ -0,0 +1,228 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP +#define BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP + + namespace boost { namespace math { namespace detail { + + // primary template for term of continued fraction + template + struct hypergeometric_pFq_cf_term; + + // partial specialization for 0F1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& b, const T& z): + n(1), b(b), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++b; ++n; + numer = -(z / (b * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T b; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1F0 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& z): + n(1), a(a), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++n; + numer = -((a * z) / n); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1F1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& z): + n(1), a(a), b(b), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++n; + numer = -((a * z) / (b * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1f2 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z): + n(1), a(a), b(b), c(c), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++c; ++n; + numer = -((a * z) / ((b * c) * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b, c; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 2f1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z): + n(1), a(a), b(b), c(c), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++c; ++n; + numer = -(((a * b) * z) / (c * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b, c; + const T z; + T numer; + result_type term; + }; + + template + inline T compute_cf_pFq(detail::hypergeometric_pFq_cf_term& term, const Policy& pol) + { + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + const T result = tools::continued_fraction_b( + term, + boost::math::policies::get_epsilon(), + max_iter); + boost::math::policies::check_series_iterations( + "boost::math::hypergeometric_pFq_cf<%1%>(%1%,%1%,%1%)", + max_iter, + pol); + return result; + } + + template + inline T hypergeometric_0F1_cf(const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(b, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((z / b) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F0_cf(const T& a, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((a * z) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F1_cf(const T& a, const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, z); + T result = detail::compute_cf_pFq(f, pol); + result = (((a * z) / b) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F2_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, c, z); + T result = detail::compute_cf_pFq(f, pol); + result = (((a * z) / (b * c)) / result) + 1; + return result; + } + + template + inline T hypergeometric_2F1_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, c, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((((a * b) * z) / c) / result) + 1; + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp new file mode 100644 index 0000000000000..3adc86f74fb5a --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp @@ -0,0 +1,671 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) + +#ifndef BOOST_HYPERGEOMETRIC_PFQ_SERIES_HPP_ +#define BOOST_HYPERGEOMETRIC_PFQ_SERIES_HPP_ + +#ifndef BOOST_MATH_PFQ_MAX_B_TERMS +# define BOOST_MATH_PFQ_MAX_B_TERMS 5 +#endif + +#include +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + template + unsigned set_crossover_locations(const Seq& aj, const Seq& bj, const Real& z, unsigned int* crossover_locations) + { + BOOST_MATH_STD_USING + unsigned N_terms = 0; + + if(aj.size() == 1 && bj.size() == 1) + { + // + // For 1F1 we can work out where the peaks in the series occur, + // which is to say when: + // + // (a + k)z / (k(b + k)) == +-1 + // + // Then we are at either a maxima or a minima in the series, and the + // last such point must be a maxima since the series is globally convergent. + // Potentially then we are solving 2 quadratic equations and have up to 4 + // solutions, any solutions which are complex or negative are discarded, + // leaving us with 4 options: + // + // 0 solutions: The series is directly convergent. + // 1 solution : The series diverges to a maxima before converging. + // 2 solutions: The series is initially convergent, followed by divergence to a maxima before final convergence. + // 3 solutions: The series diverges to a maxima, converges to a minima before diverging again to a second maxima before final convergence. + // 4 solutions: The series converges to a minima before diverging to a maxima, converging to a minima, diverging to a second maxima and then converging. + // + // The first 2 situations are adequately handled by direct series evaluation, while the 2,3 and 4 solutions are not. + // + Real a = *aj.begin(); + Real b = *bj.begin(); + Real sq = 4 * a * z + b * b - 2 * b * z + z * z; + if (sq >= 0) + { + Real t = (-sqrt(sq) - b + z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + t = (sqrt(sq) - b + z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + } + sq = -4 * a * z + b * b + 2 * b * z + z * z; + if (sq >= 0) + { + Real t = (-sqrt(sq) - b - z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + t = (sqrt(sq) - b - z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + } + std::sort(crossover_locations, crossover_locations + N_terms, std::less()); + // + // Now we need to discard every other terms, as these are the minima: + // + switch (N_terms) + { + case 0: + case 1: + break; + case 2: + crossover_locations[0] = crossover_locations[1]; + --N_terms; + break; + case 3: + crossover_locations[1] = crossover_locations[2]; + --N_terms; + break; + case 4: + crossover_locations[0] = crossover_locations[1]; + crossover_locations[1] = crossover_locations[3]; + N_terms -= 2; + break; + } + } + else + { + unsigned n = 0; + for (auto bi = bj.begin(); bi != bj.end(); ++bi, ++n) + { + crossover_locations[n] = *bi >= 0 ? 0 : itrunc(-*bi) + 1; + } + std::sort(crossover_locations, crossover_locations + bj.size(), std::less()); + N_terms = (unsigned)bj.size(); + } + return N_terms; + } + + template + std::pair hypergeometric_pFq_checked_series_impl(const Seq& aj, const Seq& bj, const Real& z, const Policy& pol, const Terminal& termination, long long& log_scale) + { + BOOST_MATH_STD_USING + Real result = 1; + Real abs_result = 1; + Real term = 1; + Real term0 = 0; + Real tol = boost::math::policies::get_epsilon(); + std::uintmax_t k = 0; + Real upper_limit(sqrt(boost::math::tools::max_value())), diff; + Real lower_limit(1 / upper_limit); + long long log_scaling_factor = lltrunc(boost::math::tools::log_max_value()) - 2; + Real scaling_factor = exp(Real(log_scaling_factor)); + Real term_m1; + long long local_scaling = 0; + bool have_no_correct_bits = false; + + if ((aj.size() == 1) && (bj.size() == 0)) + { + if (fabs(z) > 1) + { + if ((z > 0) && (floor(*aj.begin()) != *aj.begin())) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == 1 and q == 0 and |z| > 1, result is imaginary", z, pol); + return std::make_pair(r, r); + } + std::pair r = hypergeometric_pFq_checked_series_impl(aj, bj, Real(1 / z), pol, termination, log_scale); + + #if (defined(__GNUC__) && __GNUC__ == 13) + Real mul = pow(-z, Real(-*aj.begin())); + #else + Real mul = pow(-z, -*aj.begin()); + #endif + + r.first *= mul; + r.second *= mul; + return r; + } + } + + if (aj.size() > bj.size()) + { + if (aj.size() == bj.size() + 1) + { + if (fabs(z) > 1) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| > 1, series does not converge", z, pol); + return std::make_pair(r, r); + } + if (fabs(z) == 1) + { + Real s = 0; + for (auto i = bj.begin(); i != bj.end(); ++i) + s += *i; + for (auto i = aj.begin(); i != aj.end(); ++i) + s -= *i; + if ((z == 1) && (s <= 0)) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| == 1, in a situation where the series does not converge", z, pol); + return std::make_pair(r, r); + } + if ((z == -1) && (s <= -1)) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| == 1, in a situation where the series does not converge", z, pol); + return std::make_pair(r, r); + } + } + } + else + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p > q+1, series does not converge", z, pol); + return std::make_pair(r, r); + } + } + + while (!termination(k)) + { + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term *= *ai + k; + } + if (term == 0) + { + // There is a negative integer in the aj's: + return std::make_pair(result, abs_result); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term /= *bi + k; + } + term *= z; + ++k; + term /= k; + //std::cout << k << " " << *bj.begin() + k << " " << result << " " << term << /*" " << term_at_k(*aj.begin(), *bj.begin(), z, k, pol) <<*/ std::endl; + result += term; + abs_result += abs(term); + //std::cout << "k = " << k << " term = " << term * exp(log_scale) << " result = " << result * exp(log_scale) << " abs_result = " << abs_result * exp(log_scale) << std::endl; + + // + // Rescaling: + // + if (fabs(abs_result) >= upper_limit) + { + abs_result /= scaling_factor; + result /= scaling_factor; + term /= scaling_factor; + log_scale += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(abs_result) < lower_limit) + { + abs_result *= scaling_factor; + result *= scaling_factor; + term *= scaling_factor; + log_scale -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + + if ((abs(result * tol) > abs(term)) && (abs(term0) > abs(term))) + break; + if (abs_result * tol > abs(result)) + { + // Check if result is so small compared to abs_resuslt that there are no longer any + // correct bits... we require two consecutive passes here before aborting to + // avoid false positives when result transiently drops to near zero then rebounds. + if (have_no_correct_bits) + { + // We have no correct bits in the result... just give up! + result = boost::math::policies::raise_evaluation_error("boost::math::hypergeometric_pFq<%1%>", "Cancellation is so severe that no bits in the result are correct, last result was %1%", Real(result * exp(Real(log_scale))), pol); + return std::make_pair(result, result); + } + else + have_no_correct_bits = true; + } + else + have_no_correct_bits = false; + term0 = term; + } + //std::cout << "result = " << result << std::endl; + //std::cout << "local_scaling = " << local_scaling << std::endl; + //std::cout << "Norm result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(result) * exp(boost::multiprecision::mpfr_float_50(local_scaling)) << std::endl; + // + // We have to be careful when one of the b's crosses the origin: + // + if(bj.size() > BOOST_MATH_PFQ_MAX_B_TERMS) + policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>(Seq, Seq, %1%)", + "The number of b terms must be less than the value of BOOST_MATH_PFQ_MAX_B_TERMS (" BOOST_MATH_STRINGIZE(BOOST_MATH_PFQ_MAX_B_TERMS) "), but got %1%.", + Real(bj.size()), pol); + + unsigned crossover_locations[BOOST_MATH_PFQ_MAX_B_TERMS]; + + unsigned N_crossovers = set_crossover_locations(aj, bj, z, crossover_locations); + + bool terminate = false; // Set to true if one of the a's passes through the origin and terminates the series. + + for (unsigned n = 0; n < N_crossovers; ++n) + { + if (k < crossover_locations[n]) + { + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + if ((*ai < 0) && (floor(*ai) == *ai) && (*ai > static_cast(crossover_locations[n]))) + return std::make_pair(result, abs_result); // b's will never cross the origin! + } + // + // local results: + // + Real loop_result = 0; + Real loop_abs_result = 0; + long long loop_scale = 0; + // + // loop_error_scale will be used to increase the size of the error + // estimate (absolute sum), based on the errors inherent in calculating + // the pochhammer symbols. + // + Real loop_error_scale = 0; + //boost::multiprecision::mpfi_float err_est = 0; + // + // b hasn't crossed the origin yet and the series may spring back into life at that point + // so we need to jump forward to that term and then evaluate forwards and backwards from there: + // + unsigned s = crossover_locations[n]; + std::uintmax_t backstop = k; + long long s1(1), s2(1); + term = 0; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + if ((floor(*ai) == *ai) && (*ai < 0) && (-*ai <= static_cast(s))) + { + // One of the a terms has passed through zero and terminated the series: + terminate = true; + break; + } + else + { + int ls = 1; + Real p = log_pochhammer(*ai, s, pol, &ls); + s1 *= ls; + term += p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est += boost::multiprecision::mpfi_float(p); + } + } + //std::cout << "term = " << term << std::endl; + if (terminate) + break; + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + int ls = 1; + Real p = log_pochhammer(*bi, s, pol, &ls); + s2 *= ls; + term -= p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est -= boost::multiprecision::mpfi_float(p); + } + //std::cout << "term = " << term << std::endl; + Real p = lgamma(Real(s + 1), pol); + term -= p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est -= boost::multiprecision::mpfi_float(p); + p = s * log(fabs(z)); + term += p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est += boost::multiprecision::mpfi_float(p); + //err_est = exp(err_est); + //std::cout << err_est << std::endl; + // + // Convert loop_error scale to the absolute error + // in term after exp is applied: + // + loop_error_scale *= tools::epsilon(); + // + // Convert to relative error after exp: + // + loop_error_scale = fabs(expm1(loop_error_scale, pol)); + // + // Convert to multiplier for the error term: + // + loop_error_scale /= tools::epsilon(); + + if (z < 0) + s1 *= (s & 1 ? -1 : 1); + + if (term <= tools::log_min_value()) + { + // rescale if we can: + long long scale = lltrunc(floor(term - tools::log_min_value()) - 2); + term -= scale; + loop_scale += scale; + } + if (term > 10) + { + int scale = itrunc(floor(term)); + term -= scale; + loop_scale += scale; + } + //std::cout << "term = " << term << std::endl; + term = s1 * s2 * exp(term); + //std::cout << "term = " << term << std::endl; + //std::cout << "loop_scale = " << loop_scale << std::endl; + k = s; + term0 = term; + long long saved_loop_scale = loop_scale; + bool terms_are_growing = true; + bool trivial_small_series_check = false; + do + { + loop_result += term; + loop_abs_result += fabs(term); + //std::cout << "k = " << k << " term = " << term * exp(loop_scale) << " result = " << loop_result * exp(loop_scale) << " abs_result = " << loop_abs_result * exp(loop_scale) << std::endl; + if (fabs(loop_result) >= upper_limit) + { + loop_result /= scaling_factor; + loop_abs_result /= scaling_factor; + term /= scaling_factor; + loop_scale += log_scaling_factor; + } + if (fabs(loop_result) < lower_limit) + { + loop_result *= scaling_factor; + loop_abs_result *= scaling_factor; + term *= scaling_factor; + loop_scale -= log_scaling_factor; + } + term_m1 = term; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term *= *ai + k; + } + if (term == 0) + { + // There is a negative integer in the aj's: + return std::make_pair(result, abs_result); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term /= *bi + k; + } + term *= z / (k + 1); + + ++k; + diff = fabs(term / loop_result); + terms_are_growing = fabs(term) > fabs(term_m1); + if (!trivial_small_series_check && !terms_are_growing) + { + // + // Now that we have started to converge, check to see if the value of + // this local sum is trivially small compared to the result. If so + // abort this part of the series. + // + trivial_small_series_check = true; + Real d; + if (loop_scale > local_scaling) + { + long long rescale = local_scaling - loop_scale; + if (rescale < tools::log_min_value()) + d = 1; // arbitrary value, we want to keep going + else + d = fabs(term / (result * exp(Real(rescale)))); + } + else + { + long long rescale = loop_scale - local_scaling; + if (rescale < tools::log_min_value()) + d = 0; // terminate this loop + else + d = fabs(term * exp(Real(rescale)) / result); + } + if (d < boost::math::policies::get_epsilon()) + break; + } + } while (!termination(k - s) && ((diff > boost::math::policies::get_epsilon()) || terms_are_growing)); + + //std::cout << "Norm loop result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(loop_result)* exp(boost::multiprecision::mpfr_float_50(loop_scale)) << std::endl; + // + // We now need to combine the results of the first series summation with whatever + // local results we have now. First though, rescale abs_result by loop_error_scale + // to factor in the error in the pochhammer terms at the start of this block: + // + std::uintmax_t next_backstop = k; + loop_abs_result += loop_error_scale * fabs(loop_result); + if (loop_scale > local_scaling) + { + // + // Need to shrink previous result: + // + long long rescale = local_scaling - loop_scale; + local_scaling = loop_scale; + log_scale -= rescale; + Real ex = exp(Real(rescale)); + result *= ex; + abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else if (local_scaling > loop_scale) + { + // + // Need to shrink local result: + // + long long rescale = loop_scale - local_scaling; + Real ex = exp(Real(rescale)); + loop_result *= ex; + loop_abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else + { + result += loop_result; + abs_result += loop_abs_result; + } + // + // Now go backwards as well: + // + k = s; + term = term0; + loop_result = 0; + loop_abs_result = 0; + loop_scale = saved_loop_scale; + trivial_small_series_check = false; + do + { + --k; + if (k == backstop) + break; + term_m1 = term; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term /= *ai + k; + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term *= *bi + k; + } + term *= (k + 1) / z; + loop_result += term; + loop_abs_result += fabs(term); + + if (!trivial_small_series_check && (fabs(term) < fabs(term_m1))) + { + // + // Now that we have started to converge, check to see if the value of + // this local sum is trivially small compared to the result. If so + // abort this part of the series. + // + trivial_small_series_check = true; + Real d; + if (loop_scale > local_scaling) + { + long long rescale = local_scaling - loop_scale; + if (rescale < tools::log_min_value()) + d = 1; // keep going + else + d = fabs(term / (result * exp(Real(rescale)))); + } + else + { + long long rescale = loop_scale - local_scaling; + if (rescale < tools::log_min_value()) + d = 0; // stop, underflow + else + d = fabs(term * exp(Real(rescale)) / result); + } + if (d < boost::math::policies::get_epsilon()) + break; + } + + //std::cout << "k = " << k << " result = " << result << " abs_result = " << abs_result << std::endl; + if (fabs(loop_result) >= upper_limit) + { + loop_result /= scaling_factor; + loop_abs_result /= scaling_factor; + term /= scaling_factor; + loop_scale += log_scaling_factor; + } + if (fabs(loop_result) < lower_limit) + { + loop_result *= scaling_factor; + loop_abs_result *= scaling_factor; + term *= scaling_factor; + loop_scale -= log_scaling_factor; + } + diff = fabs(term / loop_result); + } while (!termination(s - k) && ((diff > boost::math::policies::get_epsilon()) || (fabs(term) > fabs(term_m1)))); + + //std::cout << "Norm loop result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(loop_result)* exp(boost::multiprecision::mpfr_float_50(loop_scale)) << std::endl; + // + // We now need to combine the results of the first series summation with whatever + // local results we have now. First though, rescale abs_result by loop_error_scale + // to factor in the error in the pochhammer terms at the start of this block: + // + loop_abs_result += loop_error_scale * fabs(loop_result); + // + if (loop_scale > local_scaling) + { + // + // Need to shrink previous result: + // + long long rescale = local_scaling - loop_scale; + local_scaling = loop_scale; + log_scale -= rescale; + Real ex = exp(Real(rescale)); + result *= ex; + abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else if (local_scaling > loop_scale) + { + // + // Need to shrink local result: + // + long long rescale = loop_scale - local_scaling; + Real ex = exp(Real(rescale)); + loop_result *= ex; + loop_abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else + { + result += loop_result; + abs_result += loop_abs_result; + } + // + // Reset k to the largest k we reached + // + k = next_backstop; + } + } + + return std::make_pair(result, abs_result); + } + + struct iteration_terminator + { + iteration_terminator(std::uintmax_t i) : m(i) {} + + bool operator()(std::uintmax_t v) const { return v >= m; } + + std::uintmax_t m; + }; + + template + Real hypergeometric_pFq_checked_series_impl(const Seq& aj, const Seq& bj, const Real& z, const Policy& pol, long long& log_scale) + { + BOOST_MATH_STD_USING + iteration_terminator term(boost::math::policies::get_max_series_iterations()); + std::pair result = hypergeometric_pFq_checked_series_impl(aj, bj, z, pol, term, log_scale); + // + // Check to see how many digits we've lost, if it's more than half, raise an evaluation error - + // this is an entirely arbitrary cut off, but not unreasonable. + // + if (result.second * sqrt(boost::math::policies::get_epsilon()) > abs(result.first)) + { + return boost::math::policies::raise_evaluation_error("boost::math::hypergeometric_pFq<%1%>", "Cancellation is so severe that fewer than half the bits in the result are correct, last result was %1%", Real(result.first * exp(Real(log_scale))), pol); + } + return result.first; + } + + template + inline Real hypergeometric_1F1_checked_series_impl(const Real& a, const Real& b, const Real& z, const Policy& pol, long long& log_scale) + { + std::array aj = { a }; + std::array bj = { b }; + return hypergeometric_pFq_checked_series_impl(aj, bj, z, pol, log_scale); + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_PFQ_SERIES_HPP_ diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pade.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pade.hpp new file mode 100644 index 0000000000000..29d8179114bf4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_pade.hpp @@ -0,0 +1,131 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_PADE_HPP +#define BOOST_MATH_HYPERGEOMETRIC_PADE_HPP + + namespace boost{ namespace math{ namespace detail{ + + // Luke: C ---------- SUBROUTINE R1F1P(CP, Z, A, B, N) ---------- + // Luke: C ----- PADE APPROXIMATION OF 1F1( 1 ; CP ; -Z ) ------- + template + inline T hypergeometric_1F1_pade(const T& cp, const T& zp, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T one = T(1); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T zz = z * z; + T b0 = one; + T a0 = one; + T xi1 = one; + T ct1 = cp + one; + T cp1 = cp - one; + + T b1 = one + (z / ct1); + T a1 = b1 - (z / cp); + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T b2 = T(0), a2 = T(0); + T result = T(0), prev_result; + + for (unsigned k = 1; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + const T ct2 = ct1 * ct1; + const T g1 = one + ((cp1 / (ct2 + ct1 + ct1)) * z); + const T g2 = ((xi1 / (ct2 - one)) * ((xi1 + cp1) / ct2)) * zz; + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b2 = (g1 * b1) + (g2 * b0); + a2 = (g1 * a1) + (g2 * a0); + + prev_result = result; + result = a2 / b2; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result)) + break; + + b0 = b1; b1 = b2; + a0 = a1; a1 = a2; + + ct1 += 2; + xi1 += 1; + } + + return a2 / b2; + } + + // Luke: C -------- SUBROUTINE R2F1P(BP, CP, Z, A, B, N) -------- + // Luke: C ---- PADE APPROXIMATION OF 2F1( 1 , BP; CP ; -Z ) ---- + template + inline T hypergeometric_2F1_pade(const T& bp, const T& cp, const T& zp, const Policy&) + { + BOOST_MATH_STD_USING + + static const T one = T(1); + + // Luke: C ---------- INITIALIZATION ----------- + const T z = -zp; + const T zz = z * z; + T b0 = one; + T a0 = one; + T xi1 = one; + T ct1 = cp; + const T b1c1 = (cp - one) * (bp - one); + + T b1 = one + ((z / (cp + one)) * (bp + one)); + T a1 = b1 - ((bp / cp) * z); + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T b2 = T(0), a2 = T(0); + T result = T(0), prev_result = a1 / b1; + + for (unsigned k = 1; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + const T ct2 = ct1 + xi1; + const T ct3 = ct2 * ct2; + const T g2 = (((((ct1 / ct3) * (bp - ct1)) / (ct3 - one)) * xi1) * (bp + xi1)) * zz; + ++xi1; + const T g1 = one + (((((xi1 + xi1) * ct1) + b1c1) / (ct3 + ct2 + ct2)) * z); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b2 = (g1 * b1) + (g2 * b0); + a2 = (g1 * a1) + (g2 * a0); + + prev_result = result; + result = a2 / b2; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result)) + break; + + b0 = b1; b1 = b2; + a0 = a1; a1 = a2; + + ++ct1; + } + + return a2 / b2; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_PADE_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_rational.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_rational.hpp new file mode 100644 index 0000000000000..b958e3af66f23 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_rational.hpp @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_RATIONAL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_RATIONAL_HPP + + #include + + namespace boost{ namespace math{ namespace detail{ + + // Luke: C ------- SUBROUTINE R1F1P(AP, CP, Z, A, B, N) --------- + // Luke: C --- RATIONAL APPROXIMATION OF 1F1( AP ; CP ; -Z ) ---- + template + inline T hypergeometric_1F1_rational(const T& ap, const T& cp, const T& zp, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T zero = T(0), one = T(1), two = T(2), three = T(3); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T z2 = z / two; + + T ct1 = ap * (z / cp); + T ct2 = z2 / (one + cp); + T xn3 = zero; + T xn2 = one; + T xn1 = two; + T xn0 = three; + + T b1 = one; + T a1 = one; + T b2 = one + ((one + ap) * (z2 / cp)); + T a2 = b2 - ct1; + T b3 = one + ((two + b2) * (((two + ap) / three) * ct2)); + T a3 = b3 - ((one + ct2) * ct1); + ct1 = three; + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T a4 = T(0), b4 = T(0); + T result = T(0), prev_result = a3 / b3; + + for (unsigned k = 2; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + ct2 = (z2 / ct1) / (cp + xn1); + const T g1 = one + (ct2 * (xn2 - ap)); + ct2 *= ((ap + xn1) / (cp + xn2)); + const T g2 = ct2 * ((cp - xn1) + (((ap + xn0) / (ct1 + two)) * z2)); + const T g3 = ((ct2 * z2) * (((z2 / ct1) / (ct1 - two)) * ((ap + xn2)) / (cp + xn3))) * (ap - xn2); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b4 = (g1 * b3) + (g2 * b2) + (g3 * b1); + a4 = (g1 * a3) + (g2 * a2) + (g3 * a1); + + prev_result = result; + result = a4 / b4; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result) / fabs(result)) + break; + + b1 = b2; b2 = b3; b3 = b4; + a1 = a2; a2 = a3; a3 = a4; + + xn3 = xn2; + xn2 = xn1; + xn1 = xn0; + xn0 += 1; + ct1 += two; + } + + return result; + } + + // Luke: C ----- SUBROUTINE R2F1P(AB, BP, CP, Z, A, B, N) ------- + // Luke: C -- RATIONAL APPROXIMATION OF 2F1( AB , BP; CP ; -Z ) - + template + inline T hypergeometric_2F1_rational(const T& ap, const T& bp, const T& cp, const T& zp, const unsigned n, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T one = T(1), two = T(2), three = T(3), four = T(4), + six = T(6), half_7 = T(3.5), half_3 = T(1.5), forth_3 = T(0.75); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T z2 = z / two; + + T sabz = (ap + bp) * z; + const T ab = ap * bp; + const T abz = ab * z; + const T abz1 = z + (abz + sabz); + const T abz2 = abz1 + (sabz + (three * z)); + const T cp1 = cp + one; + const T ct1 = cp1 + cp1; + + T b1 = one; + T a1 = one; + T b2 = one + (abz1 / (cp + cp)); + T a2 = b2 - (abz / cp); + T b3 = one + ((abz2 / ct1) * (one + (abz1 / ((-six) + (three * ct1))))); + T a3 = b3 - ((abz / cp) * (one + ((abz2 - abz1) / ct1))); + sabz /= four; + + const T abz1_div_4 = abz1 / four; + const T cp1_inc = cp1 + one; + const T cp1_mul_cp1_inc = cp1 * cp1_inc; + + std::array d = {{ + ((half_7 - ab) * z2) - sabz, + abz1_div_4, + abz1_div_4 - (two * sabz), + cp1_inc, + cp1_mul_cp1_inc, + cp * cp1_mul_cp1_inc, + half_3, + forth_3, + forth_3 * z + }}; + + T xi = three; + T a4 = T(0), b4 = T(0); + for (unsigned k = 2; k < n; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + T g3 = (d[2] / d[7]) * (d[1] / d[5]); + d[1] += d[8] + sabz; + d[2] += d[8] - sabz; + g3 *= d[1] / d[6]; + T g1 = one + (((d[1] + d[0]) / d[6]) / d[3]); + T g2 = (d[1] / d[4]) / d[6]; + d[7] += two * d[6]; + ++d[6]; + g2 *= cp1 - (xi + ((d[2] + d[0]) / d[6])); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b4 = (g1 * b3) + (g2 * b2) + (g3 * b1); + a4 = (g1 * a3) + (g2 * a2) + (g3 * a1); + b1 = b2; b2 = b3; b3 = b4; + a1 = a2; a2 = a3; a3 = a4; + + d[8] += z2; + d[0] += two * d[8]; + d[5] += three * d[4]; + d[4] += two * d[3]; + ++d[3]; + ++xi; + } + + return a4 / b4; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_RATIONAL_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_separated_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_separated_series.hpp new file mode 100644 index 0000000000000..3baff69f41d37 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_separated_series.hpp @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP +#define BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP + + namespace boost { namespace math { namespace detail { + + template + inline T hypergeometric_1F1_separated_series(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING + + std::uintmax_t max_iter = policies::get_max_series_iterations(); + const T factor = policies::get_epsilon(); + + T denom = 1, numer = 1; + T intermediate_result = 1, result = 1; + T a_pochhammer = a, z_pow = z; + unsigned N = 0; + while (--max_iter) + { + ++N; + const T mult = (((b + N) - 1) * N); + denom *= mult; numer *= mult; + numer += a_pochhammer * z_pow; + + result = numer / denom; + + if (fabs(factor * result) > fabs(result - intermediate_result)) + break; + + intermediate_result = result; + + a_pochhammer *= (a + N); + z_pow *= z; + } + + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_series.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_series.hpp new file mode 100644 index 0000000000000..2a2a54af9bd37 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/hypergeometric_series.hpp @@ -0,0 +1,434 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) +// +#ifndef BOOST_MATH_DETAIL_HYPERGEOMETRIC_SERIES_HPP +#define BOOST_MATH_DETAIL_HYPERGEOMETRIC_SERIES_HPP + +#include +#include +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + // primary template for term of Taylor series + template + struct hypergeometric_pFq_generic_series_term; + + // partial specialization for 0F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& b, const T& z) + : n(0), term(1), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= ((1 / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T b, z; + }; + + // partial specialization for 1F0 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& z) + : n(0), term(1), a(a), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / (n + 1)) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, z; + }; + + // partial specialization for 1F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& b, const T& z) + : n(0), term(1), a(a), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, b, z; + }; + + // partial specialization for 1F2 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& b1, const T& b2, const T& z) + : n(0), term(1), a(a), b1(b1), b2(b2), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / ((b1 + n) * (b2 + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, b1, b2, z; + }; + + // partial specialization for 2F0 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a1, const T& a2, const T& z) + : n(0), term(1), a1(a1), a2(a2), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a1 + n) * (a2 + n) / (n + 1)) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a1, a2, z; + }; + + // partial specialization for 2F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a1, const T& a2, const T& b, const T& z) + : n(0), term(1), a1(a1), a2(a2), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a1 + n) * (a2 + n) / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a1, a2, b, z; + }; + + // we don't need to define extra check and make a polinom from + // series, when p(i) and q(i) are negative integers and p(i) >= q(i) + // as described in functions.wolfram.alpha, because we always + // stop summation when result (in this case numerator) is zero. + template + inline T sum_pFq_series(detail::hypergeometric_pFq_generic_series_term& term, const Policy& pol) + { + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + const T result = boost::math::tools::sum_series(term, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::hypergeometric_pFq_generic_series<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result; + } + + template + inline T hypergeometric_0F1_generic_series(const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(b, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_1F0_generic_series(const T& a, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T log_pochhammer(T z, unsigned n, const Policy pol, int* s = nullptr) + { + BOOST_MATH_STD_USING +#if 0 + if (z < 0) + { + if (n < -z) + { + if(s) + *s = (n & 1 ? -1 : 1); + return log_pochhammer(T(-z + (1 - (int)n)), n, pol); + } + else + { + int cross = itrunc(ceil(-z)); + return log_pochhammer(T(-z + (1 - cross)), cross, pol, s) + log_pochhammer(T(cross + z), n - cross, pol); + } + } + else +#endif + { + if (z + n < 0) + { + T r = log_pochhammer(T(-z - n + 1), n, pol, s); + if (s) + *s *= (n & 1 ? -1 : 1); + return r; + } + int s1, s2; + auto r = static_cast(boost::math::lgamma(T(z + n), &s1, pol) - boost::math::lgamma(z, &s2, pol)); + if(s) + *s = s1 * s2; + return r; + } + } + + template + inline T hypergeometric_1F1_generic_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling, const char* function) + { + BOOST_MATH_STD_USING + T sum(0), term(1), upper_limit(sqrt(boost::math::tools::max_value())), diff; + T lower_limit(1 / upper_limit); + unsigned n = 0; + long long log_scaling_factor = lltrunc(boost::math::tools::log_max_value()) - 2; + T scaling_factor = exp(T(log_scaling_factor)); + T term_m1 = 0; + long long local_scaling = 0; + // + // When a is very small, then (a+n)/n => 1 faster than + // z / (b+n) => 1, as a result the series starts off + // converging, then at some unspecified time very gradually + // starts to diverge, potentially resulting in some very large + // values being missed. As a result we need a check for small + // a in the convergence criteria. Note that this issue occurs + // even when all the terms are positive. + // + bool small_a = fabs(a) < 0.25; + + unsigned summit_location = 0; + bool have_minima = false; + T sq = 4 * a * z + b * b - 2 * b * z + z * z; + if (sq >= 0) + { + T t = (-sqrt(sq) - b + z) / 2; + if (t > 1) // Don't worry about a minima between 0 and 1. + have_minima = true; + t = (sqrt(sq) - b + z) / 2; + if (t > 0) + summit_location = itrunc(t); + } + + if (summit_location > boost::math::policies::get_max_series_iterations() / 4) + { + // + // Skip forward to the location of the largest term in the series and + // evaluate outwards from there: + // + int s1, s2; + term = log_pochhammer(a, summit_location, pol, &s1) + summit_location * log(z) - log_pochhammer(b, summit_location, pol, &s2) - lgamma(T(summit_location + 1), pol); + //std::cout << term << " " << log_pochhammer(boost::multiprecision::mpfr_float(a), summit_location, pol, &s1) + summit_location * log(boost::multiprecision::mpfr_float(z)) - log_pochhammer(boost::multiprecision::mpfr_float(b), summit_location, pol, &s2) - lgamma(boost::multiprecision::mpfr_float(summit_location + 1), pol) << std::endl; + local_scaling = lltrunc(term); + log_scaling += local_scaling; + term = s1 * s2 * exp(term - local_scaling); + //std::cout << term << " " << exp(log_pochhammer(boost::multiprecision::mpfr_float(a), summit_location, pol, &s1) + summit_location * log(boost::multiprecision::mpfr_float(z)) - log_pochhammer(boost::multiprecision::mpfr_float(b), summit_location, pol, &s2) - lgamma(boost::multiprecision::mpfr_float(summit_location + 1), pol) - local_scaling) << std::endl; + n = summit_location; + } + else + summit_location = 0; + + T saved_term = term; + long long saved_scale = local_scaling; + + do + { + sum += term; + //std::cout << n << " " << term * exp(boost::multiprecision::mpfr_float(local_scaling)) << " " << rising_factorial(boost::multiprecision::mpfr_float(a), n) * pow(boost::multiprecision::mpfr_float(z), n) / (rising_factorial(boost::multiprecision::mpfr_float(b), n) * factorial(n)) << std::endl; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + term_m1 = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n - summit_location > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + ++n; + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon()) || (fabs(term_m1) < fabs(term)) || (small_a && n < 10)); + + // + // See if we need to go backwards as well: + // + if (summit_location) + { + // + // Backup state: + // + term = saved_term * exp(T(local_scaling - saved_scale)); + n = summit_location; + term *= (b + (n - 1)) * n / ((a + (n - 1)) * z); + --n; + + do + { + sum += term; + //std::cout << n << " " << term * exp(boost::multiprecision::mpfr_float(local_scaling)) << " " << rising_factorial(boost::multiprecision::mpfr_float(a), n) * pow(boost::multiprecision::mpfr_float(z), n) / (rising_factorial(boost::multiprecision::mpfr_float(b), n) * factorial(n)) << std::endl; + if (n == 0) + break; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + term_m1 = term; + term *= (b + (n - 1)) * n / ((a + (n - 1)) * z); + if (summit_location - n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + --n; + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon()) || (fabs(term_m1) < fabs(term))); + } + + if (have_minima && n && summit_location) + { + // + // There are a few terms starting at n == 0 which + // haven't been accounted for yet... + // + unsigned backstop = n; + n = 0; + term = exp(T(-local_scaling)); + do + { + sum += term; + //std::cout << n << " " << term << " " << sum << std::endl; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + } + //term_m1 = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + if (++n == backstop) + break; // we've caught up with ourselves. + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon())/* || (fabs(term_m1) < fabs(term))*/); + } + //std::cout << sum << std::endl; + return sum; + } + + template + inline T hypergeometric_1F2_generic_series(const T& a, const T& b1, const T& b2, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a, b1, b2, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_2F0_generic_series(const T& a1, const T& a2, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a1, a2, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_2F1_generic_series(const T& a1, const T& a2, const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a1, a2, b, z); + return detail::sum_pFq_series(s, pol); + } + + } } } // namespaces + +#endif // BOOST_MATH_DETAIL_HYPERGEOMETRIC_SERIES_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inv_ab.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inv_ab.hpp new file mode 100644 index 0000000000000..aab18f50f1b70 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inv_ab.hpp @@ -0,0 +1,331 @@ +// (C) Copyright John Maddock 2006. +// 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) + +// +// This is not a complete header file, it is included by beta.hpp +// after it has defined it's definitions. This inverts the incomplete +// beta functions ibeta and ibetac on the first parameters "a" +// and "b" using a generic root finding algorithm (TOMS Algorithm 748). +// + +#ifndef BOOST_MATH_SP_DETAIL_BETA_INV_AB +#define BOOST_MATH_SP_DETAIL_BETA_INV_AB + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct beta_inv_ab_t +{ + BOOST_MATH_GPU_ENABLED beta_inv_ab_t(T b_, T z_, T p_, bool invert_, bool swap_ab_) : b(b_), z(z_), p(p_), invert(invert_), swap_ab(swap_ab_) {} + BOOST_MATH_GPU_ENABLED T operator()(T a) + { + return invert ? + p - boost::math::ibetac(swap_ab ? b : a, swap_ab ? a : b, z, Policy()) + : boost::math::ibeta(swap_ab ? b : a, swap_ab ? a : b, z, Policy()) - p; + } +private: + T b, z, p; + bool invert, swap_ab; +}; + +template +BOOST_MATH_GPU_ENABLED T inverse_negative_binomial_cornish_fisher(T n, T sf, T sfc, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING + // mean: + T m = n * (sfc) / sf; + T t = sqrt(n * (sfc)); + // standard deviation: + T sigma = t / sf; + // skewness + T sk = (1 + sfc) / t; + // kurtosis: + T k = (6 - sf * (5+sfc)) / (n * (sfc)); + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + // + // Add on correction due to kurtosis. + // + if(n >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + + w = m + sigma * w; + if(w < tools::min_value()) + return tools::min_value(); + return w; +} + +template +BOOST_MATH_GPU_ENABLED T ibeta_inv_ab_imp(const T& b, const T& z, const T& p, const T& q, bool swap_ab, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std lib math functions + // + // Special cases first: + // + BOOST_MATH_INSTRUMENT_CODE("b = " << b << " z = " << z << " p = " << p << " q = " << " swap = " << swap_ab); + if(p == 0) + { + return swap_ab ? tools::min_value() : tools::max_value(); + } + if(q == 0) + { + return swap_ab ? tools::max_value() : tools::min_value(); + } + // + // Function object, this is the functor whose root + // we have to solve: + // + beta_inv_ab_t f(b, z, (p < q) ? p : q, (p < q) ? false : true, swap_ab); + // + // Tolerance: full precision. + // + tools::eps_tolerance tol(policies::digits()); + // + // Now figure out a starting guess for what a may be, + // we'll start out with a value that'll put p or q + // right bang in the middle of their range, the functions + // are quite sensitive so we should need too many steps + // to bracket the root from there: + // + T guess = 0; + T factor = 5; + // + // Convert variables to parameters of a negative binomial distribution: + // + T n = b; + T sf = swap_ab ? z : 1-z; + T sfc = swap_ab ? 1-z : z; + T u = swap_ab ? p : q; + T v = swap_ab ? q : p; + if(u <= pow(sf, n)) + { + // + // Result is less than 1, negative binomial approximation + // is useless.... + // + if((p < q) != swap_ab) + { + guess = BOOST_MATH_GPU_SAFE_MIN(T(b * 2), T(1)); + } + else + { + guess = BOOST_MATH_GPU_SAFE_MIN(T(b / 2), T(1)); + } + } + if(n * n * n * u * sf > 0.005) + guess = 1 + inverse_negative_binomial_cornish_fisher(n, sf, sfc, u, v, pol); + + if(guess < 10) + { + // + // Negative binomial approximation not accurate in this area: + // + if((p < q) != swap_ab) + { + guess = BOOST_MATH_GPU_SAFE_MIN(T(b * 2), T(10)); + } + else + { + guess = BOOST_MATH_GPU_SAFE_MIN(T(b / 2), T(10)); + } + } + else + factor = (v < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + boost::math::pair r = bracket_and_solve_root(f, guess, factor, swap_ab ? true : false, tol, max_iter, pol); + if(max_iter >= policies::get_max_root_iterations()) + return policies::raise_evaluation_error("boost::math::ibeta_invab_imp<%1%>(%1%,%1%,%1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol); + return (r.first + r.second) / 2; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type + ibeta_inva(RT1 b, RT2 x, RT3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + constexpr auto function = "boost::math::ibeta_inva<%1%>(%1%,%1%,%1%)"; + if(p == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(p == 1) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(b), + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + false, pol), + function); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type + ibetac_inva(RT1 b, RT2 x, RT3 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + constexpr auto function = "boost::math::ibetac_inva<%1%>(%1%,%1%,%1%)"; + if(q == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(b), + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + false, pol), + function); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 x, RT3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + constexpr auto function = "boost::math::ibeta_invb<%1%>(%1%,%1%,%1%)"; + if(p == 0) + { + return tools::min_value(); + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(a), + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + true, pol), + function); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 x, RT3 q, const Policy& pol) +{ + constexpr auto function = "boost::math::ibeta_invb<%1%>(%1%, %1%, %1%)"; + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(q == 1) + { + return tools::min_value(); + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(a), + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + true, pol), + function); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inva(RT1 b, RT2 x, RT3 p) +{ + return boost::math::ibeta_inva(b, x, p, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_inva(RT1 b, RT2 x, RT3 q) +{ + return boost::math::ibetac_inva(b, x, q, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 x, RT3 p) +{ + return boost::math::ibeta_invb(a, x, p, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 x, RT3 q) +{ + return boost::math::ibetac_invb(a, x, q, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_DETAIL_BETA_INV_AB + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inverse.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inverse.hpp new file mode 100644 index 0000000000000..2465a11ed6b7e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/ibeta_inverse.hpp @@ -0,0 +1,1122 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007 +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_IBETA_INVERSE_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_IBETA_INVERSE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// Helper object used by root finding +// code to convert eta to x. +// +template +struct temme_root_finder +{ + BOOST_MATH_GPU_ENABLED temme_root_finder(const T t_, const T a_) : t(t_), a(a_) { + BOOST_MATH_ASSERT( + math::tools::epsilon() <= a && !(boost::math::isinf)(a)); + } + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(T x) + { + BOOST_MATH_STD_USING // ADL of std names + + T y = 1 - x; + T f = log(x) + a * log(y) + t; + T f1 = (1 / x) - (a / (y)); + return boost::math::make_tuple(f, f1); + } +private: + T t, a; +}; +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 2. +// +template +BOOST_MATH_GPU_ENABLED T temme_method_1_ibeta_inverse(T a, T b, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + const T r2 = sqrt(T(2)); + // + // get the first approximation for eta from the inverse + // error function (Eq: 2.9 and 2.10). + // + T eta0 = boost::math::erfc_inv(2 * z, pol); + eta0 /= -sqrt(a / 2); + + T terms[4] = { eta0 }; + T workspace[7]; + // + // calculate powers: + // + T B = b - a; + T B_2 = B * B; + T B_3 = B_2 * B; + // + // Calculate correction terms: + // + + // See eq following 2.15: + workspace[0] = -B * r2 / 2; + workspace[1] = (1 - 2 * B) / 8; + workspace[2] = -(B * r2 / 48); + workspace[3] = T(-1) / 192; + workspace[4] = -B * r2 / 3840; + terms[1] = tools::evaluate_polynomial(workspace, eta0, 5); + // Eq Following 2.17: + workspace[0] = B * r2 * (3 * B - 2) / 12; + workspace[1] = (20 * B_2 - 12 * B + 1) / 128; + workspace[2] = B * r2 * (20 * B - 1) / 960; + workspace[3] = (16 * B_2 + 30 * B - 15) / 4608; + workspace[4] = B * r2 * (21 * B + 32) / 53760; + workspace[5] = (-32 * B_2 + 63) / 368640; + workspace[6] = -B * r2 * (120 * B + 17) / 25804480; + terms[2] = tools::evaluate_polynomial(workspace, eta0, 7); + // Eq Following 2.17: + workspace[0] = B * r2 * (-75 * B_2 + 80 * B - 16) / 480; + workspace[1] = (-1080 * B_3 + 868 * B_2 - 90 * B - 45) / 9216; + workspace[2] = B * r2 * (-1190 * B_2 + 84 * B + 373) / 53760; + workspace[3] = (-2240 * B_3 - 2508 * B_2 + 2100 * B - 165) / 368640; + terms[3] = tools::evaluate_polynomial(workspace, eta0, 4); + // + // Bring them together to get a final estimate for eta: + // + T eta = tools::evaluate_polynomial(terms, T(1/a), 4); + // + // now we need to convert eta to x, by solving the appropriate + // quadratic equation: + // + T eta_2 = eta * eta; + T c = -exp(-eta_2 / 2); + T x; + if(eta_2 == 0) + x = static_cast(0.5f); + else + x = (1 + eta * sqrt((1 + c) / eta_2)) / 2; + // + // These are post-conditions of the method, but the addition above + // may result in us being out by 1ulp either side of the boundary, + // so just check that we're in bounds and adjust as needed. + // See https://github.com/boostorg/math/issues/961 + // + if (x < 0) + x = 0; + else if (x > 1) + x = 1; + + BOOST_MATH_ASSERT(eta * (x - 0.5) >= 0); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 1: " << x << std::endl; +#endif + return x; +} +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 3. +// +template +BOOST_MATH_GPU_ENABLED T temme_method_2_ibeta_inverse(T /*a*/, T /*b*/, T z, T r, T theta, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + // + // Get first estimate for eta, see Eq 3.9 and 3.10, + // but note there is a typo in Eq 3.10: + // + T eta0 = boost::math::erfc_inv(2 * z, pol); + eta0 /= -sqrt(r / 2); + + T s = sin(theta); + T c = cos(theta); + // + // Now we need to perturb eta0 to get eta, which we do by + // evaluating the polynomial in 1/r at the bottom of page 151, + // to do this we first need the error terms e1, e2 e3 + // which we'll fill into the array "terms". Since these + // terms are themselves polynomials, we'll need another + // array "workspace" to calculate those... + // + T terms[4] = { eta0 }; + T workspace[6]; + // + // some powers of sin(theta)cos(theta) that we'll need later: + // + T sc = s * c; + T sc_2 = sc * sc; + T sc_3 = sc_2 * sc; + T sc_4 = sc_2 * sc_2; + T sc_5 = sc_2 * sc_3; + T sc_6 = sc_3 * sc_3; + T sc_7 = sc_4 * sc_3; + // + // Calculate e1 and put it in terms[1], see the middle of page 151: + // + workspace[0] = (2 * s * s - 1) / (3 * s * c); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co1[] = { -1, -5, 5 }; + workspace[1] = -tools::evaluate_even_polynomial(co1, s, 3) / (36 * sc_2); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co2[] = { 1, 21, -69, 46 }; + workspace[2] = tools::evaluate_even_polynomial(co2, s, 4) / (1620 * sc_3); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co3[] = { 7, -2, 33, -62, 31 }; + workspace[3] = -tools::evaluate_even_polynomial(co3, s, 5) / (6480 * sc_4); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co4[] = { 25, -52, -17, 88, -115, 46 }; + workspace[4] = tools::evaluate_even_polynomial(co4, s, 6) / (90720 * sc_5); + terms[1] = tools::evaluate_polynomial(workspace, eta0, 5); + // + // Now evaluate e2 and put it in terms[2]: + // + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co5[] = { 7, 12, -78, 52 }; + workspace[0] = -tools::evaluate_even_polynomial(co5, s, 4) / (405 * sc_3); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co6[] = { -7, 2, 183, -370, 185 }; + workspace[1] = tools::evaluate_even_polynomial(co6, s, 5) / (2592 * sc_4); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co7[] = { -533, 776, -1835, 10240, -13525, 5410 }; + workspace[2] = -tools::evaluate_even_polynomial(co7, s, 6) / (204120 * sc_5); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co8[] = { -1579, 3747, -3372, -15821, 45588, -45213, 15071 }; + workspace[3] = -tools::evaluate_even_polynomial(co8, s, 7) / (2099520 * sc_6); + terms[2] = tools::evaluate_polynomial(workspace, eta0, 4); + // + // And e3, and put it in terms[3]: + // + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co9[] = {449, -1259, -769, 6686, -9260, 3704 }; + workspace[0] = tools::evaluate_even_polynomial(co9, s, 6) / (102060 * sc_5); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co10[] = { 63149, -151557, 140052, -727469, 2239932, -2251437, 750479 }; + workspace[1] = -tools::evaluate_even_polynomial(co10, s, 7) / (20995200 * sc_6); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co11[] = { 29233, -78755, 105222, 146879, -1602610, 3195183, -2554139, 729754 }; + workspace[2] = tools::evaluate_even_polynomial(co11, s, 8) / (36741600 * sc_7); + terms[3] = tools::evaluate_polynomial(workspace, eta0, 3); + // + // Bring the correction terms together to evaluate eta, + // this is the last equation on page 151: + // + T eta = tools::evaluate_polynomial(terms, T(1/r), 4); + // + // Now that we have eta we need to back solve for x, + // we seek the value of x that gives eta in Eq 3.2. + // The two methods used are described in section 5. + // + // Begin by defining a few variables we'll need later: + // + T x; + T s_2 = s * s; + T c_2 = c * c; + T alpha = c / s; + alpha *= alpha; + T lu = (-(eta * eta) / (2 * s_2) + log(s_2) + c_2 * log(c_2) / s_2); + // + // Temme doesn't specify what value to switch on here, + // but this seems to work pretty well: + // + if(fabs(eta) < 0.7) + { + // + // Small eta use the expansion Temme gives in the second equation + // of section 5, it's a polynomial in eta: + // + workspace[0] = s * s; + workspace[1] = s * c; + workspace[2] = (1 - 2 * workspace[0]) / 3; + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co12[] = { 1, -13, 13 }; + workspace[3] = tools::evaluate_polynomial(co12, workspace[0], 3) / (36 * s * c); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co13[] = { 1, 21, -69, 46 }; + workspace[4] = tools::evaluate_polynomial(co13, workspace[0], 4) / (270 * workspace[0] * c * c); + x = tools::evaluate_polynomial(workspace, eta, 5); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 2 (small eta): " << x << std::endl; +#endif + } + else + { + // + // If eta is large we need to solve Eq 3.2 more directly, + // begin by getting an initial approximation for x from + // the last equation on page 155, this is a polynomial in u: + // + T u = exp(lu); + workspace[0] = u; + workspace[1] = alpha; + workspace[2] = 0; + workspace[3] = 3 * alpha * (3 * alpha + 1) / 6; + workspace[4] = 4 * alpha * (4 * alpha + 1) * (4 * alpha + 2) / 24; + workspace[5] = 5 * alpha * (5 * alpha + 1) * (5 * alpha + 2) * (5 * alpha + 3) / 120; + x = tools::evaluate_polynomial(workspace, u, 6); + // + // At this point we may or may not have the right answer, Eq-3.2 has + // two solutions for x for any given eta, however the mapping in 3.2 + // is 1:1 with the sign of eta and x-sin^2(theta) being the same. + // So we can check if we have the right root of 3.2, and if not + // switch x for 1-x. This transformation is motivated by the fact + // that the distribution is *almost* symmetric so 1-x will be in the right + // ball park for the solution: + // + if((x - s_2) * eta < 0) + x = 1 - x; +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 2 (large eta): " << x << std::endl; +#endif + } + // + // The final step is a few Newton-Raphson iterations to + // clean up our approximation for x, this is pretty cheap + // in general, and very cheap compared to an incomplete beta + // evaluation. The limits set on x come from the observation + // that the sign of eta and x-sin^2(theta) are the same. + // + T lower, upper; + if(eta < 0) + { + lower = 0; + upper = s_2; + } + else + { + lower = s_2; + upper = 1; + } + // + // If our initial approximation is out of bounds then bisect: + // + if((x < lower) || (x > upper)) + x = (lower+upper) / 2; + // + // And iterate: + // +#ifndef BOOST_MATH_NO_EXCEPTIONS + try { +#endif + x = tools::newton_raphson_iterate( + temme_root_finder(-lu, alpha), x, lower, upper, policies::digits() / 2); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch (const boost::math::evaluation_error&) + { + // Due to numerical instability we may have cases where no root is found when + // in fact we should just touch the origin. We simply ignore the error here + // and return our best guess for x so far... + // Maybe we should special case the symmetrical parameter case, but it's not clear + // whether that is the only situation when problems can occur. + // See https://github.com/boostorg/math/issues/1169 + } +#endif + return x; +} +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 4. +// +template +BOOST_MATH_GPU_ENABLED T temme_method_3_ibeta_inverse(T a, T b, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + + // + // Begin by getting an initial approximation for the quantity + // eta from the dominant part of the incomplete beta: + // + T eta0; + if(p < q) + eta0 = boost::math::gamma_q_inv(b, p, pol); + else + eta0 = boost::math::gamma_p_inv(b, q, pol); + eta0 /= a; + // + // Define the variables and powers we'll need later on: + // + T mu = b / a; + T w = sqrt(1 + mu); + T w_2 = w * w; + T w_3 = w_2 * w; + T w_4 = w_2 * w_2; + T w_5 = w_3 * w_2; + T w_6 = w_3 * w_3; + T w_7 = w_4 * w_3; + T w_8 = w_4 * w_4; + T w_9 = w_5 * w_4; + T w_10 = w_5 * w_5; + T d = eta0 - mu; + T d_2 = d * d; + T d_3 = d_2 * d; + T d_4 = d_2 * d_2; + T w1 = w + 1; + T w1_2 = w1 * w1; + T w1_3 = w1 * w1_2; + T w1_4 = w1_2 * w1_2; + // + // Now we need to compute the perturbation error terms that + // convert eta0 to eta, these are all polynomials of polynomials. + // Probably these should be re-written to use tabulated data + // (see examples above), but it's less of a win in this case as we + // need to calculate the individual powers for the denominator terms + // anyway, so we might as well use them for the numerator-polynomials + // as well.... + // + // Refer to p154-p155 for the details of these expansions: + // + T e1 = (w + 2) * (w - 1) / (3 * w); + e1 += (w_3 + 9 * w_2 + 21 * w + 5) * d / (36 * w_2 * w1); + e1 -= (w_4 - 13 * w_3 + 69 * w_2 + 167 * w + 46) * d_2 / (1620 * w1_2 * w_3); + e1 -= (7 * w_5 + 21 * w_4 + 70 * w_3 + 26 * w_2 - 93 * w - 31) * d_3 / (6480 * w1_3 * w_4); + e1 -= (75 * w_6 + 202 * w_5 + 188 * w_4 - 888 * w_3 - 1345 * w_2 + 118 * w + 138) * d_4 / (272160 * w1_4 * w_5); + + T e2 = (28 * w_4 + 131 * w_3 + 402 * w_2 + 581 * w + 208) * (w - 1) / (1620 * w1 * w_3); + e2 -= (35 * w_6 - 154 * w_5 - 623 * w_4 - 1636 * w_3 - 3983 * w_2 - 3514 * w - 925) * d / (12960 * w1_2 * w_4); + e2 -= (2132 * w_7 + 7915 * w_6 + 16821 * w_5 + 35066 * w_4 + 87490 * w_3 + 141183 * w_2 + 95993 * w + 21640) * d_2 / (816480 * w_5 * w1_3); + e2 -= (11053 * w_8 + 53308 * w_7 + 117010 * w_6 + 163924 * w_5 + 116188 * w_4 - 258428 * w_3 - 677042 * w_2 - 481940 * w - 105497) * d_3 / (T(14696640) * w1_4 * w_6); + + T e3 = -((3592 * w_7 + 8375 * w_6 - 1323 * w_5 - 29198 * w_4 - 89578 * w_3 - 154413 * w_2 - 116063 * w - 29632) * (w - 1)) / (816480 * w_5 * w1_2); + e3 -= (442043 * w_9 + T(2054169) * w_8 + T(3803094) * w_7 + T(3470754) * w_6 + T(2141568) * w_5 - T(2393568) * w_4 - T(19904934) * w_3 - T(34714674) * w_2 - T(23128299) * w - T(5253353)) * d / (T(146966400) * w_6 * w1_3); + e3 -= (116932 * w_10 + 819281 * w_9 + T(2378172) * w_8 + T(4341330) * w_7 + T(6806004) * w_6 + T(10622748) * w_5 + T(18739500) * w_4 + T(30651894) * w_3 + T(30869976) * w_2 + T(15431867) * w + T(2919016)) * d_2 / (T(146966400) * w1_4 * w_7); + // + // Combine eta0 and the error terms to compute eta (Second equation p155): + // + T eta = eta0 + e1 / a + e2 / (a * a) + e3 / (a * a * a); + // + // Now we need to solve Eq 4.2 to obtain x. For any given value of + // eta there are two solutions to this equation, and since the distribution + // may be very skewed, these are not related by x ~ 1-x we used when + // implementing section 3 above. However we know that: + // + // cross < x <= 1 ; iff eta < mu + // x == cross ; iff eta == mu + // 0 <= x < cross ; iff eta > mu + // + // Where cross == 1 / (1 + mu) + // Many thanks to Prof Temme for clarifying this point. + // + // Therefore we'll just jump straight into Newton iterations + // to solve Eq 4.2 using these bounds, and simple bisection + // as the first guess, in practice this converges pretty quickly + // and we only need a few digits correct anyway: + // + if(eta <= 0) + eta = tools::min_value(); + T u = eta - mu * log(eta) + (1 + mu) * log(1 + mu) - mu; + T cross = 1 / (1 + mu); + T lower = eta < mu ? cross : 0; + T upper = eta < mu ? 1 : cross; + T x = (lower + upper) / 2; + + // Early exit for cases with numerical precision issues. + if (cross == 0 || cross == 1) { return cross; } + + x = tools::newton_raphson_iterate( + temme_root_finder(u, mu), x, lower, upper, policies::digits() / 2); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 3: " << x << std::endl; +#endif + return x; +} + +template +struct ibeta_roots +{ + BOOST_MATH_GPU_ENABLED ibeta_roots(T _a, T _b, T t, bool inv = false) + : a(_a), b(_b), target(t), invert(inv) {} + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(T x) + { + BOOST_MATH_STD_USING // ADL of std names + + BOOST_FPU_EXCEPTION_GUARD + + T f1; + T y = 1 - x; + T f = ibeta_imp(a, b, x, Policy(), invert, true, &f1) - target; + if(invert) + f1 = -f1; + if(y == 0) + y = tools::min_value() * 64; + if(x == 0) + x = tools::min_value() * 64; + + T f2 = f1 * (-y * a + (b - 2) * x + 1); + if(fabs(f2) < y * x * tools::max_value()) + f2 /= (y * x); + if(invert) + f2 = -f2; + + // make sure we don't have a zero derivative: + if(f1 == 0) + f1 = (invert ? -1 : 1) * tools::min_value() * 64; + + return boost::math::make_tuple(f, f1, f2); + } +private: + T a, b, target; + bool invert; +}; + +template +BOOST_MATH_GPU_ENABLED T ibeta_inv_imp(T a, T b, T p, T q, const Policy& pol, T* py) +{ + BOOST_MATH_STD_USING // For ADL of math functions. + + // + // The flag invert is set to true if we swap a for b and p for q, + // in which case the result has to be subtracted from 1: + // + bool invert = false; + // + // Handle trivial cases first: + // + if(q == 0) + { + if(py) *py = 0; + return 1; + } + else if(p == 0) + { + if(py) *py = 1; + return 0; + } + else if(a == 1) + { + if(b == 1) + { + if(py) *py = 1 - p; + return p; + } + // Change things around so we can handle as b == 1 special case below: + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = true; + } + // + // Depending upon which approximation method we use, we may end up + // calculating either x or y initially (where y = 1-x): + // + T x = 0; // Set to a safe zero to avoid a + // MSVC 2005 warning C4701: potentially uninitialized local variable 'x' used + // But code inspection appears to ensure that x IS assigned whatever the code path. + T y; + + // For some of the methods we can put tighter bounds + // on the result than simply [0,1]: + // + T lower = 0; + T upper = 1; + // + // Student's T with b = 0.5 gets handled as a special case, swap + // around if the arguments are in the "wrong" order: + // + if(a == 0.5f) + { + if(b == 0.5f) + { + x = sin(p * constants::half_pi()); + x *= x; + if(py) + { + *py = sin(q * constants::half_pi()); + *py *= *py; + } + return x; + } + else if(b > 0.5f) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = !invert; + } + } + // + // Select calculation method for the initial estimate: + // + if((b == 0.5f) && (a >= 0.5f) && (p != 1)) + { + // + // We have a Student's T distribution: + x = find_ibeta_inv_from_t_dist(a, p, q, &y, pol); + } + else if(b == 1) + { + if(p < q) + { + if(a > 1) + { + x = pow(p, 1 / a); + y = -boost::math::expm1(log(p) / a, pol); + } + else + { + x = pow(p, 1 / a); + y = 1 - x; + } + } + else + { + x = exp(boost::math::log1p(-q, pol) / a); + y = -boost::math::expm1(boost::math::log1p(-q, pol) / a, pol); + } + if(invert) + BOOST_MATH_GPU_SAFE_SWAP(x, y); + if(py) + *py = y; + return x; + } + else if(a + b > 5) + { + // + // When a+b is large then we can use one of Prof Temme's + // asymptotic expansions, begin by swapping things around + // so that p < 0.5, we do this to avoid cancellations errors + // when p is large. + // + if(p > 0.5) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = !invert; + } + T minv = BOOST_MATH_GPU_SAFE_MIN(a, b); + T maxv = BOOST_MATH_GPU_SAFE_MAX(a, b); + if((sqrt(minv) > (maxv - minv)) && (minv > 5)) + { + // + // When a and b differ by a small amount + // the curve is quite symmetrical and we can use an error + // function to approximate the inverse. This is the cheapest + // of the three Temme expansions, and the calculated value + // for x will never be much larger than p, so we don't have + // to worry about cancellation as long as p is small. + // + x = temme_method_1_ibeta_inverse(a, b, p, pol); + y = 1 - x; + } + else + { + T r = a + b; + T theta = asin(sqrt(a / r)); + T lambda = minv / r; + if((lambda >= 0.2) && (lambda <= 0.8) && (r >= 10)) + { + // + // The second error function case is the next cheapest + // to use, it brakes down when the result is likely to be + // very small, if a+b is also small, but we can use a + // cheaper expansion there in any case. As before x won't + // be much larger than p, so as long as p is small we should + // be free of cancellation error. + // + T ppa = pow(p, 1/a); + if((ppa < 0.0025) && (a + b < 200)) + { + x = ppa * pow(a * boost::math::beta(a, b, pol), 1/a); + } + else + x = temme_method_2_ibeta_inverse(a, b, p, r, theta, pol); + y = 1 - x; + } + else + { + // + // If we get here then a and b are very different in magnitude + // and we need to use the third of Temme's methods which + // involves inverting the incomplete gamma. This is much more + // expensive than the other methods. We also can only use this + // method when a > b, which can lead to cancellation errors + // if we really want y (as we will when x is close to 1), so + // a different expansion is used in that case. + // + if(a < b) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = !invert; + } + // + // Try and compute the easy way first: + // + T bet = 0; + if (b < 2) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + bet = boost::math::beta(a, b, pol); + + typedef typename Policy::overflow_error_type overflow_type; + + BOOST_MATH_IF_CONSTEXPR(overflow_type::value != boost::math::policies::throw_on_error) + if(bet > tools::max_value()) + bet = tools::max_value(); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::overflow_error&) + { + bet = tools::max_value(); + } +#endif + } + if(bet != 0) + { + y = pow(b * q * bet, 1/b); + x = 1 - y; + } + else + y = 1; + if((y > 1e-5) && BOOST_MATH_GPU_SAFE_MIN(a, b) < 1000) + { + x = temme_method_3_ibeta_inverse(a, b, p, q, pol); + y = 1 - x; + } + else if ((y > 1e-5) && BOOST_MATH_GPU_SAFE_MIN(a, b) > 1000) + { + // All options have failed, use the saddle point as a starting location: + x = BOOST_MATH_GPU_SAFE_MAX(a, b) / (a + b); + y = BOOST_MATH_GPU_SAFE_MIN(a, b) / (a + b); + } + } + } + } + else if((a < 1) && (b < 1)) + { + // + // Both a and b less than 1, + // there is a point of inflection at xs: + // + T xs = (1 - a) / (2 - a - b); + // + // Now we need to ensure that we start our iteration from the + // right side of the inflection point: + // + T fs = boost::math::ibeta(a, b, xs, pol) - p; + if(fabs(fs) / p < tools::epsilon() * 3) + { + // The result is at the point of inflection, best just return it: + *py = invert ? xs : 1 - xs; + return invert ? 1-xs : xs; + } + if(fs < 0) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = !invert; + xs = 1 - xs; + } + if ((a < tools::min_value()) && (b > tools::min_value())) + { + if (py) + { + *py = invert ? 0 : 1; + } + return invert ? 1 : 0; // nothing interesting going on here. + } + // + // The call to beta may overflow, plus the alternative using lgamma may do the same + // if T is a type where 1/T is infinite for small values (denorms for example). + // + T bet = 0; + T xg; + bool overflow = false; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try { +#endif + bet = boost::math::beta(a, b, pol); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch (const std::runtime_error&) + { + overflow = true; + } +#endif + if (overflow || !(boost::math::isfinite)(bet)) + { + xg = exp((boost::math::lgamma(a + 1, pol) + boost::math::lgamma(b, pol) - boost::math::lgamma(a + b, pol) + log(p)) / a); + if (xg > 2 / tools::epsilon()) + xg = 2 / tools::epsilon(); + } + else + xg = pow(a * p * bet, 1/a); + x = xg / (1 + xg); + y = 1 / (1 + xg); + // + // And finally we know that our result is below the inflection + // point, so set an upper limit on our search: + // + if(x > xs) + x = xs; + upper = xs; + } + else if((a > 1) && (b > 1)) + { + // + // Small a and b, both greater than 1, + // there is a point of inflection at xs, + // and it's complement is xs2, we must always + // start our iteration from the right side of the + // point of inflection. + // + T xs = (a - 1) / (a + b - 2); + T xs2 = (b - 1) / (a + b - 2); + T ps = boost::math::ibeta(a, b, xs, pol) - p; + + if(ps < 0) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + BOOST_MATH_GPU_SAFE_SWAP(xs, xs2); + invert = !invert; + } + // + // Estimate x and y, using expm1 to get a good estimate + // for y when it's very small: + // + T lx = log(p * a * boost::math::beta(a, b, pol)) / a; + x = exp(lx); + y = x < 0.9 ? T(1 - x) : (T)(-boost::math::expm1(lx, pol)); + + if((b < a) && (x < 0.2)) + { + // + // Under a limited range of circumstances we can improve + // our estimate for x, frankly it's clear if this has much effect! + // + T ap1 = a - 1; + T bm1 = b - 1; + T a_2 = a * a; + T a_3 = a * a_2; + T b_2 = b * b; + T terms[5] = { 0, 1 }; + terms[2] = bm1 / ap1; + ap1 *= ap1; + terms[3] = bm1 * (3 * a * b + 5 * b + a_2 - a - 4) / (2 * (a + 2) * ap1); + ap1 *= (a + 1); + terms[4] = bm1 * (33 * a * b_2 + 31 * b_2 + 8 * a_2 * b_2 - 30 * a * b - 47 * b + 11 * a_2 * b + 6 * a_3 * b + 18 + 4 * a - a_3 + a_2 * a_2 - 10 * a_2) + / (3 * (a + 3) * (a + 2) * ap1); + x = tools::evaluate_polynomial(terms, x, 5); + } + // + // And finally we know that our result is below the inflection + // point, so set an upper limit on our search: + // + if(x > xs) + x = xs; + upper = xs; + } + else /*if((a <= 1) != (b <= 1))*/ + { + // + // If all else fails we get here, only one of a and b + // is above 1, and a+b is small. Start by swapping + // things around so that we have a concave curve with b > a + // and no points of inflection in [0,1]. As long as we expect + // x to be small then we can use the simple (and cheap) power + // term to estimate x, but when we expect x to be large then + // this greatly underestimates x and leaves us trying to + // iterate "round the corner" which may take almost forever... + // + // We could use Temme's inverse gamma function case in that case, + // this works really rather well (albeit expensively) even though + // strictly speaking we're outside it's defined range. + // + // However it's expensive to compute, and an alternative approach + // which models the curve as a distorted quarter circle is much + // cheaper to compute, and still keeps the number of iterations + // required down to a reasonable level. With thanks to Prof Temme + // for this suggestion. + // + if(b < a) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + invert = !invert; + } + if (a < tools::min_value()) + { + // Avoid spurious overflows for denorms: + if (p < 1) + { + x = 1; + y = 0; + } + else + { + x = 0; + y = 1; + } + } + else if(pow(p, 1/a) < 0.5) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + x = pow(p * a * boost::math::beta(a, b, pol), 1 / a); + if ((x > 1) || !(boost::math::isfinite)(x)) + x = 1; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch (const std::overflow_error&) + { + x = 1; + } +#endif + if(x == 0) + x = boost::math::tools::min_value(); + y = 1 - x; + } + else /*if(pow(q, 1/b) < 0.1)*/ + { + // model a distorted quarter circle: +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + y = pow(1 - pow(p, b * boost::math::beta(a, b, pol)), 1/b); + if ((y > 1) || !(boost::math::isfinite)(y)) + y = 1; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch (const std::overflow_error&) + { + y = 1; + } +#endif + if(y == 0) + y = boost::math::tools::min_value(); + x = 1 - y; + } + } + + // + // Now we have a guess for x (and for y) we can set things up for + // iteration. If x > 0.5 it pays to swap things round: + // + if(x > 0.5) + { + BOOST_MATH_GPU_SAFE_SWAP(a, b); + BOOST_MATH_GPU_SAFE_SWAP(p, q); + BOOST_MATH_GPU_SAFE_SWAP(x, y); + invert = !invert; + T l = 1 - upper; + T u = 1 - lower; + lower = l; + upper = u; + } + // + // lower bound for our search: + // + // We're not interested in denormalised answers as these tend to + // these tend to take up lots of iterations, given that we can't get + // accurate derivatives in this area (they tend to be infinite). + // + if(lower == 0) + { + if(invert && (py == 0)) + { + // + // We're not interested in answers smaller than machine epsilon: + // + lower = boost::math::tools::epsilon(); + if(x < lower) + x = lower; + } + else + lower = boost::math::tools::min_value(); + if(x < lower) + x = lower; + } + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + boost::math::uintmax_t max_iter_used = 0; + // + // Figure out how many digits to iterate towards: + // + int digits = boost::math::policies::digits() / 2; + if((x < 1e-50) && ((a < 1) || (b < 1))) + { + // + // If we're in a region where the first derivative is very + // large, then we have to take care that the root-finder + // doesn't terminate prematurely. We'll bump the precision + // up to avoid this, but we have to take care not to set the + // precision too high or the last few iterations will just + // thrash around and convergence may be slow in this case. + // Try 3/4 of machine epsilon: + // + digits *= 3; + digits /= 2; + } + // + // Now iterate, we can use either p or q as the target here + // depending on which is smaller: + // + // Since we can't use halley_iterate on device we use newton raphson + // + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + x = boost::math::tools::halley_iterate( + #else + x = boost::math::tools::newton_raphson_iterate( + #endif + boost::math::detail::ibeta_roots(a, b, (p < q ? p : q), (p < q ? false : true)), x, lower, upper, digits, max_iter); + policies::check_root_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%)", max_iter + max_iter_used, pol); + // + // We don't really want these asserts here, but they are useful for sanity + // checking that we have the limits right, uncomment if you suspect bugs *only*. + // + //BOOST_MATH_ASSERT(x != upper); + //BOOST_MATH_ASSERT((x != lower) || (x == boost::math::tools::min_value()) || (x == boost::math::tools::epsilon())); + // + // Tidy up, if we "lower" was too high then zero is the best answer we have: + // + if(x == lower) + x = 0; + if(py) + *py = invert ? x : 1 - x; + return invert ? 1-x : x; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol) +{ + constexpr auto function = "boost::math::ibeta_inv<%1%>(%1%,%1%,%1%)"; + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol); + if((p < 0) || (p > 1)) + return policies::raise_domain_error(function, "Argument p outside the range [0,1] in the incomplete beta function inverse (got p=%1%).", p, pol); + + value_type rx, ry; + + rx = detail::ibeta_inv_imp( + static_cast(a), + static_cast(b), + static_cast(p), + static_cast(1 - p), + forwarding_policy(), &ry); + + if(py) *py = policies::checked_narrowing_cast(ry, function); + return policies::checked_narrowing_cast(rx, function); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py) +{ + return ibeta_inv(a, b, p, py, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p) +{ + typedef typename tools::promote_args::type result_type; + return ibeta_inv(a, b, p, static_cast(nullptr), policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return ibeta_inv(a, b, p, static_cast(nullptr), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol) +{ + constexpr auto function = "boost::math::ibetac_inv<%1%>(%1%,%1%,%1%)"; + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol); + if((q < 0) || (q > 1)) + return policies::raise_domain_error(function, "Argument q outside the range [0,1] in the incomplete beta function inverse (got q=%1%).", q, pol); + + value_type rx, ry; + + rx = detail::ibeta_inv_imp( + static_cast(a), + static_cast(b), + static_cast(1 - q), + static_cast(q), + forwarding_policy(), &ry); + + if(py) *py = policies::checked_narrowing_cast(ry, function); + return policies::checked_narrowing_cast(rx, function); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py) +{ + return ibetac_inv(a, b, q, py, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q) +{ + typedef typename tools::promote_args::type result_type; + return ibetac_inv(a, b, q, static_cast(nullptr), policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return ibetac_inv(a, b, q, static_cast(nullptr), pol); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/iconv.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/iconv.hpp new file mode 100644 index 0000000000000..20889d411e2a1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/iconv.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2009 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) + +#ifndef BOOST_MATH_ICONV_HPP +#define BOOST_MATH_ICONV_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline int iconv_imp(T v, Policy const&, boost::math::true_type const&) +{ + return static_cast(v); +} + +template +BOOST_MATH_GPU_ENABLED inline int iconv_imp(T v, Policy const& pol, boost::math::false_type const&) +{ + BOOST_MATH_STD_USING + return iround(v, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline int iconv(T v, Policy const& pol) +{ + typedef typename boost::math::is_convertible::type tag_type; + return iconv_imp(v, pol, tag_type()); +} + + +}}} // namespaces + +#endif // BOOST_MATH_ICONV_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/igamma_inverse.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/igamma_inverse.hpp new file mode 100644 index 0000000000000..4efd4f78a3176 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/igamma_inverse.hpp @@ -0,0 +1,587 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T find_inverse_s(T p, T q) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 32. + // + BOOST_MATH_STD_USING + T t; + if(p < T(0.5)) + { + t = sqrt(-2 * log(p)); + } + else + { + t = sqrt(-2 * log(q)); + } + BOOST_MATH_STATIC const double a[4] = { 3.31125922108741, 11.6616720288968, 4.28342155967104, 0.213623493715853 }; + BOOST_MATH_STATIC const double b[5] = { 1, 6.61053765625462, 6.40691597760039, 1.27364489782223, 0.3611708101884203e-1 }; + T s = t - tools::evaluate_polynomial(a, t) / tools::evaluate_polynomial(b, t); + if(p < T(0.5)) + s = -s; + return s; +} + +template +BOOST_MATH_GPU_ENABLED T didonato_SN(T a, T x, unsigned N, T tolerance = 0) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 34. + // + T sum = 1; + if(N >= 1) + { + T partial = x / (a + 1); + sum += partial; + for(unsigned i = 2; i <= N; ++i) + { + partial *= x / (a + i); + sum += partial; + if(partial < tolerance) + break; + } + } + return sum; +} + +template +BOOST_MATH_GPU_ENABLED inline T didonato_FN(T p, T a, T x, unsigned N, T tolerance, const Policy& pol) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 34. + // + BOOST_MATH_STD_USING + T u = log(p) + boost::math::lgamma(a + 1, pol); + return exp((u + x - log(didonato_SN(a, x, N, tolerance))) / a); +} + +template +BOOST_MATH_GPU_ENABLED T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) +{ + // + // In order to understand what's going on here, you will + // need to refer to: + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + BOOST_MATH_STD_USING + + T result; + *p_has_10_digits = false; + + if(a == 1) + { + result = -log(q); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(a < 1) + { + T g = boost::math::tgamma(a, pol); + T b = q * g; + BOOST_MATH_INSTRUMENT_VARIABLE(g); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + if((b >T(0.6)) || ((b >= T(0.45)) && (a >= T(0.3)))) + { + // DiDonato & Morris Eq 21: + // + // There is a slight variation from DiDonato and Morris here: + // the first form given here is unstable when p is close to 1, + // making it impossible to compute the inverse of Q(a,x) for small + // q. Fortunately the second form works perfectly well in this case. + // + T u; + if((b * q > T(1e-8)) && (q > T(1e-5))) + { + u = pow(p * g * a, 1 / a); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + } + else + { + u = exp((-q / a) - constants::euler()); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + } + result = u / (1 - (u / (a + 1))); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if((a < 0.3) && (b >= 0.35)) + { + // DiDonato & Morris Eq 22: + T t = exp(-constants::euler() - b); + T u = t * exp(t); + result = t * exp(u); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if((b > 0.15) || (a >= 0.3)) + { + // DiDonato & Morris Eq 23: + T y = -log(b); + T u = y - (1 - a) * log(y); + result = y - (1 - a) * log(u) - log(1 + (1 - a) / (1 + u)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (b > 0.1) + { + // DiDonato & Morris Eq 24: + T y = -log(b); + T u = y - (1 - a) * log(y); + result = y - (1 - a) * log(u) - log((u * u + 2 * (3 - a) * u + (2 - a) * (3 - a)) / (u * u + (5 - a) * u + 2)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato & Morris Eq 25: + T y = -log(b); + T c1 = (a - 1) * log(y); + T c1_2 = c1 * c1; + T c1_3 = c1_2 * c1; + T c1_4 = c1_2 * c1_2; + T a_2 = a * a; + T a_3 = a_2 * a; + + T c2 = (a - 1) * (1 + c1); + T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2); + T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6); + T c5 = (a - 1) * (-(c1_4 / 4) + + (11 * a - 17) * c1_3 / 6 + + (-3 * a_2 + 13 * a -13) * c1_2 + + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2 + + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12); + + T y_2 = y * y; + T y_3 = y_2 * y; + T y_4 = y_2 * y_2; + result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(b < 1e-28f) + *p_has_10_digits = true; + } + } + else + { + // DiDonato and Morris Eq 31: + T s = find_inverse_s(p, q); + + BOOST_MATH_INSTRUMENT_VARIABLE(s); + + T s_2 = s * s; + T s_3 = s_2 * s; + T s_4 = s_2 * s_2; + T s_5 = s_4 * s; + T ra = sqrt(a); + + BOOST_MATH_INSTRUMENT_VARIABLE(ra); + + T w = a + s * ra + (s * s -1) / 3; + w += (s_3 - 7 * s) / (36 * ra); + w -= (3 * s_4 + 7 * s_2 - 16) / (810 * a); + w += (9 * s_5 + 256 * s_3 - 433 * s) / (38880 * a * ra); + + BOOST_MATH_INSTRUMENT_VARIABLE(w); + + if((a >= 500) && (fabs(1 - w / a) < 1e-6)) + { + result = w; + *p_has_10_digits = true; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (p > 0.5) + { + if(w < 3 * a) + { + result = w; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + T D = BOOST_MATH_GPU_SAFE_MAX(T(2), T(a * (a - 1))); + T lg = boost::math::lgamma(a, pol); + T lb = log(q) + lg; + if(lb < -D * T(2.3)) + { + // DiDonato and Morris Eq 25: + T y = -lb; + T c1 = (a - 1) * log(y); + T c1_2 = c1 * c1; + T c1_3 = c1_2 * c1; + T c1_4 = c1_2 * c1_2; + T a_2 = a * a; + T a_3 = a_2 * a; + + T c2 = (a - 1) * (1 + c1); + T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2); + T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6); + T c5 = (a - 1) * (-(c1_4 / 4) + + (11 * a - 17) * c1_3 / 6 + + (-3 * a_2 + 13 * a -13) * c1_2 + + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2 + + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12); + + T y_2 = y * y; + T y_3 = y_2 * y; + T y_4 = y_2 * y_2; + result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato and Morris Eq 33: + T u = -lb + (a - 1) * log(w) - log(1 + (1 - a) / (1 + w)); + result = -lb + (a - 1) * log(u) - log(1 + (1 - a) / (1 + u)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + else + { + T z = w; + T ap1 = a + 1; + T ap2 = a + 2; + if(w < 0.15f * ap1) + { + // DiDonato and Morris Eq 35: + T v = log(p) + boost::math::lgamma(ap1, pol); + z = exp((v + w) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol); + z = exp((v + z - s) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol); + z = exp((v + z - s) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2 * (1 + z / (a + 3))), pol); + z = exp((v + z - s) / a); + BOOST_MATH_INSTRUMENT_VARIABLE(z); + } + + if((z <= 0.01 * ap1) || (z > 0.7 * ap1)) + { + result = z; + if(z <= T(0.002) * ap1) + *p_has_10_digits = true; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato and Morris Eq 36: + T ls = log(didonato_SN(a, z, 100, T(1e-4))); + T v = log(p) + boost::math::lgamma(ap1, pol); + z = exp((v + z - ls) / a); + result = z * (1 - (a * log(z) - z - v + ls) / (a - z)); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + return result; +} + +template +struct gamma_p_inverse_func +{ + BOOST_MATH_GPU_ENABLED gamma_p_inverse_func(T a_, T p_, bool inv) : a(a_), p(p_), invert(inv) + { + // + // If p is too near 1 then P(x) - p suffers from cancellation + // errors causing our root-finding algorithms to "thrash", better + // to invert in this case and calculate Q(x) - (1-p) instead. + // + // Of course if p is *very* close to 1, then the answer we get will + // be inaccurate anyway (because there's not enough information in p) + // but at least we will converge on the (inaccurate) answer quickly. + // + if(p > T(0.9)) + { + p = 1 - p; + invert = !invert; + } + } + + BOOST_MATH_GPU_ENABLED boost::math::tuple operator()(const T& x)const + { + BOOST_FPU_EXCEPTION_GUARD + // + // Calculate P(x) - p and the first two derivates, or if the invert + // flag is set, then Q(x) - q and it's derivatives. + // + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING // For ADL of std functions. + + T f, f1; + value_type ft; + f = static_cast(boost::math::detail::gamma_incomplete_imp( + static_cast(a), + static_cast(x), + true, invert, + forwarding_policy(), &ft)); + f1 = static_cast(ft); + T f2; + T div = (a - x - 1) / x; + f2 = f1; + if(fabs(div) > 1) + { + // split if statement to address M1 mac clang bug; + // see issue 826 + if (tools::max_value() / fabs(div) < f2) + { + // overflow: + f2 = -tools::max_value() / 2; + } + else + { + f2 *= div; + } + } + else + { + f2 *= div; + } + + if(invert) + { + f1 = -f1; + f2 = -f2; + } + + return boost::math::make_tuple(static_cast(f - p), f1, f2); + } +private: + T a, p; + bool invert; +}; + +template +BOOST_MATH_GPU_ENABLED T gamma_p_inv_imp(T a, T p, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions. + + constexpr auto function = "boost::math::gamma_p_inv<%1%>(%1%, %1%)"; + + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(p); + + if(a <= 0) + return policies::raise_domain_error(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol); + if((p < 0) || (p > 1)) + return policies::raise_domain_error(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got p=%1%).", p, pol); + if(p == 1) + return policies::raise_overflow_error(function, nullptr, Policy()); + if(p == 0) + return 0; + bool has_10_digits; + T guess = detail::find_inverse_gamma(a, p, 1 - p, pol, &has_10_digits); + if((policies::digits() <= 36) && has_10_digits) + return guess; + T lower = tools::min_value(); + if(guess <= lower) + guess = tools::min_value(); + BOOST_MATH_INSTRUMENT_VARIABLE(guess); + // + // Work out how many digits to converge to, normally this is + // 2/3 of the digits in T, but if the first derivative is very + // large convergence is slow, so we'll bump it up to full + // precision to prevent premature termination of the root-finding routine. + // + unsigned digits = policies::digits(); + if(digits < 30) + { + digits *= 2; + digits /= 3; + } + else + { + digits /= 2; + digits -= 1; + } + if((a < T(0.125)) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) + digits = policies::digits() - 2; + // + // Go ahead and iterate: + // + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + guess = tools::halley_iterate( + detail::gamma_p_inverse_func(a, p, false), + guess, + lower, + tools::max_value(), + digits, + max_iter); + #else + guess = tools::newton_raphson_iterate( + detail::gamma_p_inverse_func(a, p, false), + guess, + lower, + tools::max_value(), + digits, + max_iter); + #endif + + policies::check_root_iterations(function, max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(guess); + if(guess == lower) + guess = policies::raise_underflow_error(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol); + return guess; +} + +template +BOOST_MATH_GPU_ENABLED T gamma_q_inv_imp(T a, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions. + + constexpr auto function = "boost::math::gamma_q_inv<%1%>(%1%, %1%)"; + + if(a <= 0) + return policies::raise_domain_error(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol); + if((q < 0) || (q > 1)) + return policies::raise_domain_error(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got q=%1%).", q, pol); + if(q == 0) + return policies::raise_overflow_error(function, nullptr, Policy()); + if(q == 1) + return 0; + bool has_10_digits; + T guess = detail::find_inverse_gamma(a, 1 - q, q, pol, &has_10_digits); + if((policies::digits() <= 36) && has_10_digits) + return guess; + T lower = tools::min_value(); + if(guess <= lower) + guess = tools::min_value(); + // + // Work out how many digits to converge to, normally this is + // 2/3 of the digits in T, but if the first derivative is very + // large convergence is slow, so we'll bump it up to full + // precision to prevent premature termination of the root-finding routine. + // + unsigned digits = policies::digits(); + if(digits < 30) + { + digits *= 2; + digits /= 3; + } + else + { + digits /= 2; + digits -= 1; + } + if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) + digits = policies::digits(); + // + // Go ahead and iterate: + // + boost::math::uintmax_t max_iter = policies::get_max_root_iterations(); + + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + guess = tools::halley_iterate( + detail::gamma_p_inverse_func(a, q, true), + guess, + lower, + tools::max_value(), + digits, + max_iter); + #else + guess = tools::newton_raphson_iterate( + detail::gamma_p_inverse_func(a, q, true), + guess, + lower, + tools::max_value(), + digits, + max_iter); + #endif + + policies::check_root_iterations(function, max_iter, pol); + if(guess == lower) + guess = policies::raise_underflow_error(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol); + return guess; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_p_inv(T1 a, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::gamma_p_inv_imp( + static_cast(a), + static_cast(p), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_q_inv(T1 a, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::gamma_q_inv_imp( + static_cast(a), + static_cast(p), pol); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_p_inv(T1 a, T2 p) +{ + return gamma_p_inv(a, p, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + gamma_q_inv(T1 a, T2 p) +{ + return gamma_q_inv(a, p, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/igamma_large.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/igamma_large.hpp new file mode 100644 index 0000000000000..e585748183537 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/igamma_large.hpp @@ -0,0 +1,823 @@ +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024. +// 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) +// +// This file implements the asymptotic expansions of the incomplete +// gamma functions P(a, x) and Q(a, x), used when a is large and +// x ~ a. +// +// The primary reference is: +// +// "The Asymptotic Expansion of the Incomplete Gamma Functions" +// N. M. Temme. +// Siam J. Math Anal. Vol 10 No 4, July 1979, p757. +// +// A different way of evaluating these expansions, +// plus a lot of very useful background information is in: +// +// "A Set of Algorithms For the Incomplete Gamma Functions." +// N. M. Temme. +// Probability in the Engineering and Informational Sciences, +// 8, 1994, 291. +// +// An alternative implementation is in: +// +// "Computation of the Incomplete Gamma Function Ratios and their Inverse." +// A. R. Didonato and A. H. Morris. +// ACM TOMS, Vol 12, No 4, Dec 1986, p377. +// +// There are various versions of the same code below, each accurate +// to a different precision. To understand the code, refer to Didonato +// and Morris, from Eq 17 and 18 onwards. +// +// The coefficients used here are not taken from Didonato and Morris: +// the domain over which these expansions are used is slightly different +// to theirs, and their constants are not quite accurate enough for +// 128-bit long double's. Instead the coefficients were calculated +// using the methods described by Temme p762 from Eq 3.8 onwards. +// The values obtained agree with those obtained by Didonato and Morris +// (at least to the first 30 digits that they provide). +// At double precision the degrees of polynomial required for full +// machine precision are close to those recommended to Didonato and Morris, +// but of course many more terms are needed for larger types. +// +#ifndef BOOST_MATH_DETAIL_IGAMMA_LARGE +#define BOOST_MATH_DETAIL_IGAMMA_LARGE + +#ifdef _MSC_VER +#pragma once +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// This version will never be called (at runtime), it's a stub used +// when T is unsuitable to be passed to these routines: +// +template +BOOST_MATH_GPU_ENABLED inline T igamma_temme_large(T, T, const Policy& /* pol */, const boost::math::integral_constant&) +{ + // stub function, should never actually be called + BOOST_MATH_ASSERT(0); + return 0; +} +// +// This version is accurate for up to 64-bit mantissa's, +// (80-bit long double, or 10^-20). +// + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +BOOST_MATH_GPU_ENABLED T igamma_temme_large(T a, T x, const Policy& pol, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[13]; + + // LCOV_EXCL_START + BOOST_MATH_STATIC const T C0[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0833333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0148148148148148148148), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00115740740740740740741), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000352733686067019400353), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0001787551440329218107), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.39192631785224377817e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.218544851067999216147e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.18540622107151599607e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.829671134095308600502e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.176659527368260793044e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.670785354340149858037e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.102618097842403080426e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.438203601845335318655e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.914769958223679023418e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.255141939949462497669e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.583077213255042506746e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.243619480206674162437e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.502766928011417558909e-11), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + BOOST_MATH_STATIC const T C1[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00185185185185185185185), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00347222222222222222222), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00264550264550264550265), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000990226337448559670782), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000205761316872427983539), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.40187757201646090535e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.18098550334489977837e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.764916091608111008464e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.161209008945634460038e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.464712780280743434226e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.137863344691572095931e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.575254560351770496402e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.119516285997781473243e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.175432417197476476238e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.100915437106004126275e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.416279299184258263623e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.856390702649298063807e-10), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + BOOST_MATH_STATIC const T C2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00413359788359788359788), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00268132716049382716049), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000771604938271604938272), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.200938786008230452675e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000107366532263651605215), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.529234488291201254164e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.127606351886187277134e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.342357873409613807419e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.137219573090629332056e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.629899213838005502291e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142806142060642417916e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.204770984219908660149e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.140925299108675210533e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.622897408492202203356e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.136704883966171134993e-8), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + BOOST_MATH_STATIC const T C3[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000649434156378600823045), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000229472093621399176955), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000469189494395255712128), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000267720632062838852962), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.756180167188397641073e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.239650511386729665193e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.110826541153473023615e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.56749528269915965675e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142309007324358839146e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.278610802915281422406e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.169584040919302772899e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.809946490538808236335e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.191111684859736540607e-7), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + BOOST_MATH_STATIC const T C4[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000861888290916711698605), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000784039221720066627474), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000299072480303190179733), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.146384525788434181781e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.664149821546512218666e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.396836504717943466443e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.113757269706784190981e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.250749722623753280165e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.169541495365583060147e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.890750753220530968883e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.229293483400080487057e-6), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + BOOST_MATH_STATIC const T C5[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000336798553366358150309), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.697281375836585777429e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277275324495939207873), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000199325705161888477003), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.679778047793720783882e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.141906292064396701483e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.135940481897686932785e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.801847025633420153972e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.229148117650809517038e-5), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + BOOST_MATH_STATIC const T C6[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000531307936463992223166), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000592166437353693882865), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000270878209671804482771), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.790235323266032787212e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.815396936756196875093e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.561168275310624965004e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.183291165828433755673e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.307961345060330478256e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.346515536880360908674e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.20291327396058603727e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.57887928631490037089e-6), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + BOOST_MATH_STATIC const T C7[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000344367606892377671254), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.517179090826059219337e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000334931610811422363117), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000281269515476323702274), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000109765822446847310235), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.127410090954844853795e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.277444515115636441571e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.182634888057113326614e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.578769494973505239894e-5), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + BOOST_MATH_STATIC const T C8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000652623918595309418922), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000839498720672087279993), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000438297098541721005061), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.696909145842055197137e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000166448466420675478374), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000127835176797692185853), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.462995326369130429061e-4), + }; + workspace[8] = tools::evaluate_polynomial(C8, z); + + BOOST_MATH_STATIC const T C9[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000596761290192746250124), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.720489541602001055909e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000678230883766732836162), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0006401475260262758451), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277501076343287044992), + }; + workspace[9] = tools::evaluate_polynomial(C9, z); + + BOOST_MATH_STATIC const T C10[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00133244544948006563713), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0019144384985654775265), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00110893691345966373396), + }; + workspace[10] = tools::evaluate_polynomial(C10, z); + + BOOST_MATH_STATIC const T C11[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00157972766073083495909), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000162516262783915816899), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00206334210355432762645), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00213896861856890981541), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00101085593912630031708), + }; + workspace[11] = tools::evaluate_polynomial(C11, z); + + BOOST_MATH_STATIC const T C12[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00407251211951401664727), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00640336283380806979482), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00404101610816766177474), + }; + // LCOV_EXCL_STOP + + workspace[12] = tools::evaluate_polynomial(C12, z); + + T result = tools::evaluate_polynomial<13, T, T>(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} + +#endif + +// +// This one is accurate for 53-bit mantissa's +// (IEEE double precision or 10^-17). +// +template +BOOST_MATH_GPU_ENABLED T igamma_temme_large(T a, T x, const Policy& pol, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[10]; + + // LCOV_EXCL_START + BOOST_MATH_STATIC const T C0[] = { + static_cast(-0.33333333333333333L), + static_cast(0.083333333333333333L), + static_cast(-0.014814814814814815L), + static_cast(0.0011574074074074074L), + static_cast(0.0003527336860670194L), + static_cast(-0.00017875514403292181L), + static_cast(0.39192631785224378e-4L), + static_cast(-0.21854485106799922e-5L), + static_cast(-0.185406221071516e-5L), + static_cast(0.8296711340953086e-6L), + static_cast(-0.17665952736826079e-6L), + static_cast(0.67078535434014986e-8L), + static_cast(0.10261809784240308e-7L), + static_cast(-0.43820360184533532e-8L), + static_cast(0.91476995822367902e-9L), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + BOOST_MATH_STATIC const T C1[] = { + static_cast(-0.0018518518518518519L), + static_cast(-0.0034722222222222222L), + static_cast(0.0026455026455026455L), + static_cast(-0.00099022633744855967L), + static_cast(0.00020576131687242798L), + static_cast(-0.40187757201646091e-6L), + static_cast(-0.18098550334489978e-4L), + static_cast(0.76491609160811101e-5L), + static_cast(-0.16120900894563446e-5L), + static_cast(0.46471278028074343e-8L), + static_cast(0.1378633446915721e-6L), + static_cast(-0.5752545603517705e-7L), + static_cast(0.11951628599778147e-7L), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + BOOST_MATH_STATIC const T C2[] = { + static_cast(0.0041335978835978836L), + static_cast(-0.0026813271604938272L), + static_cast(0.00077160493827160494L), + static_cast(0.20093878600823045e-5L), + static_cast(-0.00010736653226365161L), + static_cast(0.52923448829120125e-4L), + static_cast(-0.12760635188618728e-4L), + static_cast(0.34235787340961381e-7L), + static_cast(0.13721957309062933e-5L), + static_cast(-0.6298992138380055e-6L), + static_cast(0.14280614206064242e-6L), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + BOOST_MATH_STATIC const T C3[] = { + static_cast(0.00064943415637860082L), + static_cast(0.00022947209362139918L), + static_cast(-0.00046918949439525571L), + static_cast(0.00026772063206283885L), + static_cast(-0.75618016718839764e-4L), + static_cast(-0.23965051138672967e-6L), + static_cast(0.11082654115347302e-4L), + static_cast(-0.56749528269915966e-5L), + static_cast(0.14230900732435884e-5L), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + BOOST_MATH_STATIC const T C4[] = { + static_cast(-0.0008618882909167117L), + static_cast(0.00078403922172006663L), + static_cast(-0.00029907248030319018L), + static_cast(-0.14638452578843418e-5L), + static_cast(0.66414982154651222e-4L), + static_cast(-0.39683650471794347e-4L), + static_cast(0.11375726970678419e-4L), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + BOOST_MATH_STATIC const T C5[] = { + static_cast(-0.00033679855336635815L), + static_cast(-0.69728137583658578e-4L), + static_cast(0.00027727532449593921L), + static_cast(-0.00019932570516188848L), + static_cast(0.67977804779372078e-4L), + static_cast(0.1419062920643967e-6L), + static_cast(-0.13594048189768693e-4L), + static_cast(0.80184702563342015e-5L), + static_cast(-0.22914811765080952e-5L), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + BOOST_MATH_STATIC const T C6[] = { + static_cast(0.00053130793646399222L), + static_cast(-0.00059216643735369388L), + static_cast(0.00027087820967180448L), + static_cast(0.79023532326603279e-6L), + static_cast(-0.81539693675619688e-4L), + static_cast(0.56116827531062497e-4L), + static_cast(-0.18329116582843376e-4L), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + BOOST_MATH_STATIC const T C7[] = { + static_cast(0.00034436760689237767L), + static_cast(0.51717909082605922e-4L), + static_cast(-0.00033493161081142236L), + static_cast(0.0002812695154763237L), + static_cast(-0.00010976582244684731L), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + BOOST_MATH_STATIC const T C8[] = { + static_cast(-0.00065262391859530942L), + static_cast(0.00083949872067208728L), + static_cast(-0.00043829709854172101L), + }; + // LCOV_EXCL_STOP + workspace[8] = tools::evaluate_polynomial(C8, z); + workspace[9] = static_cast(-0.00059676129019274625L); + + T result = tools::evaluate_polynomial<10, T, T>(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result += ::erfcf(::sqrtf(y)) / 2; + } + else + { + result += ::erfc(::sqrt(y)) / 2; + } + #else + result += boost::math::erfc(sqrt(y), pol) / 2; + #endif + + return result; +} +// +// This one is accurate for 24-bit mantissa's +// (IEEE float precision, or 10^-8) +// +template +BOOST_MATH_GPU_ENABLED T igamma_temme_large(T a, T x, const Policy& pol, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[3]; + + // LCOV_EXCL_START + BOOST_MATH_STATIC const T C0[] = { + static_cast(-0.333333333L), + static_cast(0.0833333333L), + static_cast(-0.0148148148L), + static_cast(0.00115740741L), + static_cast(0.000352733686L), + static_cast(-0.000178755144L), + static_cast(0.391926318e-4L), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + BOOST_MATH_STATIC const T C1[] = { + static_cast(-0.00185185185L), + static_cast(-0.00347222222L), + static_cast(0.00264550265L), + static_cast(-0.000990226337L), + static_cast(0.000205761317L), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + BOOST_MATH_STATIC const T C2[] = { + static_cast(0.00413359788L), + static_cast(-0.00268132716L), + static_cast(0.000771604938L), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + // LCOV_EXCL_STOP + + T result = tools::evaluate_polynomial(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result += ::erfcf(::sqrtf(y)) / 2; + } + else + { + result += ::erfc(::sqrt(y)) / 2; + } + #else + result += boost::math::erfc(sqrt(y), pol) / 2; + #endif + + return result; +} +// +// And finally, a version for 113-bit mantissa's +// (128-bit long doubles, or 10^-34). +// Note this one has been optimised for a > 200 +// It's use for a < 200 is not recommended, that would +// require many more terms in the polynomials. +// +// LCOV_EXCL_START: 128-bit floats not deliberately tested in our coverage tests (takes too long) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +BOOST_MATH_GPU_ENABLED T igamma_temme_large(T a, T x, const Policy& pol, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[14]; + + BOOST_MATH_STATIC const T C0[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0833333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0148148148148148148148148148148148148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00115740740740740740740740740740740741), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003527336860670194003527336860670194), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000178755144032921810699588477366255144), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.391926317852243778169704095630021556e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.218544851067999216147364295512443661e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.185406221071515996070179883622956325e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.829671134095308600501624213166443227e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.17665952736826079304360054245742403e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.670785354340149858036939710029613572e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.102618097842403080425739573227252951e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.438203601845335318655297462244719123e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.914769958223679023418248817633113681e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.255141939949462497668779537993887013e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.583077213255042506746408945040035798e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.243619480206674162436940696707789943e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.502766928011417558909054985925744366e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110043920319561347708374174497293411e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.337176326240098537882769884169200185e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.13923887224181620659193661848957998e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.285348938070474432039669099052828299e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.513911183424257261899064580300494205e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.197522882943494428353962401580710912e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.809952115670456133407115668702575255e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.165225312163981618191514820265351162e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.253054300974788842327061090060267385e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.116869397385595765888230876507793475e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.477003704982048475822167804084816597e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.969912605905623712420709685898585354e-18), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + BOOST_MATH_STATIC const T C1[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00185185185185185185185185185185185185), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00347222222222222222222222222222222222), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026455026455026455026455026455026455), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000990226337448559670781893004115226337), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000205761316872427983539094650205761317), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.401877572016460905349794238683127572e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.180985503344899778370285914867533523e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.76491609160811100846374214980916921e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16120900894563446003775221882217767e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.464712780280743434226135033938722401e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137863344691572095931187533077488877e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.575254560351770496402194531835048307e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119516285997781473243076536699698169e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.175432417197476476237547551202312502e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.100915437106004126274577504686681675e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.416279299184258263623372347219858628e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.856390702649298063807431562579670208e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.606721510160475861512701762169919581e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.716249896481148539007961017165545733e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.293318664377143711740636683615595403e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.599669636568368872330374527568788909e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.216717865273233141017100472779701734e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.497833997236926164052815522048108548e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.202916288237134247736694804325894226e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.413125571381061004935108332558187111e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.828651623988309644380188591057589316e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.341003088693333279336339355910600992e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.138541953028939715357034547426313703e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.281234665322887466568860332727259483e-16), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + BOOST_MATH_STATIC const T C2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0041335978835978835978835978835978836), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00268132716049382716049382716049382716), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000771604938271604938271604938271604938), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.200938786008230452674897119341563786e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107366532263651605215391223621676297), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.529234488291201254164217127180090143e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.127606351886187277133779191392360117e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.34235787340961380741902003904747389e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137219573090629332055943852926020279e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.629899213838005502290672234278391876e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.142806142060642417915846008822771748e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.204770984219908660149195854409200226e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.140925299108675210532930244154315272e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.622897408492202203356394293530327112e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.136704883966171134992724380284402402e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.942835615901467819547711211663208075e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.128722524000893180595479368872770442e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.556459561343633211465414765894951439e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119759355463669810035898150310311343e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.416897822518386350403836626692480096e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.109406404278845944099299008640802908e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.4662239946390135746326204922464679e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.990510576390690597844122258212382301e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.189318767683735145056885183170630169e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.885922187259112726176031067028740667e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.373782039804640545306560251777191937e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.786883363903515525774088394065960751e-15), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + BOOST_MATH_STATIC const T C3[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000649434156378600823045267489711934156), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000229472093621399176954732510288065844), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000469189494395255712128140111679206329), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000267720632062838852962309752433209223), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.756180167188397641072538191879755666e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.239650511386729665193314027333231723e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110826541153473023614770299726861227e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.567495282699159656749963105701560205e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14230900732435883914551894470580433e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.278610802915281422405802158211174452e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16958404091930277289864168795820267e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.809946490538808236335278504852724081e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.191111684859736540606728140872727635e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.239286204398081179686413514022282056e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.206201318154887984369925818486654549e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.946049666185513217375417988510192814e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.215410497757749078380130268468744512e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.138882333681390304603424682490735291e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.218947616819639394064123400466489455e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.979099895117168512568262802255883368e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.217821918801809621153859472011393244e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.62088195734079014258166361684972205e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.212697836327973697696702537114614471e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.934468879151743333127396765626749473e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.204536712267828493249215913063207436e-13), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + BOOST_MATH_STATIC const T C4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000861888290916711698604702719929057378), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00078403922172006662747403488144228885), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000299072480303190179733389609932819809), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.146384525788434181781232535690697556e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.664149821546512218665853782451862013e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.396836504717943466443123507595386882e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113757269706784190980552042885831759e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.250749722623753280165221942390057007e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169541495365583060147164356781525752e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.890750753220530968882898422505515924e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.229293483400080487057216364891158518e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.295679413754404904696572852500004588e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.288658297427087836297341274604184504e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.141897394378032193894774303903982717e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.344635804994648970659527720474194356e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.230245171745280671320192735850147087e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.394092330280464052750697640085291799e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.186023389685045019134258533045185639e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.435632300505661804380678327446262424e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.127860010162962312660550463349930726e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.467927502665791946200382739991760062e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.214924647061348285410535341910721086e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.490881561480965216323649688463984082e-12), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + BOOST_MATH_STATIC const T C5[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000336798553366358150308767592718210002), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.697281375836585777429398828575783308e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00027727532449593920787336425196507501), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000199325705161888477003360405280844238), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.679778047793720783881640176604435742e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.141906292064396701483392727105575757e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.135940481897686932784583938837504469e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.80184702563342015397192571980419684e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.229148117650809517038048790128781806e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.325247355129845395166230137750005047e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.346528464910852649559195496827579815e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.184471871911713432765322367374920978e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.482409670378941807563762631738989002e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.179894667217435153025754291716644314e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.630619450001352343517516981425944698e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.316241762877456793773762181540969623e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.784092425369742929000839303523267545e-9), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + BOOST_MATH_STATIC const T C6[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00053130793646399222316574854297762391), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000592166437353693882864836225604401187), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000270878209671804482771279183488328692), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.790235323266032787212032944390816666e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.815396936756196875092890088464682624e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.561168275310624965003775619041471695e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.183291165828433755673259749374098313e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.307961345060330478256414192546677006e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.346515536880360908673728529745376913e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.202913273960586037269527254582695285e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.578879286314900370889997586203187687e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233863067382665698933480579231637609e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.88286007463304835250508524317926246e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.474359588804081278032150770595852426e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.125454150207103824457130611214783073e-7), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + BOOST_MATH_STATIC const T C7[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000344367606892377671254279625108523655), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.517179090826059219337057843002058823e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000334931610811422363116635090580012327), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000281269515476323702273722110707777978), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000109765822446847310235396824500789005), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.127410090954844853794579954588107623e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.277444515115636441570715073933712622e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.182634888057113326614324442681892723e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.578769494973505239894178121070843383e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.493875893393627039981813418398565502e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105953670140260427338098566209633945e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.616671437611040747858836254004890765e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.175629733590604619378669693914265388e-6), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + BOOST_MATH_STATIC const T C8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000652623918595309418922034919726622692), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000839498720672087279993357516764983445), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000438297098541721005061087953050560377), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.696909145842055197136911097362072702e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00016644846642067547837384572662326101), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000127835176797692185853344001461664247), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.462995326369130429061361032704489636e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.455790986792270771162749294232219616e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105952711258051954718238500312872328e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.678334290486516662273073740749269432e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210754766662588042469972680229376445e-5), + }; + workspace[8] = tools::evaluate_polynomial(C8, z); + + BOOST_MATH_STATIC const T C9[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000596761290192746250124390067179459605), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.720489541602001055908571930225015052e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000678230883766732836161951166000673426), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000640147526026275845100045652582354779), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000277501076343287044992374518205845463), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.181970083804651510461686554030325202e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.847950711706850318239732559632810086e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.610519208250153101764709122740859458e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210739201834048624082975255893773306e-4), + }; + workspace[9] = tools::evaluate_polynomial(C9, z); + + BOOST_MATH_STATIC const T C10[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00133244544948006563712694993432717968), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00191443849856547752650089885832852254), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0011089369134596637339607446329267522), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.993240412264229896742295262075817566e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000508745012930931989848393025305956774), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00042735056665392884328432271160040444), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000168588537679107988033552814662382059), + }; + workspace[10] = tools::evaluate_polynomial(C10, z); + + BOOST_MATH_STATIC const T C11[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157972766073083495908785631307733022), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000162516262783915816898635123980270998), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00206334210355432762645284467690276817), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00213896861856890981541061922797693947), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00101085593912630031708085801712479376), + }; + workspace[11] = tools::evaluate_polynomial(C11, z); + + BOOST_MATH_STATIC const T C12[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00407251211951401664727281097914544601), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00640336283380806979482363809026579583), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00404101610816766177473974858518094879), + }; + workspace[12] = tools::evaluate_polynomial(C12, z); + workspace[13] = -0.0059475779383993002845382844736066323L; + + T result = tools::evaluate_polynomial(workspace, T(1/a)); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} +// LCOV_EXCL_STOP + +#endif + +} // namespace detail +} // namespace math +} // namespace math + + +#endif // BOOST_MATH_DETAIL_IGAMMA_LARGE + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/lambert_w_lookup_table.ipp b/third-party/boost-math/include/boost/math/special_functions/detail/lambert_w_lookup_table.ipp new file mode 100644 index 0000000000000..b38aeb49c3241 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/lambert_w_lookup_table.ipp @@ -0,0 +1,134 @@ +// 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 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 Thu Jan 25 16:52:07 2018 + +// Sizes of arrays of z values for Lambert W[0], W[1] ... W[64]" and W[-1], W[-2] ... W[-64]. + +namespace boost { +namespace math { +namespace lambert_w_detail { +namespace lambert_w_lookup +{ +static constexpr std::size_t noof_sqrts = 12; +static constexpr std::size_t noof_halves = 12; +static constexpr std::size_t noof_w0es = 65; +static constexpr std::size_t noof_w0zs = 65; +static constexpr std::size_t noof_wm1es = 64; +static constexpr std::size_t noof_wm1zs = 64; + +static constexpr lookup_t halves[noof_halves] = +{ // Common to Lambert W0 and W-1 (and exactly representable). + 0.5L, 0.25L, 0.125L, 0.0625L, 0.03125L, 0.015625L, 0.0078125L, 0.00390625L, 0.001953125L, 0.0009765625L, 0.00048828125L, 0.000244140625L +}; // halves, 0.5, 0.25, ... 0.000244140625, common to W0 and W-1. + +static constexpr lookup_t sqrtw0s[noof_sqrts] = +{ // For Lambert W0 only. + 0.6065306597126334242631173765403218567L, 0.77880078307140486866846070009071995L, 0.882496902584595403104717592968701829L, 0.9394130628134757862473572557999761753L, 0.9692332344763440819139583751755278177L, 0.9844964370054084060204319075254540376L, 0.9922179382602435121227899136829802692L, 0.996101369470117490071323985506950379L, 0.9980487811074754727142805899944244847L, 0.9990239141819756622368328253791383317L, 0.9995118379398893653889967919448497792L, 0.9997558891748972165136242351259789505L +}; // sqrtw0s + +static constexpr lookup_t sqrtwm1s[noof_sqrts] = +{ // For Lambert W-1 only. + 1.648721270700128146848650787814163572L, 1.284025416687741484073420568062436458L, 1.133148453066826316829007227811793873L, 1.064494458917859429563390594642889673L, 1.031743407499102670938747815281507144L, 1.015747708586685747458535072082351749L, 1.007843097206447977693453559760123579L, 1.003913889338347573443609603903460282L, 1.001955033591002812046518898047477216L, 1.000977039492416535242845292611606506L, 1.000488400478694473126173623807163354L, 1.000244170429747854937005233924135774L +}; // sqrtwm1s + +static constexpr lookup_t w0es[noof_w0zs] = +{ // Fukushima e powers array e[0] = 2.718, 1., e[2] = e^-1 = 0.135, e[3] = e^-2 = 0.133 ... e[64] = 4.3596100000630809736231248158884615452e-28. + 2.7182818284590452353602874713526624978e+00L, + 1.0000000000000000000000000000000000000e+00L, 3.6787944117144232159552377016146086745e-01L, 1.3533528323661269189399949497248440341e-01L, 4.9787068367863942979342415650061776632e-02L, + 1.8315638888734180293718021273241242212e-02L, 6.7379469990854670966360484231484242488e-03L, 2.4787521766663584230451674308166678915e-03L, 9.1188196555451620800313608440928262647e-04L, + 3.3546262790251183882138912578086101931e-04L, 1.2340980408667954949763669073003382607e-04L, 4.5399929762484851535591515560550610238e-05L, 1.6701700790245659312635517360580879078e-05L, + 6.1442123533282097586823081788055323112e-06L, 2.2603294069810543257852772905386894694e-06L, 8.3152871910356788406398514256526229461e-07L, 3.0590232050182578837147949770228963937e-07L, + 1.1253517471925911451377517906012719164e-07L, 4.1399377187851666596510277189552806229e-08L, 1.5229979744712628436136629233517431862e-08L, 5.6027964375372675400129828162064630798e-09L, + 2.0611536224385578279659403801558209764e-09L, 7.5825604279119067279417432412681264430e-10L, 2.7894680928689248077189130306442932077e-10L, 1.0261879631701890303927527840612497760e-10L, + 3.7751345442790977516449695475234067792e-11L, 1.3887943864964020594661763746086856910e-11L, 5.1090890280633247198744001934792157666e-12L, 1.8795288165390832947582704184221926212e-12L, + 6.9144001069402030094125846587414092712e-13L, 2.5436656473769229103033856148576816666e-13L, 9.3576229688401746049158322233787067450e-14L, 3.4424771084699764583923893328515572846e-14L, + 1.2664165549094175723120904155965096382e-14L, 4.6588861451033973641842455436101684114e-15L, 1.7139084315420129663027203425760492412e-15L, 6.3051167601469893856390211922465427614e-16L, + 2.3195228302435693883122636097380800411e-16L, 8.5330476257440657942780498229412441658e-17L, 3.1391327920480296287089646522319196491e-17L, 1.1548224173015785986262442063323868655e-17L, + 4.2483542552915889953292347828586580179e-18L, 1.5628821893349887680908829951058341550e-18L, 5.7495222642935598066643808805734234249e-19L, 2.1151310375910804866314010070226514702e-19L, + 7.7811322411337965157133167292798981918e-20L, 2.8625185805493936444701216291839372068e-20L, 1.0530617357553812378763324449428108806e-20L, 3.8739976286871871129314774972691278293e-21L, + 1.4251640827409351062853210280340602263e-21L, 5.2428856633634639371718053028323436716e-22L, 1.9287498479639177830173428165270125748e-22L, 7.0954741622847041389832693878080734877e-23L, + 2.6102790696677048047026953153318648093e-23L, 9.6026800545086760302307696700074909076e-24L, 3.5326285722008070297353928101772088374e-24L, 1.2995814250075030736007134060714855303e-24L, + 4.7808928838854690812771770423179628939e-25L, 1.7587922024243116489558751288034363178e-25L, 6.4702349256454603261540395529264893765e-26L, 2.3802664086944006058943245888024963309e-26L, + 8.7565107626965203384887328007391660366e-27L, 3.2213402859925160890012477758489437534e-27L, 1.1850648642339810062850307390972809891e-27L, 4.3596100000630809736231248158884596428e-28L, + +}; // w0es + +static constexpr lookup_t w0zs[noof_w0zs] = +{ // z values for W[0], W[1], W[2] ... W[64] (Fukushima array Fk). + 0.0000000000000000000000000000000000000e+00L, + 2.7182818284590452353602874713526624978e+00L, 1.4778112197861300454460854921150015626e+01L, 6.0256610769563003222785588963745153691e+01L, 2.1839260013257695631244104481144351361e+02L, + 7.4206579551288301710557790020276139812e+02L, 2.4205727609564107356503230832603296776e+03L, 7.6764321089992101948460416680168500271e+03L, 2.3847663896333826197948736795623109390e+04L, + 7.2927755348178456069389970204894839685e+04L, 2.2026465794806716516957900645284244366e+05L, 6.5861555886717600300859134371483559776e+05L, 1.9530574970280470496960624587818413980e+06L, + 5.7513740961159665432393360873381476632e+06L, 1.6836459978306874888489314790750032292e+07L, 4.9035260587081659589527825691375819733e+07L, 1.4217776832812596218820837985250320561e+08L, + 4.1063419681078006965118239806655900596e+08L, 1.1818794444719492004981570586630806042e+09L, 3.3911637183005579560532906419857313738e+09L, 9.7033039081958055593821366108308111737e+09L, + 2.7695130424147508641409976558651358487e+10L, 7.8868082614895014356985518811525255163e+10L, 2.2413047926372475980079655175092843139e+11L, 6.3573893111624333505933989166748517618e+11L, + 1.8001224834346468131040337866531539479e+12L, 5.0889698451498078710141863447784789126e+12L, 1.4365302496248562650461177217211790925e+13L, 4.0495197800161304862957327843914007993e+13L, + 1.1400869461717722015726999684446230289e+14L, 3.2059423744573386440971405952224204950e+14L, 9.0051433962267018216365614546207459567e+14L, 2.5268147258457822451512967243234631750e+15L, + 7.0832381329352301326018261305316090522e+15L, 1.9837699245933465967698692976753294646e+16L, 5.5510470830970075484537561902113104381e+16L, 1.5520433569614702817608320254284931407e+17L, + 4.3360826779369661842459877227403719730e+17L, 1.2105254067703227363724895246493485480e+18L, 3.3771426165357561311906703760513324357e+18L, 9.4154106734807994163159964299613921804e+18L, + 2.6233583234732252918129199544138403574e+19L, 7.3049547543861043990576614751671879498e+19L, 2.0329709713386190214340167519800405595e+20L, 5.6547040503180956413560918381429636734e+20L, + 1.5720421975868292906615658755032744790e+21L, 4.3682149334771264822761478593874428627e+21L, 1.2132170565093316762294432610117848880e+22L, 3.3680332378068632345542636794533635462e+22L, + 9.3459982052259884835729892206738573922e+22L, 2.5923527642935362320437266614667426924e+23L, 7.1876803203773878618909930893087860822e+23L, 1.9921241603726199616378561653688236827e+24L, + 5.5192924995054165325072406547517121131e+24L, 1.5286067837683347062387143159276002521e+25L, 4.2321318958281094260005100745711666956e+25L, 1.1713293177672778461879598480402173158e+26L, + 3.2408603996214813669049988277609543829e+26L, 8.9641258264226027960478448084812796397e+26L, 2.4787141382364034104243901241243054434e+27L, 6.8520443388941057019777430988685937812e+27L, + 1.8936217407781711443114787060753312270e+28L, 5.2317811346197017832254642778313331353e+28L, 1.4450833904658542238325922893692265683e+29L, 3.9904954117194348050619127737142206367e+29L + +}; // w0zs + +static constexpr lookup_t wm1es[noof_wm1es] = +{ // Fukushima e array e[0] = e^1 = 2.718, e[1] = e^2 = 7.39 ... e[64] = 4.60718e+28. + 2.7182818284590452353602874713526624978e+00L, + 7.3890560989306502272304274605750078132e+00L, 2.0085536923187667740928529654581717897e+01L, 5.4598150033144239078110261202860878403e+01L, 1.4841315910257660342111558004055227962e+02L, + 4.0342879349273512260838718054338827961e+02L, 1.0966331584284585992637202382881214324e+03L, 2.9809579870417282747435920994528886738e+03L, 8.1030839275753840077099966894327599650e+03L, + 2.2026465794806716516957900645284244366e+04L, 5.9874141715197818455326485792257781614e+04L, 1.6275479141900392080800520489848678317e+05L, 4.4241339200892050332610277594908828178e+05L, + 1.2026042841647767777492367707678594494e+06L, 3.2690173724721106393018550460917213155e+06L, 8.8861105205078726367630237407814503508e+06L, 2.4154952753575298214775435180385823880e+07L, + 6.5659969137330511138786503259060033569e+07L, 1.7848230096318726084491003378872270388e+08L, 4.8516519540979027796910683054154055868e+08L, 1.3188157344832146972099988837453027851e+09L, + 3.5849128461315915616811599459784206892e+09L, 9.7448034462489026000346326848229752776e+09L, 2.6489122129843472294139162152811882341e+10L, 7.2004899337385872524161351466126157915e+10L, + 1.9572960942883876426977639787609534279e+11L, 5.3204824060179861668374730434117744166e+11L, 1.4462570642914751736770474229969288569e+12L, 3.9313342971440420743886205808435276858e+12L, + 1.0686474581524462146990468650741401650e+13L, 2.9048849665247425231085682111679825667e+13L, 7.8962960182680695160978022635108224220e+13L, 2.1464357978591606462429776153126088037e+14L, + 5.8346174252745488140290273461039101900e+14L, 1.5860134523134307281296446257746601252e+15L, 4.3112315471151952271134222928569253908e+15L, 1.1719142372802611308772939791190194522e+16L, + 3.1855931757113756220328671701298646000e+16L, 8.6593400423993746953606932719264934250e+16L, 2.3538526683701998540789991074903480451e+17L, 6.3984349353005494922266340351557081888e+17L, + 1.7392749415205010473946813036112352261e+18L, 4.7278394682293465614744575627442803708e+18L, 1.2851600114359308275809299632143099258e+19L, 3.4934271057485095348034797233406099533e+19L, + 9.4961194206024488745133649117118323102e+19L, 2.5813128861900673962328580021527338043e+20L, 7.0167359120976317386547159988611740546e+20L, 1.9073465724950996905250998409538484474e+21L, + 5.1847055285870724640874533229334853848e+21L, 1.4093490824269387964492143312370168789e+22L, 3.8310080007165768493035695487861993899e+22L, 1.0413759433029087797183472933493796440e+23L, + 2.8307533032746939004420635480140745409e+23L, 7.6947852651420171381827455901293939921e+23L, 2.0916594960129961539070711572146737782e+24L, 5.6857199993359322226403488206332533034e+24L, + 1.5455389355901039303530766911174620068e+25L, 4.2012104037905142549565934307191617684e+25L, 1.1420073898156842836629571831447656302e+26L, 3.1042979357019199087073421411071003721e+26L, + 8.4383566687414544890733294803731179601e+26L, 2.2937831594696098790993528402686136005e+27L, 6.2351490808116168829092387089284697448e+27L +}; // wm1es + +static constexpr lookup_t wm1zs[noof_wm1zs] = +{ // Fukushima G array of z values for integral K, (Fukushima Gk) g[0] (k = -1) = 1 ... g[64] = -1.0264389699511303e-26. + -3.6787944117144232159552377016146086745e-01L, + -2.7067056647322538378799898994496880682e-01L, -1.4936120510359182893802724695018532990e-01L, -7.3262555554936721174872085092964968848e-02L, -3.3689734995427335483180242115742121244e-02L, + -1.4872513059998150538271004584900007349e-02L, -6.3831737588816134560219525908649783853e-03L, -2.6837010232200947105711130062468881545e-03L, -1.1106882367801159454787302165703044346e-03L, + -4.5399929762484851535591515560550610238e-04L, -1.8371870869270225243899069096638966986e-04L, -7.3730548239938517104187698145666387735e-05L, -2.9384282290753706235208604777002963102e-05L, + -1.1641402067449950376895791995913672125e-05L, -4.5885348075273868255721924655343445906e-06L, -1.8005627955081458322204028649620350662e-06L, -7.0378941219347833214067471222239770590e-07L, + -2.7413963540482731185045932620331377352e-07L, -1.0645313231320808326024667350792279852e-07L, -4.1223072448771156559318807603116419528e-08L, -1.5923376898615004128677660806663065530e-08L, + -6.1368298043116345769816086674174450569e-09L, -2.3602323152914347699033314033408744848e-09L, -9.0603229062698346039479269140561762700e-10L, -3.4719859662410051486654409365217142276e-10L, + -1.3283631472964644271673440503045960993e-10L, -5.0747278046555248958473301297399200773e-11L, -1.9360320299432568426355237044475945959e-11L, -7.3766303773930764398798182830872768331e-12L, + -2.8072868906520523814747496670136120235e-12L, -1.0671679036256927021016406931839827582e-12L, -4.0525329757101362313986893299088308423e-13L, -1.5374324278841211301808010293913555758e-13L, + -5.8272886672428440854292491647585674200e-14L, -2.2067908660514462849736574172862899665e-14L, -8.3502821888768497979241489950570881481e-15L, -3.1572276215253043438828784344882603413e-15L, + -1.1928704609782512589094065678481294667e-15L, -4.5038074274761565346423524046963087756e-16L, -1.6993417021166355981316939131434632072e-16L, -6.4078169762734539491726202799339200356e-17L, + -2.4147993510032951187990399698408378385e-17L, -9.0950634616416460925150243301974013218e-18L, -3.4236981860988704669138593608831552044e-18L, -1.2881333612472271400115547331327717431e-18L, + -4.8440839844747536942311292467369300505e-19L, -1.8207788854829779430777944237164900798e-19L, -6.8407875971564885101695409345634890862e-20L, -2.5690139750480973292141845983878483991e-20L, + -9.6437492398195889150867140826350628738e-21L, -3.6186918227651991108814673877821174787e-21L, -1.3573451162272064984454015639725697008e-21L, -5.0894204288895982960223079251039701810e-22L, + -1.9076194289884357960571121174956927722e-22L, -7.1476978375412669048039237333931704166e-23L, -2.6773000149758626855152191436980592206e-23L, -1.0025115553818576399048488234179587012e-23L, + -3.7527362568743669891693429406973638384e-24L, -1.4043571811296963574776515073934728352e-24L, -5.2539064576179122030932396804434996219e-25L, -1.9650175744554348142907611432678556896e-25L, + -7.3474021582506822389671905824031421322e-26L, -2.7465543000397410133825686340097295749e-26L, -1.0264389699511282259046957018510946438e-26L +}; // wm1zs +} // namespace lambert_w_lookup +} // namespace detail +} // namespace math +} // namespace boost diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/lanczos_sse2.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/lanczos_sse2.hpp new file mode 100644 index 0000000000000..43353ce2b5108 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/lanczos_sse2.hpp @@ -0,0 +1,238 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2 +#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2 + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#if defined(__GNUC__) || defined(__PGI) || defined(__SUNPRO_CC) +#define ALIGN16 __attribute__((__aligned__(16))) +#else +#define ALIGN16 __declspec(align(16)) +#endif + +namespace boost{ namespace math{ namespace lanczos{ + +template <> +inline double lanczos13m53::lanczos_sum(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast(2.506628274631000270164908177133837338626L), + static_cast(1u), + static_cast(210.8242777515793458725097339207133627117L), + static_cast(66u), + static_cast(8071.672002365816210638002902272250613822L), + static_cast(1925u), + static_cast(186056.2653952234950402949897160456992822L), + static_cast(32670u), + static_cast(2876370.628935372441225409051620849613599L), + static_cast(357423u), + static_cast(31426415.58540019438061423162831820536287L), + static_cast(2637558u), + static_cast(248874557.8620541565114603864132294232163L), + static_cast(13339535u), + static_cast(1439720407.311721673663223072794912393972L), + static_cast(45995730u), + static_cast(6039542586.35202800506429164430729792107L), + static_cast(105258076u), + static_cast(17921034426.03720969991975575445893111267L), + static_cast(150917976u), + static_cast(35711959237.35566804944018545154716670596L), + static_cast(120543840u), + static_cast(42919803642.64909876895789904700198885093L), + static_cast(39916800u), + static_cast(23531376880.41075968857200767445163675473L), + static_cast(0u) + }; + + static const double lim = 4.31965e+25; // By experiment, the largest x for which the SSE2 code does not go bad. + + if (x > lim) + { + double z = 1 / x; + return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]); + } + + __m128d vx = _mm_load1_pd(&x); + __m128d sum_even = _mm_load_pd(coeff); + __m128d sum_odd = _mm_load_pd(coeff+2); + __m128d nc_odd, nc_even; + __m128d vx2 = _mm_mul_pd(vx, vx); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 4); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 6); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 8); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 10); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 12); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 14); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 16); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 18); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 20); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 22); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 24); + sum_odd = _mm_mul_pd(sum_odd, vx); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_even = _mm_add_pd(sum_even, sum_odd); + + + double ALIGN16 t[2]; + _mm_store_pd(t, sum_even); + + return t[0] / t[1]; +} + +template <> +inline double lanczos13m53::lanczos_sum_expG_scaled(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast(0.006061842346248906525783753964555936883222L), + static_cast(1u), + static_cast(0.5098416655656676188125178644804694509993L), + static_cast(66u), + static_cast(19.51992788247617482847860966235652136208L), + static_cast(1925u), + static_cast(449.9445569063168119446858607650988409623L), + static_cast(32670u), + static_cast(6955.999602515376140356310115515198987526L), + static_cast(357423u), + static_cast(75999.29304014542649875303443598909137092L), + static_cast(2637558u), + static_cast(601859.6171681098786670226533699352302507L), + static_cast(13339535u), + static_cast(3481712.15498064590882071018964774556468L), + static_cast(45995730u), + static_cast(14605578.08768506808414169982791359218571L), + static_cast(105258076u), + static_cast(43338889.32467613834773723740590533316085L), + static_cast(150917976u), + static_cast(86363131.28813859145546927288977868422342L), + static_cast(120543840u), + static_cast(103794043.1163445451906271053616070238554L), + static_cast(39916800u), + static_cast(56906521.91347156388090791033559122686859L), + static_cast(0u) + }; + + static const double lim = 4.76886e+25; // By experiment, the largest x for which the SSE2 code does not go bad. + + if (x > lim) + { + double z = 1 / x; + return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]); + } + + __m128d vx = _mm_load1_pd(&x); + __m128d sum_even = _mm_load_pd(coeff); + __m128d sum_odd = _mm_load_pd(coeff+2); + __m128d nc_odd, nc_even; + __m128d vx2 = _mm_mul_pd(vx, vx); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 4); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 6); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 8); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 10); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 12); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 14); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 16); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 18); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 20); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 22); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 24); + sum_odd = _mm_mul_pd(sum_odd, vx); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_even = _mm_add_pd(sum_even, sum_odd); + + + double ALIGN16 t[2]; + _mm_store_pd(t, sum_even); + + return t[0] / t[1]; +} + +#ifdef _MSC_VER + +static_assert(sizeof(double) == sizeof(long double), "sizeof(long double) != sizeof(double) is not supported"); + +template <> +inline long double lanczos13m53::lanczos_sum(const long double& x) +{ + return lanczos_sum(static_cast(x)); +} +template <> +inline long double lanczos13m53::lanczos_sum_expG_scaled(const long double& x) +{ + return lanczos_sum_expG_scaled(static_cast(x)); +} +#endif + +} // namespace lanczos +} // namespace math +} // namespace boost + +#undef ALIGN16 + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS + + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/lgamma_small.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/lgamma_small.hpp new file mode 100644 index 0000000000000..706d200db8883 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/lgamma_small.hpp @@ -0,0 +1,569 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL +#define BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace detail{ + +// +// These need forward declaring to keep GCC happy: +// +template +BOOST_MATH_GPU_ENABLED T gamma_imp(T z, const Policy& pol, const Lanczos& l); +template +BOOST_MATH_GPU_ENABLED T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos& l); + +// +// lgamma for small arguments: +// +template +BOOST_MATH_GPU_ENABLED T lgamma_small_imp(T z, T zm1, T zm2, const boost::math::integral_constant&, const Policy& /* l */, const Lanczos&) +{ + // This version uses rational approximations for small + // values of z accurate enough for 64-bit mantissas + // (80-bit long doubles), works well for 53-bit doubles as well. + // Lanczos is only used to select the Lanczos function. + + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + + BOOST_MATH_ASSERT(z >= tools::root_epsilon()); + /* + * Can not be reached: + * + if(z < tools::epsilon()) + { + result = -log(z); + } + */ + if((zm1 == 0) || (zm2 == 0)) + { + // nothing to do, result is zero.... + } + else if(z > 2) + { + // + // Begin by performing argument reduction until + // z is in [2,3): + // + if(z >= 3) + { + do + { + z -= 1; + zm2 -= 1; + result += log(z); + }while(z >= 3); + // Update zm2, we need it below: + zm2 = z - 2; + } + + // + // Use the following form: + // + // lgamma(z) = (z-2)(z+1)(Y + R(z-2)) + // + // where R(z-2) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-2) has the following properties: + // + // At double: Max error found: 4.231e-18 + // At long double: Max error found: 1.987e-21 + // Maximum Deviation Found (approximation error): 5.900e-24 + // + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.180355685678449379109e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25126649619989678683e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.494103151567532234274e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.172491608709613993966e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.259453563205438108893e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.541009869215204396339e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.324588649825948492091e-4)) + }; + BOOST_MATH_STATIC const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.196202987197795200688e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.148019669424231326694e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.541391432071720958364e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.988504251128010129477e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.82130967464889339326e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.224936291922115757597e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.223352763208617092964e-6)) + }; + + // LCOV_EXCL_STOP + constexpr float Y = 0.158963680267333984375e0f; + + T r = zm2 * (z + 1); + T R = tools::evaluate_polynomial(P, zm2); + R /= tools::evaluate_polynomial(Q, zm2); + + result += r * Y + r * R; + } + else + { + // + // If z is less than 1 use recurrence to shift to + // z in the interval [1,2]: + // + if(z < 1) + { + result += -log(z); + zm2 = zm1; + zm1 = z; + z += 1; + } + // + // Two approximations, on for z in [1,1.5] and + // one for z in [1.5,2]: + // + if(z <= T(1.5)) + { + // + // Use the following form: + // + // lgamma(z) = (z-1)(z-2)(Y + R(z-1)) + // + // where R(z-1) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-1) has the following properties: + // + // At double precision: Max error found: 1.230011e-17 + // At 80-bit long double precision: Max error found: 5.631355e-21 + // Maximum Deviation Found: 3.139e-021 + // Expected Error Term: 3.139e-021 + + // LCOV_EXCL_START + constexpr float Y = 0.52815341949462890625f; + + BOOST_MATH_STATIC const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.490622454069039543534e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.969117530159521214579e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.414983358359495381969e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.406567124211938417342e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.158413586390692192217e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.240149820648571559892e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100346687696279557415e-2)) + }; + BOOST_MATH_STATIC const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.302349829846463038743e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.348739585360723852576e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.191415588274426679201e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.507137738614363510846e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.577039722690451849648e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.195768102601107189171e-2)) + }; + // LCOV_EXCL_STOP + + T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1); + T prefix = zm1 * zm2; + + result += prefix * Y + prefix * r; + } + else + { + // + // Use the following form: + // + // lgamma(z) = (2-z)(1-z)(Y + R(2-z)) + // + // where R(2-z) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(2-z) has the following properties: + // + // At double precision, max error found: 1.797565e-17 + // At 80-bit long double precision, max error found: 9.306419e-21 + // Maximum Deviation Found: 2.151e-021 + // Expected Error Term: 2.150e-021 + // + // LCOV_EXCL_START + constexpr float Y = 0.452017307281494140625f; + + BOOST_MATH_STATIC const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.292329721830270012337e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.144216267757192309184e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.142440390738631274135e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.542809694055053558157e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.850535976868336437746e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.431171342679297331241e-3)) + }; + BOOST_MATH_STATIC const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.150169356054485044494e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.846973248876495016101e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.220095151814995745555e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25582797155975869989e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100666795539143372762e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.827193521891290553639e-6)) + }; + // LCOV_EXCL_STOP + + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2)); + + result += r * Y + r * R; + } + } + return result; +} + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +// +// 128-bit floats aren't directly tested in our coverage tests (takes too long) +// LCOV_EXCL_START +// +template +T lgamma_small_imp(T z, T zm1, T zm2, const boost::math::integral_constant&, const Policy& /* l */, const Lanczos&) +{ + // + // This version uses rational approximations for small + // values of z accurate enough for 113-bit mantissas + // (128-bit long doubles). + // + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + BOOST_MATH_ASSERT(z >= tools::root_epsilon()); + /* + * Can not be reached: + if(z < tools::epsilon()) + { + result = -log(z); + BOOST_MATH_INSTRUMENT_CODE(result); + } + */ + if((zm1 == 0) || (zm2 == 0)) + { + // nothing to do, result is zero.... + } + else if(z > 2) + { + // + // Begin by performing argument reduction until + // z is in [2,3): + // + if(z >= 3) + { + do + { + z -= 1; + result += log(z); + }while(z >= 3); + zm2 = z - 2; + } + BOOST_MATH_INSTRUMENT_CODE(zm2); + BOOST_MATH_INSTRUMENT_CODE(z); + BOOST_MATH_INSTRUMENT_CODE(result); + + // + // Use the following form: + // + // lgamma(z) = (z-2)(z+1)(Y + R(z-2)) + // + // where R(z-2) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // Maximum Deviation Found (approximation error) 3.73e-37 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.018035568567844937910504030027467476655), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.013841458273109517271750705401202404195), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.062031842739486600078866923383017722399), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.052518418329052161202007865149435256093), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.01881718142472784129191838493267755758), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0025104830367021839316463675028524702846), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00021043176101831873281848891452678568311), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00010249622350908722793327719494037981166), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11381479670982006841716879074288176994e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.49999811718089980992888533630523892389e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.70529798686542184668416911331718963364e-8) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5877485070422317542808137697939233685), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8797959228352591788629602533153837126), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8030885955284082026405495275461180977), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.69774331297747390169238306148355428436), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.17261566063277623942044077039756583802), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.02729301254544230229429621192443000121), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026776425891195270663133581960016620433), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00015244249160486584591370355730402168106), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.43997034032479866020546814475414346627e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.46295080708455613044541885534408170934e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.93326638207459533682980757982834180952e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.42316456553164995177177407325292867513e-13) + }; + + T R = tools::evaluate_polynomial(P, zm2); + R /= tools::evaluate_polynomial(Q, zm2); + + static const float Y = 0.158963680267333984375F; + + T r = zm2 * (z + 1); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // + // If z is less than 1 use recurrence to shift to + // z in the interval [1,2]: + // + if(z < 1) + { + result += -log(z); + zm2 = zm1; + zm1 = z; + z += 1; + } + BOOST_MATH_INSTRUMENT_CODE(result); + BOOST_MATH_INSTRUMENT_CODE(z); + BOOST_MATH_INSTRUMENT_CODE(zm2); + // + // Three approximations, on for z in [1,1.35], [1.35,1.625] and [1.625,1] + // + if(z <= 1.35) + { + // + // Use the following form: + // + // lgamma(z) = (z-1)(z-2)(Y + R(z-1)) + // + // where R(z-1) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-1) has the following properties: + // + // Maximum Deviation Found (approximation error) 1.659e-36 + // Expected Error Term (theoretical error) 1.343e-36 + // Max error found at 128-bit long double precision 1.007e-35 + // + static const float Y = 0.54076099395751953125f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.036454670944013329356512090082402429697), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.066235835556476033710068679907798799959), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.67492399795577182387312206593595565371), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4345555263962411429855341651960000166), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4894319559821365820516771951249649563), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.87210277668067964629483299712322411566), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29602090537771744401524080430529369136), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0561832587517836908929331992218879676), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0053236785487328044334381502530383140443), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00018629360291358130461736386077971890789), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.10164985672213178500790406939467614498e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13680157145361387405588201461036338274e-8) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9106336261005990534095838574132225599), + BOOST_MATH_BIG_CONSTANT(T, 113, 10.258804800866438510889341082793078432), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.88588976846826108836629960537466889), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.3455000546999704314454891036700998428), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.6428823682421746343233362007194282703), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.97465989807254572142266753052776132252), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15121052897097822172763084966793352524), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.012017363555383555123769849654484594893), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003583032812720649835431669893011257277) + }; + + T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1); + T prefix = zm1 * zm2; + + result += prefix * Y + prefix * r; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else if(z <= 1.625) + { + // + // Use the following form: + // + // lgamma(z) = (2-z)(1-z)(Y + R(2-z)) + // + // where R(2-z) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(2-z) has the following properties: + // + // Max error found at 128-bit long double precision 9.634e-36 + // Maximum Deviation Found (approximation error) 1.538e-37 + // Expected Error Term (theoretical error) 2.350e-38 + // + static const float Y = 0.483787059783935546875f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.017977422421608624353488126610933005432), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.18484528905298309555089509029244135703), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.40401251514859546989565001431430884082), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.40277179799147356461954182877921388182), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.21993421441282936476709677700477598816), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.069595742223850248095697771331107571011), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.012681481427699686635516772923547347328), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0012489322866834830413292771335113136034), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.57058739515423112045108068834668269608e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.8207548771933585614380644961342925976e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.9629552288944259229543137757200262073), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.7118380799042118987185957298964772755), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.5569815272165399297600586376727357187), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0546764918220835097855665680632153367), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26574021300894401276478730940980810831), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.03996289731752081380552901986471233462), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033398680924544836817826046380586480873), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00013288854760548251757651556792598235735), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.17194794958274081373243161848194745111e-5) + }; + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(0.625 - zm1)) / tools::evaluate_polynomial(Q, T(0.625 - zm1)); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // + // Same form as above. + // + // Max error found (at 128-bit long double precision) 1.831e-35 + // Maximum Deviation Found (approximation error) 8.588e-36 + // Expected Error Term (theoretical error) 1.458e-36 + // + static const float Y = 0.443811893463134765625f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.021027558364667626231512090082402429494), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15128811104498736604523586803722368377), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26249631480066246699388544451126410278), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.21148748610533489823742352180628489742), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.093964130697489071999873506148104370633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.024292059227009051652542804957550866827), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0036284453226534839926304745756906117066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0002939230129315195346843036254392485984), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11088589183158123733132268042570710338e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13240510580220763969511741896361984162e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.4240003754444040525462170802796471996), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4868383476933178722203278602342786002), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4047068395206343375520721509193698547), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.47583809087867443858344765659065773369), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.09865724264554556400463655444270700132), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.012238223514176587501074150988445109735), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00084625068418239194670614419707491797097), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.2796574430456237061420839429225710602e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.30202973883316730694433702165188835331e-6) + }; + // (2 - x) * (1 - x) * (c + R(2 - x)) + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2)); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + BOOST_MATH_INSTRUMENT_CODE(result); + return result; +} +// LCOV_EXCL_STOP + +template +BOOST_MATH_GPU_ENABLED T lgamma_small_imp(T z, T zm1, T zm2, const boost::math::integral_constant&, const Policy& pol, const Lanczos& l) +{ + // + // No rational approximations are available because either + // T has no numeric_limits support (so we can't tell how + // many digits it has), or T has more digits than we know + // what to do with.... we do have a Lanczos approximation + // though, and that can be used to keep errors under control. + // + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + + BOOST_MATH_ASSERT(z >= tools::root_epsilon()); + /* + * Not reachable: + if(z < tools::epsilon()) + { + result = -log(z); + } + */ + if(z < 0.5) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, Lanczos())); + } + else if(z >= 3) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, Lanczos())); + } + else if(z >= 1.5) + { + // special case near 2: + T dz = zm2; + result = dz * log((z + lanczos_g_near_1_and_2(l) - T(0.5)) / boost::math::constants::e()); + result += boost::math::log1p(dz / (lanczos_g_near_1_and_2(l) + T(1.5)), pol) * T(1.5); + result += boost::math::log1p(Lanczos::lanczos_sum_near_2(dz), pol); + } + else + { + // special case near 1: + T dz = zm1; + result = dz * log((z + lanczos_g_near_1_and_2(l) - T(0.5)) / boost::math::constants::e()); + result += boost::math::log1p(dz / (lanczos_g_near_1_and_2(l) + T(0.5)), pol) / 2; + result += boost::math::log1p(Lanczos::lanczos_sum_near_1(dz), pol); + } + return result; +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +}}} // namespaces + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/polygamma.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/polygamma.hpp new file mode 100644 index 0000000000000..a608f22c7fe0b --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/polygamma.hpp @@ -0,0 +1,538 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2013 Paul Bristow +// 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) + +#ifndef _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_ + #define _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#endif + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +namespace boost { namespace math { namespace detail{ + + template + T polygamma_atinfinityplus(const int n, const T& x, const Policy& pol, const char* function) // for large values of x such as for x> 400 + { + // See http://functions.wolfram.com/GammaBetaErf/PolyGamma2/06/02/0001/ + BOOST_MATH_STD_USING + // + // sum == current value of accumulated sum. + // term == value of current term to be added to sum. + // part_term == value of current term excluding the Bernoulli number part + // + if(n + x == x) + { + // x is crazy large, just concentrate on the first part of the expression and use logs: + if(n == 1) return 1 / x; + T nlx = n * log(x); + if((nlx < tools::log_max_value()) && (n < (int)max_factorial::value)) + return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * static_cast(pow(x, T(-n))); + else + return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x)); + } + T term, sum, part_term; + T x_squared = x * x; + // + // Start by setting part_term to: + // + // (n-1)! / x^(n+1) + // + // which is common to both the first term of the series (with k = 1) + // and to the leading part. + // We can then get to the leading term by: + // + // part_term * (n + 2 * x) / 2 + // + // and to the first term in the series + // (excluding the Bernoulli number) by: + // + // part_term n * (n + 1) / (2x) + // + // If either the factorial would overflow, + // or the power term underflows, this just gets set to 0 and then we + // know that we have to use logs for the initial terms: + // + part_term = ((n > (int)boost::math::max_factorial::value) && (T(n) * n > tools::log_max_value())) + ? T(0) : static_cast(boost::math::factorial(n - 1, pol) * pow(x, T(-n - 1))); + if(part_term == 0) + { + // Either n is very large, or the power term underflows, + // set the initial values of part_term, term and sum via logs: + part_term = static_cast(T(boost::math::lgamma(n, pol)) - (n + 1) * log(x)); + sum = exp(part_term + log(n + 2 * x) - boost::math::constants::ln_two()); + part_term += log(T(n) * (n + 1)) - boost::math::constants::ln_two() - log(x); + part_term = exp(part_term); + } + else + { + sum = part_term * (n + 2 * x) / 2; + part_term *= (T(n) * (n + 1)) / 2; + part_term /= x; + } + // + // If the leading term is 0, so is the result: + // + if(sum == 0) + return sum; + + for(unsigned k = 1;;) + { + term = part_term * boost::math::bernoulli_b2n(k, pol); + sum += term; + // + // Normal termination condition: + // + if(fabs(term / sum) < tools::epsilon()) + break; + // + // Increment our counter, and move part_term on to the next value: + // + ++k; + part_term *= T(n + 2 * k - 2) * (n - 1 + 2 * k); + part_term /= (2 * k - 1) * 2 * k; + part_term /= x_squared; + // + // Emergency get out termination condition: + // + if(k > policies::get_max_series_iterations()) + { + return policies::raise_evaluation_error(function, "Series did not converge, closest value was %1%", sum, pol); + } + } + + if((n - 1) & 1) + sum = -sum; + + return sum; + } + + template + T polygamma_attransitionplus(const int n, const T& x, const Policy& pol, const char* function) + { + // See: http://functions.wolfram.com/GammaBetaErf/PolyGamma2/16/01/01/0017/ + + // Use N = (0.4 * digits) + (4 * n) for target value for x: + BOOST_MATH_STD_USING + const int d4d = static_cast(0.4F * policies::digits_base10()); + const int N = d4d + (4 * n); + const int m = n; + const int iter = N - itrunc(x); + + if(iter > (int)policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, ("Exceeded maximum series evaluations evaluating at n = " + std::to_string(n) + " and x = %1%").c_str(), x, pol); + + const int minus_m_minus_one = -m - 1; + + T z(x); + T sum0(0); + T z_plus_k_pow_minus_m_minus_one(0); + + // Forward recursion to larger x, need to check for overflow first though: + if(log(z + iter) * minus_m_minus_one > -tools::log_max_value()) + { + for(int k = 1; k <= iter; ++k) + { + z_plus_k_pow_minus_m_minus_one = static_cast(pow(z, T(minus_m_minus_one))); + sum0 += z_plus_k_pow_minus_m_minus_one; + z += 1; + } + sum0 *= boost::math::factorial(n, pol); + } + else + { + for(int k = 1; k <= iter; ++k) + { + T log_term = log(z) * minus_m_minus_one + boost::math::lgamma(T(n + 1), pol); + sum0 += exp(log_term); + z += 1; + } + } + if((n - 1) & 1) + sum0 = -sum0; + + return sum0 + polygamma_atinfinityplus(n, z, pol, function); + } + + template + T polygamma_nearzero(int n, T x, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // + // If we take this expansion for polygamma: http://functions.wolfram.com/06.15.06.0003.02 + // and substitute in this expression for polygamma(n, 1): http://functions.wolfram.com/06.15.03.0009.01 + // we get an alternating series for polygamma when x is small in terms of zeta functions of + // integer arguments (which are easy to evaluate, at least when the integer is even). + // + // In order to avoid spurious overflow, save the n! term for later, and rescale at the end: + // + T scale = boost::math::factorial(n, pol); + // + // "factorial_part" contains everything except the zeta function + // evaluations in each term: + // + T factorial_part = 1; + // + // "prefix" is what we'll be adding the accumulated sum to, it will + // be n! / z^(n+1), but since we're scaling by n! it's just + // 1 / z^(n+1) for now: + // + T prefix = static_cast(pow(x, T(n + 1))); // Warning supression: Integer power returns at least a double + if(prefix == 0) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + prefix = 1 / prefix; + // + // First term in the series is necessarily < zeta(2) < 2, so + // ignore the sum if it will have no effect on the result anyway: + // + if(prefix > 2 / policies::get_epsilon()) + return ((n & 1) ? 1 : -1) * + (tools::max_value() / prefix < scale ? policies::raise_overflow_error(function, nullptr, pol) : prefix * scale); + // + // As this is an alternating series we could accelerate it using + // "Convergence Acceleration of Alternating Series", + // Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier, Experimental Mathematics, 1999. + // In practice however, it appears not to make any difference to the number of terms + // required except in some edge cases which are filtered out anyway before we get here. + // + T sum = prefix; + for(unsigned k = 0;;) + { + // Get the k'th term: + T term = factorial_part * boost::math::zeta(T(k + n + 1), pol); + sum += term; + // Termination condition: + if(fabs(term) < fabs(sum * boost::math::policies::get_epsilon())) + break; + // + // Move on k and factorial_part: + // + ++k; + factorial_part *= (-x * (n + k)) / k; + // + // Last chance exit: + // + if(k > policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + } + // + // We need to multiply by the scale, at each stage checking for overflow: + // + if(boost::math::tools::max_value() / scale < sum) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + sum *= scale; + return n & 1 ? sum : T(-sum); + } + + // + // Helper function which figures out which slot our coefficient is in + // given an angle multiplier for the cosine term of power: + // + template + typename Table::value_type::reference dereference_table(Table& table, unsigned row, unsigned power) + { + return table[row][power / 2]; + } + + + + template + T poly_cot_pi(int n, T x, T xc, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // Return n'th derivative of cot(pi*x) at x, these are simply + // tabulated for up to n = 9, beyond that it is possible to + // calculate coefficients as follows: + // + // The general form of each derivative is: + // + // pi^n * SUM{k=0, n} C[k,n] * cos^k(pi * x) * csc^(n+1)(pi * x) + // + // With constant C[0,1] = -1 and all other C[k,n] = 0; + // Then for each k < n+1: + // C[k-1, n+1] -= k * C[k, n]; + // C[k+1, n+1] += (k-n-1) * C[k, n]; + // + // Note that there are many different ways of representing this derivative thanks to + // the many trigonometric identies available. In particular, the sum of powers of + // cosines could be replaced by a sum of cosine multiple angles, and indeed if you + // plug the derivative into Mathematica this is the form it will give. The two + // forms are related via the Chebeshev polynomials of the first kind and + // T_n(cos(x)) = cos(n x). The polynomial form has the great advantage that + // all the cosine terms are zero at half integer arguments - right where this + // function has it's minimum - thus avoiding cancellation error in this region. + // + // And finally, since every other term in the polynomials is zero, we can save + // space by only storing the non-zero terms. This greatly complexifies + // subscripting the tables in the calculation, but halves the storage space + // (and complexity for that matter). + // + T s = fabs(x) < fabs(xc) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(xc, pol); + T c = boost::math::cos_pi(x, pol); + switch(n) + { + case 1: + return -constants::pi() / (s * s); + case 2: + { + return 2 * constants::pi() * constants::pi() * c / boost::math::pow<3>(s, pol); + } + case 3: + { + constexpr int P[] = { -2, -4 }; + return boost::math::pow<3>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<4>(s, pol); + } + case 4: + { + constexpr int P[] = { 16, 8 }; + return boost::math::pow<4>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<5>(s, pol); + } + case 5: + { + constexpr int P[] = { -16, -88, -16 }; + return boost::math::pow<5>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<6>(s, pol); + } + case 6: + { + constexpr int P[] = { 272, 416, 32 }; + return boost::math::pow<6>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<7>(s, pol); + } + case 7: + { + constexpr int P[] = { -272, -2880, -1824, -64 }; + return boost::math::pow<7>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<8>(s, pol); + } + case 8: + { + constexpr int P[] = { 7936, 24576, 7680, 128 }; + return boost::math::pow<8>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<9>(s, pol); + } + case 9: + { + constexpr int P[] = { -7936, -137216, -185856, -31616, -256 }; + return boost::math::pow<9>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<10>(s, pol); + } + case 10: + { + constexpr int P[] = { 353792, 1841152, 1304832, 128512, 512 }; + return boost::math::pow<10>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<11>(s, pol); + } + case 11: + { + constexpr int P[] = { -353792, -9061376, -21253376, -8728576, -518656, -1024}; + return boost::math::pow<11>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<12>(s, pol); + } + case 12: + { + constexpr int P[] = { 22368256, 175627264, 222398464, 56520704, 2084864, 2048 }; + return boost::math::pow<12>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<13>(s, pol); + } +#ifndef BOOST_NO_LONG_LONG + case 13: + { + constexpr long long P[] = { -22368256LL, -795300864LL, -2868264960LL, -2174832640LL, -357888000LL, -8361984LL, -4096 }; + return boost::math::pow<13>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<14>(s, pol); + } + case 14: + { + constexpr long long P[] = { 1903757312LL, 21016670208LL, 41731645440LL, 20261765120LL, 2230947840LL, 33497088LL, 8192 }; + return boost::math::pow<14>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<15>(s, pol); + } + case 15: + { + constexpr long long P[] = { -1903757312LL, -89702612992LL, -460858269696LL, -559148810240LL, -182172651520LL, -13754155008LL, -134094848LL, -16384 }; + return boost::math::pow<15>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<16>(s, pol); + } + case 16: + { + constexpr long long P[] = { 209865342976LL, 3099269660672LL, 8885192097792LL, 7048869314560LL, 1594922762240LL, 84134068224LL, 536608768LL, 32768 }; + return boost::math::pow<16>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<17>(s, pol); + } + case 17: + { + constexpr long long P[] = { -209865342976LL, -12655654469632LL, -87815735738368LL, -155964390375424LL, -84842998005760LL, -13684856848384LL, -511780323328LL, -2146926592LL, -65536 }; + return boost::math::pow<17>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<18>(s, pol); + } + case 18: + { + constexpr long long P[] = { 29088885112832LL, 553753414467584LL, 2165206642589696LL, 2550316668551168LL, 985278548541440LL, 115620218667008LL, 3100738912256LL, 8588754944LL, 131072 }; + return boost::math::pow<18>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<19>(s, pol); + } + case 19: + { + constexpr long long P[] = { -29088885112832LL, -2184860175433728LL, -19686087844429824LL, -48165109676113920LL, -39471306959486976LL, -11124607890751488LL, -965271355195392LL, -18733264797696LL, -34357248000LL, -262144 }; + return boost::math::pow<19>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<20>(s, pol); + } + case 20: + { + constexpr long long P[] = { 4951498053124096LL, 118071834535526400LL, 603968063567560704LL, 990081991141490688LL, 584901762421358592LL, 122829335169859584LL, 7984436548730880LL, 112949304754176LL, 137433710592LL, 524288 }; + return boost::math::pow<20>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<21>(s, pol); + } +#endif + } + + // + // We'll have to compute the coefficients up to n, + // complexity is O(n^2) which we don't worry about for now + // as the values are computed once and then cached. + // However, if the final evaluation would have too many + // terms just bail out right away: + // + if((unsigned)n / 2u > policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, "The value of n is so large that we're unable to compute the result in reasonable time, best guess is %1%", 0, pol); +#ifdef BOOST_MATH_HAS_THREADS + static std::mutex m; + std::lock_guard l(m); +#endif + static int digits = tools::digits(); + static std::vector > table(1, std::vector(1, T(-1))); + + int current_digits = tools::digits(); + + if(digits != current_digits) + { + // Oh my... our precision has changed! + table = std::vector >(1, std::vector(1, T(-1))); + digits = current_digits; + } + + int index = n - 1; + + if(index >= (int)table.size()) + { + for(int i = (int)table.size() - 1; i < index; ++i) + { + int offset = i & 1; // 1 if the first cos power is 0, otherwise 0. + int sin_order = i + 2; // order of the sin term + int max_cos_order = sin_order - 1; // largest order of the polynomial of cos terms + int max_columns = (max_cos_order - offset) / 2; // How many entries there are in the current row. + int next_offset = offset ? 0 : 1; + int next_max_columns = (max_cos_order + 1 - next_offset) / 2; // How many entries there will be in the next row + table.push_back(std::vector(next_max_columns + 1, T(0))); + + for(int column = 0; column <= max_columns; ++column) + { + int cos_order = 2 * column + offset; // order of the cosine term in entry "column" + BOOST_MATH_ASSERT(column < (int)table[i].size()); + BOOST_MATH_ASSERT((cos_order + 1) / 2 < (int)table[i + 1].size()); + table[i + 1][(cos_order + 1) / 2] += ((cos_order - sin_order) * table[i][column]) / (sin_order - 1); + if(cos_order) + table[i + 1][(cos_order - 1) / 2] += (-cos_order * table[i][column]) / (sin_order - 1); + } + } + + } + T sum = boost::math::tools::evaluate_even_polynomial(&table[index][0], c, table[index].size()); + if(index & 1) + sum *= c; // First coefficient is order 1, and really an odd polynomial. + if(sum == 0) + return sum; + // + // The remaining terms are computed using logs since the powers and factorials + // get real large real quick: + // + T power_terms = n * log(boost::math::constants::pi()); + if(s == 0) + return sum * boost::math::policies::raise_overflow_error(function, nullptr, pol); + power_terms -= log(fabs(s)) * (n + 1); + power_terms += boost::math::lgamma(T(n), pol); + power_terms += log(fabs(sum)); + + if(power_terms > boost::math::tools::log_max_value()) + return sum * boost::math::policies::raise_overflow_error(function, nullptr, pol); + + return exp(power_terms) * ((s < 0) && ((n + 1) & 1) ? -1 : 1) * boost::math::sign(sum); + } + + template + inline T polygamma_imp(const int n, T x, const Policy &pol) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::polygamma<%1%>(int, %1%)"; + + if(n < 0) + return policies::raise_domain_error(function, "Order must be >= 0, but got %1%", static_cast(n), pol); + if(x < 0) + { + if(floor(x) == x) + { + // + // Result is infinity if x is odd, and a pole error if x is even. + // + if(lltrunc(x) & 1) + return policies::raise_overflow_error(function, nullptr, pol); + else + return policies::raise_pole_error(function, "Evaluation at negative integer %1%", x, pol); + } + T z = 1 - x; + T result = polygamma_imp(n, z, pol) + constants::pi() * poly_cot_pi(n, z, x, pol, function); + return n & 1 ? T(-result) : result; + } + // + // Limit for use of small-x-series is chosen + // so that the series doesn't go too divergent + // in the first few terms. Ordinarily this + // would mean setting the limit to ~ 1 / n, + // but we can tolerate a small amount of divergence: + // + T small_x_limit = (std::min)(T(T(5) / n), T(0.25f)); + if(x < small_x_limit) + { + return polygamma_nearzero(n, x, pol, function); + } + else if(x > 0.4F * policies::digits_base10() + 4.0f * n) + { + return polygamma_atinfinityplus(n, x, pol, function); + } + else if(x == 1) + { + return (n & 1 ? 1 : -1) * boost::math::factorial(n, pol) * boost::math::zeta(T(n + 1), pol); + } + else if(x == 0.5f) + { + T result = (n & 1 ? 1 : -1) * boost::math::factorial(n, pol) * boost::math::zeta(T(n + 1), pol); + if(fabs(result) >= ldexp(tools::max_value(), -n - 1)) + return boost::math::sign(result) * policies::raise_overflow_error(function, nullptr, pol); + result *= ldexp(T(1), n + 1) - 1; + return result; + } + else + { + return polygamma_attransitionplus(n, x, pol, function); + } + } + +} } } // namespace boost::math::detail + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_ + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/round_fwd.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/round_fwd.hpp new file mode 100644 index 0000000000000..7d69f8b9c59d7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/round_fwd.hpp @@ -0,0 +1,87 @@ +// Copyright John Maddock 2008. +// Copyright Matt Borland 2024 + +// 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) + +#ifndef BOOST_MATH_SPECIAL_ROUND_FWD_HPP +#define BOOST_MATH_SPECIAL_ROUND_FWD_HPP + +#include +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost +{ + namespace math + { + + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args::type trunc(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args::type trunc(const T& v); + template + BOOST_MATH_GPU_ENABLED int itrunc(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED int itrunc(const T& v); + template + BOOST_MATH_GPU_ENABLED long ltrunc(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED long ltrunc(const T& v); + template + BOOST_MATH_GPU_ENABLED long long lltrunc(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED long long lltrunc(const T& v); + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args::type round(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args::type round(const T& v); + template + BOOST_MATH_GPU_ENABLED int iround(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED int iround(const T& v); + template + BOOST_MATH_GPU_ENABLED long lround(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED long lround(const T& v); + template + BOOST_MATH_GPU_ENABLED long long llround(const T& v, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED long long llround(const T& v); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, T* ipart, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, T* ipart); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, int* ipart, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, int* ipart); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, long* ipart, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, long* ipart); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, long long* ipart, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T modf(const T& v, long long* ipart); + } +} + +#undef BOOST_MATH_STD_USING +#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE\ + using boost::math::round;\ + using boost::math::iround;\ + using boost::math::lround;\ + using boost::math::trunc;\ + using boost::math::itrunc;\ + using boost::math::ltrunc;\ + using boost::math::modf; + + +#endif // BOOST_MATH_SPECIAL_ROUND_FWD_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/t_distribution_inv.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/t_distribution_inv.hpp new file mode 100644 index 0000000000000..4b55b4fe21507 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/t_distribution_inv.hpp @@ -0,0 +1,567 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007 +// 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) + +#ifndef BOOST_MATH_SF_DETAIL_INV_T_HPP +#define BOOST_MATH_SF_DETAIL_INV_T_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// The main method used is due to Hill: +// +// G. W. Hill, Algorithm 396, Student's t-Quantiles, +// Communications of the ACM, 13(10): 619-620, Oct., 1970. +// +template +BOOST_MATH_GPU_ENABLED T inverse_students_t_hill(T ndf, T u, const Policy& pol) +{ + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(u <= 0.5); + + T a, b, c, d, q, x, y; + + if (ndf > 1e20f) + return -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + + a = 1 / (ndf - 0.5f); + b = 48 / (a * a); + c = ((20700 * a / b - 98) * a - 16) * a + 96.36f; + d = ((94.5f / (b + c) - 3) / b + 1) * sqrt(a * constants::pi() / 2) * ndf; + y = pow(d * 2 * u, 2 / ndf); + + if (y > (0.05f + a)) + { + // + // Asymptotic inverse expansion about normal: + // + x = -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + y = x * x; + + if (ndf < 5) + c += 0.3f * (ndf - 4.5f) * (x + 0.6f); + c += (((0.05f * d * x - 5) * x - 7) * x - 2) * x + b; + y = (((((0.4f * y + 6.3f) * y + 36) * y + 94.5f) / c - y - 3) / b + 1) * x; + y = boost::math::expm1(a * y * y, pol); + } + else + { + y = static_cast(((1 / (((ndf + 6) / (ndf * y) - 0.089f * d - 0.822f) + * (ndf + 2) * 3) + 0.5 / (ndf + 4)) * y - 1) + * (ndf + 1) / (ndf + 2) + 1 / y); + } + q = sqrt(ndf * y); + + return -q; +} +// +// Tail and body series are due to Shaw: +// +// www.mth.kcl.ac.uk/~shaww/web_page/papers/Tdistribution06.pdf +// +// Shaw, W.T., 2006, "Sampling Student's T distribution - use of +// the inverse cumulative distribution function." +// Journal of Computational Finance, Vol 9 Issue 4, pp 37-73, Summer 2006 +// +template +BOOST_MATH_GPU_ENABLED T inverse_students_t_tail_series(T df, T v, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Tail series expansion, see section 6 of Shaw's paper. + // w is calculated using Eq 60: + T w = boost::math::tgamma_delta_ratio(df / 2, constants::half(), pol) + * sqrt(df * constants::pi()) * v; + // define some variables: + T np2 = df + 2; + T np4 = df + 4; + T np6 = df + 6; + // + // Calculate the coefficients d(k), these depend only on the + // number of degrees of freedom df, so at least in theory + // we could tabulate these for fixed df, see p15 of Shaw: + // + T d[7] = { 1, }; + d[1] = -(df + 1) / (2 * np2); + np2 *= (df + 2); + d[2] = -df * (df + 1) * (df + 3) / (8 * np2 * np4); + np2 *= df + 2; + d[3] = -df * (df + 1) * (df + 5) * (((3 * df) + 7) * df -2) / (48 * np2 * np4 * np6); + np2 *= (df + 2); + np4 *= (df + 4); + d[4] = -df * (df + 1) * (df + 7) * + ( (((((15 * df) + 154) * df + 465) * df + 286) * df - 336) * df + 64 ) + / (384 * np2 * np4 * np6 * (df + 8)); + np2 *= (df + 2); + d[5] = -df * (df + 1) * (df + 3) * (df + 9) + * (((((((35 * df + 452) * df + 1573) * df + 600) * df - 2020) * df) + 928) * df -128) + / (1280 * np2 * np4 * np6 * (df + 8) * (df + 10)); + np2 *= (df + 2); + np4 *= (df + 4); + np6 *= (df + 6); + d[6] = -df * (df + 1) * (df + 11) + * ((((((((((((945 * df) + 31506) * df + 425858) * df + 2980236) * df + 11266745) * df + 20675018) * df + 7747124) * df - 22574632) * df - 8565600) * df + 18108416) * df - 7099392) * df + 884736) + / (46080 * np2 * np4 * np6 * (df + 8) * (df + 10) * (df +12)); + // + // Now bring everything together to provide the result, + // this is Eq 62 of Shaw: + // + T rn = sqrt(df); + T div = pow(rn * w, 1 / df); + T power = div * div; + T result = tools::evaluate_polynomial<7, T, T>(d, power); + result *= rn; + result /= div; + return -result; +} + +template +BOOST_MATH_GPU_ENABLED T inverse_students_t_body_series(T df, T u, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Body series for small N: + // + // Start with Eq 56 of Shaw: + // + T v = boost::math::tgamma_delta_ratio(df / 2, constants::half(), pol) + * sqrt(df * constants::pi()) * (u - constants::half()); + // + // Workspace for the polynomial coefficients: + // + T c[11] = { 0, 1, }; + // + // Figure out what the coefficients are, note these depend + // only on the degrees of freedom (Eq 57 of Shaw): + // + T in = 1 / df; + c[2] = static_cast(0.16666666666666666667 + 0.16666666666666666667 * in); + c[3] = static_cast((0.0083333333333333333333 * in + + 0.066666666666666666667) * in + + 0.058333333333333333333); + c[4] = static_cast(((0.00019841269841269841270 * in + + 0.0017857142857142857143) * in + + 0.026785714285714285714) * in + + 0.025198412698412698413); + c[5] = static_cast((((2.7557319223985890653e-6 * in + + 0.00037477954144620811287) * in + - 0.0011078042328042328042) * in + + 0.010559964726631393298) * in + + 0.012039792768959435626); + c[6] = static_cast(((((2.5052108385441718775e-8 * in + - 0.000062705427288760622094) * in + + 0.00059458674042007375341) * in + - 0.0016095979637646304313) * in + + 0.0061039211560044893378) * in + + 0.0038370059724226390893); + c[7] = static_cast((((((1.6059043836821614599e-10 * in + + 0.000015401265401265401265) * in + - 0.00016376804137220803887) * in + + 0.00069084207973096861986) * in + - 0.0012579159844784844785) * in + + 0.0010898206731540064873) * in + + 0.0032177478835464946576); + c[8] = static_cast(((((((7.6471637318198164759e-13 * in + - 3.9851014346715404916e-6) * in + + 0.000049255746366361445727) * in + - 0.00024947258047043099953) * in + + 0.00064513046951456342991) * in + - 0.00076245135440323932387) * in + + 0.000033530976880017885309) * in + + 0.0017438262298340009980); + c[9] = static_cast((((((((2.8114572543455207632e-15 * in + + 1.0914179173496789432e-6) * in + - 0.000015303004486655377567) * in + + 0.000090867107935219902229) * in + - 0.00029133414466938067350) * in + + 0.00051406605788341121363) * in + - 0.00036307660358786885787) * in + - 0.00031101086326318780412) * in + + 0.00096472747321388644237); + c[10] = static_cast(((((((((8.2206352466243297170e-18 * in + - 3.1239569599829868045e-7) * in + + 4.8903045291975346210e-6) * in + - 0.000033202652391372058698) * in + + 0.00012645437628698076975) * in + - 0.00028690924218514613987) * in + + 0.00035764655430568632777) * in + - 0.00010230378073700412687) * in + - 0.00036942667800009661203) * in + + 0.00054229262813129686486); + // + // The result is then a polynomial in v (see Eq 56 of Shaw): + // + return tools::evaluate_odd_polynomial<11, T, T>(c, v); +} + +template +BOOST_MATH_GPU_ENABLED T inverse_students_t(T df, T u, T v, const Policy& pol, bool* pexact = nullptr) +{ + // + // df = number of degrees of freedom. + // u = probability. + // v = 1 - u. + // l = lanczos type to use. + // + BOOST_MATH_STD_USING + bool invert = false; + T result = 0; + if(pexact) + *pexact = false; + if(u > v) + { + // function is symmetric, invert it: + BOOST_MATH_GPU_SAFE_SWAP(u, v); + invert = true; + } + if((floor(df) == df) && (df < 20)) + { + // + // we have integer degrees of freedom, try for the special + // cases first: + // + T tolerance = ldexp(1.0f, (2 * policies::digits()) / 3); + + switch(itrunc(df, Policy())) + { + case 1: + { + // + // df = 1 is the same as the Cauchy distribution, see + // Shaw Eq 35: + // + if(u == 0.5) + result = 0; + else + result = -cos(constants::pi() * u) / sin(constants::pi() * u); + if(pexact) + *pexact = true; + break; + } + case 2: + { + // + // df = 2 has an exact result, see Shaw Eq 36: + // + result =(2 * u - 1) / sqrt(2 * u * v); + if(pexact) + *pexact = true; + break; + } + case 4: + { + // + // df = 4 has an exact result, see Shaw Eq 38 & 39: + // + T alpha = 4 * u * v; + T root_alpha = sqrt(alpha); + T r = 4 * cos(acos(root_alpha) / 3) / root_alpha; + T x = sqrt(r - 4); + result = u - 0.5f < 0 ? (T)-x : x; + if(pexact) + *pexact = true; + break; + } + case 6: + { + // + // We get numeric overflow in this area: + // + if(u < 1e-150) + return (invert ? -1 : 1) * inverse_students_t_hill(df, u, pol); + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + T a = 4 * (u - u * u);//1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = boost::math::cbrt(a, pol); + static const T c = static_cast(0.85498797333834849467655443627193); + T p = 6 * (1 + c * (1 / b - 1)); + T p0; + do{ + T p2 = p * p; + T p4 = p2 * p2; + T p5 = p * p4; + p0 = p; + // next term is given by Eq 41: + p = 2 * (8 * a * p5 - 270 * p2 + 2187) / (5 * (4 * a * p4 - 216 * p - 243)); + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? (T)-p : p; + break; + } +#if 0 + // + // These are Shaw's "exact" but iterative solutions + // for even df, the numerical accuracy of these is + // rather less than Hill's method, so these are disabled + // for now, which is a shame because they are reasonably + // quick to evaluate... + // + case 8: + { + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + static const T c8 = 0.85994765706259820318168359251872L; + T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = pow(a, T(1) / 4); + T p = 8 * (1 + c8 * (1 / b - 1)); + T p0 = p; + do{ + T p5 = p * p; + p5 *= p5 * p; + p0 = p; + // Next term is given by Eq 42: + p = 2 * (3 * p + (640 * (160 + p * (24 + p * (p + 4)))) / (-5120 + p * (-2048 - 960 * p + a * p5))) / 7; + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? -p : p; + break; + } + case 10: + { + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + static const T c10 = 0.86781292867813396759105692122285L; + T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = pow(a, T(1) / 5); + T p = 10 * (1 + c10 * (1 / b - 1)); + T p0; + do{ + T p6 = p * p; + p6 *= p6 * p6; + p0 = p; + // Next term given by Eq 43: + p = (8 * p) / 9 + (218750 * (21875 + 4 * p * (625 + p * (75 + 2 * p * (5 + p))))) / + (9 * (-68359375 + 8 * p * (-2343750 + p * (-546875 - 175000 * p + 8 * a * p6)))); + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? -p : p; + break; + } +#endif + default: + goto calculate_real; + } + } + else + { +calculate_real: + if(df > 0x10000000) + { + result = -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + if((pexact) && (df >= 1e20)) + *pexact = true; + } + else if(df < 3) + { + // + // Use a roughly linear scheme to choose between Shaw's + // tail series and body series: + // + T crossover = 0.2742f - df * 0.0242143f; + if(u > crossover) + { + result = boost::math::detail::inverse_students_t_body_series(df, u, pol); + } + else + { + result = boost::math::detail::inverse_students_t_tail_series(df, u, pol); + } + } + else + { + // + // Use Hill's method except in the extreme tails + // where we use Shaw's tail series. + // The crossover point is roughly exponential in -df: + // + int u_exp; + T m_exp = frexp(u, &u_exp); + // The following is equivalent to: u > 2^df/-0.654 + if(m_exp > 0 && u_exp < df / 0.654f) + { + result = boost::math::detail::inverse_students_t_hill(df, u, pol); + } + else + { + result = boost::math::detail::inverse_students_t_tail_series(df, u, pol); + } + } + } + return invert ? (T)-result : result; +} + +template +BOOST_MATH_GPU_ENABLED inline T find_ibeta_inv_from_t_dist(T a, T p, T /*q*/, T* py, const Policy& pol) +{ + T u = p / 2; + T v = 1 - u; + T df = a * 2; + T t = boost::math::detail::inverse_students_t(df, u, v, pol); + *py = t * t / (df + t * t); + return df / (df + t * t); +} + +// NVRTC requires this forward decl because there is a header cycle between here and ibeta_inverse.hpp +#ifdef BOOST_MATH_HAS_NVRTC + +} // Namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol); + +namespace detail { + +#endif + +template +BOOST_MATH_GPU_ENABLED inline T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const boost::math::false_type*) +{ + BOOST_MATH_STD_USING + // + // Need to use inverse incomplete beta to get + // required precision so not so fast: + // + T probability = (p > 0.5) ? 1 - p : p; + T t, x, y(0); + x = ibeta_inv(df / 2, T(0.5), 2 * probability, &y, pol); + if(df * y > tools::max_value() * x) + t = policies::raise_overflow_error("boost::math::students_t_quantile<%1%>(%1%,%1%)", nullptr, pol); + else + t = sqrt(df * y / x); + // + // Figure out sign based on the size of p: + // + if(p < 0.5) + t = -t; + return t; +} + +template +BOOST_MATH_GPU_ENABLED T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const boost::math::true_type*) +{ + BOOST_MATH_STD_USING + bool invert = false; + if((df < 2) && (floor(df) != df)) + return boost::math::detail::fast_students_t_quantile_imp(df, p, pol, static_cast(nullptr)); + if(p > 0.5) + { + p = 1 - p; + invert = true; + } + // + // Get an estimate of the result: + // + bool exact; + T t = inverse_students_t(df, p, T(1-p), pol, &exact); + if((t == 0) || exact) + return invert ? -t : t; // can't do better! + // + // Change variables to inverse incomplete beta: + // + T t2 = t * t; + T xb = df / (df + t2); + T y = t2 / (df + t2); + T a = df / 2; + // + // t can be so large that x underflows, + // just return our estimate in that case: + // + if(xb == 0) + return t; + // + // Get incomplete beta and it's derivative: + // + T f1; + T f0 = xb < y ? ibeta_imp(a, constants::half(), xb, pol, false, true, &f1) + : ibeta_imp(constants::half(), a, y, pol, true, true, &f1); + + // Get cdf from incomplete beta result: + T p0 = f0 / 2 - p; + // Get pdf from derivative: + T p1 = f1 * sqrt(y * xb * xb * xb / df); + // + // Second derivative divided by p1: + // + // yacas gives: + // + // In> PrettyForm(Simplify(D(t) (1 + t^2/v) ^ (-(v+1)/2))) + // + // | | v + 1 | | + // | -| ----- + 1 | | + // | | 2 | | + // -| | 2 | | + // | | t | | + // | | -- + 1 | | + // | ( v + 1 ) * | v | * t | + // --------------------------------------------- + // v + // + // Which after some manipulation is: + // + // -p1 * t * (df + 1) / (t^2 + df) + // + T p2 = t * (df + 1) / (t * t + df); + // Halley step: + t = fabs(t); + t += p0 / (p1 + p0 * p2 / 2); + return !invert ? -t : t; +} + +template +BOOST_MATH_GPU_ENABLED inline T fast_students_t_quantile(T df, T p, const Policy& pol) +{ + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef boost::math::integral_constant::digits <= 53) + && + (boost::math::numeric_limits::is_specialized) + && + (boost::math::numeric_limits::radix == 2) + > tag_type; + return policies::checked_narrowing_cast(fast_students_t_quantile_imp(static_cast(df), static_cast(p), pol, static_cast(nullptr)), "boost::math::students_t_quantile<%1%>(%1%,%1%,%1%)"); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_INV_T_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_bernoulli.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_bernoulli.hpp new file mode 100644 index 0000000000000..676332983a1f7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_bernoulli.hpp @@ -0,0 +1,1305 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2013 John Maddock +// Copyright 2013 Paul Bristow +// 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) + +#ifndef BOOST_MATH_UNCHECKED_BERNOULLI_HPP +#define BOOST_MATH_UNCHECKED_BERNOULLI_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + +template +struct max_bernoulli_index +{ + static constexpr unsigned value = 17; +}; + +template <> +struct max_bernoulli_index<1> +{ + static constexpr unsigned value = 32; +}; + +template <> +struct max_bernoulli_index<2> +{ + static constexpr unsigned value = 129; +}; + +template <> +struct max_bernoulli_index<3> +{ + static constexpr unsigned value = 1156; +}; + +template <> +struct max_bernoulli_index<4> +{ + static constexpr unsigned value = 11; +}; + +template +struct bernoulli_imp_variant +{ + static constexpr unsigned value = + (std::numeric_limits::max_exponent == 128) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 1 : + ( + (std::numeric_limits::max_exponent == 1024) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 2 : + ( + (std::numeric_limits::max_exponent == 16384) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 3 : (!std::is_convertible::value ? 4 : 0) + ) + ); +}; + +} // namespace detail + +template +struct max_bernoulli_b2n : public detail::max_bernoulli_index::value>{}; + +namespace detail { + // + // See https://github.com/boostorg/math/issues/923 + // for rationale behind using struct's here for constexpr data. + // + template + struct unchecked_bernoulli_data; + + template + struct unchecked_bernoulli_data + { +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr std::array::value> numerators = + { { + std::int64_t(+1LL), + std::int64_t(+1LL), + std::int64_t(-1LL), + std::int64_t(+1LL), + std::int64_t(-1LL), + std::int64_t(+5LL), + std::int64_t(-691LL), + std::int64_t(+7LL), + std::int64_t(-3617LL), + std::int64_t(+43867LL), + std::int64_t(-174611LL), + std::int64_t(+854513LL), + std::int64_t(-236364091LL), + std::int64_t(+8553103LL), + std::int64_t(-23749461029LL), + std::int64_t(+8615841276005LL), + std::int64_t(-7709321041217LL), + std::int64_t(+2577687858367LL) + } }; + + static constexpr std::array::value> denominators = + { { + std::int64_t(1LL), + std::int64_t(6LL), + std::int64_t(30LL), + std::int64_t(42LL), + std::int64_t(30LL), + std::int64_t(66LL), + std::int64_t(2730LL), + std::int64_t(6LL), + std::int64_t(510LL), + std::int64_t(798LL), + std::int64_t(330LL), + std::int64_t(138LL), + std::int64_t(2730LL), + std::int64_t(6LL), + std::int64_t(870LL), + std::int64_t(14322LL), + std::int64_t(510LL), + std::int64_t(6LL) + } }; +#else + static const std::array::value> denominators; + static const std::array::value> numerators; +#endif + }; + +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + constexpr std::array::value> unchecked_bernoulli_data::numerators; + template + constexpr std::array::value> unchecked_bernoulli_data::denominators; +#else + template + const std::array::value> unchecked_bernoulli_data::numerators = + { { + std::int64_t(+1LL), + std::int64_t(+1LL), + std::int64_t(-1LL), + std::int64_t(+1LL), + std::int64_t(-1LL), + std::int64_t(+5LL), + std::int64_t(-691LL), + std::int64_t(+7LL), + std::int64_t(-3617LL), + std::int64_t(+43867LL), + std::int64_t(-174611LL), + std::int64_t(+854513LL), + std::int64_t(-236364091LL), + std::int64_t(+8553103LL), + std::int64_t(-23749461029LL), + std::int64_t(+8615841276005LL), + std::int64_t(-7709321041217LL), + std::int64_t(+2577687858367LL) + } }; + + template + const std::array::value> unchecked_bernoulli_data::denominators = + { { + std::int64_t(1LL), + std::int64_t(6LL), + std::int64_t(30LL), + std::int64_t(42LL), + std::int64_t(30LL), + std::int64_t(66LL), + std::int64_t(2730LL), + std::int64_t(6LL), + std::int64_t(510LL), + std::int64_t(798LL), + std::int64_t(330LL), + std::int64_t(138LL), + std::int64_t(2730LL), + std::int64_t(6LL), + std::int64_t(870LL), + std::int64_t(14322LL), + std::int64_t(510LL), + std::int64_t(6LL) + } }; +#endif + + template + inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant&) + { + return T(unchecked_bernoulli_data::numerators[n]) / unchecked_bernoulli_data::denominators[n]; + } + + template + struct unchecked_bernoulli_data + { +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr std::array::value> bernoulli_data = + { { + +1.00000000000000000000000000000000000000000F, + +0.166666666666666666666666666666666666666667F, + -0.0333333333333333333333333333333333333333333F, + +0.0238095238095238095238095238095238095238095F, + -0.0333333333333333333333333333333333333333333F, + +0.0757575757575757575757575757575757575757576F, + -0.253113553113553113553113553113553113553114F, + +1.16666666666666666666666666666666666666667F, + -7.09215686274509803921568627450980392156863F, + +54.9711779448621553884711779448621553884712F, + -529.124242424242424242424242424242424242424F, + +6192.12318840579710144927536231884057971014F, + -86580.2531135531135531135531135531135531136F, + +1.42551716666666666666666666666666666666667e6F, + -2.72982310678160919540229885057471264367816e7F, + +6.01580873900642368384303868174835916771401e8F, + -1.51163157670921568627450980392156862745098e10F, + +4.29614643061166666666666666666666666666667e11F, + -1.37116552050883327721590879485616327721591e13F, + +4.88332318973593166666666666666666666666667e14F, + -1.92965793419400681486326681448632668144863e16F, + +8.41693047573682615000553709856035437430786e17F, + -4.03380718540594554130768115942028985507246e19F, + +2.11507486380819916056014539007092198581560e21F, + -1.20866265222965259346027311937082525317819e23F, + +7.50086674607696436685572007575757575757576e24F, + -5.03877810148106891413789303052201257861635e26F, + +3.65287764848181233351104308429711779448622e28F, + -2.84987693024508822262691464329106781609195e30F, + +2.38654274996836276446459819192192149717514e32F, + -2.13999492572253336658107447651910973926742e34F, + +2.05009757234780975699217330956723102516667e36F, + -2.09380059113463784090951852900279701847092e38F, + } }; +#else + static const std::array::value> bernoulli_data; +#endif + }; + +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + constexpr std::array::value> unchecked_bernoulli_data::bernoulli_data; +#else + template + const std::array::value> unchecked_bernoulli_data::bernoulli_data = + { { + +1.00000000000000000000000000000000000000000F, + +0.166666666666666666666666666666666666666667F, + -0.0333333333333333333333333333333333333333333F, + +0.0238095238095238095238095238095238095238095F, + -0.0333333333333333333333333333333333333333333F, + +0.0757575757575757575757575757575757575757576F, + -0.253113553113553113553113553113553113553114F, + +1.16666666666666666666666666666666666666667F, + -7.09215686274509803921568627450980392156863F, + +54.9711779448621553884711779448621553884712F, + -529.124242424242424242424242424242424242424F, + +6192.12318840579710144927536231884057971014F, + -86580.2531135531135531135531135531135531136F, + +1.42551716666666666666666666666666666666667e6F, + -2.72982310678160919540229885057471264367816e7F, + +6.01580873900642368384303868174835916771401e8F, + -1.51163157670921568627450980392156862745098e10F, + +4.29614643061166666666666666666666666666667e11F, + -1.37116552050883327721590879485616327721591e13F, + +4.88332318973593166666666666666666666666667e14F, + -1.92965793419400681486326681448632668144863e16F, + +8.41693047573682615000553709856035437430786e17F, + -4.03380718540594554130768115942028985507246e19F, + +2.11507486380819916056014539007092198581560e21F, + -1.20866265222965259346027311937082525317819e23F, + +7.50086674607696436685572007575757575757576e24F, + -5.03877810148106891413789303052201257861635e26F, + +3.65287764848181233351104308429711779448622e28F, + -2.84987693024508822262691464329106781609195e30F, + +2.38654274996836276446459819192192149717514e32F, + -2.13999492572253336658107447651910973926742e34F, + +2.05009757234780975699217330956723102516667e36F, + -2.09380059113463784090951852900279701847092e38F, + } }; +#endif + + template + inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant&) + { + return unchecked_bernoulli_data::bernoulli_data[n]; + } + + template + struct unchecked_bernoulli_data + { +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr std::array::value> bernoulli_data = + { { + +1.00000000000000000000000000000000000000000, + +0.166666666666666666666666666666666666666667, + -0.0333333333333333333333333333333333333333333, + +0.0238095238095238095238095238095238095238095, + -0.0333333333333333333333333333333333333333333, + +0.0757575757575757575757575757575757575757576, + -0.253113553113553113553113553113553113553114, + +1.16666666666666666666666666666666666666667, + -7.09215686274509803921568627450980392156863, + +54.9711779448621553884711779448621553884712, + -529.124242424242424242424242424242424242424, + +6192.12318840579710144927536231884057971014, + -86580.2531135531135531135531135531135531136, + +1.42551716666666666666666666666666666666667e6, + -2.72982310678160919540229885057471264367816e7, + +6.01580873900642368384303868174835916771401e8, + -1.51163157670921568627450980392156862745098e10, + +4.29614643061166666666666666666666666666667e11, + -1.37116552050883327721590879485616327721591e13, + +4.88332318973593166666666666666666666666667e14, + -1.92965793419400681486326681448632668144863e16, + +8.41693047573682615000553709856035437430786e17, + -4.03380718540594554130768115942028985507246e19, + +2.11507486380819916056014539007092198581560e21, + -1.20866265222965259346027311937082525317819e23, + +7.50086674607696436685572007575757575757576e24, + -5.03877810148106891413789303052201257861635e26, + +3.65287764848181233351104308429711779448622e28, + -2.84987693024508822262691464329106781609195e30, + +2.38654274996836276446459819192192149717514e32, + -2.13999492572253336658107447651910973926742e34, + +2.05009757234780975699217330956723102516667e36, + -2.09380059113463784090951852900279701847092e38, + +2.27526964884635155596492603527692645814700e40, + -2.62577102862395760473030497361582020814490e42, + +3.21250821027180325182047923042649852435219e44, + -4.15982781667947109139170744952623589366896e46, + +5.69206954820352800238834562191210586444805e48, + -8.21836294197845756922906534686173330145509e50, + +1.25029043271669930167323398297028955241772e53, + -2.00155832332483702749253291988132987687242e55, + +3.36749829153643742333966769033387530162196e57, + -5.94709705031354477186604968440515408405791e59, + +1.10119103236279775595641307904376916046305e62, + -2.13552595452535011886583850190410656789733e64, + +4.33288969866411924196166130593792062184514e66, + -9.18855282416693282262005552155018971389604e68, + +2.03468967763290744934550279902200200659751e71, + -4.70038339580357310785752555350060606545967e73, + +1.13180434454842492706751862577339342678904e76, + -2.83822495706937069592641563364817647382847e78, + +7.40642489796788506297508271409209841768797e80, + -2.00964548027566044834656196727153631868673e83, + +5.66571700508059414457193460305193569614195e85, + -1.65845111541362169158237133743199123014950e88, + +5.03688599504923774192894219151801548124424e90, + -1.58614682376581863693634015729664387827410e93, + +5.17567436175456269840732406825071225612408e95, + -1.74889218402171173396900258776181591451415e98, + +6.11605199949521852558245252642641677807677e100, + -2.21227769127078349422883234567129324455732e103, + +8.27227767987709698542210624599845957312047e105, + -3.19589251114157095835916343691808148735263e108, + +1.27500822233877929823100243029266798669572e111, + -5.25009230867741338994028246245651754469199e113, + +2.23018178942416252098692981988387281437383e116, + -9.76845219309552044386335133989802393011669e118, + +4.40983619784529542722726228748131691918758e121, + -2.05085708864640888397293377275830154864566e124, + +9.82144332797912771075729696020975210414919e126, + -4.84126007982088805087891967099634127611305e129, + +2.45530888014809826097834674040886903996737e132, + -1.28069268040847475487825132786017857218118e135, + +6.86761671046685811921018885984644004360924e137, + -3.78464685819691046949789954163795568144895e140, + +2.14261012506652915508713231351482720966602e143, + -1.24567271371836950070196429616376072194583e146, + +7.43457875510001525436796683940520613117807e148, + -4.55357953046417048940633332233212748767721e151, + +2.86121128168588683453638472510172325229190e154, + -1.84377235520338697276882026536287854875414e157, + +1.21811545362210466995013165065995213558174e160, + -8.24821871853141215484818457296893447301419e162, + +5.72258779378329433296516498142978615918685e165, + -4.06685305250591047267679693831158655602196e168, + +2.95960920646420500628752695815851870426379e171, + -2.20495225651894575090311752273445984836379e174, + +1.68125970728895998058311525151360665754464e177, + -1.31167362135569576486452806355817153004431e180, + +1.04678940094780380821832853929823089643829e183, + -8.54328935788337077185982546299082774593270e185, + +7.12878213224865423522884066771438224721245e188, + -6.08029314555358993000847118686477458461988e191, + +5.29967764248499239300942910043247266228490e194, + -4.71942591687458626443646229013379911103761e197, + +4.29284137914029810894168296541074669045521e200, + -3.98767449682322074434477655542938795106651e203, + +3.78197804193588827138944181161393327898220e206, + -3.66142336836811912436858082151197348755196e209, + +3.61760902723728623488554609298914089477541e212, + -3.64707726451913543621383088655499449048682e215, + +3.75087554364544090983452410104814189306842e218, + -3.93458672964390282694891288533713429355657e221, + +4.20882111481900820046571171111494898242731e224, + -4.59022962206179186559802940573325591059371e227, + +5.10317257726295759279198185106496768539760e230, + -5.78227623036569554015377271242917142512200e233, + +6.67624821678358810322637794412809363451080e236, + -7.85353076444504163225916259639312444428230e239, + +9.41068940670587255245443288258762485293948e242, + -1.14849338734651839938498599206805592548354e246, + +1.42729587428487856771416320087122499897180e249, + -1.80595595869093090142285728117654560926719e252, + +2.32615353076608052161297985184708876161736e255, + -3.04957517154995947681942819261542593785327e258, + +4.06858060764339734424012124124937318633684e261, + -5.52310313219743616252320044093186392324280e264, + +7.62772793964343924869949690204961215533859e267, + -1.07155711196978863132793524001065396932667e271, + +1.53102008959691884453440916153355334355847e274, + -2.22448916821798346676602348865048510824835e277, + +3.28626791906901391668189736436895275365183e280, + -4.93559289559603449020711938191575963496999e283, + +7.53495712008325067212266049779283956727824e286, + -1.16914851545841777278088924731655041783900e290, + +1.84352614678389394126646201597702232396492e293, + -2.95368261729680829728014917350525183485207e296, + +4.80793212775015697668878704043264072227967e299, + -7.95021250458852528538243631671158693036798e302, + +1.33527841873546338750122832017820518292039e306 + } }; +#else + static const std::array::value> bernoulli_data; +#endif + }; + +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + constexpr const std::array::value> unchecked_bernoulli_data::bernoulli_data; +#else + template + const std::array::value> unchecked_bernoulli_data::bernoulli_data = + { { + +1.00000000000000000000000000000000000000000, + +0.166666666666666666666666666666666666666667, + -0.0333333333333333333333333333333333333333333, + +0.0238095238095238095238095238095238095238095, + -0.0333333333333333333333333333333333333333333, + +0.0757575757575757575757575757575757575757576, + -0.253113553113553113553113553113553113553114, + +1.16666666666666666666666666666666666666667, + -7.09215686274509803921568627450980392156863, + +54.9711779448621553884711779448621553884712, + -529.124242424242424242424242424242424242424, + +6192.12318840579710144927536231884057971014, + -86580.2531135531135531135531135531135531136, + +1.42551716666666666666666666666666666666667e6, + -2.72982310678160919540229885057471264367816e7, + +6.01580873900642368384303868174835916771401e8, + -1.51163157670921568627450980392156862745098e10, + +4.29614643061166666666666666666666666666667e11, + -1.37116552050883327721590879485616327721591e13, + +4.88332318973593166666666666666666666666667e14, + -1.92965793419400681486326681448632668144863e16, + +8.41693047573682615000553709856035437430786e17, + -4.03380718540594554130768115942028985507246e19, + +2.11507486380819916056014539007092198581560e21, + -1.20866265222965259346027311937082525317819e23, + +7.50086674607696436685572007575757575757576e24, + -5.03877810148106891413789303052201257861635e26, + +3.65287764848181233351104308429711779448622e28, + -2.84987693024508822262691464329106781609195e30, + +2.38654274996836276446459819192192149717514e32, + -2.13999492572253336658107447651910973926742e34, + +2.05009757234780975699217330956723102516667e36, + -2.09380059113463784090951852900279701847092e38, + +2.27526964884635155596492603527692645814700e40, + -2.62577102862395760473030497361582020814490e42, + +3.21250821027180325182047923042649852435219e44, + -4.15982781667947109139170744952623589366896e46, + +5.69206954820352800238834562191210586444805e48, + -8.21836294197845756922906534686173330145509e50, + +1.25029043271669930167323398297028955241772e53, + -2.00155832332483702749253291988132987687242e55, + +3.36749829153643742333966769033387530162196e57, + -5.94709705031354477186604968440515408405791e59, + +1.10119103236279775595641307904376916046305e62, + -2.13552595452535011886583850190410656789733e64, + +4.33288969866411924196166130593792062184514e66, + -9.18855282416693282262005552155018971389604e68, + +2.03468967763290744934550279902200200659751e71, + -4.70038339580357310785752555350060606545967e73, + +1.13180434454842492706751862577339342678904e76, + -2.83822495706937069592641563364817647382847e78, + +7.40642489796788506297508271409209841768797e80, + -2.00964548027566044834656196727153631868673e83, + +5.66571700508059414457193460305193569614195e85, + -1.65845111541362169158237133743199123014950e88, + +5.03688599504923774192894219151801548124424e90, + -1.58614682376581863693634015729664387827410e93, + +5.17567436175456269840732406825071225612408e95, + -1.74889218402171173396900258776181591451415e98, + +6.11605199949521852558245252642641677807677e100, + -2.21227769127078349422883234567129324455732e103, + +8.27227767987709698542210624599845957312047e105, + -3.19589251114157095835916343691808148735263e108, + +1.27500822233877929823100243029266798669572e111, + -5.25009230867741338994028246245651754469199e113, + +2.23018178942416252098692981988387281437383e116, + -9.76845219309552044386335133989802393011669e118, + +4.40983619784529542722726228748131691918758e121, + -2.05085708864640888397293377275830154864566e124, + +9.82144332797912771075729696020975210414919e126, + -4.84126007982088805087891967099634127611305e129, + +2.45530888014809826097834674040886903996737e132, + -1.28069268040847475487825132786017857218118e135, + +6.86761671046685811921018885984644004360924e137, + -3.78464685819691046949789954163795568144895e140, + +2.14261012506652915508713231351482720966602e143, + -1.24567271371836950070196429616376072194583e146, + +7.43457875510001525436796683940520613117807e148, + -4.55357953046417048940633332233212748767721e151, + +2.86121128168588683453638472510172325229190e154, + -1.84377235520338697276882026536287854875414e157, + +1.21811545362210466995013165065995213558174e160, + -8.24821871853141215484818457296893447301419e162, + +5.72258779378329433296516498142978615918685e165, + -4.06685305250591047267679693831158655602196e168, + +2.95960920646420500628752695815851870426379e171, + -2.20495225651894575090311752273445984836379e174, + +1.68125970728895998058311525151360665754464e177, + -1.31167362135569576486452806355817153004431e180, + +1.04678940094780380821832853929823089643829e183, + -8.54328935788337077185982546299082774593270e185, + +7.12878213224865423522884066771438224721245e188, + -6.08029314555358993000847118686477458461988e191, + +5.29967764248499239300942910043247266228490e194, + -4.71942591687458626443646229013379911103761e197, + +4.29284137914029810894168296541074669045521e200, + -3.98767449682322074434477655542938795106651e203, + +3.78197804193588827138944181161393327898220e206, + -3.66142336836811912436858082151197348755196e209, + +3.61760902723728623488554609298914089477541e212, + -3.64707726451913543621383088655499449048682e215, + +3.75087554364544090983452410104814189306842e218, + -3.93458672964390282694891288533713429355657e221, + +4.20882111481900820046571171111494898242731e224, + -4.59022962206179186559802940573325591059371e227, + +5.10317257726295759279198185106496768539760e230, + -5.78227623036569554015377271242917142512200e233, + +6.67624821678358810322637794412809363451080e236, + -7.85353076444504163225916259639312444428230e239, + +9.41068940670587255245443288258762485293948e242, + -1.14849338734651839938498599206805592548354e246, + +1.42729587428487856771416320087122499897180e249, + -1.80595595869093090142285728117654560926719e252, + +2.32615353076608052161297985184708876161736e255, + -3.04957517154995947681942819261542593785327e258, + +4.06858060764339734424012124124937318633684e261, + -5.52310313219743616252320044093186392324280e264, + +7.62772793964343924869949690204961215533859e267, + -1.07155711196978863132793524001065396932667e271, + +1.53102008959691884453440916153355334355847e274, + -2.22448916821798346676602348865048510824835e277, + +3.28626791906901391668189736436895275365183e280, + -4.93559289559603449020711938191575963496999e283, + +7.53495712008325067212266049779283956727824e286, + -1.16914851545841777278088924731655041783900e290, + +1.84352614678389394126646201597702232396492e293, + -2.95368261729680829728014917350525183485207e296, + +4.80793212775015697668878704043264072227967e299, + -7.95021250458852528538243631671158693036798e302, + +1.33527841873546338750122832017820518292039e306 + } }; +#endif + + template + inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant&) + { + return unchecked_bernoulli_data::bernoulli_data[n]; + } + + template + struct unchecked_bernoulli_data + { +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr std::array::value> bernoulli_data = + { { + +1.00000000000000000000000000000000000000000L, + +0.166666666666666666666666666666666666666667L, + -0.0333333333333333333333333333333333333333333L, + +0.0238095238095238095238095238095238095238095L, + -0.0333333333333333333333333333333333333333333L, + +0.0757575757575757575757575757575757575757576L, + -0.253113553113553113553113553113553113553114L, + +1.16666666666666666666666666666666666666667L, + -7.09215686274509803921568627450980392156863L, + +54.9711779448621553884711779448621553884712L, + -529.124242424242424242424242424242424242424L, + +6192.12318840579710144927536231884057971014L, + -86580.2531135531135531135531135531135531136L, + +1.42551716666666666666666666666666666666667E6L, + -2.72982310678160919540229885057471264367816E7L, + +6.01580873900642368384303868174835916771401E8L, + -1.51163157670921568627450980392156862745098E10L, + +4.29614643061166666666666666666666666666667E11L, + -1.37116552050883327721590879485616327721591E13L, + +4.88332318973593166666666666666666666666667E14L, + -1.92965793419400681486326681448632668144863E16L, + +8.41693047573682615000553709856035437430786E17L, + -4.03380718540594554130768115942028985507246E19L, + +2.11507486380819916056014539007092198581560E21L, + -1.20866265222965259346027311937082525317819E23L, + +7.50086674607696436685572007575757575757576E24L, + -5.03877810148106891413789303052201257861635E26L, + +3.65287764848181233351104308429711779448622E28L, + -2.84987693024508822262691464329106781609195E30L, + +2.38654274996836276446459819192192149717514E32L, + -2.13999492572253336658107447651910973926742E34L, + +2.05009757234780975699217330956723102516667E36L, + -2.09380059113463784090951852900279701847092E38L, + +2.27526964884635155596492603527692645814700E40L, + -2.62577102862395760473030497361582020814490E42L, + +3.21250821027180325182047923042649852435219E44L, + -4.15982781667947109139170744952623589366896E46L, + +5.69206954820352800238834562191210586444805E48L, + -8.21836294197845756922906534686173330145509E50L, + +1.25029043271669930167323398297028955241772E53L, + -2.00155832332483702749253291988132987687242E55L, + +3.36749829153643742333966769033387530162196E57L, + -5.94709705031354477186604968440515408405791E59L, + +1.10119103236279775595641307904376916046305E62L, + -2.13552595452535011886583850190410656789733E64L, + +4.33288969866411924196166130593792062184514E66L, + -9.18855282416693282262005552155018971389604E68L, + +2.03468967763290744934550279902200200659751E71L, + -4.70038339580357310785752555350060606545967E73L, + +1.13180434454842492706751862577339342678904E76L, + -2.83822495706937069592641563364817647382847E78L, + +7.40642489796788506297508271409209841768797E80L, + -2.00964548027566044834656196727153631868673E83L, + +5.66571700508059414457193460305193569614195E85L, + -1.65845111541362169158237133743199123014950E88L, + +5.03688599504923774192894219151801548124424E90L, + -1.58614682376581863693634015729664387827410E93L, + +5.17567436175456269840732406825071225612408E95L, + -1.74889218402171173396900258776181591451415E98L, + +6.11605199949521852558245252642641677807677E100L, + -2.21227769127078349422883234567129324455732E103L, + +8.27227767987709698542210624599845957312047E105L, + -3.19589251114157095835916343691808148735263E108L, + +1.27500822233877929823100243029266798669572E111L, + -5.25009230867741338994028246245651754469199E113L, + +2.23018178942416252098692981988387281437383E116L, + -9.76845219309552044386335133989802393011669E118L, + +4.40983619784529542722726228748131691918758E121L, + -2.05085708864640888397293377275830154864566E124L, + +9.82144332797912771075729696020975210414919E126L, + -4.84126007982088805087891967099634127611305E129L, + +2.45530888014809826097834674040886903996737E132L, + -1.28069268040847475487825132786017857218118E135L, + +6.86761671046685811921018885984644004360924E137L, + -3.78464685819691046949789954163795568144895E140L, + +2.14261012506652915508713231351482720966602E143L, + -1.24567271371836950070196429616376072194583E146L, + +7.43457875510001525436796683940520613117807E148L, + -4.55357953046417048940633332233212748767721E151L, + +2.86121128168588683453638472510172325229190E154L, + -1.84377235520338697276882026536287854875414E157L, + +1.21811545362210466995013165065995213558174E160L, + -8.24821871853141215484818457296893447301419E162L, + +5.72258779378329433296516498142978615918685E165L, + -4.06685305250591047267679693831158655602196E168L, + +2.95960920646420500628752695815851870426379E171L, + -2.20495225651894575090311752273445984836379E174L, + +1.68125970728895998058311525151360665754464E177L, + -1.31167362135569576486452806355817153004431E180L, + +1.04678940094780380821832853929823089643829E183L, + -8.54328935788337077185982546299082774593270E185L, + +7.12878213224865423522884066771438224721245E188L, + -6.08029314555358993000847118686477458461988E191L, + +5.29967764248499239300942910043247266228490E194L, + -4.71942591687458626443646229013379911103761E197L, + +4.29284137914029810894168296541074669045521E200L, + -3.98767449682322074434477655542938795106651E203L, + +3.78197804193588827138944181161393327898220E206L, + -3.66142336836811912436858082151197348755196E209L, + +3.61760902723728623488554609298914089477541E212L, + -3.64707726451913543621383088655499449048682E215L, + +3.75087554364544090983452410104814189306842E218L, + -3.93458672964390282694891288533713429355657E221L, + +4.20882111481900820046571171111494898242731E224L, + -4.59022962206179186559802940573325591059371E227L, + +5.10317257726295759279198185106496768539760E230L, + -5.78227623036569554015377271242917142512200E233L, + +6.67624821678358810322637794412809363451080E236L, + -7.85353076444504163225916259639312444428230E239L, + +9.41068940670587255245443288258762485293948E242L, + -1.14849338734651839938498599206805592548354E246L, + +1.42729587428487856771416320087122499897180E249L, + -1.80595595869093090142285728117654560926719E252L, + +2.32615353076608052161297985184708876161736E255L, + -3.04957517154995947681942819261542593785327E258L, + +4.06858060764339734424012124124937318633684E261L, + -5.52310313219743616252320044093186392324280E264L, + +7.62772793964343924869949690204961215533859E267L, + -1.07155711196978863132793524001065396932667E271L, + +1.53102008959691884453440916153355334355847E274L, + -2.22448916821798346676602348865048510824835E277L, + +3.28626791906901391668189736436895275365183E280L, + -4.93559289559603449020711938191575963496999E283L, + +7.53495712008325067212266049779283956727824E286L, + -1.16914851545841777278088924731655041783900E290L, + +1.84352614678389394126646201597702232396492E293L, + -2.95368261729680829728014917350525183485207E296L, + +4.80793212775015697668878704043264072227967E299L, + -7.95021250458852528538243631671158693036798E302L, + +1.33527841873546338750122832017820518292039E306L, + #if LDBL_MAX_EXP == 16384 + // Entries 260 - 600 http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C258%2C600%2C2}] + - 2.277640649601959593875058983506938037019e309L, + 3.945184036046326234163525556422667595884e312L, + -6.938525772130602106071724989641405550473e315L, + 1.238896367577564823729057820219210929986e319L, + -2.245542599169309759499987966025604480745e322L, + 4.131213176073842359732511639489669404266e325L, + -7.713581346815269584960928069762882771369e328L, + 1.461536066837669600638613788471335541313e332L, + -2.809904606225532896862935642992712059631e335L, + 5.480957121318876639512096994413992284327e338L, + -1.084573284087686110518125291186079616320e342L, + 2.176980775647663539729165173863716459962e345L, + -4.431998786117553751947439433256752608068e348L, + 9.150625657715535047417756278073770096073e351L, + -1.915867353003157351316577579148683133613e355L, + 4.067256303542212258698836003682016040629e358L, + -8.754223791037736616228150209910348734629e361L, + 1.910173688735533667244373747124109379826e365L, + -4.225001320265091714631115064713174404607e368L, + 9.471959352547827678466770796787503034505e371L, + -2.152149973279986829719817376756088198573e375L, + 4.955485775334221051344839716507812871361e378L, + -1.156225941759134696630956889716381968142e382L, + 2.733406597646137698610991926705098514017e385L, + -6.546868135325176947099912523279938546333e388L, + 1.588524912441221472814692121069821695547e392L, + -3.904354800861715180218598151050191841308e395L, + 9.719938686092045781827273411668132975319e398L, + -2.450763621049522051234479737511375679283e402L, + 6.257892098396815305085674126334317095277e405L, + -1.618113552083806592527989531636955084420e409L, + 4.236528795217618357348618613216833722648e412L, + -1.123047068199051008086174989124136878992e416L, + 3.013971787525654770217283559392286666886e419L, + -8.188437573221553030375681429202969070420e422L, + 2.251910591336716809153958146725775718707e426L, + -6.268411292043789823075314151509139413399e429L, + 1.765990845202322642693572112511312471527e433L, + -5.035154436231331651259071296731160882240e436L, + 1.452779356460483245253765356664402207266e440L, + -4.241490890130137339052414960684151515166e443L, + 1.252966001692427774088293833338841893293e447L, + -3.744830047478272947978103227876747240343e450L, + 1.132315806695710930595876001089232216024e454L, + -3.463510845942701805991786197773934662578e457L, + 1.071643382649675572086865465873916611537e461L, + -3.353824475439933688957233489984711465335e464L, + 1.061594257145875875963152734129803268488e468L, + -3.398420969215528955528654193586189805265e471L, + 1.100192502000434096206138068020551065890e475L, + -3.601686379213993374332690210094863486472e478L, + 1.192235170430164900533187239994513019475e482L, + -3.990342751779668381699052942504119409180e485L, + 1.350281800938769780891258894167663309221e489L, + -4.619325443466054312873093650888507562249e492L, + 1.597522243968586548227514639959727696694e496L, + -5.584753729092155108530929002119620487652e499L, + 1.973443623104646193229794524759543752089e503L, + -7.048295441989615807045620880311201930244e506L, + 2.544236702499719094591873151590280263560e510L, + -9.281551595258615205927443367289948150345e513L, + 3.421757163154453657766296828520235351572e517L, + -1.274733639384538364282697627345068947433e521L, + 4.798524805311016034711205886780460173566e524L, + -1.825116948422858388787806917284878870034e528L, + 7.013667442807288452441777981425055613982e531L, + -2.723003862685989740898815670978399383114e535L, + 1.068014853917260290630122222858884658850e539L, + -4.231650952273697842269381683768681118533e542L, + 1.693650052202594386658903598564772900388e546L, + -6.846944855806453360616258582310883597678e549L, + 2.795809132238082267120232174243715559601e553L, + -1.153012972808983269106716828311318981951e557L, + 4.802368854268746357511997492039592697149e560L, + -2.019995255271910836389761734035403905781e564L, + 8.580207235032617856059250643095019760968e567L, + -3.680247942263468164408192134916355198549e571L, + 1.593924457586765331397457407661306895942e575L, + -6.970267175232643679233530367569943057501e578L, + 3.077528087427698518703282907890556154309e582L, + -1.371846760052887888926055417297342106614e586L, + 6.173627360829553396851763207025505289166e589L, + -2.804703130495506384463249394043486916669e593L, + 1.286250900087150126167490951216207186092e597L, + -5.954394420063617872366818601092036543220e600L, + 2.782297785278756426177542270854984091406e604L, + -1.312214674935307746141207680066262384215e608L, + 6.246299145383554153167974732783934504370e611L, + -3.000812007679574430883792565577444226490e615L, + 1.454904877136007844493861746476079537075e619L, + -7.118558521873800304612781121044077357278e622L, + 3.514739820897817389472822276832677887997e626L, + -1.751137068816377401163011262831890828437e630L, + 8.803498091818800678575314081978951179602e633L, + -4.465612911700593572269200981612564161010e637L, + 2.285494565287530681465757798517033542888e641L, + -1.180145168917737098025683613598595411329e645L, + 6.147941849198393232663105284575149616925e648L, + -3.231069156963603593233679426198974663352e652L, + 1.713042725635435041806895849197608270935e656L, + -9.161761363270648920537613435771882898051e659L, + 4.942675965960539112005679080810117766825e663L, + -2.689684712697383518131267222872386600031e667L, + 1.476320014229917759615308193449511534656e671L, + -8.173037740864781506597184122049453514594e674L, + 4.563462313190521363235182420178784459580e678L, + -2.569790015236158475703055501886439298708e682L, + 1.459410219452119981958355737832022375085e686L, + -8.358304882556983795372406183642486436653e689L, + 4.827305091483557818593092377664570208355e693L, + -2.811394311081493166793414157061950132403e697L, + 1.651026863340675349245561261339568827739e701L, + -9.776578579336866764167878646459810047899e704L, + 5.837207965197521880181236529616560780535e708L, + -3.513938957938032127105389702846371181520e712L, + 2.132747371360190507595748444536911078788e716L, + -1.305047363239192640729466563372665311602e720L, + 8.050825342678337497636292798039996484780e723L, + -5.006884161223862543665524155681082112689e727L, + 3.139016066011452177570812014513491361235e731L, + -1.983829535212711378291469356666001365873e735L, + 1.263822427649676371257598052486237628698e739L, + -8.115678659900522918802121684491754629503e742L, + 5.252995164972075271667364371449050412435e746L, + -3.427038125662404660056511738625477058135e750L, + 2.253446011834352733279946306835940729858e754L, + -1.493407341897034717876962786798831719683e758L, + 9.974681322653365118752729509398728354442e761L, + -6.714230142773850863927710112350816379426e765L, + 4.554668668931723346600337564274944733530e769L, + -3.113635386023220127834102980385275379533e773L, + 2.144945411287666204679363498162954050208e777L, + -1.488982121181387164932397544378555256016e781L, + 1.041537218854627455352298173588983048748e785L, + -7.341073881786613676177562822942175683993e788L, + 5.213524272587199574980117351016322518428e792L, + -3.730592531776514409283897139216167197989e796L, + 2.689592876341877079083449497724049500175e800L, + -1.953643788231947582529884602972233135002e804L, + 1.429691073080500563348668321308878246277e808L, + -1.054059177095488639836063073070536825675e812L, + 7.828919160938693948399336431565350676613e815L, + -5.857884457184396382550955498026762014753e819L, + 4.415401588264172474136969345712659422380e823L, + -3.352573884181287635796498822858109969161e827L, + 2.564210385719224000156548240934108974447e831L, + -1.975534392116037602837941409848663077528e835L, + 1.533062123975940045180943006948008486466e839L, + -1.198306160488763291730059994812781226903e843L, + 9.434034267770711698676321369174735725321e846L, + -7.480619200038505368468483892246806488879e850L, + 5.974161898439971564124576801455052907638e854L, + -4.805125663714699771668630995361572639386e858L, + 3.892332138028039952403812726744593073776e862L, + -3.175276505779699340738548328810180869575e866L, + 2.608608681939322393581069188271626122519e870L, + -2.158148554392732439392868052394994052628e874L, + 1.797993483301448477700600221980862686033e878L, + -1.508407575089108597171576068862286462909e882L, + 1.274273406242459482708930389008701147244e886L, + -1.083950475353171986748233157909397370193e890L, + 9.284292630726328432038470356821265395331e893L, + -8.007012115449516364480417355063446317414e897L, + 6.952871948429568933888979915833266241471e901L, + -6.078828929473797621198666799700739891205e905L, + 5.350908089710964244671334224708057812633e909L, + -4.742168072503284973969982758434401589090e913L, + 4.231149239401967697257534662010605751136e917L, + -3.800684612827828851942743291026898158947e921L, + 3.436984796314246158361599955909956583986e925L, + -3.128930718993658356398482705317381808301e929L, + // + // 602-1300: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C602%2C1300%2C2}] + 2.867524740577223817164663595437919813239e933L, -2.645462974939090580963101220449509725942e937L, 2.456800827789169780295419018499543141869e941L, -2.296690549725790064673528302231294870532e945L, 2.161174697699793265715182091764676666457e949L, -2.047023224586087259305754002882269123194e953L, 1.951604806042481282712736234132803700277e957L, -1.872785206668284042110390583158639495143e961L, 1.808847160923282257302788929692654262867e965L, -1.758427529634609613399327744595257497188e969L, 1.720468488019528147087036246754294757647e973L, -1.694180279355332648057740852839804839425e977L, 1.679013685251183870616469618951463869496e981L, -1.674640861433092946269144173974414945664e985L, 1.680943600147858322148767806987527412112e989L, -1.698008433134805056489370119323402510305e993L, 1.726128304411348354183882648263448448633e997L, -1.765810838736918108045764015629875016219e1001L, 1.817793526882665071123822455897912718293e1005L, -1.883066459765807128944897377914669600374e1009L, 1.962903588035940537938222992228124233567e1013L, -2.058903881920696086033171142046100185783e1017L, 2.173044241735786946064676598703393618281e1021L, -2.307746591425236218893160658331303115253e1025L, 2.465962312241418731528973526597433097256e1029L, -2.651278087802503406316742676403301581549e1033L, 2.868048395658440423778896607880692085708e1037L, -3.121561373094393453726645989392054731637e1041L, 3.418246710091027042099932753084126095820e1045L, -3.765936717592482928796920675282930034018e1049L, 4.174194967165213973474293718362757753877e1053L, -4.654731142471753017867105249805137855862e1057L, 5.221926310090434518253178454907900079787e1061L, -5.893500145664015254409680930288710794031e1065L, 6.691361332576333738130720616841706994101e1069L, -7.642695184575063524608775697714741180954e1073L, 8.781359617440634128952082759434723165820e1077L, -1.014968338800868135594698909567734048618e1082L, 1.180079105471061498849752479044520598414e1086L, -1.380162016721660241308046692646452732446e1090L, 1.623685158291375662775444238282343536948e1094L, -1.921404880943289359290531906131400049399e1098L, 2.287040419533950152851434188305457266969e1102L, -2.738162880206032093123060939173765335255e1106L, 3.297371307848643161532227459901386725801e1110L, -3.993854689967542662299211323085023297602e1114L, 4.865474805885735467044047308902313673643e1118L, -5.961554732739027308247618738765152679497e1122L, 7.346627151757492821447573639763873833441e1126L, -9.105493288459908620636712748727395637965e1130L, 1.135007867626164861991621396462821975167e1135L, -1.422876214067403769204874786137232627418e1139L, 1.793912271573925309173135913914667878908e1143L, -2.274542916104231188526120123855259514144e1147L, 2.900273688809987694128857655036783261991e1151L, -3.719022795563122339874875448447744493398e1155L, 4.795753420982845153626611023078973364321e1159L, -6.218937220186281310109009529226561379773e1163L, 8.109611247999584815668395828940708619394e1167L, -1.063412316303440216539797215354141158589e1172L, 1.402214363674117662460496032135704328989e1176L, -1.859223235464558752766840772026058694872e1180L, 2.478828203789903637835992128856742276028e1184L, -3.323169416193176673655321536761413885767e1188L, 4.479640207312477092938541546776915956580e1192L, -6.071721672924085739424644485636889518799e1196L, 8.274698015123579607850404326757887762270e1200L, -1.133855131459773018024052539697784205966e1205L, 1.562146222050424344025824344480153248984e1209L, -2.163904570724750459592352173471446831752e1213L, 3.013703210722669908901286635073603018696e1217L, -4.219903244242308803914269531001720703294e1221L, 5.940703220571043642186808904696174833998e1225L, -8.408147464216029127243257448169774333631e1229L, 1.196419999747411909144144315499654470715e1234L, -1.711518922741148710381740436694440587059e1238L, 2.461434539630850545757453894977350505251e1242L, -3.558748530932574002484841810677232366801e1246L, 5.172525606281917297657859608800373729529e1250L, -7.557850217376323621984784308774476917753e1254L, 1.110141075986004209769735296234549704181e1259L, -1.639216556732622481406083885926912451281e1263L, 2.433138328152562628385514545400044125983e1267L, -3.630476645219033020888837165221286413171e1271L, 5.445289518636306992942604775585977779418e1275L, -8.209806424989072060381590985042272020067e1279L, 1.244209849774134691374848390346442737613e1284L, -1.895384488692308848372754844910263931874e1288L, 2.902272596647764894203369746806169285113e1292L, -4.466944174025026625137032739317650862593e1296L, 6.910485739507636504313238347702354354916e1300L, -1.074550085668784170644854815272144687769e1305L, 1.679419258904938802199084915274175753529e1309L, -2.638155207645646220849795321076977230763e1313L, 4.165284786632654168563096850610185378233e1317L, -6.609774274649031371770290191295685774584e1321L, 1.054194100570841329575393359295845860860e1326L, -1.689822316104196916970708778265725885275e1330L, 2.722340957904912685605914893019783431164e1334L, -4.407776313964403233676810178851005163725e1338L, 7.172436210641903635864868181569129834361e1342L, -1.172947440100495955246356688225986736990e1347L, 1.927745674072824377954824961348211728006e1351L, -3.184013467435655962214317208087993711563e1355L, 5.285045125125832341263897233405196808096e1359L, -8.815883582819232027207118521581424783107e1363L, 1.477818368424505276711779171224799759099e1368L, -2.489482576496570159333357550363134602876e1372L, 4.214292881345076419678976329218843808204e1376L, -7.169068531615459070909644981451297906220e1380L, 1.225513133750594558180516896275774441895e1385L, -2.105160827387119480607950260289853896637e1389L, 3.633787605672960549893307203363402915249e1393L, -6.302830804027849515239463308430185990705e1397L, 1.098521433860299633481449685364914115468e1402L, -1.923858597401607622723144320370279518600e1406L, 3.385512828549942051667348582951554570164e1410L, -5.986286250836771248147827011780631183980e1414L, 1.063572794668186370728928272374836554300e1419L, -1.898666684876492795233907174493757572290e1423L, 3.405627002840442789235393111726609930533e1427L, -6.137724140284450036591063946055819333244e1431L, 1.111411024660941507986132154479364267486e1436L, -2.022060876221034821890406900217875915949e1440L, 3.696248025817144690840539132103538834108e1444L, -6.788448439024998306316860676030442691610e1448L, 1.252615233049059554031883468823648511657e1453L, -2.322190433141265975888955985950824418729e1457L, 4.325200102353909846882217732999001735342e1461L, -8.093531903011880118699218269369570178812e1465L, 1.521558881878323790120983450270946857209e1470L, -2.873780311010933807686415826253380907421e1474L, 5.452903697278823304173192839252276211670e1478L, -1.039457922537509500320638240809547113575e1483L, 1.990610112724715126895008793014214505760e1487L, -3.829667853173777076954453401761025071562e1491L, 7.401624504283011888971231756333356050310e1495L, -1.437075122764477911733220492562365990710e1500L, 2.802940275035867428066581228962104019228e1504L, -5.491938363067613321364335249495394164430e1508L, 1.080961960603953462180593404647115933651e1513L, -2.137290931892412298654741768897581319007e1517L, 4.245031321673807283498263276791307370788e1521L, -8.469499523038763989328773224520912663309e1525L, 1.697421812794203793865032206191322699261e1530L, -3.417217332563937242285349373774004020539e1534L, 6.910378594841763785923780822895851271770e1538L, -1.403696282437585785557998429691459557649e1543L, 2.864060533055333035232343601021192111053e1547L, -5.869818290384811353182423286543086530728e1551L, 1.208359745327224593486268988808338456906e1556L, -2.498576742140453770373914215325521001990e1560L, 5.189311407347546310078739863704346083861e1564L, -1.082537954843916294257278789980768336964e1569L, 2.268238255751421312559806122980932952706e1573L, -4.773557403917983369065731568732198697502e1577L, 1.009019097334998841920279535262007639746e1582L, -2.142181266523235177327239693359275472557e1586L, 4.567814904130855969979178320003286614868e1590L, -9.782550516204803195398428611221899469345e1594L, 2.104180123097086948576304557651398411373e1599L, -4.545658958087323864004652894518442709646e1603L, 9.862563944609427542603740078470901803131e1607L, -2.149105846582226970866569209122813809019e1612L, 4.703235567543888152049628411354542509156e1616L, -1.033719212601584878353206879472796545848e1621L, 2.281767401903848796732740825793310514456e1625L, -5.058236070813950229238666252351966279306e1629L, 1.126112519657857205642546937554224492775e1634L, -2.517766761987679577706779689880657777343e1638L, 5.653225190181653388317503182908983211029e1642L, -1.274735955461074142223278576503188429497e1647L, 2.886578974679460464298863945016671299242e1651L, -6.564203307141426181809363135003467581753e1655L, 1.499036144473064593308260681782048262301e1660L, -3.437714715599902386917108442954580869236e1664L, 7.916830957072777234152907034541325149479e1668L, -1.830850567422571420661248197094782575285e1673L, 4.251778280827419894527511469762091846660e1677L, -9.915182507286989818033146623995507108134e1681L, 2.321878208636697663781227497233334385222e1686L, -5.459879022461660582811365437190884471726e1690L, 1.289222044549922720398543474297554204559e1695L, -3.056819658344217799458557578658863826289e1699L, 7.277891759142725294172926258364455941365e1703L, -1.739928293433385104144012025546489673795e1708L, 4.176797408823713136137404972612780406904e1712L, -1.006788178307821554781930741698052910780e1717L, 2.436754569909644399766538111317379484511e1721L, -5.921896599028498715774458493117079340155e1725L, 1.445045688171565118619109316933316429671e1730L, -3.540547766876069233350621578795319652040e1734L, 8.710114552028472554054293344204504325978e1738L, -2.151484527880464463303897113553085899101e1743L, 5.335928195512405709733771642389502809087e1747L, -1.328726408335015910030370523083559660016e1752L, 3.322090527232917400247098823651437597786e1756L, -8.339387326241218096865362177688582376376e1760L, 2.101842203781264395369771906884644062395e1765L, -5.318704469415522036482913743767085545209e1769L, 1.351288005941730688647540059088127991581e1774L, -3.446853546858473171100748720136784228698e1778L, 8.827284762030783576089954173424852998700e1782L, -2.269642226090373319660782216907175419317e1787L, 5.858820683661708553422363777419430816755e1791L, -1.518385813684321665045387969920683656625e1796L, 3.950661327164595923092260035122668890334e1800L, -1.031976516347387969958181456058243183780e1805L, 2.706317892325103782207094286049104555552e1809L, -7.125140422584701175967252533378906957380e1813L, 1.883260203116768075569432925204868418472e1818L, -4.997193687108743666000994570700725873035e1822L, 1.331182722092654526185433799891693838871e1827L, -3.559930289076558484535632566755216035553e1831L, 9.557281027056970446117541983785660301558e1835L, -2.575805002229372523547972911961335317502e1840L, 6.969058431277067406841032797913179025984e1844L, -1.892842481279278678390672746902260183506e1849L, 5.160964211693777744707760614147460787285e1853L, -1.412602588198037643242529860614298968137e1858L, 3.881313379962387603749693387037174052146e1862L, -1.070542170988009009334148472388319844527e1867L, 2.964094312414144330805731101996829908435e1871L, -8.238350132106899955856124602934281976453e1875L, 2.298504171050560756192352106062598639825e1880L, -6.437303944649223478093890316531995121228e1884L, 1.809727811843121957353712606428292269805e1889L, -5.107047553992257935533518628886728031061e1893L, 1.446674478990385642488446075734631327506e1898L, -4.113513327511444762766719175770513771122e1902L, 1.174067517257431444028448391638451935667e1907L, -3.363630086409895071362533854123306097827e1911L, 9.672868956071838221096869293070568259792e1915L, -2.792101741911955365960369780457612630184e1920L, 8.089710604557382430162031502761771390568e1924L, -2.352650988877130983061761312962677887796e1929L, 6.867549079740051556501575104006222995568e1933L, -2.012161201632998475706904405535757516336e1938L, 5.917489529279588702317256137229398357271e1942L, -1.746718667239329545125902248821502764273e1947L, 5.175069416058975040990816515838893249437e1951L, -1.538913401594651457295303469904084052963e1956L, 4.593185746210984655636051293374195150815e1960L, -1.375981868450401919299150690829612124045e1965L, 4.137207965217520410530508053863759216958e1969L, -1.248518564582257710069294326648626362439e1974L, 3.781575291117895093413381897917341286951e1978L, -1.149575999691408110085856948595444100435e1983L, 3.507413095836612229403470531176947165451e1987L, -1.074032838410645352804690949680310176413e1992L, 3.300857202456564870338466973024760446263e1996L, -1.018149578840803516349758843017979498322e2001L, 3.151876950233613792531594490714752800621e2005L, -9.792574827376149360558532022944033224780e2009L, 3.053456145978161645823454710737904504036e2014L, -9.555442346102849014299990542596620094035e2018L, 3.001037449298122384017009412541525703002e2023L, -9.459120112371096268275049056229023773120e2027L, 2.992168042152196502453442556462819104060e2032L, -9.498922680869041470681858599915282791899e2036L, 3.026307717971075309746179763189393755074e2041L, -9.676079238806159594565350708123427510151e2045L, 3.104778286352798464772361361434013339088e2050L, -9.997786802782252742109475924344598057966e2054L, 3.230847952724856366943939804248186203776e2059L, -1.047769651900498931701604323213605884945e2064L, 3.409958102134053489747140426163802214042e2068L, -1.113687894644055086152064258459886518528e2073L, 3.650114509271160332136458711252217684956e2077L, -1.200536387553969483433239131469825141412e2082L, 3.962482337718333099498977337189304099484e2086L, -1.312441206957064803437100929905979391106e2091L, 4.362246723746013772563799740886664288515e2095L, -1.454975881895253548422481637083633839534e2100L, 4.869831412214692119172895822285084162147e2104L, -1.635618419512383251104125916207188960680e2109L, 5.512611314145041257838234038980389596534e2113L, -1.864392957231340288547618808749072127289e2118L, 6.327317613106621547060670091824665547127e2122L, -2.154772001506498703267302897994526372056e2127L, 7.363426139490286496267931634843475368903e2131L, -2.524950643808031915843604894357998905460e2136L, 8.687956390288096215918373666581638675156e2140L, -2.999656978200020459428228924242615592768e2145L, 1.039231328851609224822335039430898644149e2150L, -3.612742437616019936358910410005123924796e2154L, 1.260211309932738404790711574105022002093e2159L, -4.410916378453971105434385837025433805752e2163L, 1.549140617923265948720013792673729394719e2168L, -5.459173749226782924959103886664322964926e2172L, 1.930343307630952098252884031069043541182e2177L, -6.848749229218425353808144618581305978045e2181L, 2.438117138001365487681440577590059588102e2186L, -8.708873656769794358508423272379627581292e2190L, 3.121268068338199458891764932384819739714e2195L, -1.122430216307539309816165910733145404999e2200L, 4.049900779207199370582177687160985635615e2204L, -1.466167983141158219266077836130256565915e2209L, 5.325678718693772500250292767751070974887e2213L, -1.940955845102272053048140384364058448998e2218L, 7.097467198361219669927211698104447309186e2222L, -2.603968771680987683436428778397387110896e2227L, 9.585403285394812946713320044815117440444e2231L, -3.540176030547640510648455468270569908446e2236L, 1.311827683984025111744358347783996339730e2241L, -4.877124229155333857009747836542843294702e2245L, 1.819213075760490882591173222316749809951e2250L, -6.808221630329265915405178596748950929642e2254L, 2.556299969544109052724772800143396857058e2259L, -9.629763347675306704861859899230073979116e2263L, 3.639508580119285595844040783082958425575e2268L, -1.380037493555816309137481185927387732499e2273L, 5.249980712165216709135893538080020409581e2277L, -2.003737844109055078145975651407367170529e2282L, 7.672522280806944397358668566379646540213e2286L, -2.947454993639165318799389781921184991045e2291L, 1.135966912801707623489383623092951142963e2296L, -4.392293711194501621873299212059053651432e2300L, 1.703813210168560937608104155973968112409e2305L, -6.630636743874062041158387022015853902938e2309L, 2.588742636486379690203698247275411406029e2314L, -1.013959594068423546627946242481463893979e2319L, 3.984265821528043268586235974854766821078e2323L, -1.570614519682157047612769672066387881154e2328L, 6.211297381339606877062824459742129064477e2332L, -2.464246931985476159686671650962783785426e2337L, 9.807833742601662212615240518855757197483e2341L, -3.916036434571217691317276306031837539092e2346L, 1.568566392975837368624727722120313955274e2351L, -6.302885887601142677858008037129298948063e2355L, 2.540704455306077495480843691828334210014e2360L, -1.027412480318234348899627142408950111875e2365L, 4.167823618450297116765978030480648316769e2369L, -1.696076602731914277275203926124423530377e2374L, 6.923904505633301788461482786634220738504e2378L, -2.835463065742506394026733592206185459035e2383L, 1.164828772275756526225951620927486307632e2388L, -4.800242878545012539781545966693324656699e2392L, 1.984381759611877246529319121941597679107e2397L, -8.228979942542641498511023600269641046627e2401L, 3.423130231367101727862739208673375060101e2406L, -1.428418168129733054582191895023094524495e2411L, 5.979153801634459282232521647160044877770e2415L, -2.510581926948409809562349588087762800160e2420L, 1.057443785053915411991029410076722022815e2425L, -4.467723713549428749678277264414266162837e2429L, 1.893474116528533144079731251913008472748e2434L, -8.049601965052954947260081891142509464888e2438L, 3.432648527503971149009691133946275281368e2443L, -1.468324699963694393989960228042259134294e2448L, + // + // 1302-1600: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1302%2C1600%2C2}] + 6.300146502435743791500010801885493871234e2452L, -2.711520667146768856688291798851999580833e2457L, 1.170595555513900137297344452318266434006e2462L, -5.069095411973246242900074508988493530542e2466L, 2.201819284807954055092117706033113168896e2471L, -9.593088725189386197503123561368325167085e2475L, 4.192362385909155628936230811010649614060e2480L, -1.837725836941968309866675158105812946762e2485L, 8.080201101491972605313807752565294881374e2489L, -3.563536075527215702966392543784039539240e2494L, 1.576361051321107275181955665159661781175e2499L, -6.994292466180175594372663323941761853364e2503L, 3.112744353537336702834647901141392426258e2508L, -1.389481328370627358752727485697345194612e2513L, 6.221134636655213696041740685131223999953e2517L, -2.793779613656947577224654924852010601105e2522L, 1.258399062987759035354039924686781081603e2527L, -5.685208194704131918461885165870560583895e2531L, 2.576167857759537340210434756292816456179e2536L, -1.170846052338591953257169251219597581763e2541L, 5.337296787116189575571202979672747140313e2545L, -2.440264475369219459038748840841422948951e2550L, 1.119037151526195093932933161706501865175e2555L, -5.146858829220973887154576240993607686435e2559L, 2.374259791963193693837576781321391741634e2564L, -1.098501215269400934956638118646657823799e2569L, 5.097500369683616795005376807036889542869e2573L, -2.372446971688020647583535886090779018865e2578L, 1.107430282014636546248612381377039463753e2583L, -5.184597227131050012643138079903381280471e2587L, 2.434392040100910394476893838832599310265e2592L, -1.146412753331162872665743308094817095949e2597L, 5.414578104816988124950636101250217797539e2601L, -2.564835392810685332173156758121489913946e2606L, 1.218495070518549208066544111736985586178e2611L, -5.805713573821806672815019495319510297824e2615L, 2.774298194574319430697819781128985128618e2620L, -1.329580186505564627453485444017911980430e2625L, 6.390545858902318479863947547243743500916e2629L, -3.080502542499571035376377703435361520427e2634L, 1.489236104239976282318361008292980814533e2639L, -7.220413839991892382038608955317126799684e2643L, 3.510874916591640642524021216241607185085e2648L, -1.712070118580404599831061485055269100525e2653L, 8.372956919832386730490070625622785478703e2657L, -4.106629146981883685523102256292669054596e2662L, 2.019945438530802964718619732330776495740e2667L, -9.964133277392242111939720494354938982970e2671L, 4.929278642971447854669801547226335041410e2676L, -2.445509657169810919463982615395074704130e2681L, 1.216734421265677299127016883839223226884e2686L, -6.071008437677720186241562251151490713584e2690L, 3.037824949882992896564570441252792097027e2695L, -1.524402878612630565501569310883356490225e2700L, 7.671320530781999359200097739951316234193e2704L, -3.871436167706734376478728954716915204399e2709L, 1.959313530432202158587932399068682252335e2714L, -9.944063618400630821320953821427307024297e2718L, 5.061161998202463346818982228476199873781e2723L, -2.583219090831132705328958245740715185448e2728L, 1.322193991367293532684189527174543501836e2733L, -6.786569982732483290873213417465458376706e2737L, 3.493212334804776543395067018414547811062e2742L, -1.803090099978261928508495412750404640933e2747L, 9.333100843930216567894508007158644926767e2751L, -4.844499031405982604449146511179496492045e2756L, 2.521648090959971240812330574936006906830e2761L, -1.316227870932708474838173333385377250286e2766L, 6.889488826832738674261056521130795910494e2770L, -3.616184242864384509259984293501533623932e2775L, 1.903356124758119137116543283603627028779e2780L, -1.004601544584640657081847200643996069583e2785L, 5.317043885597842225603585588404817559596e2789L, -2.821938866752488868682751438901900485500e2794L, 1.501842023003449590337997900945924161741e2799L, -8.014908048137216649348740300633172710524e2803L, 4.289126235121619907138036129192558937445e2808L, -2.301619137231461344870820700320913118444e2813L, 1.238485136850053215006962645111854705210e2818L, -6.682503731149007943059244518074044280490e2822L, 3.615572393938012932030234169574978859655e2827L, -1.961565108627429629104703146282982075623e2832L, 1.067123259692924564435881096382837264046e2837L, -5.821179870182035246401397327057170726418e2841L, 3.184127229476322727732208017279268211356e2846L, -1.746429902183019597973436257300843998825e2851L, 9.604873565299766333876882842813498685054e2855L, -5.296759978724702692134960752308186890356e2860L, 2.928906353338652198977536576170287112391e2865L, -1.623961162577704769945821804737884742792e2870L, 9.028574047002736235613238355032484299017e2874L, -5.033087486357905828950503441308068892610e2879L, 2.813325650062267479031371852434194635210e2884L, -1.576791132296320840138263753339056345362e2889L, 8.861258343945925667272164531504265693289e2893L, -4.993236404321511029440212686547068244002e2898L, 2.821192993950901287717082243608730217471e2903L, -1.598254169674379493385730199445427966752e2908L, 9.078617590346932363947095804057608979359e2912L, -5.170742114456472142154347566092068443393e2917L, 2.952866185102528847516095880416675972086e2922L, -1.690794578626103552690094140317813413244e2927L, 9.707168799669516048238542260085175133847e2931L, -5.587884732306715493795271931175883605707e2936L, 3.225179489154957423492905957887744116530e2941L, -1.866424419669188178697802576490431604300e2946L, 1.082967626854618222657109354056973072044e2951L, -6.300392007169862865282706277272018077291e2955L, 3.675066377245428685118763485986517510658e2960L, -2.149348371085132073107516253339849053182e2965L, 1.260349351812619395000600434630904474324e2970L, -7.409963623771231302980906971935254993610e2974L, 4.367980758467862686643231700861155889684e2979L, -2.581566823350789671250829457603555544100e2984L, 1.529757357568342629912560827243282062227e2989L, -9.088595394263364554625061567617375176719e2993L, 5.413829169254585648363594604231030415354e2998L, -3.233288119606092759447005827969216281573e3003L, 1.936042437734875803183915765854038424658e3008L, -1.162289934202291715747729318797398221667e3013L, 6.995870350500567071550614251287615697508e3017L, -4.221776496490106417392945233048068288503e3022L, 2.554309239868912570382343877718991746122e3027L, -1.549440871550119801225143558087410562418e3032L, 9.423199525954784955533959981278992475051e3036L, -5.745689660772387668861183913170050552119e3041L, 3.512407521007240798565045328376471603253e3046L, -2.152708113797517364614914569890010876143e3051L, 1.322761289733739440340237168659770154654e3056L, -8.148777388506488753591136948542248584098e3060L, 5.032880858479326069741729004270784264612e3065L, -3.116396010103058126269735274818345780360e3070L, 1.934634831148214353514796782480703021435e3075L, -1.204077166243116651938489240924641810276e3080L, 7.513065583444964704795707060501161621868e3084L, -4.699873512563164914493150520500838535415e3089L, 2.947541197349762411713872934523813866703e3094L, -1.853262416286420077763886100673646141885e3099L, 1.168196427912100545575264493997591040800e3104L, -7.382362285873345348505276546404015842875e3108L, 4.677071041058096429847797962954927487730e3113L, -2.970642034084362431442183248944824506476e3118L, 1.891572688282564476274920103912259755482e3123L, -1.207509963440193713810418554061532113326e3128L, 7.727731208240101791845515599659441557781e3132L, -4.957988488048495669466804712012179891532e3137L, 3.188965862446236259925047956715566822864e3142L, -2.056286895821370106507670239256782411337e3147L, 1.329246918771714093479509313343886287414e3152L, -8.614188519577835653765633797787633659253e3156L, + // + // 1602-1900: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1602%2C1900%2C2}] + 5.596396533621874175909933615343145642161e3161L, -3.644908483469388437457938883454376864180e3166L, 2.379838409026860469990569665632800095988e3171L, -1.557720925267669865362152155022069166772e3176L, 1.022143420270029721682551084917730373739e3181L, -6.723767358891570842116651998814252095792e3185L, 4.433950491570308179905446963723780229747e3190L, -2.931196854668917448553150023532223509373e3195L, 1.942557068752664549549945921392100172355e3200L, -1.290553202978622786891265558106235068695e3205L, 8.595082329732118303768775883557789195136e3209L, -5.738453265222970049867280061719670658457e3214L, 3.840687915100689856736926915331157331684e3219L, -2.576862441955523551149886625900059307506e3224L, 1.733166107320377310388765047659987844208e3229L, -1.168569552450178559412843683052610870569e3234L, 7.898289836694980777809433306209459851871e3238L, -5.351485909164216694400535493924387979018e3243L, 3.634772439350395177931952925644409735777e3248L, -2.474801048002975145046569303233576339695e3253L, 1.689126939254790850063878942448569759390e3258L, -1.155691524500722774057997965355407962525e3263L, 7.926435404542361405718288670391575676323e3267L, -5.449654814183048796524718620178906854846e3272L, 3.755898589900254795894812942275711835138e3277L, -2.594843902682143854622514329649211211808e3282L, 1.797048752397789969347915328338360264536e3287L, -1.247551415074438712713815166107969504456e3292L, 8.681719521514448143910215886388510318746e3296L, -6.056203898213120922016159444227958572276e3301L, 4.234882876331814099029781995617143573641e3306L, -2.968432911643338866295929748049749932906e3311L, 2.085723508930484816454740610260790948864e3316L, -1.469023169879432026361623513301566735138e3321L, 1.037150346505052892302077637883522696572e3326L, -7.339977067836656769144838365069396168014e3330L, 5.206985412168234130596004552956337839140e3335L, -3.702673773319239583641029108403509825141e3340L, 2.639251227995760315076225206168354089692e3345L, -1.885736353072698581595150856674914203383e3350L, 1.350563292338261784288559687678302458996e3355L, -9.695749980998301526113046898985991802000e3359L, 6.977167462628398202151721319169989304520e3364L, -5.032768280399753942925624560483352299263e3369L, 3.638844963651800168080623511900705036698e3374L, -2.637228631269251606169613775399022890118e3379L, 1.915836351653767108720464847696767898597e3384L, -1.395064293615007319328267865803567670760e3389L, 1.018249052614943190644465556486933211307e3394L, -7.449662162606857550867922631658930320805e3398L, 5.463119632208085241594107781601567713991e3403L, -4.015736541676989144201935890497836963875e3408L, 2.958754190183866660901503059509579790900e3413L, -2.185096074054288399312733179064098492511e3418L, 1.617517444557020250864919655301189186103e3423L, -1.200170662015511746748935675940010250555e3428L, 8.925888349899029449015791684428724952411e3432L, -6.653851763691885517669938275618991145962e3437L, 4.971722031098457895973348076474071155918e3442L, -3.723500582577984967442020337848702786829e3447L, 2.795153783541721373364976034391375710110e3452L, -2.103141577212720698169118819883801186873e3457L, 1.586129575320959267959148073466004084241e3462L, -1.198988457279648730711646682156242973137e3467L, 9.084402368157025658430300252246526602197e3471L, -6.898927494435965163817354296023108913714e3476L, 5.251332286149361587885046891266325872375e3481L, -4.006442950956739933884502808470603581850e3486L, 3.063718202820270282280659950794978994604e3491L, -2.348215284130973783732145823834807395920e3496L, 1.803952490148087317330011096671019781340e3501L, -1.389022326803437345760911068933754707688e3506L, 1.071986115818329525986099441493200866389e3511L, -8.292085224650940719705699485423856363908e3515L, 6.428829064452939640541475198655560890344e3520L, -4.995654440302797445368056643032307686314e3525L, 3.890847042582299188849273838681034339406e3530L, -3.037288555751484681537442833929275697351e3535L, 2.376385803695694695338601696534348875191e3540L, -1.863527130251861900692886008704804849076e3545L, 1.464674913498036269270793715104706378182e3550L, -1.153804954579033578659954846698233083197e3555L, 9.109783835348935092264268296199541780964e3559L, -7.208869193983001804305451104827153729326e3564L, 5.717530734277611949162917337810749919265e3569L, -4.544970302634007326980094771330550661605e3574L, 3.621042850825283032134228901678636353355e3579L, -2.891447067949778492831490654980043715471e3584L, 2.314060419397710657435821461707043283167e3589L, -1.856140759923563235273220981623595304434e3594L, 1.492185412981476596273279338314204171587e3599L, -1.202290032627175365810126250991853594801e3604L, 9.708881154579770196658265042625239421053e3608L, -7.857809850747029705680072304049448493252e3613L, 6.373898598298513400228819113197728735438e3618L, -5.181780406472117449048907989647202286666e3623L, 4.222036621953044040518942750638183171221e3628L, -3.447728386429130175025813550845575613047e3633L, 2.821701521717856346224159586852612710800e3638L, -2.314488376711998526455043944505424906920e3643L, 1.902671298033180765286213227393060711096e3648L, -1.567603736821312488140289549008391847440e3653L, 1.294408945316538946551785312385509945367e3658L, -1.071194533081615830960091702262923009420e3663L, 8.884351908108581551151252566466606126397e3667L, -7.384866682828103669170236267589653324531e3672L, 6.152023838008155718180876735217718355563e3677L, -5.136304310431705506236573876510219357975e3682L, 4.297736808124296434723193397876220759378e3687L, -3.603994887745884762510172194982172483480e3692L, 3.028884745605031552399167746007361297342e3697L, -2.551141302205187365552982635794121855138e3702L, 2.153467982869535549299173317536193051608e3707L, -1.821769476343602094059466497311600827296e3712L, 1.544537580582347892980177956984101211006e3717L, -1.312358705945937257247030754517293537539e3722L, 1.117518229297781388884979995402355617235e3727L, -9.536820860779441793021624381677086661097e3731L, 8.156400668831968026931547065507466530546e3736L, -6.990984948728184142718575396052260691181e3741L, 6.005124901126818071638224144541102727563e3746L, -5.169500241880947716732682089328427995109e3751L, 4.459815478235310026240134567325749844182e3756L, -3.855902253361684187081283218890336962427e3761L, 3.340988024176995223515640815937037040546e3766L, -2.901099226680215736735094376078800376829e3771L, 2.524573363444334459448089563912567842927e3776L, -2.201659455716348555524529213295341212492e3781L, 1.924190302190936448078364755844591374353e3786L, -1.685313186099770223843319514432495898517e3791L, 1.479268235966730475749985741048766689808e3796L, -1.301205702893883803117530921635013780575e3801L, 1.147035071153450453405384269242743907426e3806L, -1.013300250456366849150496776951686112298e3811L, 8.970761720605591762300958007557533865346e3815L, -7.958829781488943084496783248922217392838e3820L, 7.076146954685024795720193943027902028642e3825L, -6.304798526260409199660290516451546966159e3830L, 5.629519616664188107056583939722984509867e3835L, -5.037281594099054092767959480843344929292e3840L, 4.516946091316834843581919268794683123349e3845L, -4.058975118925834202620358386772092359951e3850L, 3.655187798978978909014603682039470653549e3855L, -3.298555903041546671060101785513812175322e3860L, 2.983031738662727912016882399515879119620e3865L, -2.703403043317732979516341931451317866898e3870L, 2.455170460800096241793872443768546335444e3875L, -2.234443928432490538417605502448376856290e3880L, 2.037854924078003280537856980560782325730e3885L, -1.862482033918775734840779765743099458137e3890L, + // + // 1902-2200: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1902%2C2200%2C2}] + 1.705787724951999960095629912416210969679e3895L, -1.565564556110550991891247404758895970376e3900L, 1.439889351869832939488618785632174464789e3905L, -1.327084102784257406218693901793045990520e3910L, 1.225682557296027075027021534960026145706e3915L, -1.134401635488994148555787301654561211982e3920L, 1.052116934052356802920509999705307165985e3925L, -9.778417073593082219082361206542342793584e3929L, 9.107088061888562704837019028349522303725e3934L, -8.499551364633102138471246155980056936129e3939L, 7.949082681085658044610890152056533167407e3944L, -7.449748809722797718736397140511396011691e3949L, 6.996307824769340144608141799981589288378e3954L, -6.584122718472954006131003060359621706243e3959L, 6.209086595833487707192492087176843233407e3964L, -5.867557793863165391821489909125720982339e3969L, 5.556303538475260373917478405626416604297e3974L, -5.272450955936249442242634142613834212778e3979L, 5.013444428433789818228792126117223030641e3984L, -4.777008429684552423800736200488532033034e3989L, 4.561115100786341787876705283291018781137e3994L, -4.363955932181992701667719449097126840439e3999L, 4.183917007557000586305945495258591147615e4004L, -4.019557342177353010692923286760895584096e4009L, 3.869589913635745758786275231296652917580e4014L, -3.732865038934070181861017140563175000872e4019L, 3.608355799736107390800162778737339576843e4024L, -3.495145258697474565347261083975193776541e4029L, 3.392415245050326563747729613872524362741e4034L, -3.299436517958948801426629481782413630714e4039L, 3.215560142306355508598119430378551642857e4044L, -3.140209934146377815556058799557727461298e4049L, 3.072875852591406752692761744649563131272e4054L, -3.013108231854799187724018548255922550991e4059L, 2.960512761914376268185064129600549308882e4064L, -2.914746139139036596123006476633770383901e4069L, 2.875512319506974985103149834921665445532e4074L, -2.842559316984704569380036093537576068104e4079L, 2.815676498441436148701483904115879856704e4084L, -2.794692334326268275058539147656334465534e4089L, 2.779472571396106785963004020814493340829e4094L, -2.769918800191406321625251621260024635680e4099L, 2.765967395840433013288935879837390099329e4104L, -2.767588816244119880300161388073836623878e4109L, 2.774787246856347651152278076466043136230e4114L, -2.787600586224957950622601135620189837948e4119L, 2.806100771288225169339048358106052817280e4124L, -2.830394446218080573456394167711739786431e4129L, 2.860623983452244712039094143642843717029e4134L, -2.896968870550611723525738907034588104300e4139L, 2.939647481737606306044335918078617963078e4144L, -2.988919258547518526076380181812161398808e4149L, 3.045087329976721023952450383837883029431e4154L, -3.108501609077197464748958150625867523408e4159L, 3.179562410123820875787052833975010965963e4164L, -3.258724638491880104953913719767939138170e4169L, 3.346502614347964869115073881474258766546e4174L, -3.443475601364631413158991572423086599816e4179L, 3.550294123121350747300886840907918182129e4184L, -3.667687162886053419715985091863398517145e4189L, 3.796470357354794420044278000297864085607e4194L, -3.937555311976846882455930574021795626971e4199L, 4.091960185075595842547638450930710467324e4204L, -4.260821710519620959138720129506770036460e4209L, 4.445408854703156440576808070360934740837e4214L, -4.647138333645908068599900650548418672065e4219L, 4.867592250805288922190809906525766574205e4224L, -5.108538156515551259475573296900660666192e4229L, 5.371951876776035157276013631113314852508e4234L, -5.660043513521220243900043448456234873940e4239L, 5.975287081834808618140945840817834710330e4244L, -6.320454323372684034118816565375206053746e4249L, 6.698653321371992324876559665938996023646e4254L, -7.113372643219128807424340495235606473967e4259L, 7.568531854202750881338746432078817214052e4264L, -8.068539383842553693076672384509126681464e4269L, 8.618358887685935324188596304168259394311e4274L, -9.223585437012291673660319256730398171887e4279L, 9.890533091606747031464718533600572123091e4284L, -1.062633567277107015128545384570274268438e4290L, 1.143906286231591191271274413511275981288e4295L, -1.233785411712565904499340744089870916842e4300L, 1.333307331840530219050170916015276125870e4305L, -1.443648758235403286296065629219598769529e4310L, 1.566147425967471851736562867318748510088e4315L, -1.702326086290842780634120184324081017286e4320L, 1.853920350455786350409148418966087344063e4325L, -2.022911043115598592197907512410632615740e4330L, 2.211561842992792253055716743938240466613e4335L, -2.422463130294011318178080247305407476096e4340L, 2.658583129381772791030436640519847627789e4345L, -2.923327636881988941081365085520742216540e4350L, 3.220609866329557159104267531058019683271e4355L, -3.554932228621330128152149026066400241546e4360L, 3.931482212643167323798366327390058684499e4365L, -4.356244944221399578650235478583297389113e4370L, 4.836135498303121165971331625888490168138e4375L, -5.379154636371461359750682662639062606297e4380L, 5.994572359716861309678596804350346692501e4385L, -6.693144535124290060793936095397161934045e4390L, 7.487368894313509797084395689517008597061e4395L, -8.391787970609807810531578161564037339793e4400L, 9.423348062978921203475110312003096820035e4405L, -1.060182516651648405903017734022504884319e4411L, 1.195033105063952979885086754342706651656e4416L, -1.349591538868673992167798923586925758429e4421L, 1.527028315253291113905307092657539132480e4426L, -1.731065051510920640409442255224015234974e4431L, 1.966076741510092840076264635935585216200e4436L, -2.237214093245750681191361238831105906202e4441L, 2.550550094903891445719729187215253324232e4446L, -2.913255853313667303707651906277658164129e4451L, 3.333811847072394764285817140850092324169e4456L, -3.822262084288044913490118858492563410392e4461L, 4.390520310533864198186202368026630430120e4466L, -5.052739449335052080092114976206610871466e4471L, 5.825757966350870043117899492954521458799e4476L, -6.729639942938203582008846884575881320532e4481L, 7.788329466816396015493306357116312471970e4486L, -9.030444674469025073047417528762134025409e4491L, 1.049024263381993629167658236142000524752e4497L, -1.220879351508964912255081664072251573277e4502L, 1.423541151220109512749655991050110438471e4507L, -1.662940118618541616964708044356967429362e4512L, 1.946219185900482116137855064775635250366e4517L, -2.281995008842006909631764011781911322493e4522L, 2.680678198213108543648324254258111216040e4527L, -3.154866427472784086389609599207759103500e4532L, 3.719827710160801797530420206201570269720e4537L, -4.394095404360277919140027580071549980218e4542L, 5.200201854779615608741690339830306148442e4547L, -6.165584312943608652377791415603277251516e4552L, 7.323705248531382981433751104158852636445e4557L, -8.715439846124090647163930834760361817820e4562L, 1.039079696609215651011736087603304766850e4568L, -1.241105689556982425619608247473478857800e4573L, 1.485143079696380339521658550262280772546e4578L, -1.780437412164973637340821168154300094802e4583L, 2.138372099157518882088209435171770222745e4588L, -2.572985071149069551034276570909360759588e4593L, 3.101615379617643734762997559011097203354e4598L, -3.745713657616368229906151946770042703357e4603L, 4.531859496161940719835150033082561700677e4608L, -5.493040495326927998321538336584233566465e4613L, 6.670262730603009306595018122252730741798e4618L, -8.114581584793494903775255213273982440688e4623L, 9.889666561810883044159054730371102725871e4628L, -1.207504541653929734716275932570097623330e4634L, 1.477021377885843688233899471354959308782e4639L, -1.809984912147908767583043524070645821179e4644L, + // + // 2202-2320: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C2202%2C2320%2C2}] + 2.222043594325228980916360265527780300093e4649L, -2.732869701246338361699515268224049951411e4654L, 3.367233945421922463553518272642397177145e4659L, -4.156377225041273602431272489314020150392e4664L, 5.139764368092890466235162431795350591151e4669L, -6.367329693760865476879589228002216011370e4674L, 7.902356742934106007362514378717026407839e4679L, -9.825176966314431712897976595483070301406e4684L, 1.223792760178593282435724837135946867088e4690L, -1.527068151452750404853140815207477555192e4695L, 1.908935682572268829496101580401263597905e4700L, -2.390593888616966248780378941331847473699e4705L, 2.999171106576893833644521002894489856321e4710L, -3.769440655453736670024798444784356437578e4715L, 4.746047769851891438576002047529258107351e4720L, -5.986405469241447720766576164546767533359e4725L, 7.564466155536872051712519119999711534616e4730L, -9.575641408047918720040356745796976488951e4735L, 1.214322951835035451699619713803395497423e4741L, -1.542682591979864353012093794301924196234e4746L, 1.963334539793192183270983986567556358603e4751L, -2.503148969013901182572118121398034622584e4756L, 3.197076711250102964526567664729089847162e4761L, -4.090653552025822488578293526174572934858e4766L, 5.243302769651520536759521264615159906699e4771L, -6.732697170903775309261288127044088674182e4776L, 8.660529543801770516930589210020128142543e4781L, -1.116015823611149634592870112730519454113e4787L, 1.440675306432920129218036927923030695520e4792L, -1.863078034853256227415397798026969938881e4797L, 2.413595413458810442409656314019115041699e4802L, -3.132317029597258599678590012779717945144e4807L, 4.072246763371584312534474102756137619716e4812L, -5.303577511521827157146305369181950467569e4817L, 6.919417518688636032335131253584331645491e4822L, -9.043473312934241153732087612484569398979e4827L, 1.184037400265044213826044590639924237359e4833L, -1.552956685415800894409743993367334099777e4838L, 2.040404893052952221581694807126473204625e4843L, -2.685565763841580219033402331219206776210e4848L, 3.540927057361929050327811875290025248120e4853L, -4.676912607538885419407656762767991163574e4858L, 6.188165903566760647569323704623433330229e4863L, -8.202087471895029964699042637255411806373e4868L, 1.089045274355389654614196651761310970580e4874L, -1.448524684976553869119447042300206226148e4879L, 1.930028100376784839502387280956424581974e4884L, -2.576074799096023589462128312524664980682e4889L, 3.444369635011990347297134928452972402038e4894L, -4.613354441299253694113609154769978684993e4899L, 6.189834306866879018555349507257537840922e4904L, -8.319470760665157534580593571258276368233e4909L, 1.120124240070996761986102680587384813245e4915L, -1.510740451399746828351090108638980398124e4920L, 2.041108231091323198877509959371257503819e4925L, -2.762447751447012472733302936575873838539e4930L, + #endif + } }; +#else + static const std::array::value> bernoulli_data; +#endif + }; + +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + constexpr const std::array::value> unchecked_bernoulli_data::bernoulli_data; +#else + template + const std::array::value> unchecked_bernoulli_data::bernoulli_data = + { { + +1.00000000000000000000000000000000000000000L, + +0.166666666666666666666666666666666666666667L, + -0.0333333333333333333333333333333333333333333L, + +0.0238095238095238095238095238095238095238095L, + -0.0333333333333333333333333333333333333333333L, + +0.0757575757575757575757575757575757575757576L, + -0.253113553113553113553113553113553113553114L, + +1.16666666666666666666666666666666666666667L, + -7.09215686274509803921568627450980392156863L, + +54.9711779448621553884711779448621553884712L, + -529.124242424242424242424242424242424242424L, + +6192.12318840579710144927536231884057971014L, + -86580.2531135531135531135531135531135531136L, + +1.42551716666666666666666666666666666666667E6L, + -2.72982310678160919540229885057471264367816E7L, + +6.01580873900642368384303868174835916771401E8L, + -1.51163157670921568627450980392156862745098E10L, + +4.29614643061166666666666666666666666666667E11L, + -1.37116552050883327721590879485616327721591E13L, + +4.88332318973593166666666666666666666666667E14L, + -1.92965793419400681486326681448632668144863E16L, + +8.41693047573682615000553709856035437430786E17L, + -4.03380718540594554130768115942028985507246E19L, + +2.11507486380819916056014539007092198581560E21L, + -1.20866265222965259346027311937082525317819E23L, + +7.50086674607696436685572007575757575757576E24L, + -5.03877810148106891413789303052201257861635E26L, + +3.65287764848181233351104308429711779448622E28L, + -2.84987693024508822262691464329106781609195E30L, + +2.38654274996836276446459819192192149717514E32L, + -2.13999492572253336658107447651910973926742E34L, + +2.05009757234780975699217330956723102516667E36L, + -2.09380059113463784090951852900279701847092E38L, + +2.27526964884635155596492603527692645814700E40L, + -2.62577102862395760473030497361582020814490E42L, + +3.21250821027180325182047923042649852435219E44L, + -4.15982781667947109139170744952623589366896E46L, + +5.69206954820352800238834562191210586444805E48L, + -8.21836294197845756922906534686173330145509E50L, + +1.25029043271669930167323398297028955241772E53L, + -2.00155832332483702749253291988132987687242E55L, + +3.36749829153643742333966769033387530162196E57L, + -5.94709705031354477186604968440515408405791E59L, + +1.10119103236279775595641307904376916046305E62L, + -2.13552595452535011886583850190410656789733E64L, + +4.33288969866411924196166130593792062184514E66L, + -9.18855282416693282262005552155018971389604E68L, + +2.03468967763290744934550279902200200659751E71L, + -4.70038339580357310785752555350060606545967E73L, + +1.13180434454842492706751862577339342678904E76L, + -2.83822495706937069592641563364817647382847E78L, + +7.40642489796788506297508271409209841768797E80L, + -2.00964548027566044834656196727153631868673E83L, + +5.66571700508059414457193460305193569614195E85L, + -1.65845111541362169158237133743199123014950E88L, + +5.03688599504923774192894219151801548124424E90L, + -1.58614682376581863693634015729664387827410E93L, + +5.17567436175456269840732406825071225612408E95L, + -1.74889218402171173396900258776181591451415E98L, + +6.11605199949521852558245252642641677807677E100L, + -2.21227769127078349422883234567129324455732E103L, + +8.27227767987709698542210624599845957312047E105L, + -3.19589251114157095835916343691808148735263E108L, + +1.27500822233877929823100243029266798669572E111L, + -5.25009230867741338994028246245651754469199E113L, + +2.23018178942416252098692981988387281437383E116L, + -9.76845219309552044386335133989802393011669E118L, + +4.40983619784529542722726228748131691918758E121L, + -2.05085708864640888397293377275830154864566E124L, + +9.82144332797912771075729696020975210414919E126L, + -4.84126007982088805087891967099634127611305E129L, + +2.45530888014809826097834674040886903996737E132L, + -1.28069268040847475487825132786017857218118E135L, + +6.86761671046685811921018885984644004360924E137L, + -3.78464685819691046949789954163795568144895E140L, + +2.14261012506652915508713231351482720966602E143L, + -1.24567271371836950070196429616376072194583E146L, + +7.43457875510001525436796683940520613117807E148L, + -4.55357953046417048940633332233212748767721E151L, + +2.86121128168588683453638472510172325229190E154L, + -1.84377235520338697276882026536287854875414E157L, + +1.21811545362210466995013165065995213558174E160L, + -8.24821871853141215484818457296893447301419E162L, + +5.72258779378329433296516498142978615918685E165L, + -4.06685305250591047267679693831158655602196E168L, + +2.95960920646420500628752695815851870426379E171L, + -2.20495225651894575090311752273445984836379E174L, + +1.68125970728895998058311525151360665754464E177L, + -1.31167362135569576486452806355817153004431E180L, + +1.04678940094780380821832853929823089643829E183L, + -8.54328935788337077185982546299082774593270E185L, + +7.12878213224865423522884066771438224721245E188L, + -6.08029314555358993000847118686477458461988E191L, + +5.29967764248499239300942910043247266228490E194L, + -4.71942591687458626443646229013379911103761E197L, + +4.29284137914029810894168296541074669045521E200L, + -3.98767449682322074434477655542938795106651E203L, + +3.78197804193588827138944181161393327898220E206L, + -3.66142336836811912436858082151197348755196E209L, + +3.61760902723728623488554609298914089477541E212L, + -3.64707726451913543621383088655499449048682E215L, + +3.75087554364544090983452410104814189306842E218L, + -3.93458672964390282694891288533713429355657E221L, + +4.20882111481900820046571171111494898242731E224L, + -4.59022962206179186559802940573325591059371E227L, + +5.10317257726295759279198185106496768539760E230L, + -5.78227623036569554015377271242917142512200E233L, + +6.67624821678358810322637794412809363451080E236L, + -7.85353076444504163225916259639312444428230E239L, + +9.41068940670587255245443288258762485293948E242L, + -1.14849338734651839938498599206805592548354E246L, + +1.42729587428487856771416320087122499897180E249L, + -1.80595595869093090142285728117654560926719E252L, + +2.32615353076608052161297985184708876161736E255L, + -3.04957517154995947681942819261542593785327E258L, + +4.06858060764339734424012124124937318633684E261L, + -5.52310313219743616252320044093186392324280E264L, + +7.62772793964343924869949690204961215533859E267L, + -1.07155711196978863132793524001065396932667E271L, + +1.53102008959691884453440916153355334355847E274L, + -2.22448916821798346676602348865048510824835E277L, + +3.28626791906901391668189736436895275365183E280L, + -4.93559289559603449020711938191575963496999E283L, + +7.53495712008325067212266049779283956727824E286L, + -1.16914851545841777278088924731655041783900E290L, + +1.84352614678389394126646201597702232396492E293L, + -2.95368261729680829728014917350525183485207E296L, + +4.80793212775015697668878704043264072227967E299L, + -7.95021250458852528538243631671158693036798E302L, + +1.33527841873546338750122832017820518292039E306L, +#if LDBL_MAX_EXP == 16384 + // Entries 260 - 600 http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C258%2C600%2C2}] + - 2.277640649601959593875058983506938037019e309L, + 3.945184036046326234163525556422667595884e312L, + -6.938525772130602106071724989641405550473e315L, + 1.238896367577564823729057820219210929986e319L, + -2.245542599169309759499987966025604480745e322L, + 4.131213176073842359732511639489669404266e325L, + -7.713581346815269584960928069762882771369e328L, + 1.461536066837669600638613788471335541313e332L, + -2.809904606225532896862935642992712059631e335L, + 5.480957121318876639512096994413992284327e338L, + -1.084573284087686110518125291186079616320e342L, + 2.176980775647663539729165173863716459962e345L, + -4.431998786117553751947439433256752608068e348L, + 9.150625657715535047417756278073770096073e351L, + -1.915867353003157351316577579148683133613e355L, + 4.067256303542212258698836003682016040629e358L, + -8.754223791037736616228150209910348734629e361L, + 1.910173688735533667244373747124109379826e365L, + -4.225001320265091714631115064713174404607e368L, + 9.471959352547827678466770796787503034505e371L, + -2.152149973279986829719817376756088198573e375L, + 4.955485775334221051344839716507812871361e378L, + -1.156225941759134696630956889716381968142e382L, + 2.733406597646137698610991926705098514017e385L, + -6.546868135325176947099912523279938546333e388L, + 1.588524912441221472814692121069821695547e392L, + -3.904354800861715180218598151050191841308e395L, + 9.719938686092045781827273411668132975319e398L, + -2.450763621049522051234479737511375679283e402L, + 6.257892098396815305085674126334317095277e405L, + -1.618113552083806592527989531636955084420e409L, + 4.236528795217618357348618613216833722648e412L, + -1.123047068199051008086174989124136878992e416L, + 3.013971787525654770217283559392286666886e419L, + -8.188437573221553030375681429202969070420e422L, + 2.251910591336716809153958146725775718707e426L, + -6.268411292043789823075314151509139413399e429L, + 1.765990845202322642693572112511312471527e433L, + -5.035154436231331651259071296731160882240e436L, + 1.452779356460483245253765356664402207266e440L, + -4.241490890130137339052414960684151515166e443L, + 1.252966001692427774088293833338841893293e447L, + -3.744830047478272947978103227876747240343e450L, + 1.132315806695710930595876001089232216024e454L, + -3.463510845942701805991786197773934662578e457L, + 1.071643382649675572086865465873916611537e461L, + -3.353824475439933688957233489984711465335e464L, + 1.061594257145875875963152734129803268488e468L, + -3.398420969215528955528654193586189805265e471L, + 1.100192502000434096206138068020551065890e475L, + -3.601686379213993374332690210094863486472e478L, + 1.192235170430164900533187239994513019475e482L, + -3.990342751779668381699052942504119409180e485L, + 1.350281800938769780891258894167663309221e489L, + -4.619325443466054312873093650888507562249e492L, + 1.597522243968586548227514639959727696694e496L, + -5.584753729092155108530929002119620487652e499L, + 1.973443623104646193229794524759543752089e503L, + -7.048295441989615807045620880311201930244e506L, + 2.544236702499719094591873151590280263560e510L, + -9.281551595258615205927443367289948150345e513L, + 3.421757163154453657766296828520235351572e517L, + -1.274733639384538364282697627345068947433e521L, + 4.798524805311016034711205886780460173566e524L, + -1.825116948422858388787806917284878870034e528L, + 7.013667442807288452441777981425055613982e531L, + -2.723003862685989740898815670978399383114e535L, + 1.068014853917260290630122222858884658850e539L, + -4.231650952273697842269381683768681118533e542L, + 1.693650052202594386658903598564772900388e546L, + -6.846944855806453360616258582310883597678e549L, + 2.795809132238082267120232174243715559601e553L, + -1.153012972808983269106716828311318981951e557L, + 4.802368854268746357511997492039592697149e560L, + -2.019995255271910836389761734035403905781e564L, + 8.580207235032617856059250643095019760968e567L, + -3.680247942263468164408192134916355198549e571L, + 1.593924457586765331397457407661306895942e575L, + -6.970267175232643679233530367569943057501e578L, + 3.077528087427698518703282907890556154309e582L, + -1.371846760052887888926055417297342106614e586L, + 6.173627360829553396851763207025505289166e589L, + -2.804703130495506384463249394043486916669e593L, + 1.286250900087150126167490951216207186092e597L, + -5.954394420063617872366818601092036543220e600L, + 2.782297785278756426177542270854984091406e604L, + -1.312214674935307746141207680066262384215e608L, + 6.246299145383554153167974732783934504370e611L, + -3.000812007679574430883792565577444226490e615L, + 1.454904877136007844493861746476079537075e619L, + -7.118558521873800304612781121044077357278e622L, + 3.514739820897817389472822276832677887997e626L, + -1.751137068816377401163011262831890828437e630L, + 8.803498091818800678575314081978951179602e633L, + -4.465612911700593572269200981612564161010e637L, + 2.285494565287530681465757798517033542888e641L, + -1.180145168917737098025683613598595411329e645L, + 6.147941849198393232663105284575149616925e648L, + -3.231069156963603593233679426198974663352e652L, + 1.713042725635435041806895849197608270935e656L, + -9.161761363270648920537613435771882898051e659L, + 4.942675965960539112005679080810117766825e663L, + -2.689684712697383518131267222872386600031e667L, + 1.476320014229917759615308193449511534656e671L, + -8.173037740864781506597184122049453514594e674L, + 4.563462313190521363235182420178784459580e678L, + -2.569790015236158475703055501886439298708e682L, + 1.459410219452119981958355737832022375085e686L, + -8.358304882556983795372406183642486436653e689L, + 4.827305091483557818593092377664570208355e693L, + -2.811394311081493166793414157061950132403e697L, + 1.651026863340675349245561261339568827739e701L, + -9.776578579336866764167878646459810047899e704L, + 5.837207965197521880181236529616560780535e708L, + -3.513938957938032127105389702846371181520e712L, + 2.132747371360190507595748444536911078788e716L, + -1.305047363239192640729466563372665311602e720L, + 8.050825342678337497636292798039996484780e723L, + -5.006884161223862543665524155681082112689e727L, + 3.139016066011452177570812014513491361235e731L, + -1.983829535212711378291469356666001365873e735L, + 1.263822427649676371257598052486237628698e739L, + -8.115678659900522918802121684491754629503e742L, + 5.252995164972075271667364371449050412435e746L, + -3.427038125662404660056511738625477058135e750L, + 2.253446011834352733279946306835940729858e754L, + -1.493407341897034717876962786798831719683e758L, + 9.974681322653365118752729509398728354442e761L, + -6.714230142773850863927710112350816379426e765L, + 4.554668668931723346600337564274944733530e769L, + -3.113635386023220127834102980385275379533e773L, + 2.144945411287666204679363498162954050208e777L, + -1.488982121181387164932397544378555256016e781L, + 1.041537218854627455352298173588983048748e785L, + -7.341073881786613676177562822942175683993e788L, + 5.213524272587199574980117351016322518428e792L, + -3.730592531776514409283897139216167197989e796L, + 2.689592876341877079083449497724049500175e800L, + -1.953643788231947582529884602972233135002e804L, + 1.429691073080500563348668321308878246277e808L, + -1.054059177095488639836063073070536825675e812L, + 7.828919160938693948399336431565350676613e815L, + -5.857884457184396382550955498026762014753e819L, + 4.415401588264172474136969345712659422380e823L, + -3.352573884181287635796498822858109969161e827L, + 2.564210385719224000156548240934108974447e831L, + -1.975534392116037602837941409848663077528e835L, + 1.533062123975940045180943006948008486466e839L, + -1.198306160488763291730059994812781226903e843L, + 9.434034267770711698676321369174735725321e846L, + -7.480619200038505368468483892246806488879e850L, + 5.974161898439971564124576801455052907638e854L, + -4.805125663714699771668630995361572639386e858L, + 3.892332138028039952403812726744593073776e862L, + -3.175276505779699340738548328810180869575e866L, + 2.608608681939322393581069188271626122519e870L, + -2.158148554392732439392868052394994052628e874L, + 1.797993483301448477700600221980862686033e878L, + -1.508407575089108597171576068862286462909e882L, + 1.274273406242459482708930389008701147244e886L, + -1.083950475353171986748233157909397370193e890L, + 9.284292630726328432038470356821265395331e893L, + -8.007012115449516364480417355063446317414e897L, + 6.952871948429568933888979915833266241471e901L, + -6.078828929473797621198666799700739891205e905L, + 5.350908089710964244671334224708057812633e909L, + -4.742168072503284973969982758434401589090e913L, + 4.231149239401967697257534662010605751136e917L, + -3.800684612827828851942743291026898158947e921L, + 3.436984796314246158361599955909956583986e925L, + -3.128930718993658356398482705317381808301e929L, + // + // 602-1300: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C602%2C1300%2C2}] + 2.867524740577223817164663595437919813239e933L, -2.645462974939090580963101220449509725942e937L, 2.456800827789169780295419018499543141869e941L, -2.296690549725790064673528302231294870532e945L, 2.161174697699793265715182091764676666457e949L, -2.047023224586087259305754002882269123194e953L, 1.951604806042481282712736234132803700277e957L, -1.872785206668284042110390583158639495143e961L, 1.808847160923282257302788929692654262867e965L, -1.758427529634609613399327744595257497188e969L, 1.720468488019528147087036246754294757647e973L, -1.694180279355332648057740852839804839425e977L, 1.679013685251183870616469618951463869496e981L, -1.674640861433092946269144173974414945664e985L, 1.680943600147858322148767806987527412112e989L, -1.698008433134805056489370119323402510305e993L, 1.726128304411348354183882648263448448633e997L, -1.765810838736918108045764015629875016219e1001L, 1.817793526882665071123822455897912718293e1005L, -1.883066459765807128944897377914669600374e1009L, 1.962903588035940537938222992228124233567e1013L, -2.058903881920696086033171142046100185783e1017L, 2.173044241735786946064676598703393618281e1021L, -2.307746591425236218893160658331303115253e1025L, 2.465962312241418731528973526597433097256e1029L, -2.651278087802503406316742676403301581549e1033L, 2.868048395658440423778896607880692085708e1037L, -3.121561373094393453726645989392054731637e1041L, 3.418246710091027042099932753084126095820e1045L, -3.765936717592482928796920675282930034018e1049L, 4.174194967165213973474293718362757753877e1053L, -4.654731142471753017867105249805137855862e1057L, 5.221926310090434518253178454907900079787e1061L, -5.893500145664015254409680930288710794031e1065L, 6.691361332576333738130720616841706994101e1069L, -7.642695184575063524608775697714741180954e1073L, 8.781359617440634128952082759434723165820e1077L, -1.014968338800868135594698909567734048618e1082L, 1.180079105471061498849752479044520598414e1086L, -1.380162016721660241308046692646452732446e1090L, 1.623685158291375662775444238282343536948e1094L, -1.921404880943289359290531906131400049399e1098L, 2.287040419533950152851434188305457266969e1102L, -2.738162880206032093123060939173765335255e1106L, 3.297371307848643161532227459901386725801e1110L, -3.993854689967542662299211323085023297602e1114L, 4.865474805885735467044047308902313673643e1118L, -5.961554732739027308247618738765152679497e1122L, 7.346627151757492821447573639763873833441e1126L, -9.105493288459908620636712748727395637965e1130L, 1.135007867626164861991621396462821975167e1135L, -1.422876214067403769204874786137232627418e1139L, 1.793912271573925309173135913914667878908e1143L, -2.274542916104231188526120123855259514144e1147L, 2.900273688809987694128857655036783261991e1151L, -3.719022795563122339874875448447744493398e1155L, 4.795753420982845153626611023078973364321e1159L, -6.218937220186281310109009529226561379773e1163L, 8.109611247999584815668395828940708619394e1167L, -1.063412316303440216539797215354141158589e1172L, 1.402214363674117662460496032135704328989e1176L, -1.859223235464558752766840772026058694872e1180L, 2.478828203789903637835992128856742276028e1184L, -3.323169416193176673655321536761413885767e1188L, 4.479640207312477092938541546776915956580e1192L, -6.071721672924085739424644485636889518799e1196L, 8.274698015123579607850404326757887762270e1200L, -1.133855131459773018024052539697784205966e1205L, 1.562146222050424344025824344480153248984e1209L, -2.163904570724750459592352173471446831752e1213L, 3.013703210722669908901286635073603018696e1217L, -4.219903244242308803914269531001720703294e1221L, 5.940703220571043642186808904696174833998e1225L, -8.408147464216029127243257448169774333631e1229L, 1.196419999747411909144144315499654470715e1234L, -1.711518922741148710381740436694440587059e1238L, 2.461434539630850545757453894977350505251e1242L, -3.558748530932574002484841810677232366801e1246L, 5.172525606281917297657859608800373729529e1250L, -7.557850217376323621984784308774476917753e1254L, 1.110141075986004209769735296234549704181e1259L, -1.639216556732622481406083885926912451281e1263L, 2.433138328152562628385514545400044125983e1267L, -3.630476645219033020888837165221286413171e1271L, 5.445289518636306992942604775585977779418e1275L, -8.209806424989072060381590985042272020067e1279L, 1.244209849774134691374848390346442737613e1284L, -1.895384488692308848372754844910263931874e1288L, 2.902272596647764894203369746806169285113e1292L, -4.466944174025026625137032739317650862593e1296L, 6.910485739507636504313238347702354354916e1300L, -1.074550085668784170644854815272144687769e1305L, 1.679419258904938802199084915274175753529e1309L, -2.638155207645646220849795321076977230763e1313L, 4.165284786632654168563096850610185378233e1317L, -6.609774274649031371770290191295685774584e1321L, 1.054194100570841329575393359295845860860e1326L, -1.689822316104196916970708778265725885275e1330L, 2.722340957904912685605914893019783431164e1334L, -4.407776313964403233676810178851005163725e1338L, 7.172436210641903635864868181569129834361e1342L, -1.172947440100495955246356688225986736990e1347L, 1.927745674072824377954824961348211728006e1351L, -3.184013467435655962214317208087993711563e1355L, 5.285045125125832341263897233405196808096e1359L, -8.815883582819232027207118521581424783107e1363L, 1.477818368424505276711779171224799759099e1368L, -2.489482576496570159333357550363134602876e1372L, 4.214292881345076419678976329218843808204e1376L, -7.169068531615459070909644981451297906220e1380L, 1.225513133750594558180516896275774441895e1385L, -2.105160827387119480607950260289853896637e1389L, 3.633787605672960549893307203363402915249e1393L, -6.302830804027849515239463308430185990705e1397L, 1.098521433860299633481449685364914115468e1402L, -1.923858597401607622723144320370279518600e1406L, 3.385512828549942051667348582951554570164e1410L, -5.986286250836771248147827011780631183980e1414L, 1.063572794668186370728928272374836554300e1419L, -1.898666684876492795233907174493757572290e1423L, 3.405627002840442789235393111726609930533e1427L, -6.137724140284450036591063946055819333244e1431L, 1.111411024660941507986132154479364267486e1436L, -2.022060876221034821890406900217875915949e1440L, 3.696248025817144690840539132103538834108e1444L, -6.788448439024998306316860676030442691610e1448L, 1.252615233049059554031883468823648511657e1453L, -2.322190433141265975888955985950824418729e1457L, 4.325200102353909846882217732999001735342e1461L, -8.093531903011880118699218269369570178812e1465L, 1.521558881878323790120983450270946857209e1470L, -2.873780311010933807686415826253380907421e1474L, 5.452903697278823304173192839252276211670e1478L, -1.039457922537509500320638240809547113575e1483L, 1.990610112724715126895008793014214505760e1487L, -3.829667853173777076954453401761025071562e1491L, 7.401624504283011888971231756333356050310e1495L, -1.437075122764477911733220492562365990710e1500L, 2.802940275035867428066581228962104019228e1504L, -5.491938363067613321364335249495394164430e1508L, 1.080961960603953462180593404647115933651e1513L, -2.137290931892412298654741768897581319007e1517L, 4.245031321673807283498263276791307370788e1521L, -8.469499523038763989328773224520912663309e1525L, 1.697421812794203793865032206191322699261e1530L, -3.417217332563937242285349373774004020539e1534L, 6.910378594841763785923780822895851271770e1538L, -1.403696282437585785557998429691459557649e1543L, 2.864060533055333035232343601021192111053e1547L, -5.869818290384811353182423286543086530728e1551L, 1.208359745327224593486268988808338456906e1556L, -2.498576742140453770373914215325521001990e1560L, 5.189311407347546310078739863704346083861e1564L, -1.082537954843916294257278789980768336964e1569L, 2.268238255751421312559806122980932952706e1573L, -4.773557403917983369065731568732198697502e1577L, 1.009019097334998841920279535262007639746e1582L, -2.142181266523235177327239693359275472557e1586L, 4.567814904130855969979178320003286614868e1590L, -9.782550516204803195398428611221899469345e1594L, 2.104180123097086948576304557651398411373e1599L, -4.545658958087323864004652894518442709646e1603L, 9.862563944609427542603740078470901803131e1607L, -2.149105846582226970866569209122813809019e1612L, 4.703235567543888152049628411354542509156e1616L, -1.033719212601584878353206879472796545848e1621L, 2.281767401903848796732740825793310514456e1625L, -5.058236070813950229238666252351966279306e1629L, 1.126112519657857205642546937554224492775e1634L, -2.517766761987679577706779689880657777343e1638L, 5.653225190181653388317503182908983211029e1642L, -1.274735955461074142223278576503188429497e1647L, 2.886578974679460464298863945016671299242e1651L, -6.564203307141426181809363135003467581753e1655L, 1.499036144473064593308260681782048262301e1660L, -3.437714715599902386917108442954580869236e1664L, 7.916830957072777234152907034541325149479e1668L, -1.830850567422571420661248197094782575285e1673L, 4.251778280827419894527511469762091846660e1677L, -9.915182507286989818033146623995507108134e1681L, 2.321878208636697663781227497233334385222e1686L, -5.459879022461660582811365437190884471726e1690L, 1.289222044549922720398543474297554204559e1695L, -3.056819658344217799458557578658863826289e1699L, 7.277891759142725294172926258364455941365e1703L, -1.739928293433385104144012025546489673795e1708L, 4.176797408823713136137404972612780406904e1712L, -1.006788178307821554781930741698052910780e1717L, 2.436754569909644399766538111317379484511e1721L, -5.921896599028498715774458493117079340155e1725L, 1.445045688171565118619109316933316429671e1730L, -3.540547766876069233350621578795319652040e1734L, 8.710114552028472554054293344204504325978e1738L, -2.151484527880464463303897113553085899101e1743L, 5.335928195512405709733771642389502809087e1747L, -1.328726408335015910030370523083559660016e1752L, 3.322090527232917400247098823651437597786e1756L, -8.339387326241218096865362177688582376376e1760L, 2.101842203781264395369771906884644062395e1765L, -5.318704469415522036482913743767085545209e1769L, 1.351288005941730688647540059088127991581e1774L, -3.446853546858473171100748720136784228698e1778L, 8.827284762030783576089954173424852998700e1782L, -2.269642226090373319660782216907175419317e1787L, 5.858820683661708553422363777419430816755e1791L, -1.518385813684321665045387969920683656625e1796L, 3.950661327164595923092260035122668890334e1800L, -1.031976516347387969958181456058243183780e1805L, 2.706317892325103782207094286049104555552e1809L, -7.125140422584701175967252533378906957380e1813L, 1.883260203116768075569432925204868418472e1818L, -4.997193687108743666000994570700725873035e1822L, 1.331182722092654526185433799891693838871e1827L, -3.559930289076558484535632566755216035553e1831L, 9.557281027056970446117541983785660301558e1835L, -2.575805002229372523547972911961335317502e1840L, 6.969058431277067406841032797913179025984e1844L, -1.892842481279278678390672746902260183506e1849L, 5.160964211693777744707760614147460787285e1853L, -1.412602588198037643242529860614298968137e1858L, 3.881313379962387603749693387037174052146e1862L, -1.070542170988009009334148472388319844527e1867L, 2.964094312414144330805731101996829908435e1871L, -8.238350132106899955856124602934281976453e1875L, 2.298504171050560756192352106062598639825e1880L, -6.437303944649223478093890316531995121228e1884L, 1.809727811843121957353712606428292269805e1889L, -5.107047553992257935533518628886728031061e1893L, 1.446674478990385642488446075734631327506e1898L, -4.113513327511444762766719175770513771122e1902L, 1.174067517257431444028448391638451935667e1907L, -3.363630086409895071362533854123306097827e1911L, 9.672868956071838221096869293070568259792e1915L, -2.792101741911955365960369780457612630184e1920L, 8.089710604557382430162031502761771390568e1924L, -2.352650988877130983061761312962677887796e1929L, 6.867549079740051556501575104006222995568e1933L, -2.012161201632998475706904405535757516336e1938L, 5.917489529279588702317256137229398357271e1942L, -1.746718667239329545125902248821502764273e1947L, 5.175069416058975040990816515838893249437e1951L, -1.538913401594651457295303469904084052963e1956L, 4.593185746210984655636051293374195150815e1960L, -1.375981868450401919299150690829612124045e1965L, 4.137207965217520410530508053863759216958e1969L, -1.248518564582257710069294326648626362439e1974L, 3.781575291117895093413381897917341286951e1978L, -1.149575999691408110085856948595444100435e1983L, 3.507413095836612229403470531176947165451e1987L, -1.074032838410645352804690949680310176413e1992L, 3.300857202456564870338466973024760446263e1996L, -1.018149578840803516349758843017979498322e2001L, 3.151876950233613792531594490714752800621e2005L, -9.792574827376149360558532022944033224780e2009L, 3.053456145978161645823454710737904504036e2014L, -9.555442346102849014299990542596620094035e2018L, 3.001037449298122384017009412541525703002e2023L, -9.459120112371096268275049056229023773120e2027L, 2.992168042152196502453442556462819104060e2032L, -9.498922680869041470681858599915282791899e2036L, 3.026307717971075309746179763189393755074e2041L, -9.676079238806159594565350708123427510151e2045L, 3.104778286352798464772361361434013339088e2050L, -9.997786802782252742109475924344598057966e2054L, 3.230847952724856366943939804248186203776e2059L, -1.047769651900498931701604323213605884945e2064L, 3.409958102134053489747140426163802214042e2068L, -1.113687894644055086152064258459886518528e2073L, 3.650114509271160332136458711252217684956e2077L, -1.200536387553969483433239131469825141412e2082L, 3.962482337718333099498977337189304099484e2086L, -1.312441206957064803437100929905979391106e2091L, 4.362246723746013772563799740886664288515e2095L, -1.454975881895253548422481637083633839534e2100L, 4.869831412214692119172895822285084162147e2104L, -1.635618419512383251104125916207188960680e2109L, 5.512611314145041257838234038980389596534e2113L, -1.864392957231340288547618808749072127289e2118L, 6.327317613106621547060670091824665547127e2122L, -2.154772001506498703267302897994526372056e2127L, 7.363426139490286496267931634843475368903e2131L, -2.524950643808031915843604894357998905460e2136L, 8.687956390288096215918373666581638675156e2140L, -2.999656978200020459428228924242615592768e2145L, 1.039231328851609224822335039430898644149e2150L, -3.612742437616019936358910410005123924796e2154L, 1.260211309932738404790711574105022002093e2159L, -4.410916378453971105434385837025433805752e2163L, 1.549140617923265948720013792673729394719e2168L, -5.459173749226782924959103886664322964926e2172L, 1.930343307630952098252884031069043541182e2177L, -6.848749229218425353808144618581305978045e2181L, 2.438117138001365487681440577590059588102e2186L, -8.708873656769794358508423272379627581292e2190L, 3.121268068338199458891764932384819739714e2195L, -1.122430216307539309816165910733145404999e2200L, 4.049900779207199370582177687160985635615e2204L, -1.466167983141158219266077836130256565915e2209L, 5.325678718693772500250292767751070974887e2213L, -1.940955845102272053048140384364058448998e2218L, 7.097467198361219669927211698104447309186e2222L, -2.603968771680987683436428778397387110896e2227L, 9.585403285394812946713320044815117440444e2231L, -3.540176030547640510648455468270569908446e2236L, 1.311827683984025111744358347783996339730e2241L, -4.877124229155333857009747836542843294702e2245L, 1.819213075760490882591173222316749809951e2250L, -6.808221630329265915405178596748950929642e2254L, 2.556299969544109052724772800143396857058e2259L, -9.629763347675306704861859899230073979116e2263L, 3.639508580119285595844040783082958425575e2268L, -1.380037493555816309137481185927387732499e2273L, 5.249980712165216709135893538080020409581e2277L, -2.003737844109055078145975651407367170529e2282L, 7.672522280806944397358668566379646540213e2286L, -2.947454993639165318799389781921184991045e2291L, 1.135966912801707623489383623092951142963e2296L, -4.392293711194501621873299212059053651432e2300L, 1.703813210168560937608104155973968112409e2305L, -6.630636743874062041158387022015853902938e2309L, 2.588742636486379690203698247275411406029e2314L, -1.013959594068423546627946242481463893979e2319L, 3.984265821528043268586235974854766821078e2323L, -1.570614519682157047612769672066387881154e2328L, 6.211297381339606877062824459742129064477e2332L, -2.464246931985476159686671650962783785426e2337L, 9.807833742601662212615240518855757197483e2341L, -3.916036434571217691317276306031837539092e2346L, 1.568566392975837368624727722120313955274e2351L, -6.302885887601142677858008037129298948063e2355L, 2.540704455306077495480843691828334210014e2360L, -1.027412480318234348899627142408950111875e2365L, 4.167823618450297116765978030480648316769e2369L, -1.696076602731914277275203926124423530377e2374L, 6.923904505633301788461482786634220738504e2378L, -2.835463065742506394026733592206185459035e2383L, 1.164828772275756526225951620927486307632e2388L, -4.800242878545012539781545966693324656699e2392L, 1.984381759611877246529319121941597679107e2397L, -8.228979942542641498511023600269641046627e2401L, 3.423130231367101727862739208673375060101e2406L, -1.428418168129733054582191895023094524495e2411L, 5.979153801634459282232521647160044877770e2415L, -2.510581926948409809562349588087762800160e2420L, 1.057443785053915411991029410076722022815e2425L, -4.467723713549428749678277264414266162837e2429L, 1.893474116528533144079731251913008472748e2434L, -8.049601965052954947260081891142509464888e2438L, 3.432648527503971149009691133946275281368e2443L, -1.468324699963694393989960228042259134294e2448L, + // + // 1302-1600: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1302%2C1600%2C2}] + 6.300146502435743791500010801885493871234e2452L, -2.711520667146768856688291798851999580833e2457L, 1.170595555513900137297344452318266434006e2462L, -5.069095411973246242900074508988493530542e2466L, 2.201819284807954055092117706033113168896e2471L, -9.593088725189386197503123561368325167085e2475L, 4.192362385909155628936230811010649614060e2480L, -1.837725836941968309866675158105812946762e2485L, 8.080201101491972605313807752565294881374e2489L, -3.563536075527215702966392543784039539240e2494L, 1.576361051321107275181955665159661781175e2499L, -6.994292466180175594372663323941761853364e2503L, 3.112744353537336702834647901141392426258e2508L, -1.389481328370627358752727485697345194612e2513L, 6.221134636655213696041740685131223999953e2517L, -2.793779613656947577224654924852010601105e2522L, 1.258399062987759035354039924686781081603e2527L, -5.685208194704131918461885165870560583895e2531L, 2.576167857759537340210434756292816456179e2536L, -1.170846052338591953257169251219597581763e2541L, 5.337296787116189575571202979672747140313e2545L, -2.440264475369219459038748840841422948951e2550L, 1.119037151526195093932933161706501865175e2555L, -5.146858829220973887154576240993607686435e2559L, 2.374259791963193693837576781321391741634e2564L, -1.098501215269400934956638118646657823799e2569L, 5.097500369683616795005376807036889542869e2573L, -2.372446971688020647583535886090779018865e2578L, 1.107430282014636546248612381377039463753e2583L, -5.184597227131050012643138079903381280471e2587L, 2.434392040100910394476893838832599310265e2592L, -1.146412753331162872665743308094817095949e2597L, 5.414578104816988124950636101250217797539e2601L, -2.564835392810685332173156758121489913946e2606L, 1.218495070518549208066544111736985586178e2611L, -5.805713573821806672815019495319510297824e2615L, 2.774298194574319430697819781128985128618e2620L, -1.329580186505564627453485444017911980430e2625L, 6.390545858902318479863947547243743500916e2629L, -3.080502542499571035376377703435361520427e2634L, 1.489236104239976282318361008292980814533e2639L, -7.220413839991892382038608955317126799684e2643L, 3.510874916591640642524021216241607185085e2648L, -1.712070118580404599831061485055269100525e2653L, 8.372956919832386730490070625622785478703e2657L, -4.106629146981883685523102256292669054596e2662L, 2.019945438530802964718619732330776495740e2667L, -9.964133277392242111939720494354938982970e2671L, 4.929278642971447854669801547226335041410e2676L, -2.445509657169810919463982615395074704130e2681L, 1.216734421265677299127016883839223226884e2686L, -6.071008437677720186241562251151490713584e2690L, 3.037824949882992896564570441252792097027e2695L, -1.524402878612630565501569310883356490225e2700L, 7.671320530781999359200097739951316234193e2704L, -3.871436167706734376478728954716915204399e2709L, 1.959313530432202158587932399068682252335e2714L, -9.944063618400630821320953821427307024297e2718L, 5.061161998202463346818982228476199873781e2723L, -2.583219090831132705328958245740715185448e2728L, 1.322193991367293532684189527174543501836e2733L, -6.786569982732483290873213417465458376706e2737L, 3.493212334804776543395067018414547811062e2742L, -1.803090099978261928508495412750404640933e2747L, 9.333100843930216567894508007158644926767e2751L, -4.844499031405982604449146511179496492045e2756L, 2.521648090959971240812330574936006906830e2761L, -1.316227870932708474838173333385377250286e2766L, 6.889488826832738674261056521130795910494e2770L, -3.616184242864384509259984293501533623932e2775L, 1.903356124758119137116543283603627028779e2780L, -1.004601544584640657081847200643996069583e2785L, 5.317043885597842225603585588404817559596e2789L, -2.821938866752488868682751438901900485500e2794L, 1.501842023003449590337997900945924161741e2799L, -8.014908048137216649348740300633172710524e2803L, 4.289126235121619907138036129192558937445e2808L, -2.301619137231461344870820700320913118444e2813L, 1.238485136850053215006962645111854705210e2818L, -6.682503731149007943059244518074044280490e2822L, 3.615572393938012932030234169574978859655e2827L, -1.961565108627429629104703146282982075623e2832L, 1.067123259692924564435881096382837264046e2837L, -5.821179870182035246401397327057170726418e2841L, 3.184127229476322727732208017279268211356e2846L, -1.746429902183019597973436257300843998825e2851L, 9.604873565299766333876882842813498685054e2855L, -5.296759978724702692134960752308186890356e2860L, 2.928906353338652198977536576170287112391e2865L, -1.623961162577704769945821804737884742792e2870L, 9.028574047002736235613238355032484299017e2874L, -5.033087486357905828950503441308068892610e2879L, 2.813325650062267479031371852434194635210e2884L, -1.576791132296320840138263753339056345362e2889L, 8.861258343945925667272164531504265693289e2893L, -4.993236404321511029440212686547068244002e2898L, 2.821192993950901287717082243608730217471e2903L, -1.598254169674379493385730199445427966752e2908L, 9.078617590346932363947095804057608979359e2912L, -5.170742114456472142154347566092068443393e2917L, 2.952866185102528847516095880416675972086e2922L, -1.690794578626103552690094140317813413244e2927L, 9.707168799669516048238542260085175133847e2931L, -5.587884732306715493795271931175883605707e2936L, 3.225179489154957423492905957887744116530e2941L, -1.866424419669188178697802576490431604300e2946L, 1.082967626854618222657109354056973072044e2951L, -6.300392007169862865282706277272018077291e2955L, 3.675066377245428685118763485986517510658e2960L, -2.149348371085132073107516253339849053182e2965L, 1.260349351812619395000600434630904474324e2970L, -7.409963623771231302980906971935254993610e2974L, 4.367980758467862686643231700861155889684e2979L, -2.581566823350789671250829457603555544100e2984L, 1.529757357568342629912560827243282062227e2989L, -9.088595394263364554625061567617375176719e2993L, 5.413829169254585648363594604231030415354e2998L, -3.233288119606092759447005827969216281573e3003L, 1.936042437734875803183915765854038424658e3008L, -1.162289934202291715747729318797398221667e3013L, 6.995870350500567071550614251287615697508e3017L, -4.221776496490106417392945233048068288503e3022L, 2.554309239868912570382343877718991746122e3027L, -1.549440871550119801225143558087410562418e3032L, 9.423199525954784955533959981278992475051e3036L, -5.745689660772387668861183913170050552119e3041L, 3.512407521007240798565045328376471603253e3046L, -2.152708113797517364614914569890010876143e3051L, 1.322761289733739440340237168659770154654e3056L, -8.148777388506488753591136948542248584098e3060L, 5.032880858479326069741729004270784264612e3065L, -3.116396010103058126269735274818345780360e3070L, 1.934634831148214353514796782480703021435e3075L, -1.204077166243116651938489240924641810276e3080L, 7.513065583444964704795707060501161621868e3084L, -4.699873512563164914493150520500838535415e3089L, 2.947541197349762411713872934523813866703e3094L, -1.853262416286420077763886100673646141885e3099L, 1.168196427912100545575264493997591040800e3104L, -7.382362285873345348505276546404015842875e3108L, 4.677071041058096429847797962954927487730e3113L, -2.970642034084362431442183248944824506476e3118L, 1.891572688282564476274920103912259755482e3123L, -1.207509963440193713810418554061532113326e3128L, 7.727731208240101791845515599659441557781e3132L, -4.957988488048495669466804712012179891532e3137L, 3.188965862446236259925047956715566822864e3142L, -2.056286895821370106507670239256782411337e3147L, 1.329246918771714093479509313343886287414e3152L, -8.614188519577835653765633797787633659253e3156L, + // + // 1602-1900: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1602%2C1900%2C2}] + 5.596396533621874175909933615343145642161e3161L, -3.644908483469388437457938883454376864180e3166L, 2.379838409026860469990569665632800095988e3171L, -1.557720925267669865362152155022069166772e3176L, 1.022143420270029721682551084917730373739e3181L, -6.723767358891570842116651998814252095792e3185L, 4.433950491570308179905446963723780229747e3190L, -2.931196854668917448553150023532223509373e3195L, 1.942557068752664549549945921392100172355e3200L, -1.290553202978622786891265558106235068695e3205L, 8.595082329732118303768775883557789195136e3209L, -5.738453265222970049867280061719670658457e3214L, 3.840687915100689856736926915331157331684e3219L, -2.576862441955523551149886625900059307506e3224L, 1.733166107320377310388765047659987844208e3229L, -1.168569552450178559412843683052610870569e3234L, 7.898289836694980777809433306209459851871e3238L, -5.351485909164216694400535493924387979018e3243L, 3.634772439350395177931952925644409735777e3248L, -2.474801048002975145046569303233576339695e3253L, 1.689126939254790850063878942448569759390e3258L, -1.155691524500722774057997965355407962525e3263L, 7.926435404542361405718288670391575676323e3267L, -5.449654814183048796524718620178906854846e3272L, 3.755898589900254795894812942275711835138e3277L, -2.594843902682143854622514329649211211808e3282L, 1.797048752397789969347915328338360264536e3287L, -1.247551415074438712713815166107969504456e3292L, 8.681719521514448143910215886388510318746e3296L, -6.056203898213120922016159444227958572276e3301L, 4.234882876331814099029781995617143573641e3306L, -2.968432911643338866295929748049749932906e3311L, 2.085723508930484816454740610260790948864e3316L, -1.469023169879432026361623513301566735138e3321L, 1.037150346505052892302077637883522696572e3326L, -7.339977067836656769144838365069396168014e3330L, 5.206985412168234130596004552956337839140e3335L, -3.702673773319239583641029108403509825141e3340L, 2.639251227995760315076225206168354089692e3345L, -1.885736353072698581595150856674914203383e3350L, 1.350563292338261784288559687678302458996e3355L, -9.695749980998301526113046898985991802000e3359L, 6.977167462628398202151721319169989304520e3364L, -5.032768280399753942925624560483352299263e3369L, 3.638844963651800168080623511900705036698e3374L, -2.637228631269251606169613775399022890118e3379L, 1.915836351653767108720464847696767898597e3384L, -1.395064293615007319328267865803567670760e3389L, 1.018249052614943190644465556486933211307e3394L, -7.449662162606857550867922631658930320805e3398L, 5.463119632208085241594107781601567713991e3403L, -4.015736541676989144201935890497836963875e3408L, 2.958754190183866660901503059509579790900e3413L, -2.185096074054288399312733179064098492511e3418L, 1.617517444557020250864919655301189186103e3423L, -1.200170662015511746748935675940010250555e3428L, 8.925888349899029449015791684428724952411e3432L, -6.653851763691885517669938275618991145962e3437L, 4.971722031098457895973348076474071155918e3442L, -3.723500582577984967442020337848702786829e3447L, 2.795153783541721373364976034391375710110e3452L, -2.103141577212720698169118819883801186873e3457L, 1.586129575320959267959148073466004084241e3462L, -1.198988457279648730711646682156242973137e3467L, 9.084402368157025658430300252246526602197e3471L, -6.898927494435965163817354296023108913714e3476L, 5.251332286149361587885046891266325872375e3481L, -4.006442950956739933884502808470603581850e3486L, 3.063718202820270282280659950794978994604e3491L, -2.348215284130973783732145823834807395920e3496L, 1.803952490148087317330011096671019781340e3501L, -1.389022326803437345760911068933754707688e3506L, 1.071986115818329525986099441493200866389e3511L, -8.292085224650940719705699485423856363908e3515L, 6.428829064452939640541475198655560890344e3520L, -4.995654440302797445368056643032307686314e3525L, 3.890847042582299188849273838681034339406e3530L, -3.037288555751484681537442833929275697351e3535L, 2.376385803695694695338601696534348875191e3540L, -1.863527130251861900692886008704804849076e3545L, 1.464674913498036269270793715104706378182e3550L, -1.153804954579033578659954846698233083197e3555L, 9.109783835348935092264268296199541780964e3559L, -7.208869193983001804305451104827153729326e3564L, 5.717530734277611949162917337810749919265e3569L, -4.544970302634007326980094771330550661605e3574L, 3.621042850825283032134228901678636353355e3579L, -2.891447067949778492831490654980043715471e3584L, 2.314060419397710657435821461707043283167e3589L, -1.856140759923563235273220981623595304434e3594L, 1.492185412981476596273279338314204171587e3599L, -1.202290032627175365810126250991853594801e3604L, 9.708881154579770196658265042625239421053e3608L, -7.857809850747029705680072304049448493252e3613L, 6.373898598298513400228819113197728735438e3618L, -5.181780406472117449048907989647202286666e3623L, 4.222036621953044040518942750638183171221e3628L, -3.447728386429130175025813550845575613047e3633L, 2.821701521717856346224159586852612710800e3638L, -2.314488376711998526455043944505424906920e3643L, 1.902671298033180765286213227393060711096e3648L, -1.567603736821312488140289549008391847440e3653L, 1.294408945316538946551785312385509945367e3658L, -1.071194533081615830960091702262923009420e3663L, 8.884351908108581551151252566466606126397e3667L, -7.384866682828103669170236267589653324531e3672L, 6.152023838008155718180876735217718355563e3677L, -5.136304310431705506236573876510219357975e3682L, 4.297736808124296434723193397876220759378e3687L, -3.603994887745884762510172194982172483480e3692L, 3.028884745605031552399167746007361297342e3697L, -2.551141302205187365552982635794121855138e3702L, 2.153467982869535549299173317536193051608e3707L, -1.821769476343602094059466497311600827296e3712L, 1.544537580582347892980177956984101211006e3717L, -1.312358705945937257247030754517293537539e3722L, 1.117518229297781388884979995402355617235e3727L, -9.536820860779441793021624381677086661097e3731L, 8.156400668831968026931547065507466530546e3736L, -6.990984948728184142718575396052260691181e3741L, 6.005124901126818071638224144541102727563e3746L, -5.169500241880947716732682089328427995109e3751L, 4.459815478235310026240134567325749844182e3756L, -3.855902253361684187081283218890336962427e3761L, 3.340988024176995223515640815937037040546e3766L, -2.901099226680215736735094376078800376829e3771L, 2.524573363444334459448089563912567842927e3776L, -2.201659455716348555524529213295341212492e3781L, 1.924190302190936448078364755844591374353e3786L, -1.685313186099770223843319514432495898517e3791L, 1.479268235966730475749985741048766689808e3796L, -1.301205702893883803117530921635013780575e3801L, 1.147035071153450453405384269242743907426e3806L, -1.013300250456366849150496776951686112298e3811L, 8.970761720605591762300958007557533865346e3815L, -7.958829781488943084496783248922217392838e3820L, 7.076146954685024795720193943027902028642e3825L, -6.304798526260409199660290516451546966159e3830L, 5.629519616664188107056583939722984509867e3835L, -5.037281594099054092767959480843344929292e3840L, 4.516946091316834843581919268794683123349e3845L, -4.058975118925834202620358386772092359951e3850L, 3.655187798978978909014603682039470653549e3855L, -3.298555903041546671060101785513812175322e3860L, 2.983031738662727912016882399515879119620e3865L, -2.703403043317732979516341931451317866898e3870L, 2.455170460800096241793872443768546335444e3875L, -2.234443928432490538417605502448376856290e3880L, 2.037854924078003280537856980560782325730e3885L, -1.862482033918775734840779765743099458137e3890L, + // + // 1902-2200: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1902%2C2200%2C2}] + 1.705787724951999960095629912416210969679e3895L, -1.565564556110550991891247404758895970376e3900L, 1.439889351869832939488618785632174464789e3905L, -1.327084102784257406218693901793045990520e3910L, 1.225682557296027075027021534960026145706e3915L, -1.134401635488994148555787301654561211982e3920L, 1.052116934052356802920509999705307165985e3925L, -9.778417073593082219082361206542342793584e3929L, 9.107088061888562704837019028349522303725e3934L, -8.499551364633102138471246155980056936129e3939L, 7.949082681085658044610890152056533167407e3944L, -7.449748809722797718736397140511396011691e3949L, 6.996307824769340144608141799981589288378e3954L, -6.584122718472954006131003060359621706243e3959L, 6.209086595833487707192492087176843233407e3964L, -5.867557793863165391821489909125720982339e3969L, 5.556303538475260373917478405626416604297e3974L, -5.272450955936249442242634142613834212778e3979L, 5.013444428433789818228792126117223030641e3984L, -4.777008429684552423800736200488532033034e3989L, 4.561115100786341787876705283291018781137e3994L, -4.363955932181992701667719449097126840439e3999L, 4.183917007557000586305945495258591147615e4004L, -4.019557342177353010692923286760895584096e4009L, 3.869589913635745758786275231296652917580e4014L, -3.732865038934070181861017140563175000872e4019L, 3.608355799736107390800162778737339576843e4024L, -3.495145258697474565347261083975193776541e4029L, 3.392415245050326563747729613872524362741e4034L, -3.299436517958948801426629481782413630714e4039L, 3.215560142306355508598119430378551642857e4044L, -3.140209934146377815556058799557727461298e4049L, 3.072875852591406752692761744649563131272e4054L, -3.013108231854799187724018548255922550991e4059L, 2.960512761914376268185064129600549308882e4064L, -2.914746139139036596123006476633770383901e4069L, 2.875512319506974985103149834921665445532e4074L, -2.842559316984704569380036093537576068104e4079L, 2.815676498441436148701483904115879856704e4084L, -2.794692334326268275058539147656334465534e4089L, 2.779472571396106785963004020814493340829e4094L, -2.769918800191406321625251621260024635680e4099L, 2.765967395840433013288935879837390099329e4104L, -2.767588816244119880300161388073836623878e4109L, 2.774787246856347651152278076466043136230e4114L, -2.787600586224957950622601135620189837948e4119L, 2.806100771288225169339048358106052817280e4124L, -2.830394446218080573456394167711739786431e4129L, 2.860623983452244712039094143642843717029e4134L, -2.896968870550611723525738907034588104300e4139L, 2.939647481737606306044335918078617963078e4144L, -2.988919258547518526076380181812161398808e4149L, 3.045087329976721023952450383837883029431e4154L, -3.108501609077197464748958150625867523408e4159L, 3.179562410123820875787052833975010965963e4164L, -3.258724638491880104953913719767939138170e4169L, 3.346502614347964869115073881474258766546e4174L, -3.443475601364631413158991572423086599816e4179L, 3.550294123121350747300886840907918182129e4184L, -3.667687162886053419715985091863398517145e4189L, 3.796470357354794420044278000297864085607e4194L, -3.937555311976846882455930574021795626971e4199L, 4.091960185075595842547638450930710467324e4204L, -4.260821710519620959138720129506770036460e4209L, 4.445408854703156440576808070360934740837e4214L, -4.647138333645908068599900650548418672065e4219L, 4.867592250805288922190809906525766574205e4224L, -5.108538156515551259475573296900660666192e4229L, 5.371951876776035157276013631113314852508e4234L, -5.660043513521220243900043448456234873940e4239L, 5.975287081834808618140945840817834710330e4244L, -6.320454323372684034118816565375206053746e4249L, 6.698653321371992324876559665938996023646e4254L, -7.113372643219128807424340495235606473967e4259L, 7.568531854202750881338746432078817214052e4264L, -8.068539383842553693076672384509126681464e4269L, 8.618358887685935324188596304168259394311e4274L, -9.223585437012291673660319256730398171887e4279L, 9.890533091606747031464718533600572123091e4284L, -1.062633567277107015128545384570274268438e4290L, 1.143906286231591191271274413511275981288e4295L, -1.233785411712565904499340744089870916842e4300L, 1.333307331840530219050170916015276125870e4305L, -1.443648758235403286296065629219598769529e4310L, 1.566147425967471851736562867318748510088e4315L, -1.702326086290842780634120184324081017286e4320L, 1.853920350455786350409148418966087344063e4325L, -2.022911043115598592197907512410632615740e4330L, 2.211561842992792253055716743938240466613e4335L, -2.422463130294011318178080247305407476096e4340L, 2.658583129381772791030436640519847627789e4345L, -2.923327636881988941081365085520742216540e4350L, 3.220609866329557159104267531058019683271e4355L, -3.554932228621330128152149026066400241546e4360L, 3.931482212643167323798366327390058684499e4365L, -4.356244944221399578650235478583297389113e4370L, 4.836135498303121165971331625888490168138e4375L, -5.379154636371461359750682662639062606297e4380L, 5.994572359716861309678596804350346692501e4385L, -6.693144535124290060793936095397161934045e4390L, 7.487368894313509797084395689517008597061e4395L, -8.391787970609807810531578161564037339793e4400L, 9.423348062978921203475110312003096820035e4405L, -1.060182516651648405903017734022504884319e4411L, 1.195033105063952979885086754342706651656e4416L, -1.349591538868673992167798923586925758429e4421L, 1.527028315253291113905307092657539132480e4426L, -1.731065051510920640409442255224015234974e4431L, 1.966076741510092840076264635935585216200e4436L, -2.237214093245750681191361238831105906202e4441L, 2.550550094903891445719729187215253324232e4446L, -2.913255853313667303707651906277658164129e4451L, 3.333811847072394764285817140850092324169e4456L, -3.822262084288044913490118858492563410392e4461L, 4.390520310533864198186202368026630430120e4466L, -5.052739449335052080092114976206610871466e4471L, 5.825757966350870043117899492954521458799e4476L, -6.729639942938203582008846884575881320532e4481L, 7.788329466816396015493306357116312471970e4486L, -9.030444674469025073047417528762134025409e4491L, 1.049024263381993629167658236142000524752e4497L, -1.220879351508964912255081664072251573277e4502L, 1.423541151220109512749655991050110438471e4507L, -1.662940118618541616964708044356967429362e4512L, 1.946219185900482116137855064775635250366e4517L, -2.281995008842006909631764011781911322493e4522L, 2.680678198213108543648324254258111216040e4527L, -3.154866427472784086389609599207759103500e4532L, 3.719827710160801797530420206201570269720e4537L, -4.394095404360277919140027580071549980218e4542L, 5.200201854779615608741690339830306148442e4547L, -6.165584312943608652377791415603277251516e4552L, 7.323705248531382981433751104158852636445e4557L, -8.715439846124090647163930834760361817820e4562L, 1.039079696609215651011736087603304766850e4568L, -1.241105689556982425619608247473478857800e4573L, 1.485143079696380339521658550262280772546e4578L, -1.780437412164973637340821168154300094802e4583L, 2.138372099157518882088209435171770222745e4588L, -2.572985071149069551034276570909360759588e4593L, 3.101615379617643734762997559011097203354e4598L, -3.745713657616368229906151946770042703357e4603L, 4.531859496161940719835150033082561700677e4608L, -5.493040495326927998321538336584233566465e4613L, 6.670262730603009306595018122252730741798e4618L, -8.114581584793494903775255213273982440688e4623L, 9.889666561810883044159054730371102725871e4628L, -1.207504541653929734716275932570097623330e4634L, 1.477021377885843688233899471354959308782e4639L, -1.809984912147908767583043524070645821179e4644L, + // + // 2202-2320: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C2202%2C2320%2C2}] + 2.222043594325228980916360265527780300093e4649L, -2.732869701246338361699515268224049951411e4654L, 3.367233945421922463553518272642397177145e4659L, -4.156377225041273602431272489314020150392e4664L, 5.139764368092890466235162431795350591151e4669L, -6.367329693760865476879589228002216011370e4674L, 7.902356742934106007362514378717026407839e4679L, -9.825176966314431712897976595483070301406e4684L, 1.223792760178593282435724837135946867088e4690L, -1.527068151452750404853140815207477555192e4695L, 1.908935682572268829496101580401263597905e4700L, -2.390593888616966248780378941331847473699e4705L, 2.999171106576893833644521002894489856321e4710L, -3.769440655453736670024798444784356437578e4715L, 4.746047769851891438576002047529258107351e4720L, -5.986405469241447720766576164546767533359e4725L, 7.564466155536872051712519119999711534616e4730L, -9.575641408047918720040356745796976488951e4735L, 1.214322951835035451699619713803395497423e4741L, -1.542682591979864353012093794301924196234e4746L, 1.963334539793192183270983986567556358603e4751L, -2.503148969013901182572118121398034622584e4756L, 3.197076711250102964526567664729089847162e4761L, -4.090653552025822488578293526174572934858e4766L, 5.243302769651520536759521264615159906699e4771L, -6.732697170903775309261288127044088674182e4776L, 8.660529543801770516930589210020128142543e4781L, -1.116015823611149634592870112730519454113e4787L, 1.440675306432920129218036927923030695520e4792L, -1.863078034853256227415397798026969938881e4797L, 2.413595413458810442409656314019115041699e4802L, -3.132317029597258599678590012779717945144e4807L, 4.072246763371584312534474102756137619716e4812L, -5.303577511521827157146305369181950467569e4817L, 6.919417518688636032335131253584331645491e4822L, -9.043473312934241153732087612484569398979e4827L, 1.184037400265044213826044590639924237359e4833L, -1.552956685415800894409743993367334099777e4838L, 2.040404893052952221581694807126473204625e4843L, -2.685565763841580219033402331219206776210e4848L, 3.540927057361929050327811875290025248120e4853L, -4.676912607538885419407656762767991163574e4858L, 6.188165903566760647569323704623433330229e4863L, -8.202087471895029964699042637255411806373e4868L, 1.089045274355389654614196651761310970580e4874L, -1.448524684976553869119447042300206226148e4879L, 1.930028100376784839502387280956424581974e4884L, -2.576074799096023589462128312524664980682e4889L, 3.444369635011990347297134928452972402038e4894L, -4.613354441299253694113609154769978684993e4899L, 6.189834306866879018555349507257537840922e4904L, -8.319470760665157534580593571258276368233e4909L, 1.120124240070996761986102680587384813245e4915L, -1.510740451399746828351090108638980398124e4920L, 2.041108231091323198877509959371257503819e4925L, -2.762447751447012472733302936575873838539e4930L, +#endif + } }; +#endif + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ + return unchecked_bernoulli_data::bernoulli_data[n]; +} + +template +inline T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ + // + // Special case added for multiprecision types that have no conversion from long long, + // there are very few such types, but mpfr_class is one. + // + static const std::array::value> numerators = + {{ + std::int32_t( +1LL), + std::int32_t( +1LL), + std::int32_t( -1LL), + std::int32_t( +1LL), + std::int32_t( -1LL), + std::int32_t( +5LL), + std::int32_t( -691LL), + std::int32_t( +7LL), + std::int32_t( -3617LL), + std::int32_t( +43867LL), + std::int32_t( -174611LL), + std::int32_t( +854513LL), + }}; + + static const std::array::value> denominators = + {{ + std::int32_t( 1LL), + std::int32_t( 6LL), + std::int32_t( 30LL), + std::int32_t( 42LL), + std::int32_t( 30LL), + std::int32_t( 66LL), + std::int32_t( 2730LL), + std::int32_t( 6LL), + std::int32_t( 510LL), + std::int32_t( 798LL), + std::int32_t( 330LL), + std::int32_t( 138LL), + }}; + return T(numerators[n]) / T(denominators[n]); +} + +} // namespace detail + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n) +{ + typedef std::integral_constant::value> tag_type; + + return detail::unchecked_bernoulli_imp(n, tag_type()); +} + +}} // namespaces + +#endif // BOOST_MATH_UNCHECKED_BERNOULLI_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_factorial.hpp b/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_factorial.hpp new file mode 100644 index 0000000000000..12487eae05e58 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/detail/unchecked_factorial.hpp @@ -0,0 +1,1727 @@ +// Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SP_UC_FACTORIALS_HPP +#define BOOST_MATH_SP_UC_FACTORIALS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +# ifdef _MSC_VER +# pragma warning(push) // Temporary until lexical cast fixed. +# pragma warning(disable: 4127 4701) +# endif +# include +# ifdef _MSC_VER +# pragma warning(pop) +# endif +#endif + + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost { namespace math +{ +// Forward declarations: +template +struct max_factorial; +// +// see https://github.com/boostorg/math/issues/923 +// for the rationale behin using struct's for constexpr data: +// +template +struct unchecked_factorial_data; + +#ifdef BOOST_MATH_HAS_NVRTC + +// Need fwd decl +template +BOOST_MATH_GPU_ENABLED inline T unchecked_factorial(unsigned i); + +#endif + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +struct unchecked_factorial_data +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr boost::math::array factorials = { { + 1.0F, + 1.0F, + 2.0F, + 6.0F, + 24.0F, + 120.0F, + 720.0F, + 5040.0F, + 40320.0F, + 362880.0F, + 3628800.0F, + 39916800.0F, + 479001600.0F, + 6227020800.0F, + 87178291200.0F, + 1307674368000.0F, + 20922789888000.0F, + 355687428096000.0F, + 6402373705728000.0F, + 121645100408832000.0F, + 0.243290200817664e19F, + 0.5109094217170944e20F, + 0.112400072777760768e22F, + 0.2585201673888497664e23F, + 0.62044840173323943936e24F, + 0.15511210043330985984e26F, + 0.403291461126605635584e27F, + 0.10888869450418352160768e29F, + 0.304888344611713860501504e30F, + 0.8841761993739701954543616e31F, + 0.26525285981219105863630848e33F, + 0.822283865417792281772556288e34F, + 0.26313083693369353016721801216e36F, + 0.868331761881188649551819440128e37F, + 0.29523279903960414084761860964352e39F, + }}; +#else + static const boost::math::array factorials; +#endif +}; + +template +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr boost::math::array unchecked_factorial_data::factorials; +#else + const boost::math::array unchecked_factorial_data::factorials = {{ + 1.0F, + 1.0F, + 2.0F, + 6.0F, + 24.0F, + 120.0F, + 720.0F, + 5040.0F, + 40320.0F, + 362880.0F, + 3628800.0F, + 39916800.0F, + 479001600.0F, + 6227020800.0F, + 87178291200.0F, + 1307674368000.0F, + 20922789888000.0F, + 355687428096000.0F, + 6402373705728000.0F, + 121645100408832000.0F, + 0.243290200817664e19F, + 0.5109094217170944e20F, + 0.112400072777760768e22F, + 0.2585201673888497664e23F, + 0.62044840173323943936e24F, + 0.15511210043330985984e26F, + 0.403291461126605635584e27F, + 0.10888869450418352160768e29F, + 0.304888344611713860501504e30F, + 0.8841761993739701954543616e31F, + 0.26525285981219105863630848e33F, + 0.822283865417792281772556288e34F, + 0.26313083693369353016721801216e36F, + 0.868331761881188649551819440128e37F, + 0.29523279903960414084761860964352e39F, + }}; +#endif + +// Definitions: +template <> +BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float)) +{ + return unchecked_factorial_data::factorials[i]; +} + +#else + +template <> +BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float)) +{ + constexpr float factorials[] = { + 1.0F, + 1.0F, + 2.0F, + 6.0F, + 24.0F, + 120.0F, + 720.0F, + 5040.0F, + 40320.0F, + 362880.0F, + 3628800.0F, + 39916800.0F, + 479001600.0F, + 6227020800.0F, + 87178291200.0F, + 1307674368000.0F, + 20922789888000.0F, + 355687428096000.0F, + 6402373705728000.0F, + 121645100408832000.0F, + 0.243290200817664e19F, + 0.5109094217170944e20F, + 0.112400072777760768e22F, + 0.2585201673888497664e23F, + 0.62044840173323943936e24F, + 0.15511210043330985984e26F, + 0.403291461126605635584e27F, + 0.10888869450418352160768e29F, + 0.304888344611713860501504e30F, + 0.8841761993739701954543616e31F, + 0.26525285981219105863630848e33F, + 0.822283865417792281772556288e34F, + 0.26313083693369353016721801216e36F, + 0.868331761881188649551819440128e37F, + 0.29523279903960414084761860964352e39F, + }; + + return factorials[i]; +} + +#endif + +template <> +struct max_factorial +{ + static constexpr unsigned value = 34; +}; + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +struct unchecked_factorial_data +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr boost::math::array factorials = { { + 1.0, + 1.0, + 2.0, + 6.0, + 24.0, + 120.0, + 720.0, + 5040.0, + 40320.0, + 362880.0, + 3628800.0, + 39916800.0, + 479001600.0, + 6227020800.0, + 87178291200.0, + 1307674368000.0, + 20922789888000.0, + 355687428096000.0, + 6402373705728000.0, + 121645100408832000.0, + 0.243290200817664e19, + 0.5109094217170944e20, + 0.112400072777760768e22, + 0.2585201673888497664e23, + 0.62044840173323943936e24, + 0.15511210043330985984e26, + 0.403291461126605635584e27, + 0.10888869450418352160768e29, + 0.304888344611713860501504e30, + 0.8841761993739701954543616e31, + 0.26525285981219105863630848e33, + 0.822283865417792281772556288e34, + 0.26313083693369353016721801216e36, + 0.868331761881188649551819440128e37, + 0.29523279903960414084761860964352e39, + 0.103331479663861449296666513375232e41, + 0.3719933267899012174679994481508352e42, + 0.137637530912263450463159795815809024e44, + 0.5230226174666011117600072241000742912e45, + 0.203978820811974433586402817399028973568e47, + 0.815915283247897734345611269596115894272e48, + 0.3345252661316380710817006205344075166515e50, + 0.1405006117752879898543142606244511569936e52, + 0.6041526306337383563735513206851399750726e53, + 0.265827157478844876804362581101461589032e55, + 0.1196222208654801945619631614956577150644e57, + 0.5502622159812088949850305428800254892962e58, + 0.2586232415111681806429643551536119799692e60, + 0.1241391559253607267086228904737337503852e62, + 0.6082818640342675608722521633212953768876e63, + 0.3041409320171337804361260816606476884438e65, + 0.1551118753287382280224243016469303211063e67, + 0.8065817517094387857166063685640376697529e68, + 0.427488328406002556429801375338939964969e70, + 0.2308436973392413804720927426830275810833e72, + 0.1269640335365827592596510084756651695958e74, + 0.7109985878048634518540456474637249497365e75, + 0.4052691950487721675568060190543232213498e77, + 0.2350561331282878571829474910515074683829e79, + 0.1386831185456898357379390197203894063459e81, + 0.8320987112741390144276341183223364380754e82, + 0.507580213877224798800856812176625227226e84, + 0.3146997326038793752565312235495076408801e86, + 0.1982608315404440064116146708361898137545e88, + 0.1268869321858841641034333893351614808029e90, + 0.8247650592082470666723170306785496252186e91, + 0.5443449390774430640037292402478427526443e93, + 0.3647111091818868528824985909660546442717e95, + 0.2480035542436830599600990418569171581047e97, + 0.1711224524281413113724683388812728390923e99, + 0.1197857166996989179607278372168909873646e101, + 0.8504785885678623175211676442399260102886e102, + 0.6123445837688608686152407038527467274078e104, + 0.4470115461512684340891257138125051110077e106, + 0.3307885441519386412259530282212537821457e108, + 0.2480914081139539809194647711659403366093e110, + 0.188549470166605025498793226086114655823e112, + 0.1451830920282858696340707840863082849837e114, + 0.1132428117820629783145752115873204622873e116, + 0.8946182130782975286851441715398316520698e117, + 0.7156945704626380229481153372318653216558e119, + 0.5797126020747367985879734231578109105412e121, + 0.4753643337012841748421382069894049466438e123, + 0.3945523969720658651189747118012061057144e125, + 0.3314240134565353266999387579130131288001e127, + 0.2817104114380550276949479442260611594801e129, + 0.2422709538367273238176552320344125971528e131, + 0.210775729837952771721360051869938959523e133, + 0.1854826422573984391147968456455462843802e135, + 0.1650795516090846108121691926245361930984e137, + 0.1485715964481761497309522733620825737886e139, + 0.1352001527678402962551665687594951421476e141, + 0.1243841405464130725547532432587355307758e143, + 0.1156772507081641574759205162306240436215e145, + 0.1087366156656743080273652852567866010042e147, + 0.103299784882390592625997020993947270954e149, + 0.9916779348709496892095714015418938011582e150, + 0.9619275968248211985332842594956369871234e152, + 0.942689044888324774562618574305724247381e154, + 0.9332621544394415268169923885626670049072e156, + 0.9332621544394415268169923885626670049072e158, + 0.9425947759838359420851623124482936749562e160, + 0.9614466715035126609268655586972595484554e162, + 0.990290071648618040754671525458177334909e164, + 0.1029901674514562762384858386476504428305e167, + 0.1081396758240290900504101305800329649721e169, + 0.1146280563734708354534347384148349428704e171, + 0.1226520203196137939351751701038733888713e173, + 0.132464181945182897449989183712183259981e175, + 0.1443859583202493582204882102462797533793e177, + 0.1588245541522742940425370312709077287172e179, + 0.1762952551090244663872161047107075788761e181, + 0.1974506857221074023536820372759924883413e183, + 0.2231192748659813646596607021218715118256e185, + 0.2543559733472187557120132004189335234812e187, + 0.2925093693493015690688151804817735520034e189, + 0.339310868445189820119825609358857320324e191, + 0.396993716080872089540195962949863064779e193, + 0.4684525849754290656574312362808384164393e195, + 0.5574585761207605881323431711741977155627e197, + 0.6689502913449127057588118054090372586753e199, + 0.8094298525273443739681622845449350829971e201, + 0.9875044200833601362411579871448208012564e203, + 0.1214630436702532967576624324188129585545e206, + 0.1506141741511140879795014161993280686076e208, + 0.1882677176888926099743767702491600857595e210, + 0.237217324288004688567714730513941708057e212, + 0.3012660018457659544809977077527059692324e214, + 0.3856204823625804217356770659234636406175e216, + 0.4974504222477287440390234150412680963966e218, + 0.6466855489220473672507304395536485253155e220, + 0.8471580690878820510984568758152795681634e222, + 0.1118248651196004307449963076076169029976e225, + 0.1487270706090685728908450891181304809868e227, + 0.1992942746161518876737324194182948445223e229, + 0.269047270731805048359538766214698040105e231, + 0.3659042881952548657689727220519893345429e233, + 0.5012888748274991661034926292112253883237e235, + 0.6917786472619488492228198283114910358867e237, + 0.9615723196941089004197195613529725398826e239, + 0.1346201247571752460587607385894161555836e242, + 0.1898143759076170969428526414110767793728e244, + 0.2695364137888162776588507508037290267094e246, + 0.3854370717180072770521565736493325081944e248, + 0.5550293832739304789551054660550388118e250, + 0.80479260574719919448490292577980627711e252, + 0.1174997204390910823947958271638517164581e255, + 0.1727245890454638911203498659308620231933e257, + 0.2556323917872865588581178015776757943262e259, + 0.380892263763056972698595524350736933546e261, + 0.571338395644585459047893286526105400319e263, + 0.8627209774233240431623188626544191544816e265, + 0.1311335885683452545606724671234717114812e268, + 0.2006343905095682394778288746989117185662e270, + 0.308976961384735088795856467036324046592e272, + 0.4789142901463393876335775239063022722176e274, + 0.7471062926282894447083809372938315446595e276, + 0.1172956879426414428192158071551315525115e279, + 0.1853271869493734796543609753051078529682e281, + 0.2946702272495038326504339507351214862195e283, + 0.4714723635992061322406943211761943779512e285, + 0.7590705053947218729075178570936729485014e287, + 0.1229694218739449434110178928491750176572e290, + 0.2004401576545302577599591653441552787813e292, + 0.3287218585534296227263330311644146572013e294, + 0.5423910666131588774984495014212841843822e296, + 0.9003691705778437366474261723593317460744e298, + 0.1503616514864999040201201707840084015944e301, + 0.2526075744973198387538018869171341146786e303, + 0.4269068009004705274939251888899566538069e305, + 0.7257415615307998967396728211129263114717e307, + }}; +#else + static const boost::math::array factorials; +#endif +}; + +template +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr boost::math::array unchecked_factorial_data::factorials; +#else + const boost::math::array unchecked_factorial_data::factorials = {{ + 1.0, + 1.0, + 2.0, + 6.0, + 24.0, + 120.0, + 720.0, + 5040.0, + 40320.0, + 362880.0, + 3628800.0, + 39916800.0, + 479001600.0, + 6227020800.0, + 87178291200.0, + 1307674368000.0, + 20922789888000.0, + 355687428096000.0, + 6402373705728000.0, + 121645100408832000.0, + 0.243290200817664e19, + 0.5109094217170944e20, + 0.112400072777760768e22, + 0.2585201673888497664e23, + 0.62044840173323943936e24, + 0.15511210043330985984e26, + 0.403291461126605635584e27, + 0.10888869450418352160768e29, + 0.304888344611713860501504e30, + 0.8841761993739701954543616e31, + 0.26525285981219105863630848e33, + 0.822283865417792281772556288e34, + 0.26313083693369353016721801216e36, + 0.868331761881188649551819440128e37, + 0.29523279903960414084761860964352e39, + 0.103331479663861449296666513375232e41, + 0.3719933267899012174679994481508352e42, + 0.137637530912263450463159795815809024e44, + 0.5230226174666011117600072241000742912e45, + 0.203978820811974433586402817399028973568e47, + 0.815915283247897734345611269596115894272e48, + 0.3345252661316380710817006205344075166515e50, + 0.1405006117752879898543142606244511569936e52, + 0.6041526306337383563735513206851399750726e53, + 0.265827157478844876804362581101461589032e55, + 0.1196222208654801945619631614956577150644e57, + 0.5502622159812088949850305428800254892962e58, + 0.2586232415111681806429643551536119799692e60, + 0.1241391559253607267086228904737337503852e62, + 0.6082818640342675608722521633212953768876e63, + 0.3041409320171337804361260816606476884438e65, + 0.1551118753287382280224243016469303211063e67, + 0.8065817517094387857166063685640376697529e68, + 0.427488328406002556429801375338939964969e70, + 0.2308436973392413804720927426830275810833e72, + 0.1269640335365827592596510084756651695958e74, + 0.7109985878048634518540456474637249497365e75, + 0.4052691950487721675568060190543232213498e77, + 0.2350561331282878571829474910515074683829e79, + 0.1386831185456898357379390197203894063459e81, + 0.8320987112741390144276341183223364380754e82, + 0.507580213877224798800856812176625227226e84, + 0.3146997326038793752565312235495076408801e86, + 0.1982608315404440064116146708361898137545e88, + 0.1268869321858841641034333893351614808029e90, + 0.8247650592082470666723170306785496252186e91, + 0.5443449390774430640037292402478427526443e93, + 0.3647111091818868528824985909660546442717e95, + 0.2480035542436830599600990418569171581047e97, + 0.1711224524281413113724683388812728390923e99, + 0.1197857166996989179607278372168909873646e101, + 0.8504785885678623175211676442399260102886e102, + 0.6123445837688608686152407038527467274078e104, + 0.4470115461512684340891257138125051110077e106, + 0.3307885441519386412259530282212537821457e108, + 0.2480914081139539809194647711659403366093e110, + 0.188549470166605025498793226086114655823e112, + 0.1451830920282858696340707840863082849837e114, + 0.1132428117820629783145752115873204622873e116, + 0.8946182130782975286851441715398316520698e117, + 0.7156945704626380229481153372318653216558e119, + 0.5797126020747367985879734231578109105412e121, + 0.4753643337012841748421382069894049466438e123, + 0.3945523969720658651189747118012061057144e125, + 0.3314240134565353266999387579130131288001e127, + 0.2817104114380550276949479442260611594801e129, + 0.2422709538367273238176552320344125971528e131, + 0.210775729837952771721360051869938959523e133, + 0.1854826422573984391147968456455462843802e135, + 0.1650795516090846108121691926245361930984e137, + 0.1485715964481761497309522733620825737886e139, + 0.1352001527678402962551665687594951421476e141, + 0.1243841405464130725547532432587355307758e143, + 0.1156772507081641574759205162306240436215e145, + 0.1087366156656743080273652852567866010042e147, + 0.103299784882390592625997020993947270954e149, + 0.9916779348709496892095714015418938011582e150, + 0.9619275968248211985332842594956369871234e152, + 0.942689044888324774562618574305724247381e154, + 0.9332621544394415268169923885626670049072e156, + 0.9332621544394415268169923885626670049072e158, + 0.9425947759838359420851623124482936749562e160, + 0.9614466715035126609268655586972595484554e162, + 0.990290071648618040754671525458177334909e164, + 0.1029901674514562762384858386476504428305e167, + 0.1081396758240290900504101305800329649721e169, + 0.1146280563734708354534347384148349428704e171, + 0.1226520203196137939351751701038733888713e173, + 0.132464181945182897449989183712183259981e175, + 0.1443859583202493582204882102462797533793e177, + 0.1588245541522742940425370312709077287172e179, + 0.1762952551090244663872161047107075788761e181, + 0.1974506857221074023536820372759924883413e183, + 0.2231192748659813646596607021218715118256e185, + 0.2543559733472187557120132004189335234812e187, + 0.2925093693493015690688151804817735520034e189, + 0.339310868445189820119825609358857320324e191, + 0.396993716080872089540195962949863064779e193, + 0.4684525849754290656574312362808384164393e195, + 0.5574585761207605881323431711741977155627e197, + 0.6689502913449127057588118054090372586753e199, + 0.8094298525273443739681622845449350829971e201, + 0.9875044200833601362411579871448208012564e203, + 0.1214630436702532967576624324188129585545e206, + 0.1506141741511140879795014161993280686076e208, + 0.1882677176888926099743767702491600857595e210, + 0.237217324288004688567714730513941708057e212, + 0.3012660018457659544809977077527059692324e214, + 0.3856204823625804217356770659234636406175e216, + 0.4974504222477287440390234150412680963966e218, + 0.6466855489220473672507304395536485253155e220, + 0.8471580690878820510984568758152795681634e222, + 0.1118248651196004307449963076076169029976e225, + 0.1487270706090685728908450891181304809868e227, + 0.1992942746161518876737324194182948445223e229, + 0.269047270731805048359538766214698040105e231, + 0.3659042881952548657689727220519893345429e233, + 0.5012888748274991661034926292112253883237e235, + 0.6917786472619488492228198283114910358867e237, + 0.9615723196941089004197195613529725398826e239, + 0.1346201247571752460587607385894161555836e242, + 0.1898143759076170969428526414110767793728e244, + 0.2695364137888162776588507508037290267094e246, + 0.3854370717180072770521565736493325081944e248, + 0.5550293832739304789551054660550388118e250, + 0.80479260574719919448490292577980627711e252, + 0.1174997204390910823947958271638517164581e255, + 0.1727245890454638911203498659308620231933e257, + 0.2556323917872865588581178015776757943262e259, + 0.380892263763056972698595524350736933546e261, + 0.571338395644585459047893286526105400319e263, + 0.8627209774233240431623188626544191544816e265, + 0.1311335885683452545606724671234717114812e268, + 0.2006343905095682394778288746989117185662e270, + 0.308976961384735088795856467036324046592e272, + 0.4789142901463393876335775239063022722176e274, + 0.7471062926282894447083809372938315446595e276, + 0.1172956879426414428192158071551315525115e279, + 0.1853271869493734796543609753051078529682e281, + 0.2946702272495038326504339507351214862195e283, + 0.4714723635992061322406943211761943779512e285, + 0.7590705053947218729075178570936729485014e287, + 0.1229694218739449434110178928491750176572e290, + 0.2004401576545302577599591653441552787813e292, + 0.3287218585534296227263330311644146572013e294, + 0.5423910666131588774984495014212841843822e296, + 0.9003691705778437366474261723593317460744e298, + 0.1503616514864999040201201707840084015944e301, + 0.2526075744973198387538018869171341146786e303, + 0.4269068009004705274939251888899566538069e305, + 0.7257415615307998967396728211129263114717e307, + }}; +#endif + +template <> +BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double)) +{ + return unchecked_factorial_data::factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +#else + +template <> +BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double)) +{ + constexpr double factorials[] = { + 1, + 1, + 2, + 6, + 24, + 120, + 720, + 5040, + 40320, + 362880.0, + 3628800.0, + 39916800.0, + 479001600.0, + 6227020800.0, + 87178291200.0, + 1307674368000.0, + 20922789888000.0, + 355687428096000.0, + 6402373705728000.0, + 121645100408832000.0, + 0.243290200817664e19, + 0.5109094217170944e20, + 0.112400072777760768e22, + 0.2585201673888497664e23, + 0.62044840173323943936e24, + 0.15511210043330985984e26, + 0.403291461126605635584e27, + 0.10888869450418352160768e29, + 0.304888344611713860501504e30, + 0.8841761993739701954543616e31, + 0.26525285981219105863630848e33, + 0.822283865417792281772556288e34, + 0.26313083693369353016721801216e36, + 0.868331761881188649551819440128e37, + 0.29523279903960414084761860964352e39, + }; + + return factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 34; +}; + +#endif + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +struct unchecked_factorial_data +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr boost::math::array factorials = { { + 1L, + 1L, + 2L, + 6L, + 24L, + 120L, + 720L, + 5040L, + 40320L, + 362880.0L, + 3628800.0L, + 39916800.0L, + 479001600.0L, + 6227020800.0L, + 87178291200.0L, + 1307674368000.0L, + 20922789888000.0L, + 355687428096000.0L, + 6402373705728000.0L, + 121645100408832000.0L, + 0.243290200817664e19L, + 0.5109094217170944e20L, + 0.112400072777760768e22L, + 0.2585201673888497664e23L, + 0.62044840173323943936e24L, + 0.15511210043330985984e26L, + 0.403291461126605635584e27L, + 0.10888869450418352160768e29L, + 0.304888344611713860501504e30L, + 0.8841761993739701954543616e31L, + 0.26525285981219105863630848e33L, + 0.822283865417792281772556288e34L, + 0.26313083693369353016721801216e36L, + 0.868331761881188649551819440128e37L, + 0.29523279903960414084761860964352e39L, + 0.103331479663861449296666513375232e41L, + 0.3719933267899012174679994481508352e42L, + 0.137637530912263450463159795815809024e44L, + 0.5230226174666011117600072241000742912e45L, + 0.203978820811974433586402817399028973568e47L, + 0.815915283247897734345611269596115894272e48L, + 0.3345252661316380710817006205344075166515e50L, + 0.1405006117752879898543142606244511569936e52L, + 0.6041526306337383563735513206851399750726e53L, + 0.265827157478844876804362581101461589032e55L, + 0.1196222208654801945619631614956577150644e57L, + 0.5502622159812088949850305428800254892962e58L, + 0.2586232415111681806429643551536119799692e60L, + 0.1241391559253607267086228904737337503852e62L, + 0.6082818640342675608722521633212953768876e63L, + 0.3041409320171337804361260816606476884438e65L, + 0.1551118753287382280224243016469303211063e67L, + 0.8065817517094387857166063685640376697529e68L, + 0.427488328406002556429801375338939964969e70L, + 0.2308436973392413804720927426830275810833e72L, + 0.1269640335365827592596510084756651695958e74L, + 0.7109985878048634518540456474637249497365e75L, + 0.4052691950487721675568060190543232213498e77L, + 0.2350561331282878571829474910515074683829e79L, + 0.1386831185456898357379390197203894063459e81L, + 0.8320987112741390144276341183223364380754e82L, + 0.507580213877224798800856812176625227226e84L, + 0.3146997326038793752565312235495076408801e86L, + 0.1982608315404440064116146708361898137545e88L, + 0.1268869321858841641034333893351614808029e90L, + 0.8247650592082470666723170306785496252186e91L, + 0.5443449390774430640037292402478427526443e93L, + 0.3647111091818868528824985909660546442717e95L, + 0.2480035542436830599600990418569171581047e97L, + 0.1711224524281413113724683388812728390923e99L, + 0.1197857166996989179607278372168909873646e101L, + 0.8504785885678623175211676442399260102886e102L, + 0.6123445837688608686152407038527467274078e104L, + 0.4470115461512684340891257138125051110077e106L, + 0.3307885441519386412259530282212537821457e108L, + 0.2480914081139539809194647711659403366093e110L, + 0.188549470166605025498793226086114655823e112L, + 0.1451830920282858696340707840863082849837e114L, + 0.1132428117820629783145752115873204622873e116L, + 0.8946182130782975286851441715398316520698e117L, + 0.7156945704626380229481153372318653216558e119L, + 0.5797126020747367985879734231578109105412e121L, + 0.4753643337012841748421382069894049466438e123L, + 0.3945523969720658651189747118012061057144e125L, + 0.3314240134565353266999387579130131288001e127L, + 0.2817104114380550276949479442260611594801e129L, + 0.2422709538367273238176552320344125971528e131L, + 0.210775729837952771721360051869938959523e133L, + 0.1854826422573984391147968456455462843802e135L, + 0.1650795516090846108121691926245361930984e137L, + 0.1485715964481761497309522733620825737886e139L, + 0.1352001527678402962551665687594951421476e141L, + 0.1243841405464130725547532432587355307758e143L, + 0.1156772507081641574759205162306240436215e145L, + 0.1087366156656743080273652852567866010042e147L, + 0.103299784882390592625997020993947270954e149L, + 0.9916779348709496892095714015418938011582e150L, + 0.9619275968248211985332842594956369871234e152L, + 0.942689044888324774562618574305724247381e154L, + 0.9332621544394415268169923885626670049072e156L, + 0.9332621544394415268169923885626670049072e158L, + 0.9425947759838359420851623124482936749562e160L, + 0.9614466715035126609268655586972595484554e162L, + 0.990290071648618040754671525458177334909e164L, + 0.1029901674514562762384858386476504428305e167L, + 0.1081396758240290900504101305800329649721e169L, + 0.1146280563734708354534347384148349428704e171L, + 0.1226520203196137939351751701038733888713e173L, + 0.132464181945182897449989183712183259981e175L, + 0.1443859583202493582204882102462797533793e177L, + 0.1588245541522742940425370312709077287172e179L, + 0.1762952551090244663872161047107075788761e181L, + 0.1974506857221074023536820372759924883413e183L, + 0.2231192748659813646596607021218715118256e185L, + 0.2543559733472187557120132004189335234812e187L, + 0.2925093693493015690688151804817735520034e189L, + 0.339310868445189820119825609358857320324e191L, + 0.396993716080872089540195962949863064779e193L, + 0.4684525849754290656574312362808384164393e195L, + 0.5574585761207605881323431711741977155627e197L, + 0.6689502913449127057588118054090372586753e199L, + 0.8094298525273443739681622845449350829971e201L, + 0.9875044200833601362411579871448208012564e203L, + 0.1214630436702532967576624324188129585545e206L, + 0.1506141741511140879795014161993280686076e208L, + 0.1882677176888926099743767702491600857595e210L, + 0.237217324288004688567714730513941708057e212L, + 0.3012660018457659544809977077527059692324e214L, + 0.3856204823625804217356770659234636406175e216L, + 0.4974504222477287440390234150412680963966e218L, + 0.6466855489220473672507304395536485253155e220L, + 0.8471580690878820510984568758152795681634e222L, + 0.1118248651196004307449963076076169029976e225L, + 0.1487270706090685728908450891181304809868e227L, + 0.1992942746161518876737324194182948445223e229L, + 0.269047270731805048359538766214698040105e231L, + 0.3659042881952548657689727220519893345429e233L, + 0.5012888748274991661034926292112253883237e235L, + 0.6917786472619488492228198283114910358867e237L, + 0.9615723196941089004197195613529725398826e239L, + 0.1346201247571752460587607385894161555836e242L, + 0.1898143759076170969428526414110767793728e244L, + 0.2695364137888162776588507508037290267094e246L, + 0.3854370717180072770521565736493325081944e248L, + 0.5550293832739304789551054660550388118e250L, + 0.80479260574719919448490292577980627711e252L, + 0.1174997204390910823947958271638517164581e255L, + 0.1727245890454638911203498659308620231933e257L, + 0.2556323917872865588581178015776757943262e259L, + 0.380892263763056972698595524350736933546e261L, + 0.571338395644585459047893286526105400319e263L, + 0.8627209774233240431623188626544191544816e265L, + 0.1311335885683452545606724671234717114812e268L, + 0.2006343905095682394778288746989117185662e270L, + 0.308976961384735088795856467036324046592e272L, + 0.4789142901463393876335775239063022722176e274L, + 0.7471062926282894447083809372938315446595e276L, + 0.1172956879426414428192158071551315525115e279L, + 0.1853271869493734796543609753051078529682e281L, + 0.2946702272495038326504339507351214862195e283L, + 0.4714723635992061322406943211761943779512e285L, + 0.7590705053947218729075178570936729485014e287L, + 0.1229694218739449434110178928491750176572e290L, + 0.2004401576545302577599591653441552787813e292L, + 0.3287218585534296227263330311644146572013e294L, + 0.5423910666131588774984495014212841843822e296L, + 0.9003691705778437366474261723593317460744e298L, + 0.1503616514864999040201201707840084015944e301L, + 0.2526075744973198387538018869171341146786e303L, + 0.4269068009004705274939251888899566538069e305L, + 0.7257415615307998967396728211129263114717e307L, + }}; +#else + static const boost::math::array factorials; +#endif +}; + +template +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr boost::math::array unchecked_factorial_data::factorials; +#else + const boost::math::array unchecked_factorial_data::factorials = {{ + 1L, + 1L, + 2L, + 6L, + 24L, + 120L, + 720L, + 5040L, + 40320L, + 362880.0L, + 3628800.0L, + 39916800.0L, + 479001600.0L, + 6227020800.0L, + 87178291200.0L, + 1307674368000.0L, + 20922789888000.0L, + 355687428096000.0L, + 6402373705728000.0L, + 121645100408832000.0L, + 0.243290200817664e19L, + 0.5109094217170944e20L, + 0.112400072777760768e22L, + 0.2585201673888497664e23L, + 0.62044840173323943936e24L, + 0.15511210043330985984e26L, + 0.403291461126605635584e27L, + 0.10888869450418352160768e29L, + 0.304888344611713860501504e30L, + 0.8841761993739701954543616e31L, + 0.26525285981219105863630848e33L, + 0.822283865417792281772556288e34L, + 0.26313083693369353016721801216e36L, + 0.868331761881188649551819440128e37L, + 0.29523279903960414084761860964352e39L, + 0.103331479663861449296666513375232e41L, + 0.3719933267899012174679994481508352e42L, + 0.137637530912263450463159795815809024e44L, + 0.5230226174666011117600072241000742912e45L, + 0.203978820811974433586402817399028973568e47L, + 0.815915283247897734345611269596115894272e48L, + 0.3345252661316380710817006205344075166515e50L, + 0.1405006117752879898543142606244511569936e52L, + 0.6041526306337383563735513206851399750726e53L, + 0.265827157478844876804362581101461589032e55L, + 0.1196222208654801945619631614956577150644e57L, + 0.5502622159812088949850305428800254892962e58L, + 0.2586232415111681806429643551536119799692e60L, + 0.1241391559253607267086228904737337503852e62L, + 0.6082818640342675608722521633212953768876e63L, + 0.3041409320171337804361260816606476884438e65L, + 0.1551118753287382280224243016469303211063e67L, + 0.8065817517094387857166063685640376697529e68L, + 0.427488328406002556429801375338939964969e70L, + 0.2308436973392413804720927426830275810833e72L, + 0.1269640335365827592596510084756651695958e74L, + 0.7109985878048634518540456474637249497365e75L, + 0.4052691950487721675568060190543232213498e77L, + 0.2350561331282878571829474910515074683829e79L, + 0.1386831185456898357379390197203894063459e81L, + 0.8320987112741390144276341183223364380754e82L, + 0.507580213877224798800856812176625227226e84L, + 0.3146997326038793752565312235495076408801e86L, + 0.1982608315404440064116146708361898137545e88L, + 0.1268869321858841641034333893351614808029e90L, + 0.8247650592082470666723170306785496252186e91L, + 0.5443449390774430640037292402478427526443e93L, + 0.3647111091818868528824985909660546442717e95L, + 0.2480035542436830599600990418569171581047e97L, + 0.1711224524281413113724683388812728390923e99L, + 0.1197857166996989179607278372168909873646e101L, + 0.8504785885678623175211676442399260102886e102L, + 0.6123445837688608686152407038527467274078e104L, + 0.4470115461512684340891257138125051110077e106L, + 0.3307885441519386412259530282212537821457e108L, + 0.2480914081139539809194647711659403366093e110L, + 0.188549470166605025498793226086114655823e112L, + 0.1451830920282858696340707840863082849837e114L, + 0.1132428117820629783145752115873204622873e116L, + 0.8946182130782975286851441715398316520698e117L, + 0.7156945704626380229481153372318653216558e119L, + 0.5797126020747367985879734231578109105412e121L, + 0.4753643337012841748421382069894049466438e123L, + 0.3945523969720658651189747118012061057144e125L, + 0.3314240134565353266999387579130131288001e127L, + 0.2817104114380550276949479442260611594801e129L, + 0.2422709538367273238176552320344125971528e131L, + 0.210775729837952771721360051869938959523e133L, + 0.1854826422573984391147968456455462843802e135L, + 0.1650795516090846108121691926245361930984e137L, + 0.1485715964481761497309522733620825737886e139L, + 0.1352001527678402962551665687594951421476e141L, + 0.1243841405464130725547532432587355307758e143L, + 0.1156772507081641574759205162306240436215e145L, + 0.1087366156656743080273652852567866010042e147L, + 0.103299784882390592625997020993947270954e149L, + 0.9916779348709496892095714015418938011582e150L, + 0.9619275968248211985332842594956369871234e152L, + 0.942689044888324774562618574305724247381e154L, + 0.9332621544394415268169923885626670049072e156L, + 0.9332621544394415268169923885626670049072e158L, + 0.9425947759838359420851623124482936749562e160L, + 0.9614466715035126609268655586972595484554e162L, + 0.990290071648618040754671525458177334909e164L, + 0.1029901674514562762384858386476504428305e167L, + 0.1081396758240290900504101305800329649721e169L, + 0.1146280563734708354534347384148349428704e171L, + 0.1226520203196137939351751701038733888713e173L, + 0.132464181945182897449989183712183259981e175L, + 0.1443859583202493582204882102462797533793e177L, + 0.1588245541522742940425370312709077287172e179L, + 0.1762952551090244663872161047107075788761e181L, + 0.1974506857221074023536820372759924883413e183L, + 0.2231192748659813646596607021218715118256e185L, + 0.2543559733472187557120132004189335234812e187L, + 0.2925093693493015690688151804817735520034e189L, + 0.339310868445189820119825609358857320324e191L, + 0.396993716080872089540195962949863064779e193L, + 0.4684525849754290656574312362808384164393e195L, + 0.5574585761207605881323431711741977155627e197L, + 0.6689502913449127057588118054090372586753e199L, + 0.8094298525273443739681622845449350829971e201L, + 0.9875044200833601362411579871448208012564e203L, + 0.1214630436702532967576624324188129585545e206L, + 0.1506141741511140879795014161993280686076e208L, + 0.1882677176888926099743767702491600857595e210L, + 0.237217324288004688567714730513941708057e212L, + 0.3012660018457659544809977077527059692324e214L, + 0.3856204823625804217356770659234636406175e216L, + 0.4974504222477287440390234150412680963966e218L, + 0.6466855489220473672507304395536485253155e220L, + 0.8471580690878820510984568758152795681634e222L, + 0.1118248651196004307449963076076169029976e225L, + 0.1487270706090685728908450891181304809868e227L, + 0.1992942746161518876737324194182948445223e229L, + 0.269047270731805048359538766214698040105e231L, + 0.3659042881952548657689727220519893345429e233L, + 0.5012888748274991661034926292112253883237e235L, + 0.6917786472619488492228198283114910358867e237L, + 0.9615723196941089004197195613529725398826e239L, + 0.1346201247571752460587607385894161555836e242L, + 0.1898143759076170969428526414110767793728e244L, + 0.2695364137888162776588507508037290267094e246L, + 0.3854370717180072770521565736493325081944e248L, + 0.5550293832739304789551054660550388118e250L, + 0.80479260574719919448490292577980627711e252L, + 0.1174997204390910823947958271638517164581e255L, + 0.1727245890454638911203498659308620231933e257L, + 0.2556323917872865588581178015776757943262e259L, + 0.380892263763056972698595524350736933546e261L, + 0.571338395644585459047893286526105400319e263L, + 0.8627209774233240431623188626544191544816e265L, + 0.1311335885683452545606724671234717114812e268L, + 0.2006343905095682394778288746989117185662e270L, + 0.308976961384735088795856467036324046592e272L, + 0.4789142901463393876335775239063022722176e274L, + 0.7471062926282894447083809372938315446595e276L, + 0.1172956879426414428192158071551315525115e279L, + 0.1853271869493734796543609753051078529682e281L, + 0.2946702272495038326504339507351214862195e283L, + 0.4714723635992061322406943211761943779512e285L, + 0.7590705053947218729075178570936729485014e287L, + 0.1229694218739449434110178928491750176572e290L, + 0.2004401576545302577599591653441552787813e292L, + 0.3287218585534296227263330311644146572013e294L, + 0.5423910666131588774984495014212841843822e296L, + 0.9003691705778437366474261723593317460744e298L, + 0.1503616514864999040201201707840084015944e301L, + 0.2526075744973198387538018869171341146786e303L, + 0.4269068009004705274939251888899566538069e305L, + 0.7257415615307998967396728211129263114717e307L, + }}; +#endif + +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION long double unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double)) +{ + return unchecked_factorial_data::factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +#ifdef BOOST_MATH_USE_FLOAT128 + +template +struct unchecked_factorial_data +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static constexpr boost::math::array factorials = { { + 1, + 1, + 2, + 6, + 24, + 120, + 720, + 5040, + 40320, + 362880.0Q, + 3628800.0Q, + 39916800.0Q, + 479001600.0Q, + 6227020800.0Q, + 87178291200.0Q, + 1307674368000.0Q, + 20922789888000.0Q, + 355687428096000.0Q, + 6402373705728000.0Q, + 121645100408832000.0Q, + 0.243290200817664e19Q, + 0.5109094217170944e20Q, + 0.112400072777760768e22Q, + 0.2585201673888497664e23Q, + 0.62044840173323943936e24Q, + 0.15511210043330985984e26Q, + 0.403291461126605635584e27Q, + 0.10888869450418352160768e29Q, + 0.304888344611713860501504e30Q, + 0.8841761993739701954543616e31Q, + 0.26525285981219105863630848e33Q, + 0.822283865417792281772556288e34Q, + 0.26313083693369353016721801216e36Q, + 0.868331761881188649551819440128e37Q, + 0.29523279903960414084761860964352e39Q, + 0.103331479663861449296666513375232e41Q, + 0.3719933267899012174679994481508352e42Q, + 0.137637530912263450463159795815809024e44Q, + 0.5230226174666011117600072241000742912e45Q, + 0.203978820811974433586402817399028973568e47Q, + 0.815915283247897734345611269596115894272e48Q, + 0.3345252661316380710817006205344075166515e50Q, + 0.1405006117752879898543142606244511569936e52Q, + 0.6041526306337383563735513206851399750726e53Q, + 0.265827157478844876804362581101461589032e55Q, + 0.1196222208654801945619631614956577150644e57Q, + 0.5502622159812088949850305428800254892962e58Q, + 0.2586232415111681806429643551536119799692e60Q, + 0.1241391559253607267086228904737337503852e62Q, + 0.6082818640342675608722521633212953768876e63Q, + 0.3041409320171337804361260816606476884438e65Q, + 0.1551118753287382280224243016469303211063e67Q, + 0.8065817517094387857166063685640376697529e68Q, + 0.427488328406002556429801375338939964969e70Q, + 0.2308436973392413804720927426830275810833e72Q, + 0.1269640335365827592596510084756651695958e74Q, + 0.7109985878048634518540456474637249497365e75Q, + 0.4052691950487721675568060190543232213498e77Q, + 0.2350561331282878571829474910515074683829e79Q, + 0.1386831185456898357379390197203894063459e81Q, + 0.8320987112741390144276341183223364380754e82Q, + 0.507580213877224798800856812176625227226e84Q, + 0.3146997326038793752565312235495076408801e86Q, + 0.1982608315404440064116146708361898137545e88Q, + 0.1268869321858841641034333893351614808029e90Q, + 0.8247650592082470666723170306785496252186e91Q, + 0.5443449390774430640037292402478427526443e93Q, + 0.3647111091818868528824985909660546442717e95Q, + 0.2480035542436830599600990418569171581047e97Q, + 0.1711224524281413113724683388812728390923e99Q, + 0.1197857166996989179607278372168909873646e101Q, + 0.8504785885678623175211676442399260102886e102Q, + 0.6123445837688608686152407038527467274078e104Q, + 0.4470115461512684340891257138125051110077e106Q, + 0.3307885441519386412259530282212537821457e108Q, + 0.2480914081139539809194647711659403366093e110Q, + 0.188549470166605025498793226086114655823e112Q, + 0.1451830920282858696340707840863082849837e114Q, + 0.1132428117820629783145752115873204622873e116Q, + 0.8946182130782975286851441715398316520698e117Q, + 0.7156945704626380229481153372318653216558e119Q, + 0.5797126020747367985879734231578109105412e121Q, + 0.4753643337012841748421382069894049466438e123Q, + 0.3945523969720658651189747118012061057144e125Q, + 0.3314240134565353266999387579130131288001e127Q, + 0.2817104114380550276949479442260611594801e129Q, + 0.2422709538367273238176552320344125971528e131Q, + 0.210775729837952771721360051869938959523e133Q, + 0.1854826422573984391147968456455462843802e135Q, + 0.1650795516090846108121691926245361930984e137Q, + 0.1485715964481761497309522733620825737886e139Q, + 0.1352001527678402962551665687594951421476e141Q, + 0.1243841405464130725547532432587355307758e143Q, + 0.1156772507081641574759205162306240436215e145Q, + 0.1087366156656743080273652852567866010042e147Q, + 0.103299784882390592625997020993947270954e149Q, + 0.9916779348709496892095714015418938011582e150Q, + 0.9619275968248211985332842594956369871234e152Q, + 0.942689044888324774562618574305724247381e154Q, + 0.9332621544394415268169923885626670049072e156Q, + 0.9332621544394415268169923885626670049072e158Q, + 0.9425947759838359420851623124482936749562e160Q, + 0.9614466715035126609268655586972595484554e162Q, + 0.990290071648618040754671525458177334909e164Q, + 0.1029901674514562762384858386476504428305e167Q, + 0.1081396758240290900504101305800329649721e169Q, + 0.1146280563734708354534347384148349428704e171Q, + 0.1226520203196137939351751701038733888713e173Q, + 0.132464181945182897449989183712183259981e175Q, + 0.1443859583202493582204882102462797533793e177Q, + 0.1588245541522742940425370312709077287172e179Q, + 0.1762952551090244663872161047107075788761e181Q, + 0.1974506857221074023536820372759924883413e183Q, + 0.2231192748659813646596607021218715118256e185Q, + 0.2543559733472187557120132004189335234812e187Q, + 0.2925093693493015690688151804817735520034e189Q, + 0.339310868445189820119825609358857320324e191Q, + 0.396993716080872089540195962949863064779e193Q, + 0.4684525849754290656574312362808384164393e195Q, + 0.5574585761207605881323431711741977155627e197Q, + 0.6689502913449127057588118054090372586753e199Q, + 0.8094298525273443739681622845449350829971e201Q, + 0.9875044200833601362411579871448208012564e203Q, + 0.1214630436702532967576624324188129585545e206Q, + 0.1506141741511140879795014161993280686076e208Q, + 0.1882677176888926099743767702491600857595e210Q, + 0.237217324288004688567714730513941708057e212Q, + 0.3012660018457659544809977077527059692324e214Q, + 0.3856204823625804217356770659234636406175e216Q, + 0.4974504222477287440390234150412680963966e218Q, + 0.6466855489220473672507304395536485253155e220Q, + 0.8471580690878820510984568758152795681634e222Q, + 0.1118248651196004307449963076076169029976e225Q, + 0.1487270706090685728908450891181304809868e227Q, + 0.1992942746161518876737324194182948445223e229Q, + 0.269047270731805048359538766214698040105e231Q, + 0.3659042881952548657689727220519893345429e233Q, + 0.5012888748274991661034926292112253883237e235Q, + 0.6917786472619488492228198283114910358867e237Q, + 0.9615723196941089004197195613529725398826e239Q, + 0.1346201247571752460587607385894161555836e242Q, + 0.1898143759076170969428526414110767793728e244Q, + 0.2695364137888162776588507508037290267094e246Q, + 0.3854370717180072770521565736493325081944e248Q, + 0.5550293832739304789551054660550388118e250Q, + 0.80479260574719919448490292577980627711e252Q, + 0.1174997204390910823947958271638517164581e255Q, + 0.1727245890454638911203498659308620231933e257Q, + 0.2556323917872865588581178015776757943262e259Q, + 0.380892263763056972698595524350736933546e261Q, + 0.571338395644585459047893286526105400319e263Q, + 0.8627209774233240431623188626544191544816e265Q, + 0.1311335885683452545606724671234717114812e268Q, + 0.2006343905095682394778288746989117185662e270Q, + 0.308976961384735088795856467036324046592e272Q, + 0.4789142901463393876335775239063022722176e274Q, + 0.7471062926282894447083809372938315446595e276Q, + 0.1172956879426414428192158071551315525115e279Q, + 0.1853271869493734796543609753051078529682e281Q, + 0.2946702272495038326504339507351214862195e283Q, + 0.4714723635992061322406943211761943779512e285Q, + 0.7590705053947218729075178570936729485014e287Q, + 0.1229694218739449434110178928491750176572e290Q, + 0.2004401576545302577599591653441552787813e292Q, + 0.3287218585534296227263330311644146572013e294Q, + 0.5423910666131588774984495014212841843822e296Q, + 0.9003691705778437366474261723593317460744e298Q, + 0.1503616514864999040201201707840084015944e301Q, + 0.2526075744973198387538018869171341146786e303Q, + 0.4269068009004705274939251888899566538069e305Q, + 0.7257415615307998967396728211129263114717e307Q, + } }; +#else + static const boost::math::array factorials; +#endif +}; + +template +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES +constexpr boost::math::array unchecked_factorial_data::factorials; +#else +const boost::math::array unchecked_factorial_data::factorials = { { + 1, + 1, + 2, + 6, + 24, + 120, + 720, + 5040, + 40320, + 362880.0Q, + 3628800.0Q, + 39916800.0Q, + 479001600.0Q, + 6227020800.0Q, + 87178291200.0Q, + 1307674368000.0Q, + 20922789888000.0Q, + 355687428096000.0Q, + 6402373705728000.0Q, + 121645100408832000.0Q, + 0.243290200817664e19Q, + 0.5109094217170944e20Q, + 0.112400072777760768e22Q, + 0.2585201673888497664e23Q, + 0.62044840173323943936e24Q, + 0.15511210043330985984e26Q, + 0.403291461126605635584e27Q, + 0.10888869450418352160768e29Q, + 0.304888344611713860501504e30Q, + 0.8841761993739701954543616e31Q, + 0.26525285981219105863630848e33Q, + 0.822283865417792281772556288e34Q, + 0.26313083693369353016721801216e36Q, + 0.868331761881188649551819440128e37Q, + 0.29523279903960414084761860964352e39Q, + 0.103331479663861449296666513375232e41Q, + 0.3719933267899012174679994481508352e42Q, + 0.137637530912263450463159795815809024e44Q, + 0.5230226174666011117600072241000742912e45Q, + 0.203978820811974433586402817399028973568e47Q, + 0.815915283247897734345611269596115894272e48Q, + 0.3345252661316380710817006205344075166515e50Q, + 0.1405006117752879898543142606244511569936e52Q, + 0.6041526306337383563735513206851399750726e53Q, + 0.265827157478844876804362581101461589032e55Q, + 0.1196222208654801945619631614956577150644e57Q, + 0.5502622159812088949850305428800254892962e58Q, + 0.2586232415111681806429643551536119799692e60Q, + 0.1241391559253607267086228904737337503852e62Q, + 0.6082818640342675608722521633212953768876e63Q, + 0.3041409320171337804361260816606476884438e65Q, + 0.1551118753287382280224243016469303211063e67Q, + 0.8065817517094387857166063685640376697529e68Q, + 0.427488328406002556429801375338939964969e70Q, + 0.2308436973392413804720927426830275810833e72Q, + 0.1269640335365827592596510084756651695958e74Q, + 0.7109985878048634518540456474637249497365e75Q, + 0.4052691950487721675568060190543232213498e77Q, + 0.2350561331282878571829474910515074683829e79Q, + 0.1386831185456898357379390197203894063459e81Q, + 0.8320987112741390144276341183223364380754e82Q, + 0.507580213877224798800856812176625227226e84Q, + 0.3146997326038793752565312235495076408801e86Q, + 0.1982608315404440064116146708361898137545e88Q, + 0.1268869321858841641034333893351614808029e90Q, + 0.8247650592082470666723170306785496252186e91Q, + 0.5443449390774430640037292402478427526443e93Q, + 0.3647111091818868528824985909660546442717e95Q, + 0.2480035542436830599600990418569171581047e97Q, + 0.1711224524281413113724683388812728390923e99Q, + 0.1197857166996989179607278372168909873646e101Q, + 0.8504785885678623175211676442399260102886e102Q, + 0.6123445837688608686152407038527467274078e104Q, + 0.4470115461512684340891257138125051110077e106Q, + 0.3307885441519386412259530282212537821457e108Q, + 0.2480914081139539809194647711659403366093e110Q, + 0.188549470166605025498793226086114655823e112Q, + 0.1451830920282858696340707840863082849837e114Q, + 0.1132428117820629783145752115873204622873e116Q, + 0.8946182130782975286851441715398316520698e117Q, + 0.7156945704626380229481153372318653216558e119Q, + 0.5797126020747367985879734231578109105412e121Q, + 0.4753643337012841748421382069894049466438e123Q, + 0.3945523969720658651189747118012061057144e125Q, + 0.3314240134565353266999387579130131288001e127Q, + 0.2817104114380550276949479442260611594801e129Q, + 0.2422709538367273238176552320344125971528e131Q, + 0.210775729837952771721360051869938959523e133Q, + 0.1854826422573984391147968456455462843802e135Q, + 0.1650795516090846108121691926245361930984e137Q, + 0.1485715964481761497309522733620825737886e139Q, + 0.1352001527678402962551665687594951421476e141Q, + 0.1243841405464130725547532432587355307758e143Q, + 0.1156772507081641574759205162306240436215e145Q, + 0.1087366156656743080273652852567866010042e147Q, + 0.103299784882390592625997020993947270954e149Q, + 0.9916779348709496892095714015418938011582e150Q, + 0.9619275968248211985332842594956369871234e152Q, + 0.942689044888324774562618574305724247381e154Q, + 0.9332621544394415268169923885626670049072e156Q, + 0.9332621544394415268169923885626670049072e158Q, + 0.9425947759838359420851623124482936749562e160Q, + 0.9614466715035126609268655586972595484554e162Q, + 0.990290071648618040754671525458177334909e164Q, + 0.1029901674514562762384858386476504428305e167Q, + 0.1081396758240290900504101305800329649721e169Q, + 0.1146280563734708354534347384148349428704e171Q, + 0.1226520203196137939351751701038733888713e173Q, + 0.132464181945182897449989183712183259981e175Q, + 0.1443859583202493582204882102462797533793e177Q, + 0.1588245541522742940425370312709077287172e179Q, + 0.1762952551090244663872161047107075788761e181Q, + 0.1974506857221074023536820372759924883413e183Q, + 0.2231192748659813646596607021218715118256e185Q, + 0.2543559733472187557120132004189335234812e187Q, + 0.2925093693493015690688151804817735520034e189Q, + 0.339310868445189820119825609358857320324e191Q, + 0.396993716080872089540195962949863064779e193Q, + 0.4684525849754290656574312362808384164393e195Q, + 0.5574585761207605881323431711741977155627e197Q, + 0.6689502913449127057588118054090372586753e199Q, + 0.8094298525273443739681622845449350829971e201Q, + 0.9875044200833601362411579871448208012564e203Q, + 0.1214630436702532967576624324188129585545e206Q, + 0.1506141741511140879795014161993280686076e208Q, + 0.1882677176888926099743767702491600857595e210Q, + 0.237217324288004688567714730513941708057e212Q, + 0.3012660018457659544809977077527059692324e214Q, + 0.3856204823625804217356770659234636406175e216Q, + 0.4974504222477287440390234150412680963966e218Q, + 0.6466855489220473672507304395536485253155e220Q, + 0.8471580690878820510984568758152795681634e222Q, + 0.1118248651196004307449963076076169029976e225Q, + 0.1487270706090685728908450891181304809868e227Q, + 0.1992942746161518876737324194182948445223e229Q, + 0.269047270731805048359538766214698040105e231Q, + 0.3659042881952548657689727220519893345429e233Q, + 0.5012888748274991661034926292112253883237e235Q, + 0.6917786472619488492228198283114910358867e237Q, + 0.9615723196941089004197195613529725398826e239Q, + 0.1346201247571752460587607385894161555836e242Q, + 0.1898143759076170969428526414110767793728e244Q, + 0.2695364137888162776588507508037290267094e246Q, + 0.3854370717180072770521565736493325081944e248Q, + 0.5550293832739304789551054660550388118e250Q, + 0.80479260574719919448490292577980627711e252Q, + 0.1174997204390910823947958271638517164581e255Q, + 0.1727245890454638911203498659308620231933e257Q, + 0.2556323917872865588581178015776757943262e259Q, + 0.380892263763056972698595524350736933546e261Q, + 0.571338395644585459047893286526105400319e263Q, + 0.8627209774233240431623188626544191544816e265Q, + 0.1311335885683452545606724671234717114812e268Q, + 0.2006343905095682394778288746989117185662e270Q, + 0.308976961384735088795856467036324046592e272Q, + 0.4789142901463393876335775239063022722176e274Q, + 0.7471062926282894447083809372938315446595e276Q, + 0.1172956879426414428192158071551315525115e279Q, + 0.1853271869493734796543609753051078529682e281Q, + 0.2946702272495038326504339507351214862195e283Q, + 0.4714723635992061322406943211761943779512e285Q, + 0.7590705053947218729075178570936729485014e287Q, + 0.1229694218739449434110178928491750176572e290Q, + 0.2004401576545302577599591653441552787813e292Q, + 0.3287218585534296227263330311644146572013e294Q, + 0.5423910666131588774984495014212841843822e296Q, + 0.9003691705778437366474261723593317460744e298Q, + 0.1503616514864999040201201707840084015944e301Q, + 0.2526075744973198387538018869171341146786e303Q, + 0.4269068009004705274939251888899566538069e305Q, + 0.7257415615307998967396728211129263114717e307Q, + } }; +#endif + +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION BOOST_MATH_FLOAT128_TYPE unchecked_factorial(unsigned i) +{ + return unchecked_factorial_data::factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +#endif + +template +inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant&) +{ + // + // If you're foolish enough to instantiate factorial + // on an integer type then you end up here. But this code is + // only intended for (fixed precision) multiprecision types. + // + // Note, factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + // + static_assert(!boost::math::is_integral::value && !boost::math::numeric_limits::is_integer, "Type T must not be an integral type"); + + // We rely on C++11 thread safe initialization here: + static const boost::math::array factorials = {{ + T(boost::math::tools::convert_from_string("1")), + T(boost::math::tools::convert_from_string("1")), + T(boost::math::tools::convert_from_string("2")), + T(boost::math::tools::convert_from_string("6")), + T(boost::math::tools::convert_from_string("24")), + T(boost::math::tools::convert_from_string("120")), + T(boost::math::tools::convert_from_string("720")), + T(boost::math::tools::convert_from_string("5040")), + T(boost::math::tools::convert_from_string("40320")), + T(boost::math::tools::convert_from_string("362880")), + T(boost::math::tools::convert_from_string("3628800")), + T(boost::math::tools::convert_from_string("39916800")), + T(boost::math::tools::convert_from_string("479001600")), + T(boost::math::tools::convert_from_string("6227020800")), + T(boost::math::tools::convert_from_string("87178291200")), + T(boost::math::tools::convert_from_string("1307674368000")), + T(boost::math::tools::convert_from_string("20922789888000")), + T(boost::math::tools::convert_from_string("355687428096000")), + T(boost::math::tools::convert_from_string("6402373705728000")), + T(boost::math::tools::convert_from_string("121645100408832000")), + T(boost::math::tools::convert_from_string("2432902008176640000")), + T(boost::math::tools::convert_from_string("51090942171709440000")), + T(boost::math::tools::convert_from_string("1124000727777607680000")), + T(boost::math::tools::convert_from_string("25852016738884976640000")), + T(boost::math::tools::convert_from_string("620448401733239439360000")), + T(boost::math::tools::convert_from_string("15511210043330985984000000")), + T(boost::math::tools::convert_from_string("403291461126605635584000000")), + T(boost::math::tools::convert_from_string("10888869450418352160768000000")), + T(boost::math::tools::convert_from_string("304888344611713860501504000000")), + T(boost::math::tools::convert_from_string("8841761993739701954543616000000")), + T(boost::math::tools::convert_from_string("265252859812191058636308480000000")), + T(boost::math::tools::convert_from_string("8222838654177922817725562880000000")), + T(boost::math::tools::convert_from_string("263130836933693530167218012160000000")), + T(boost::math::tools::convert_from_string("8683317618811886495518194401280000000")), + T(boost::math::tools::convert_from_string("295232799039604140847618609643520000000")), + T(boost::math::tools::convert_from_string("10333147966386144929666651337523200000000")), + T(boost::math::tools::convert_from_string("371993326789901217467999448150835200000000")), + T(boost::math::tools::convert_from_string("13763753091226345046315979581580902400000000")), + T(boost::math::tools::convert_from_string("523022617466601111760007224100074291200000000")), + T(boost::math::tools::convert_from_string("20397882081197443358640281739902897356800000000")), + T(boost::math::tools::convert_from_string("815915283247897734345611269596115894272000000000")), + T(boost::math::tools::convert_from_string("33452526613163807108170062053440751665152000000000")), + T(boost::math::tools::convert_from_string("1405006117752879898543142606244511569936384000000000")), + T(boost::math::tools::convert_from_string("60415263063373835637355132068513997507264512000000000")), + T(boost::math::tools::convert_from_string("2658271574788448768043625811014615890319638528000000000")), + T(boost::math::tools::convert_from_string("119622220865480194561963161495657715064383733760000000000")), + T(boost::math::tools::convert_from_string("5502622159812088949850305428800254892961651752960000000000")), + T(boost::math::tools::convert_from_string("258623241511168180642964355153611979969197632389120000000000")), + T(boost::math::tools::convert_from_string("12413915592536072670862289047373375038521486354677760000000000")), + T(boost::math::tools::convert_from_string("608281864034267560872252163321295376887552831379210240000000000")), + T(boost::math::tools::convert_from_string("30414093201713378043612608166064768844377641568960512000000000000")), + T(boost::math::tools::convert_from_string("1551118753287382280224243016469303211063259720016986112000000000000")), + T(boost::math::tools::convert_from_string("80658175170943878571660636856403766975289505440883277824000000000000")), + T(boost::math::tools::convert_from_string("4274883284060025564298013753389399649690343788366813724672000000000000")), + T(boost::math::tools::convert_from_string("230843697339241380472092742683027581083278564571807941132288000000000000")), + T(boost::math::tools::convert_from_string("12696403353658275925965100847566516959580321051449436762275840000000000000")), + T(boost::math::tools::convert_from_string("710998587804863451854045647463724949736497978881168458687447040000000000000")), + T(boost::math::tools::convert_from_string("40526919504877216755680601905432322134980384796226602145184481280000000000000")), + T(boost::math::tools::convert_from_string("2350561331282878571829474910515074683828862318181142924420699914240000000000000")), + T(boost::math::tools::convert_from_string("138683118545689835737939019720389406345902876772687432540821294940160000000000000")), + T(boost::math::tools::convert_from_string("8320987112741390144276341183223364380754172606361245952449277696409600000000000000")), + T(boost::math::tools::convert_from_string("507580213877224798800856812176625227226004528988036003099405939480985600000000000000")), + T(boost::math::tools::convert_from_string("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000")), + T(boost::math::tools::convert_from_string("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000")), + T(boost::math::tools::convert_from_string("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000")), + T(boost::math::tools::convert_from_string("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000")), + T(boost::math::tools::convert_from_string("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000")), + T(boost::math::tools::convert_from_string("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000")), + T(boost::math::tools::convert_from_string("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000")), + T(boost::math::tools::convert_from_string("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000")), + T(boost::math::tools::convert_from_string("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000")), + T(boost::math::tools::convert_from_string("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000")), + T(boost::math::tools::convert_from_string("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000")), + T(boost::math::tools::convert_from_string("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000")), + T(boost::math::tools::convert_from_string("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000")), + T(boost::math::tools::convert_from_string("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000")), + T(boost::math::tools::convert_from_string("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000")), + T(boost::math::tools::convert_from_string("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000")), + T(boost::math::tools::convert_from_string("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000")), + T(boost::math::tools::convert_from_string("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000")), + T(boost::math::tools::convert_from_string("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000")), + T(boost::math::tools::convert_from_string("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000")), + T(boost::math::tools::convert_from_string("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000")), + T(boost::math::tools::convert_from_string("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000")), + T(boost::math::tools::convert_from_string("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000")), + T(boost::math::tools::convert_from_string("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000")), + T(boost::math::tools::convert_from_string("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000")), + T(boost::math::tools::convert_from_string("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000")), + T(boost::math::tools::convert_from_string("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000")), + T(boost::math::tools::convert_from_string("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000")), + T(boost::math::tools::convert_from_string("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000")), + T(boost::math::tools::convert_from_string("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000")), + T(boost::math::tools::convert_from_string("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000")), + T(boost::math::tools::convert_from_string("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000")), + T(boost::math::tools::convert_from_string("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000")), + T(boost::math::tools::convert_from_string("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000")), + T(boost::math::tools::convert_from_string("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000")), + T(boost::math::tools::convert_from_string("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000")), + T(boost::math::tools::convert_from_string("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000")), + T(boost::math::tools::convert_from_string("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000")), + T(boost::math::tools::convert_from_string("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000")), + }}; + + return factorials[i]; +} + +template +inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant&) +{ + // + // If you're foolish enough to instantiate factorial + // on an integer type then you end up here. But this code is + // only intended for (variable precision) multiprecision types. + // + // Note, factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + // + static_assert(!boost::math::is_integral::value && !boost::math::numeric_limits::is_integer, "Type T must not be an integral type"); + + static const char* const factorial_strings[] = { + "1", + "1", + "2", + "6", + "24", + "120", + "720", + "5040", + "40320", + "362880", + "3628800", + "39916800", + "479001600", + "6227020800", + "87178291200", + "1307674368000", + "20922789888000", + "355687428096000", + "6402373705728000", + "121645100408832000", + "2432902008176640000", + "51090942171709440000", + "1124000727777607680000", + "25852016738884976640000", + "620448401733239439360000", + "15511210043330985984000000", + "403291461126605635584000000", + "10888869450418352160768000000", + "304888344611713860501504000000", + "8841761993739701954543616000000", + "265252859812191058636308480000000", + "8222838654177922817725562880000000", + "263130836933693530167218012160000000", + "8683317618811886495518194401280000000", + "295232799039604140847618609643520000000", + "10333147966386144929666651337523200000000", + "371993326789901217467999448150835200000000", + "13763753091226345046315979581580902400000000", + "523022617466601111760007224100074291200000000", + "20397882081197443358640281739902897356800000000", + "815915283247897734345611269596115894272000000000", + "33452526613163807108170062053440751665152000000000", + "1405006117752879898543142606244511569936384000000000", + "60415263063373835637355132068513997507264512000000000", + "2658271574788448768043625811014615890319638528000000000", + "119622220865480194561963161495657715064383733760000000000", + "5502622159812088949850305428800254892961651752960000000000", + "258623241511168180642964355153611979969197632389120000000000", + "12413915592536072670862289047373375038521486354677760000000000", + "608281864034267560872252163321295376887552831379210240000000000", + "30414093201713378043612608166064768844377641568960512000000000000", + "1551118753287382280224243016469303211063259720016986112000000000000", + "80658175170943878571660636856403766975289505440883277824000000000000", + "4274883284060025564298013753389399649690343788366813724672000000000000", + "230843697339241380472092742683027581083278564571807941132288000000000000", + "12696403353658275925965100847566516959580321051449436762275840000000000000", + "710998587804863451854045647463724949736497978881168458687447040000000000000", + "40526919504877216755680601905432322134980384796226602145184481280000000000000", + "2350561331282878571829474910515074683828862318181142924420699914240000000000000", + "138683118545689835737939019720389406345902876772687432540821294940160000000000000", + "8320987112741390144276341183223364380754172606361245952449277696409600000000000000", + "507580213877224798800856812176625227226004528988036003099405939480985600000000000000", + "31469973260387937525653122354950764088012280797258232192163168247821107200000000000000", + "1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000", + "126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000", + "8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000", + "544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000", + "36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000", + "2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000", + "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000", + "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000", + "850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000", + "61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000", + "4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000", + "330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000", + "24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000", + "1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000", + "145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000", + "11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000", + "894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000", + "71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000", + "5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000", + "475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000", + "39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000", + "3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000", + "281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000", + "24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000", + "2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000", + "185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000", + "16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000", + "1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000", + "135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000", + "12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000", + "1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000", + "108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000", + "10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000", + "991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000", + "96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000", + "9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000", + "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000", + "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000", + }; + // + // we rely on C++11 thread safe initialization in the event that we have no thread locals: + // + static BOOST_MATH_THREAD_LOCAL T factorials[sizeof(factorial_strings) / sizeof(factorial_strings[0])]; + static BOOST_MATH_THREAD_LOCAL int digits = 0; + + int current_digits = boost::math::tools::digits(); + + if(digits != current_digits) + { + digits = current_digits; + for(unsigned k = 0; k < sizeof(factorials) / sizeof(factorials[0]); ++k) + factorials[k] = static_cast(boost::math::tools::convert_from_string(factorial_strings[k])); + } + + return factorials[i]; +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +template +BOOST_MATH_GPU_ENABLED inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant::digits>&) +{ + return unchecked_factorial(i); +} + +template +BOOST_MATH_GPU_ENABLED inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant::digits>&) +{ + return unchecked_factorial(i); +} + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +#if DBL_MANT_DIG != LDBL_MANT_DIG +template +inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant&) +{ + return unchecked_factorial(i); +} +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +template +inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant&) +{ + return unchecked_factorial(i); +} +#endif + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +template +BOOST_MATH_GPU_ENABLED inline T unchecked_factorial(unsigned i) +{ + typedef typename boost::math::policies::precision >::type tag_type; + return unchecked_factorial_imp(i, tag_type()); +} + +#ifdef BOOST_MATH_USE_FLOAT128 +#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL : boost::math::numeric_limits::digits == 113 ? max_factorial::value +#else +#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL +#endif + +template +struct max_factorial +{ + static constexpr unsigned value = + boost::math::numeric_limits::digits == boost::math::numeric_limits::digits ? max_factorial::value + : boost::math::numeric_limits::digits == boost::math::numeric_limits::digits ? max_factorial::value + #ifndef BOOST_MATH_GPU_ENABLED + : boost::math::numeric_limits::digits == boost::math::numeric_limits::digits ? max_factorial::value + BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL + #endif + : 100; +}; + +#undef BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +template +constexpr unsigned max_factorial::value; +#endif + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_UC_FACTORIALS_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/digamma.hpp b/third-party/boost-math/include/boost/math/special_functions/digamma.hpp new file mode 100644 index 0000000000000..718bd455297c7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/digamma.hpp @@ -0,0 +1,631 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SF_DIGAMMA_HPP +#define BOOST_MATH_SF_DIGAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#include +#include +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ +namespace math{ +namespace detail{ +// +// Begin by defining the smallest value for which it is safe to +// use the asymptotic expansion for digamma: +// +BOOST_MATH_GPU_ENABLED inline unsigned digamma_large_lim(const boost::math::integral_constant*) +{ return 20; } +BOOST_MATH_GPU_ENABLED inline unsigned digamma_large_lim(const boost::math::integral_constant*) +{ return 20; } +BOOST_MATH_GPU_ENABLED inline unsigned digamma_large_lim(const void*) +{ return 10; } +// +// Implementations of the asymptotic expansion come next, +// the coefficients of the series have been evaluated +// in advance at high precision, and the series truncated +// at the first term that's too small to effect the result. +// Note that the series becomes divergent after a while +// so truncation is very important. +// +// This first one gives 34-digit precision for x >= 20: +// + +#ifndef BOOST_MATH_HAS_NVRTC +template +inline T digamma_imp_large(T x, const boost::math::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.003968253968253968253968253968253968253968253968254), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0041666666666666666666666666666666666666666666666667), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0075757575757575757575757575757575757575757575757576), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.021092796092796092796092796092796092796092796092796), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.44325980392156862745098039215686274509803921568627), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.0539543302701197438039543302701197438039543302701), + BOOST_MATH_BIG_CONSTANT(T, 113, -26.456212121212121212121212121212121212121212121212), + BOOST_MATH_BIG_CONSTANT(T, 113, 281.4601449275362318840579710144927536231884057971), + BOOST_MATH_BIG_CONSTANT(T, 113, -3607.510546398046398046398046398046398046398046398), + BOOST_MATH_BIG_CONSTANT(T, 113, 54827.583333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -974936.82385057471264367816091954022988505747126437), + BOOST_MATH_BIG_CONSTANT(T, 113, 20052695.796688078946143462272494530559046688078946), + BOOST_MATH_BIG_CONSTANT(T, 113, -472384867.72162990196078431372549019607843137254902), + BOOST_MATH_BIG_CONSTANT(T, 113, 12635724795.916666666666666666666666666666666666667) + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// 19-digit precision for x >= 10: +// +template +inline T digamma_imp_large(T x, const boost::math::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.003968253968253968253968253968253968253968253968254), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0041666666666666666666666666666666666666666666666667), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0075757575757575757575757575757575757575757575757576), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.021092796092796092796092796092796092796092796092796), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.44325980392156862745098039215686274509803921568627), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.0539543302701197438039543302701197438039543302701), + BOOST_MATH_BIG_CONSTANT(T, 64, -26.456212121212121212121212121212121212121212121212), + BOOST_MATH_BIG_CONSTANT(T, 64, 281.4601449275362318840579710144927536231884057971), + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +#endif +// +// 17-digit precision for x >= 10: +// +template +BOOST_MATH_GPU_ENABLED inline T digamma_imp_large(T x, const boost::math::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + BOOST_MATH_STATIC const T P[] = { + 0.083333333333333333333333333333333333333333333333333, + -0.0083333333333333333333333333333333333333333333333333, + 0.003968253968253968253968253968253968253968253968254, + -0.0041666666666666666666666666666666666666666666666667, + 0.0075757575757575757575757575757575757575757575757576, + -0.021092796092796092796092796092796092796092796092796, + 0.083333333333333333333333333333333333333333333333333, + -0.44325980392156862745098039215686274509803921568627 + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// 9-digit precision for x >= 10: +// +template +BOOST_MATH_GPU_ENABLED inline T digamma_imp_large(T x, const boost::math::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + BOOST_MATH_STATIC const T P[] = { + 0.083333333333333333333333333333333333333333333333333f, + -0.0083333333333333333333333333333333333333333333333333f, + 0.003968253968253968253968253968253968253968253968254f + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} + +#ifndef BOOST_MATH_HAS_NVRTC +// +// Fully generic asymptotic expansion in terms of Bernoulli numbers, see: +// http://functions.wolfram.com/06.14.06.0012.01 +// +// LCOV_EXCL_START muliprecision only. +template +struct digamma_series_func +{ +private: + int k; + T xx; + T term; +public: + digamma_series_func(T x) : k(1), xx(x * x), term(1 / (x * x)) {} + T operator()() + { + T result = term * boost::math::bernoulli_b2n(k) / (2 * k); + term /= xx; + ++k; + return result; + } + typedef T result_type; +}; + +template +inline T digamma_imp_large(T x, const Policy& pol, const boost::math::integral_constant*) +{ + BOOST_MATH_STD_USING + digamma_series_func s(x); + T result = log(x) - 1 / (2 * x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, -result); + result = -result; + policies::check_series_iterations("boost::math::digamma<%1%>(%1%)", max_iter, pol); + return result; +} +// LCOV_EXCL_STOP +// +// Now follow rational approximations over the range [1,2]. +// +// 35-digit precision: +// +template +T digamma_imp_1_2(T x, const boost::math::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Max error found at 128-bit long double precision: 5.541e-35 + // Maximum Deviation Found (approximation error): 1.965e-35 + // + // LCOV_EXCL_START + static const float Y = 0.99558162689208984375F; + + static const T root1 = T(1569415565) / 1073741824uL; + static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + static const T root3 = ((T(111616537) / 1073741824uL) / 1073741824uL) / 1073741824uL; + static const T root4 = (((T(503992070) / 1073741824uL) / 1073741824uL) / 1073741824uL) / 1073741824uL; + static const T root5 = BOOST_MATH_BIG_CONSTANT(T, 113, 0.52112228569249997894452490385577338504019838794544e-36); + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.25479851061131551526977464225335883769), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.18684290534374944114622235683619897417), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.80360876047931768958995775910991929922), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.67227342794829064330498117008564270136), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26569010991230617151285010695543858005), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.05775672694575986971640757748003553385), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0071432147823164975485922555833274240665), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00048740753910766168912364555706064993274), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16454996865214115723416538844975174761e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.20327832297631728077731148515093164955e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6210924610812025425088411043163287646), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6850757078559596612621337395886392594), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.4320913706209965531250495490639289418), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.4410872083455009362557012239501953402), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.081385727399251729505165509278152487225), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089478633066857163432104815183858149496), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00055861622855066424871506755481997374154), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.1760168552357342401304462967950178554e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.20585454493572473724556649516040874384e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.90745971844439990284514121823069162795e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.48857673606545846774761343500033283272e-13), + }; + // LCOV_EXCL_STOP + T g = x - root1; + g -= root2; + g -= root3; + g -= root4; + g -= root5; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} +// +// 19-digit precision: +// +template +T digamma_imp_1_2(T x, const boost::math::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Max error found at 80-bit long double precision: 5.016e-20 + // Maximum Deviation Found (approximation error): 3.575e-20 + // + // LCOV_EXCL_START + static const float Y = 0.99558162689208984375F; + + static const T root1 = T(1569415565) / 1073741824uL; + static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.9016312093258695918615325266959189453125e-19); + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.254798510611315515235), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.314628554532916496608), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.665836341559876230295), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.314767657147375752913), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0541156266153505273939), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00289268368333918761452) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.1195759927055347547), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.54350554664961128724), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.486986018231042975162), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0660481487173569812846), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00298999662592323990972), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.165079794012604905639e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.317940243105952177571e-7) + }; + // LCOV_EXCL_STOP + T g = x - root1; + g -= root2; + g -= root3; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} + +#endif +// +// 18-digit precision: +// +template +BOOST_MATH_GPU_ENABLED T digamma_imp_1_2(T x, const boost::math::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Maximum Deviation Found: 1.466e-18 + // At double precision, max error found: 2.452e-17 + // + // LCOV_EXCL_START + BOOST_MATH_STATIC const float Y = 0.99558162689208984F; + + BOOST_MATH_STATIC const T root1 = T(1569415565) / 1073741824uL; + BOOST_MATH_STATIC const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + BOOST_MATH_STATIC const T root3 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.9016312093258695918615325266959189453125e-19); + + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.25479851061131551), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.32555031186804491), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.65031853770896507), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.28919126444774784), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.045251321448739056), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0020713321167745952) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.0767117023730469), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.4606242909763515), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.43593529692665969), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.054151797245674225), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0021284987017821144), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.55789841321675513e-6) + }; + // LCOV_EXCL_STOP + T g = x - root1; + g -= root2; + g -= root3; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} +// +// 9-digit precision: +// +template +BOOST_MATH_GPU_ENABLED inline T digamma_imp_1_2(T x, const boost::math::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Maximum Deviation Found: 3.388e-010 + // At float precision, max error found: 2.008725e-008 + // + // LCOV_EXCL_START + BOOST_MATH_STATIC const float Y = 0.99558162689208984f; + BOOST_MATH_STATIC const T root = 1532632.0f / 1048576; + BOOST_MATH_STATIC const T root_minor = static_cast(0.3700660185912626595423257213284682051735604e-6L); + BOOST_MATH_STATIC const T P[] = { + 0.25479851023250261e0f, + -0.44981331915268368e0f, + -0.43916936919946835e0f, + -0.61041765350579073e-1f + }; + BOOST_MATH_STATIC const T Q[] = { + 0.1e1f, + 0.15890202430554952e1f, + 0.65341249856146947e0f, + 0.63851690523355715e-1f + }; + // LCOV_EXCL_STOP + T g = x - root; + g -= root_minor; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED T digamma_imp(T x, const Tag* t, const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= -1) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + T remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > T(0.5)) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + if(x == 0) + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, x, pol); + // + // If we're above the lower-limit for the + // asymptotic expansion then use it: + // + #ifndef BOOST_MATH_HAS_NVRTC + if(x >= digamma_large_lim(t)) + { + result += digamma_imp_large(x, t); + } + else + #endif + { + // + // If x > 2 reduce to the interval [1,2]: + // + while(x > 2) + { + x -= 1; + result += 1/x; + } + // + // If x < 1 use recurrence to shift to > 1: + // + while(x < 1) + { + result -= 1/x; + x += 1; + } + result += digamma_imp_1_2(x, t); + } + return result; +} + +#ifndef BOOST_MATH_HAS_NVRTC + +// LCOV_EXCL_START +template +T digamma_imp(T x, const boost::math::integral_constant* t, const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + // This is covered by our real_concept tests, but these are disabled for + // code coverage runs for performance reasons. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= -1) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + T remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > T(0.5)) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1 - x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + if(x == 0) + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, x, pol); + // + // If we're above the lower-limit for the + // asymptotic expansion then use it, the + // limit is a linear interpolation with + // limit = 10 at 50 bit precision and + // limit = 250 at 1000 bit precision. + // + int lim = 10 + ((tools::digits() - 50) * 240L) / 950; + T two_x = ldexp(x, 1); + if(x >= lim) + { + result += digamma_imp_large(x, pol, t); + } + else if(floor(x) == x) + { + // + // Special case for integer arguments, see + // http://functions.wolfram.com/06.14.03.0001.01 + // + result = -constants::euler(); + T val = 1; + while(val < x) + { + result += 1 / val; + val += 1; + } + } + else if(floor(two_x) == two_x) + { + // + // Special case for half integer arguments, see: + // http://functions.wolfram.com/06.14.03.0007.01 + // + result = -2 * constants::ln_two() - constants::euler(); + int n = itrunc(x); + if(n) + { + for(int k = 1; k < n; ++k) + result += 1 / T(k); + for(int k = n; k <= 2 * n - 1; ++k) + result += 2 / T(k); + } + } + else + { + // + // Rescale so we can use the asymptotic expansion: + // + while(x < lim) + { + result -= 1 / x; + x += 1; + } + result += digamma_imp_large(x, pol, t); + } + return result; +} +// LCOV_EXCL_STOP + +#endif + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + digamma(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant 113) ? 0 : + precision_type::value <= 24 ? 24 : + precision_type::value <= 53 ? 53 : + precision_type::value <= 64 ? 64 : + precision_type::value <= 113 ? 113 : 0 > tag_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::digamma_imp(static_cast(x), static_cast(nullptr), forwarding_policy()), "boost::math::digamma<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + digamma(T x) +{ + return digamma(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_1.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_1.hpp new file mode 100644 index 0000000000000..96c7c9e9b9a14 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_1.hpp @@ -0,0 +1,815 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_1_HPP +#define BOOST_MATH_ELLINT_1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the first kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&); +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&); +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&); +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, T one_minus_k2); + +// Elliptic integral (Legendre form) of the first kind +template +BOOST_MATH_GPU_ENABLED T ellint_f_imp(T phi, T k, const Policy& pol, T one_minus_k2) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + constexpr auto function = "boost::math::ellint_f<%1%>(%1%,%1%)"; + BOOST_MATH_INSTRUMENT_VARIABLE(phi); + BOOST_MATH_INSTRUMENT_VARIABLE(k); + BOOST_MATH_INSTRUMENT_VARIABLE(function); + + bool invert = false; + if(phi < 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(phi); + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error(function, nullptr, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(phi > 1 / tools::epsilon()) + { + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + result = 2 * phi * ellint_k_imp(k, pol, one_minus_k2) / constants::pi(); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + BOOST_MATH_INSTRUMENT_CODE("pi/2 = " << constants::pi() / 2); + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + BOOST_MATH_INSTRUMENT_VARIABLE(m); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + } + T sinp = sin(rphi); + sinp *= sinp; + if (sinp * k * k >= 1) + { + return policies::raise_domain_error(function, + "Got k^2 * sin^2(phi) = %1%, but the function requires this < 1", sinp * k * k, pol); + } + T cosp = cos(rphi); + cosp *= cosp; + BOOST_MATH_INSTRUMENT_VARIABLE(sinp); + BOOST_MATH_INSTRUMENT_VARIABLE(cosp); + if(sinp > tools::min_value()) + { + BOOST_MATH_ASSERT(rphi != 0); // precondition, can't be true if sin(rphi) != 0. + // + // Use http://dlmf.nist.gov/19.25#E5, note that + // c-1 simplifies to cot^2(rphi) which avoids cancellation. + // Likewise c - k^2 is the same as (c - 1) + (1 - k^2). + // + T c = 1 / sinp; + T c_minus_one = cosp / sinp; + T arg2; + if (k != 0) + { + T cross = fabs(c / (k * k)); + if ((cross > 0.9f) && (cross < 1.1f)) + arg2 = c_minus_one + one_minus_k2; + else + arg2 = c - k * k; + } + else + arg2 = c; + result = static_cast(s * ellint_rf_imp(c_minus_one, arg2, c, pol)); + } + else + result = s * sin(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(m != 0) + { + result += m * ellint_k_imp(k, pol, one_minus_k2); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + return invert ? T(-result) : result; +} + +template +BOOST_MATH_GPU_ENABLED inline T ellint_f_imp(T phi, T k, const Policy& pol) +{ + return ellint_f_imp(phi, k, pol, T(1 - k * k)); +} + +// Complete elliptic integral (Legendre form) of the first kind +template +BOOST_MATH_GPU_ENABLED T ellint_k_imp(T k, const Policy& pol, T one_minus_k2) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + constexpr auto function = "boost::math::ellint_k<%1%>(%1%)"; + + if (abs(k) > 1) + { + return policies::raise_domain_error(function, "Got k = %1%, function requires |k| <= 1", k, pol); + } + if (abs(k) == 1) + { + return policies::raise_overflow_error(function, nullptr, pol); + } + + T x = 0; + T z = 1; + T value = ellint_rf_imp(x, one_minus_k2, z, pol); + + return value; +} +template +BOOST_MATH_GPU_ENABLED inline T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + return ellint_k_imp(k, pol, T(1 - k * k)); +} + +// +// Special versions for double and 80-bit long double precision, +// double precision versions use the coefficients from: +// "Fast computation of complete elliptic integrals and Jacobian elliptic functions", +// Celestial Mechanics and Dynamical Astronomy, April 2012. +// +// Higher precision coefficients for 80-bit long doubles can be calculated +// using for example: +// Table[N[SeriesCoefficient[ EllipticK [ m ], { m, 875/1000, i} ], 20], {i, 0, 24}] +// and checking the value of the first neglected term with: +// N[SeriesCoefficient[ EllipticK [ m ], { m, 875/1000, 24} ], 20] * (2.5/100)^24 +// +// For m > 0.9 we don't use the method of the paper above, but simply call our +// existing routines. The routine used in the above paper was tried (and is +// archived in the code below), but was found to have slightly higher error rates. +// +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + T m = k * k; + + switch (static_cast(m * 20)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + static_cast(1.591003453790792180), + static_cast(0.416000743991786912), + static_cast(0.245791514264103415), + static_cast(0.179481482914906162), + static_cast(0.144556057087555150), + static_cast(0.123200993312427711), + static_cast(0.108938811574293531), + static_cast(0.098853409871592910), + static_cast(0.091439629201749751), + static_cast(0.085842591595413900), + static_cast(0.081541118718303215), + static_cast(0.078199656811256481910) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.05)); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + static_cast(1.635256732264579992), + static_cast(0.471190626148732291), + static_cast(0.309728410831499587), + static_cast(0.252208311773135699), + static_cast(0.226725623219684650), + static_cast(0.215774446729585976), + static_cast(0.213108771877348910), + static_cast(0.216029124605188282), + static_cast(0.223255831633057896), + static_cast(0.234180501294209925), + static_cast(0.248557682972264071), + static_cast(0.266363809892617521) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.15)); + } + case 4: + case 5: + //else if (m < 0.3) + { + constexpr T coef[] = + { + static_cast(1.685750354812596043), + static_cast(0.541731848613280329), + static_cast(0.401524438390690257), + static_cast(0.369642473420889090), + static_cast(0.376060715354583645), + static_cast(0.405235887085125919), + static_cast(0.453294381753999079), + static_cast(0.520518947651184205), + static_cast(0.609426039204995055), + static_cast(0.724263522282908870), + static_cast(0.871013847709812357), + static_cast(1.057652872753547036) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.25)); + } + case 6: + case 7: + //else if (m < 0.4) + { + constexpr T coef[] = + { + static_cast(1.744350597225613243), + static_cast(0.634864275371935304), + static_cast(0.539842564164445538), + static_cast(0.571892705193787391), + static_cast(0.670295136265406100), + static_cast(0.832586590010977199), + static_cast(1.073857448247933265), + static_cast(1.422091460675497751), + static_cast(1.920387183402304829), + static_cast(2.632552548331654201), + static_cast(3.652109747319039160), + static_cast(5.115867135558865806), + static_cast(7.224080007363877411) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.35)); + } + case 8: + case 9: + //else if (m < 0.5) + { + constexpr T coef[] = + { + static_cast(1.813883936816982644), + static_cast(0.763163245700557246), + static_cast(0.761928605321595831), + static_cast(0.951074653668427927), + static_cast(1.315180671703161215), + static_cast(1.928560693477410941), + static_cast(2.937509342531378755), + static_cast(4.594894405442878062), + static_cast(7.330071221881720772), + static_cast(11.87151259742530180), + static_cast(19.45851374822937738), + static_cast(32.20638657246426863), + static_cast(53.73749198700554656), + static_cast(90.27388602940998849) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.45)); + } + case 10: + case 11: + //else if (m < 0.6) + { + constexpr T coef[] = + { + static_cast(1.898924910271553526), + static_cast(0.950521794618244435), + static_cast(1.151077589959015808), + static_cast(1.750239106986300540), + static_cast(2.952676812636875180), + static_cast(5.285800396121450889), + static_cast(9.832485716659979747), + static_cast(18.78714868327559562), + static_cast(36.61468615273698145), + static_cast(72.45292395127771801), + static_cast(145.1079577347069102), + static_cast(293.4786396308497026), + static_cast(598.3851815055010179), + static_cast(1228.420013075863451), + static_cast(2536.529755382764488) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.55)); + } + case 12: + case 13: + //else if (m < 0.7) + { + constexpr T coef[] = + { + static_cast(2.007598398424376302), + static_cast(1.248457231212347337), + static_cast(1.926234657076479729), + static_cast(3.751289640087587680), + static_cast(8.119944554932045802), + static_cast(18.66572130873555361), + static_cast(44.60392484291437063), + static_cast(109.5092054309498377), + static_cast(274.2779548232413480), + static_cast(697.5598008606326163), + static_cast(1795.716014500247129), + static_cast(4668.381716790389910), + static_cast(12235.76246813664335), + static_cast(32290.17809718320818), + static_cast(85713.07608195964685), + static_cast(228672.1890493117096), + static_cast(612757.2711915852774) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.65)); + } + case 14: + case 15: + //else if (m < static_cast(0.8)) + { + constexpr T coef[] = + { + static_cast(2.156515647499643235), + static_cast(1.791805641849463243), + static_cast(3.826751287465713147), + static_cast(10.38672468363797208), + static_cast(31.40331405468070290), + static_cast(100.9237039498695416), + static_cast(337.3268282632272897), + static_cast(1158.707930567827917), + static_cast(4060.990742193632092), + static_cast(14454.00184034344795), + static_cast(52076.66107599404803), + static_cast(189493.6591462156887), + static_cast(695184.5762413896145), + static_cast(2567994.048255284686), + static_cast(9541921.966748386322), + static_cast(35634927.44218076174), + static_cast(133669298.4612040871), + static_cast(503352186.6866284541), + static_cast(1901975729.538660119), + static_cast(7208915015.330103756) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.75)); + } + case 16: + //else if (m < static_cast(0.85)) + { + constexpr T coef[] = + { + static_cast(2.318122621712510589), + static_cast(2.616920150291232841), + static_cast(7.897935075731355823), + static_cast(30.50239715446672327), + static_cast(131.4869365523528456), + static_cast(602.9847637356491617), + static_cast(2877.024617809972641), + static_cast(14110.51991915180325), + static_cast(70621.44088156540229), + static_cast(358977.2665825309926), + static_cast(1847238.263723971684), + static_cast(9600515.416049214109), + static_cast(50307677.08502366879), + static_cast(265444188.6527127967), + static_cast(1408862325.028702687), + static_cast(7515687935.373774627) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.825)); + } + case 17: + //else if (m < static_cast(0.90)) + { + constexpr T coef[] = + { + static_cast(2.473596173751343912), + static_cast(3.727624244118099310), + static_cast(15.60739303554930496), + static_cast(84.12850842805887747), + static_cast(506.9818197040613935), + static_cast(3252.277058145123644), + static_cast(21713.24241957434256), + static_cast(149037.0451890932766), + static_cast(1043999.331089990839), + static_cast(7427974.817042038995), + static_cast(53503839.67558661151), + static_cast(389249886.9948708474), + static_cast(2855288351.100810619), + static_cast(21090077038.76684053), + static_cast(156699833947.7902014), + static_cast(1170222242422.439893), + static_cast(8777948323668.937971), + static_cast(66101242752484.95041), + static_cast(499488053713388.7989), + static_cast(37859743397240299.20) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.875)); + } + default: + // + // This handles all cases where m > 0.9, + // including all error handling: + // + return ellint_k_imp(k, pol, boost::math::integral_constant()); +#if 0 + else + { + T lambda_prime = (1 - sqrt(k)) / (2 * (1 + sqrt(k))); + T k_prime = ellint_k(sqrt((1 - k) * (1 + k))); // K(m') + T lambda_prime_4th = boost::math::pow<4>(lambda_prime); + T q_prime = ((((((20910 * lambda_prime_4th) + 1707) * lambda_prime_4th + 150) * lambda_prime_4th + 15) * lambda_prime_4th + 2) * lambda_prime_4th + 1) * lambda_prime; + /*T q_prime_2 = lambda_prime + + 2 * boost::math::pow<5>(lambda_prime) + + 15 * boost::math::pow<9>(lambda_prime) + + 150 * boost::math::pow<13>(lambda_prime) + + 1707 * boost::math::pow<17>(lambda_prime) + + 20910 * boost::math::pow<21>(lambda_prime);*/ + return -log(q_prime) * k_prime / boost::math::constants::pi(); + } +#endif + } +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(m * 20)) + { + case 0: + case 1: + { + constexpr T coef[] = + { + 1.5910034537907921801L, + 0.41600074399178691174L, + 0.24579151426410341536L, + 0.17948148291490616181L, + 0.14455605708755514976L, + 0.12320099331242771115L, + 0.10893881157429353105L, + 0.098853409871592910399L, + 0.091439629201749751268L, + 0.085842591595413899672L, + 0.081541118718303214749L, + 0.078199656811256481910L, + 0.075592617535422415648L, + 0.073562939365441925050L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05L); + } + case 2: + case 3: + { + constexpr T coef[] = + { + 1.6352567322645799924L, + 0.47119062614873229055L, + 0.30972841083149958708L, + 0.25220831177313569923L, + 0.22672562321968464974L, + 0.21577444672958597588L, + 0.21310877187734890963L, + 0.21602912460518828154L, + 0.22325583163305789567L, + 0.23418050129420992492L, + 0.24855768297226407136L, + 0.26636380989261752077L, + 0.28772845215611466775L, + 0.31290024539780334906L, + 0.34223105446381299902L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15L); + } + case 4: + case 5: + { + constexpr T coef[] = + { + 1.6857503548125960429L, + 0.54173184861328032882L, + 0.40152443839069025682L, + 0.36964247342088908995L, + 0.37606071535458364462L, + 0.40523588708512591863L, + 0.45329438175399907924L, + 0.52051894765118420473L, + 0.60942603920499505544L, + 0.72426352228290886975L, + 0.87101384770981235737L, + 1.0576528727535470365L, + 1.2945970872087764321L, + 1.5953368253888783747L, + 1.9772844873556364793L, + 2.4628890581910021287L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25L); + } + case 6: + case 7: + { + constexpr T coef[] = + { + 1.7443505972256132429L, + 0.63486427537193530383L, + 0.53984256416444553751L, + 0.57189270519378739093L, + 0.67029513626540610034L, + 0.83258659001097719939L, + 1.0738574482479332654L, + 1.4220914606754977514L, + 1.9203871834023048288L, + 2.6325525483316542006L, + 3.6521097473190391602L, + 5.1158671355588658061L, + 7.2240800073638774108L, + 10.270306349944787227L, + 14.685616935355757348L, + 21.104114212004582734L, + 30.460132808575799413L, + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35L); + } + case 8: + case 9: + { + constexpr T coef[] = + { + 1.8138839368169826437L, + 0.76316324570055724607L, + 0.76192860532159583095L, + 0.95107465366842792679L, + 1.3151806717031612153L, + 1.9285606934774109412L, + 2.9375093425313787550L, + 4.5948944054428780618L, + 7.3300712218817207718L, + 11.871512597425301798L, + 19.458513748229377383L, + 32.206386572464268628L, + 53.737491987005546559L, + 90.273886029409988491L, + 152.53312130253275268L, + 259.02388747148299086L, + 441.78537518096201946L, + 756.39903981567380952L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45L); + } + case 10: + case 11: + { + constexpr T coef[] = + { + 1.8989249102715535257L, + 0.95052179461824443490L, + 1.1510775899590158079L, + 1.7502391069863005399L, + 2.9526768126368751802L, + 5.2858003961214508892L, + 9.8324857166599797471L, + 18.787148683275595622L, + 36.614686152736981447L, + 72.452923951277718013L, + 145.10795773470691023L, + 293.47863963084970259L, + 598.38518150550101790L, + 1228.4200130758634505L, + 2536.5297553827644880L, + 5263.9832725075189576L, + 10972.138126273491753L, + 22958.388550988306870L, + 48203.103373625406989L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55L); + } + case 12: + case 13: + { + constexpr T coef[] = + { + 2.0075983984243763017L, + 1.2484572312123473371L, + 1.9262346570764797287L, + 3.7512896400875876798L, + 8.1199445549320458022L, + 18.665721308735553611L, + 44.603924842914370633L, + 109.50920543094983774L, + 274.27795482324134804L, + 697.55980086063261629L, + 1795.7160145002471293L, + 4668.3817167903899100L, + 12235.762468136643348L, + 32290.178097183208178L, + 85713.076081959646847L, + 228672.18904931170958L, + 612757.27119158527740L, + 1.6483233976504668314e6L, + 4.4492251046211960936e6L, + 1.2046317340783185238e7L, + 3.2705187507963254185e7L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65L); + } + case 14: + case 15: + { + constexpr T coef[] = + { + 2.1565156474996432354L, + 1.7918056418494632425L, + 3.8267512874657131470L, + 10.386724683637972080L, + 31.403314054680702901L, + 100.92370394986954165L, + 337.32682826322728966L, + 1158.7079305678279173L, + 4060.9907421936320917L, + 14454.001840343447947L, + 52076.661075994048028L, + 189493.65914621568866L, + 695184.57624138961450L, + 2.5679940482552846861e6L, + 9.5419219667483863221e6L, + 3.5634927442180761743e7L, + 1.3366929846120408712e8L, + 5.0335218668662845411e8L, + 1.9019757295386601192e9L, + 7.2089150153301037563e9L, + 2.7398741806339510931e10L, + 1.0439286724885300495e11L, + 3.9864875581513728207e11L, + 1.5254661585564745591e12L, + 5.8483259088850315936e12 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75L); + } + case 16: + { + constexpr T coef[] = + { + 2.3181226217125105894L, + 2.6169201502912328409L, + 7.8979350757313558232L, + 30.502397154466723270L, + 131.48693655235284561L, + 602.98476373564916170L, + 2877.0246178099726410L, + 14110.519919151803247L, + 70621.440881565402289L, + 358977.26658253099258L, + 1.8472382637239716844e6L, + 9.6005154160492141090e6L, + 5.0307677085023668786e7L, + 2.6544418865271279673e8L, + 1.4088623250287026866e9L, + 7.5156879353737746270e9L, + 4.0270783964955246149e10L, + 2.1662089325801126339e11L, + 1.1692489201929996116e12L, + 6.3306543358985679881e12 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825L); + } + case 17: + { + constexpr T coef[] = + { + 2.4735961737513439120L, + 3.7276242441180993105L, + 15.607393035549304964L, + 84.128508428058877470L, + 506.98181970406139349L, + 3252.2770581451236438L, + 21713.242419574342564L, + 149037.04518909327662L, + 1.0439993310899908390e6L, + 7.4279748170420389947e6L, + 5.3503839675586611510e7L, + 3.8924988699487084738e8L, + 2.8552883511008106195e9L, + 2.1090077038766840525e10L, + 1.5669983394779020136e11L, + 1.1702222424224398927e12L, + 8.7779483236689379709e12L, + 6.6101242752484950408e13L, + 4.9948805371338879891e14L, + 3.7859743397240299201e15L, + 2.8775996123036112296e16L, + 2.1926346839925760143e17L, + 1.6744985438468349361e18L, + 1.2814410112866546052e19L, + 9.8249807041031260167e19 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875L); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_k_imp(k, pol, boost::math::integral_constant()); + } +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T k, const Policy& pol, const boost::math::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef boost::math::integral_constant::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 54) ? 0 : + boost::math::is_floating_point::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 64) ? 1 : 2 +#endif + > precision_tag_type; + return policies::checked_narrowing_cast(detail::ellint_k_imp(static_cast(k), pol, precision_tag_type()), "boost::math::ellint_1<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T1 k, T2 phi, const boost::math::false_type&) +{ + return boost::math::ellint_1(k, phi, policies::policy<>()); +} + +} // namespace detail + +// Elliptic integral (Legendre form) of the first kind +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol) // LCOV_EXCL_LINE gcc misses this but sees the function body, strange! +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_f_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_1<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_1(k, phi, tag_type()); +} + +// Complete elliptic integral (Legendre form) of the first kind +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_1(T k) +{ + return ellint_1(k, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_1_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_2.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_2.hpp new file mode 100644 index 0000000000000..0cc1fa0944295 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_2.hpp @@ -0,0 +1,756 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_2_HPP +#define BOOST_MATH_ELLINT_2_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the second kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, const boost::math::integral_constant&); +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, const boost::math::integral_constant&); +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, const boost::math::integral_constant&); + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED T ellint_e_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if (phi == 0) + return 0; + + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error("boost::math::ellint_e<%1%>(%1%,%1%)", nullptr, pol); + } + else if(phi > 1 / tools::epsilon()) + { + typedef boost::math::integral_constant::value&& boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 54) ? 0 : + boost::math::is_floating_point::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + result = 2 * phi * ellint_e_imp(k, pol, precision_tag_type()) / constants::pi(); + } + else if(k == 0) + { + return invert ? T(-phi) : phi; + } + else if(fabs(k) == 1) + { + // + // For k = 1 ellipse actually turns to a line and every pi/2 in phi is exactly 1 in arc length + // Periodicity though is in pi, curve follows sin(pi) for 0 <= phi <= pi/2 and then + // 2 - sin(pi- phi) = 2 + sin(phi - pi) for pi/2 <= phi <= pi, so general form is: + // + // 2n + sin(phi - n * pi) ; |phi - n * pi| <= pi / 2 + // + T m = boost::math::round(phi / boost::math::constants::pi()); + T remains = phi - m * boost::math::constants::pi(); + T value = 2 * m + sin(remains); + + // negative arc length for negative phi + return invert ? -value : value; + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + } + T k2 = k * k; + if(boost::math::pow<3>(rphi) * k2 / 6 < tools::epsilon() * fabs(rphi)) + { + // See http://functions.wolfram.com/EllipticIntegrals/EllipticE2/06/01/03/0001/ + result = s * rphi; + } + else + { + // http://dlmf.nist.gov/19.25#E10 + T sinp = sin(rphi); + if (k2 * sinp * sinp >= 1) + { + return policies::raise_domain_error("boost::math::ellint_2<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); + } + T cosp = cos(rphi); + T c = 1 / (sinp * sinp); + T cm1 = cosp * cosp / (sinp * sinp); // c - 1 + result = s * ((1 - k2) * ellint_rf_imp(cm1, T(c - k2), c, pol) + k2 * (1 - k2) * ellint_rd(cm1, c, T(c - k2), pol) / 3 + k2 * sqrt(cm1 / (c * (c - k2)))); + } + if (m != 0) + { + typedef boost::math::integral_constant::value&& boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 54) ? 0 : + boost::math::is_floating_point::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + result += m * ellint_e_imp(k, pol, precision_tag_type()); + } + } + return invert ? T(-result) : result; +} + +// Complete elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED T ellint_e_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (abs(k) > 1) + { + return policies::raise_domain_error("boost::math::ellint_e<%1%>(%1%)", "Got k = %1%, function requires |k| <= 1", k, pol); + } + if (abs(k) == 1) + { + return static_cast(1); + } + + T x = 0; + T t = k * k; + T y = 1 - t; + T z = 1; + T value = 2 * ellint_rg_imp(x, y, z, pol); + + return value; +} +// +// Special versions for double and 80-bit long double precision, +// double precision versions use the coefficients from: +// "Fast computation of complete elliptic integrals and Jacobian elliptic functions", +// Celestial Mechanics and Dynamical Astronomy, April 2012. +// +// Higher precision coefficients for 80-bit long doubles can be calculated +// using for example: +// Table[N[SeriesCoefficient[ EllipticE [ m ], { m, 875/1000, i} ], 20], {i, 0, 24}] +// and checking the value of the first neglected term with: +// N[SeriesCoefficient[ EllipticE [ m ], { m, 875/1000, 24} ], 20] * (2.5/100)^24 +// +// For m > 0.9 we don't use the method of the paper above, but simply call our +// existing routines. +// +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(20 * m)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + static_cast(1.550973351780472328), + -static_cast(0.400301020103198524), + -static_cast(0.078498619442941939), + -static_cast(0.034318853117591992), + -static_cast(0.019718043317365499), + -static_cast(0.013059507731993309), + -static_cast(0.009442372874146547), + -static_cast(0.007246728512402157), + -static_cast(0.005807424012956090), + -static_cast(0.004809187786009338), + -static_cast(0.004086399233255150) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.05)); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + static_cast(1.510121832092819728), + -static_cast(0.417116333905867549), + -static_cast(0.090123820404774569), + -static_cast(0.043729944019084312), + -static_cast(0.027965493064761785), + -static_cast(0.020644781177568105), + -static_cast(0.016650786739707238), + -static_cast(0.014261960828842520), + -static_cast(0.012759847429264803), + -static_cast(0.011799303775587354), + -static_cast(0.011197445703074968) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.15)); + } + case 4: + case 5: + //else if (m < 0.3) + { + constexpr T coef[] = + { + static_cast(1.467462209339427155), + -static_cast(0.436576290946337775), + -static_cast(0.105155557666942554), + -static_cast(0.057371843593241730), + -static_cast(0.041391627727340220), + -static_cast(0.034527728505280841), + -static_cast(0.031495443512532783), + -static_cast(0.030527000890325277), + -static_cast(0.030916984019238900), + -static_cast(0.032371395314758122), + -static_cast(0.034789960386404158) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.25)); + } + case 6: + case 7: + //else if (m < 0.4) + { + constexpr T coef[] = + { + static_cast(1.422691133490879171), + -static_cast(0.459513519621048674), + -static_cast(0.125250539822061878), + -static_cast(0.078138545094409477), + -static_cast(0.064714278472050002), + -static_cast(0.062084339131730311), + -static_cast(0.065197032815572477), + -static_cast(0.072793895362578779), + -static_cast(0.084959075171781003), + -static_cast(0.102539850131045997), + -static_cast(0.127053585157696036), + -static_cast(0.160791120691274606) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.35)); + } + case 8: + case 9: + //else if (m < 0.5) + { + constexpr T coef[] = + { + static_cast(1.375401971871116291), + -static_cast(0.487202183273184837), + -static_cast(0.153311701348540228), + -static_cast(0.111849444917027833), + -static_cast(0.108840952523135768), + -static_cast(0.122954223120269076), + -static_cast(0.152217163962035047), + -static_cast(0.200495323642697339), + -static_cast(0.276174333067751758), + -static_cast(0.393513114304375851), + -static_cast(0.575754406027879147), + -static_cast(0.860523235727239756), + -static_cast(1.308833205758540162) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.45)); + } + case 10: + case 11: + //else if (m < 0.6) + { + constexpr T coef[] = + { + static_cast(1.325024497958230082), + -static_cast(0.521727647557566767), + -static_cast(0.194906430482126213), + -static_cast(0.171623726822011264), + -static_cast(0.202754652926419141), + -static_cast(0.278798953118534762), + -static_cast(0.420698457281005762), + -static_cast(0.675948400853106021), + -static_cast(1.136343121839229244), + -static_cast(1.976721143954398261), + -static_cast(3.531696773095722506), + -static_cast(6.446753640156048150), + -static_cast(11.97703130208884026) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.55)); + } + case 12: + case 13: + //else if (m < 0.7) + { + constexpr T coef[] = + { + static_cast(1.270707479650149744), + -static_cast(0.566839168287866583), + -static_cast(0.262160793432492598), + -static_cast(0.292244173533077419), + -static_cast(0.440397840850423189), + -static_cast(0.774947641381397458), + -static_cast(1.498870837987561088), + -static_cast(3.089708310445186667), + -static_cast(6.667595903381001064), + -static_cast(14.89436036517319078), + -static_cast(34.18120574251449024), + -static_cast(80.15895841905397306), + -static_cast(191.3489480762984920), + -static_cast(463.5938853480342030), + -static_cast(1137.380822169360061) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.65)); + } + case 14: + case 15: + //else if (m < 0.8) + { + constexpr T coef[] = + { + static_cast(1.211056027568459525), + -static_cast(0.630306413287455807), + -static_cast(0.387166409520669145), + -static_cast(0.592278235311934603), + -static_cast(1.237555584513049844), + -static_cast(3.032056661745247199), + -static_cast(8.181688221573590762), + -static_cast(23.55507217389693250), + -static_cast(71.04099935893064956), + -static_cast(221.8796853192349888), + -static_cast(712.1364793277635425), + -static_cast(2336.125331440396407), + -static_cast(7801.945954775964673), + -static_cast(26448.19586059191933), + -static_cast(90799.48341621365251), + -static_cast(315126.0406449163424), + -static_cast(1104011.344311591159) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.75)); + } + case 16: + //else if (m < 0.85) + { + constexpr T coef[] = + { + static_cast(1.161307152196282836), + -static_cast(0.701100284555289548), + -static_cast(0.580551474465437362), + -static_cast(1.243693061077786614), + -static_cast(3.679383613496634879), + -static_cast(12.81590924337895775), + -static_cast(49.25672530759985272), + -static_cast(202.1818735434090269), + -static_cast(869.8602699308701437), + -static_cast(3877.005847313289571), + -static_cast(17761.70710170939814), + -static_cast(83182.69029154232061), + -static_cast(396650.4505013548170), + -static_cast(1920033.413682634405) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.825)); + } + case 17: + //else if (m < 0.90) + { + constexpr T coef[] = + { + static_cast(1.124617325119752213), + -static_cast(0.770845056360909542), + -static_cast(0.844794053644911362), + -static_cast(2.490097309450394453), + -static_cast(10.23971741154384360), + -static_cast(49.74900546551479866), + -static_cast(267.0986675195705196), + -static_cast(1532.665883825229947), + -static_cast(9222.313478526091951), + -static_cast(57502.51612140314030), + -static_cast(368596.1167416106063), + -static_cast(2415611.088701091428), + -static_cast(16120097.81581656797), + -static_cast(109209938.5203089915), + -static_cast(749380758.1942496220), + -static_cast(5198725846.725541393), + -static_cast(36409256888.12139973) + }; + return boost::math::tools::evaluate_polynomial(coef, m - static_cast(0.875)); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_e_imp(k, pol, boost::math::integral_constant()); + } +} +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, boost::math::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(20 * m)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + 1.5509733517804723277L, + -0.40030102010319852390L, + -0.078498619442941939212L, + -0.034318853117591992417L, + -0.019718043317365499309L, + -0.013059507731993309191L, + -0.0094423728741465473894L, + -0.0072467285124021568126L, + -0.0058074240129560897940L, + -0.0048091877860093381762L, + -0.0040863992332551506768L, + -0.0035450302604139562644L, + -0.0031283511188028336315L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05L); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + 1.5101218320928197276L, + -0.41711633390586754922L, + -0.090123820404774568894L, + -0.043729944019084311555L, + -0.027965493064761784548L, + -0.020644781177568105268L, + -0.016650786739707238037L, + -0.014261960828842519634L, + -0.012759847429264802627L, + -0.011799303775587354169L, + -0.011197445703074968018L, + -0.010850368064799902735L, + -0.010696133481060989818L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15L); + } + case 4: + case 5: + //else if (m < 0.3L) + { + constexpr T coef[] = + { + 1.4674622093394271555L, + -0.43657629094633777482L, + -0.10515555766694255399L, + -0.057371843593241729895L, + -0.041391627727340220236L, + -0.034527728505280841188L, + -0.031495443512532782647L, + -0.030527000890325277179L, + -0.030916984019238900349L, + -0.032371395314758122268L, + -0.034789960386404158240L, + -0.038182654612387881967L, + -0.042636187648900252525L, + -0.048302272505241634467 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25L); + } + case 6: + case 7: + //else if (m < 0.4L) + { + constexpr T coef[] = + { + 1.4226911334908791711L, + -0.45951351962104867394L, + -0.12525053982206187849L, + -0.078138545094409477156L, + -0.064714278472050001838L, + -0.062084339131730310707L, + -0.065197032815572476910L, + -0.072793895362578779473L, + -0.084959075171781003264L, + -0.10253985013104599679L, + -0.12705358515769603644L, + -0.16079112069127460621L, + -0.20705400012405941376L, + -0.27053164884730888948L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35L); + } + case 8: + case 9: + //else if (m < 0.5L) + { + constexpr T coef[] = + { + 1.3754019718711162908L, + -0.48720218327318483652L, + -0.15331170134854022753L, + -0.11184944491702783273L, + -0.10884095252313576755L, + -0.12295422312026907610L, + -0.15221716396203504746L, + -0.20049532364269733857L, + -0.27617433306775175837L, + -0.39351311430437585139L, + -0.57575440602787914711L, + -0.86052323572723975634L, + -1.3088332057585401616L, + -2.0200280559452241745L, + -3.1566019548237606451L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45L); + } + case 10: + case 11: + //else if (m < 0.6L) + { + constexpr T coef[] = + { + 1.3250244979582300818L, + -0.52172764755756676713L, + -0.19490643048212621262L, + -0.17162372682201126365L, + -0.20275465292641914128L, + -0.27879895311853476205L, + -0.42069845728100576224L, + -0.67594840085310602110L, + -1.1363431218392292440L, + -1.9767211439543982613L, + -3.5316967730957225064L, + -6.4467536401560481499L, + -11.977031302088840261L, + -22.581360948073964469L, + -43.109479829481450573L, + -83.186290908288807424L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55L); + } + case 12: + case 13: + //else if (m < 0.7L) + { + constexpr T coef[] = + { + 1.2707074796501497440L, + -0.56683916828786658286L, + -0.26216079343249259779L, + -0.29224417353307741931L, + -0.44039784085042318909L, + -0.77494764138139745824L, + -1.4988708379875610880L, + -3.0897083104451866665L, + -6.6675959033810010645L, + -14.894360365173190775L, + -34.181205742514490240L, + -80.158958419053973056L, + -191.34894807629849204L, + -463.59388534803420301L, + -1137.3808221693600606L, + -2820.7073786352269339L, + -7061.1382244658715621L, + -17821.809331816437058L, + -45307.849987201897801L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65L); + } + case 14: + case 15: + //else if (m < 0.8L) + { + constexpr T coef[] = + { + 1.2110560275684595248L, + -0.63030641328745580709L, + -0.38716640952066914514L, + -0.59227823531193460257L, + -1.2375555845130498445L, + -3.0320566617452471986L, + -8.1816882215735907624L, + -23.555072173896932503L, + -71.040999358930649565L, + -221.87968531923498875L, + -712.13647932776354253L, + -2336.1253314403964072L, + -7801.9459547759646726L, + -26448.195860591919335L, + -90799.483416213652512L, + -315126.04064491634241L, + -1.1040113443115911589e6L, + -3.8998018348056769095e6L, + -1.3876249116223745041e7L, + -4.9694982823537861149e7L, + -1.7900668836197342979e8L, + -6.4817399873722371964e8L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75L); + } + case 16: + //else if (m < 0.85L) + { + constexpr T coef[] = + { + 1.1613071521962828360L, + -0.70110028455528954752L, + -0.58055147446543736163L, + -1.2436930610777866138L, + -3.6793836134966348789L, + -12.815909243378957753L, + -49.256725307599852720L, + -202.18187354340902693L, + -869.86026993087014372L, + -3877.0058473132895713L, + -17761.707101709398174L, + -83182.690291542320614L, + -396650.45050135481698L, + -1.9200334136826344054e6L, + -9.4131321779500838352e6L, + -4.6654858837335370627e7L, + -2.3343549352617609390e8L, + -1.1776928223045913454e9L, + -5.9850851892915740401e9L, + -3.0614702984618644983e10L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825L); + } + case 17: + //else if (m < 0.90L) + { + constexpr T coef[] = + { + 1.1246173251197522132L, + -0.77084505636090954218L, + -0.84479405364491136236L, + -2.4900973094503944527L, + -10.239717411543843601L, + -49.749005465514798660L, + -267.09866751957051961L, + -1532.6658838252299468L, + -9222.3134785260919507L, + -57502.516121403140303L, + -368596.11674161060626L, + -2.4156110887010914281e6L, + -1.6120097815816567971e7L, + -1.0920993852030899148e8L, + -7.4938075819424962198e8L, + -5.1987258467255413931e9L, + -3.6409256888121399726e10L, + -2.5711802891217393544e11L, + -1.8290904062978796996e12L, + -1.3096838781743248404e13L, + -9.4325465851415135118e13L, + -6.8291980829471896669e14L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875L); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_e_imp(k, pol, boost::math::integral_constant()); + } +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T k, const Policy& pol, const boost::math::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef boost::math::integral_constant::value&& boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 54) ? 0 : + boost::math::is_floating_point::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + return policies::checked_narrowing_cast(detail::ellint_e_imp(static_cast(k), pol, precision_tag_type()), "boost::math::ellint_2<%1%>(%1%)"); +} + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T1 k, T2 phi, const boost::math::false_type&) +{ + return boost::math::ellint_2(k, phi, policies::policy<>()); +} + +} // detail + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_2(k, phi, tag_type()); +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol) // LCOV_EXCL_LINE gcc misses this but sees the function body, strange! +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_e_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_2<%1%>(%1%,%1%)"); +} + + +// Complete elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_2(T k) +{ + return ellint_2(k, policies::policy<>()); +} + + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_2_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_3.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_3.hpp new file mode 100644 index 0000000000000..b8df7e264506c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_3.hpp @@ -0,0 +1,374 @@ +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the various corner cases. +// + +#ifndef BOOST_MATH_ELLINT_3_HPP +#define BOOST_MATH_ELLINT_3_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the third kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +namespace detail{ + +template +BOOST_MATH_CUDA_ENABLED T ellint_pi_imp(T v, T k, T vc, const Policy& pol); + +// Elliptic integral (Legendre form) of the third kind +template +BOOST_MATH_CUDA_ENABLED T ellint_pi_imp(T v, T phi, T k, T vc, const Policy& pol) +{ + // Note vc = 1-v presumably without cancellation error. + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::ellint_3<%1%>(%1%,%1%,%1%)"; + + + T sphi = sin(fabs(phi)); + T result = 0; + + if (k * k * sphi * sphi > 1) + { + return policies::raise_domain_error(function, "Got k = %1%, function requires |k| <= 1", k, pol); + } + // Special cases first: + if(v == 0) + { + // A&S 17.7.18 & 19 + return (k == 0) ? phi : ellint_f_imp(phi, k, pol); + } + if((v > 0) && (1 / v < (sphi * sphi))) + { + // Complex result is a domain error: + return policies::raise_domain_error(function, "Got v = %1%, but result is complex for v > 1 / sin^2(phi)", v, pol); + } + + if(v == 1) + { + if (k == 0) + return tan(phi); + + // http://functions.wolfram.com/08.06.03.0008.01 + T m = k * k; + result = sqrt(1 - m * sphi * sphi) * tan(phi) - ellint_e_imp(phi, k, pol); + result /= 1 - m; + result += ellint_f_imp(phi, k, pol); + return result; + } + if(phi == constants::half_pi()) + { + // Have to filter this case out before the next + // special case, otherwise we might get an infinity from + // tan(phi). + // Also note that since we can't represent PI/2 exactly + // in a T, this is a bit of a guess as to the users true + // intent... + // + return ellint_pi_imp(v, k, vc, pol); + } + if((phi > constants::half_pi()) || (phi < 0)) + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + // See http://functions.wolfram.com/08.06.16.0002.01 + // + if(fabs(phi) > 1 / tools::epsilon()) + { + // Invalid for v > 1, this case is caught above since v > 1 implies 1/v < sin^2(phi) + BOOST_MATH_ASSERT(v <= 1); + // + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + // + result = 2 * fabs(phi) * ellint_pi_imp(v, k, vc, pol) / constants::pi(); + } + else + { + T rphi = boost::math::tools::fmod_workaround(T(fabs(phi)), T(constants::half_pi())); + T m = boost::math::round((fabs(phi) - rphi) / constants::half_pi()); + int sign = 1; + if((m != 0) && (k >= 1)) + { + return policies::raise_domain_error(function, "Got k=1 and phi=%1% but the result is complex in that domain", phi, pol); + } + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) + { + m += 1; + sign = -1; + rphi = constants::half_pi() - rphi; + } + result = sign * ellint_pi_imp(v, rphi, k, vc, pol); + if((m > 0) && (vc > 0)) + result += m * ellint_pi_imp(v, k, vc, pol); + } + return phi < 0 ? T(-result) : result; + } + if(k == 0) + { + // A&S 17.7.20: + if(v < 1) + { + T vcr = sqrt(vc); + return atan(vcr * tan(phi)) / vcr; + } + else + { + // v > 1: + T vcr = sqrt(-vc); + T arg = vcr * tan(phi); + return (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * vcr); + } + } + if((v < 0) && fabs(k) <= 1) + { + // + // If we don't shift to 0 <= v <= 1 we get + // cancellation errors later on. Use + // A&S 17.7.15/16 to shift to v > 0. + // + // Mathematica simplifies the expressions + // given in A&S as follows (with thanks to + // Rocco Romeo for figuring these out!): + // + // V = (k2 - n)/(1 - n) + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[Sqrt[(1 - V)*(1 - k2 / V)] / Sqrt[((1 - n)*(1 - k2 / n))]]] + // Result: ((-1 + k2) n) / ((-1 + n) (-k2 + n)) + // + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[k2 / (Sqrt[-n*(k2 - n) / (1 - n)] * Sqrt[(1 - n)*(1 - k2 / n)])]] + // Result : k2 / (k2 - n) + // + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[Sqrt[1 / ((1 - n)*(1 - k2 / n))]]] + // Result : Sqrt[n / ((k2 - n) (-1 + n))] + // + T k2 = k * k; + T N = (k2 - v) / (1 - v); + T Nm1 = (1 - k2) / (1 - v); + T p2 = -v * N; + T t; + if (p2 <= tools::min_value()) + { + p2 = sqrt(-v) * sqrt(N); + } + else + p2 = sqrt(p2); + T delta = sqrt(1 - k2 * sphi * sphi); + if(N > k2) + { + result = ellint_pi_imp(N, phi, k, Nm1, pol); + result *= v / (v - 1); + result *= (k2 - 1) / (v - k2); + } + + if(k != 0) + { + t = ellint_f_imp(phi, k, pol); + t *= k2 / (k2 - v); + result += t; + } + t = v / ((k2 - v) * (v - 1)); + if(t > tools::min_value()) + { + result += atan((p2 / 2) * sin(2 * phi) / delta) * sqrt(t); + } + else + { + result += atan((p2 / 2) * sin(2 * phi) / delta) * sqrt(fabs(1 / (k2 - v))) * sqrt(fabs(v / (v - 1))); + } + return result; + } + if(k == 1) + { + // See http://functions.wolfram.com/08.06.03.0013.01 + result = sqrt(v) * atanh(sqrt(v) * sin(phi), pol) - log(1 / cos(phi) + tan(phi)); + result /= v - 1; + return result; + } +#if 0 // disabled but retained for future reference: see below. + if(v > 1) + { + // + // If v > 1 we can use the identity in A&S 17.7.7/8 + // to shift to 0 <= v <= 1. In contrast to previous + // revisions of this header, this identity does now work + // but appears not to produce better error rates in + // practice. Archived here for future reference... + // + T k2 = k * k; + T N = k2 / v; + T Nm1 = (v - k2) / v; + T p1 = sqrt((-vc) * (1 - k2 / v)); + T delta = sqrt(1 - k2 * sphi * sphi); + // + // These next two terms have a large amount of cancellation + // so it's not clear if this relation is useable even if + // the issues with phi > pi/2 can be fixed: + // + result = -ellint_pi_imp(N, phi, k, Nm1, pol); + result += ellint_f_imp(phi, k, pol); + // + // This log term gives the complex result when + // n > 1/sin^2(phi) + // However that case is dealt with as an error above, + // so we should always get a real result here: + // + result += log((delta + p1 * tan(phi)) / (delta - p1 * tan(phi))) / (2 * p1); + return result; + } +#endif + // + // Carlson's algorithm works only for |phi| <= pi/2, + // by the time we get here phi should already have been + // normalised above. + // + BOOST_MATH_ASSERT(fabs(phi) < constants::half_pi()); + BOOST_MATH_ASSERT(phi >= 0); + T x, y, z, p, t; + T cosp = cos(phi); + x = cosp * cosp; + t = sphi * sphi; + y = 1 - k * k * t; + z = 1; + if(v * t < T(0.5)) + p = 1 - v * t; + else + p = x + vc * t; + result = sphi * (ellint_rf_imp(x, y, z, pol) + v * t * ellint_rj_imp(x, y, z, p, pol) / 3); + + return result; +} + +// Complete elliptic integral (Legendre form) of the third kind +template +BOOST_MATH_CUDA_ENABLED T ellint_pi_imp(T v, T k, T vc, const Policy& pol) +{ + // Note arg vc = 1-v, possibly without cancellation errors + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + constexpr auto function = "boost::math::ellint_pi<%1%>(%1%,%1%)"; + + if (abs(k) >= 1) + { + return policies::raise_domain_error(function, "Got k = %1%, function requires |k| <= 1", k, pol); + } + if(vc <= 0) + { + // Result is complex: + return policies::raise_domain_error(function, "Got v = %1%, function requires v < 1", v, pol); + } + + if(v == 0) + { + return (k == 0) ? boost::math::constants::pi() / 2 : boost::math::ellint_1(k, pol); + } + + if(v < 0) + { + // Apply A&S 17.7.17: + T k2 = k * k; + T N = (k2 - v) / (1 - v); + T Nm1 = (1 - k2) / (1 - v); + T result = 0; + result = boost::math::detail::ellint_pi_imp(N, k, Nm1, pol); + // This next part is split in two to avoid spurious over/underflow: + result *= -v / (1 - v); + result *= (1 - k2) / (k2 - v); + result += boost::math::ellint_1(k, pol) * k2 / (k2 - v); + return result; + } + + T x = 0; + T y = 1 - k * k; + T z = 1; + T p = vc; + T value = ellint_rf_imp(x, y, z, pol) + v * ellint_rj_imp(x, y, z, p, pol) / 3; + + return value; +} + +template +BOOST_MATH_CUDA_ENABLED inline typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const boost::math::false_type&) +{ + return boost::math::ellint_3(k, v, phi, policies::policy<>()); +} + +template +BOOST_MATH_CUDA_ENABLED inline typename tools::promote_args::type ellint_3(T1 k, T2 v, const Policy& pol, const boost::math::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_pi_imp( + static_cast(v), + static_cast(k), + static_cast(1-v), + pol), "boost::math::ellint_3<%1%>(%1%,%1%)"); +} + +} // namespace detail + +template +BOOST_MATH_CUDA_ENABLED inline typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise, policies::promote_double >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::ellint_pi_imp( + static_cast(v), + static_cast(phi), + static_cast(k), + static_cast(1-v), + forwarding_policy()), "boost::math::ellint_3<%1%>(%1%,%1%,%1%)"); +} + +template +BOOST_MATH_CUDA_ENABLED typename detail::ellint_3_result::type ellint_3(T1 k, T2 v, T3 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_3(k, v, phi, tag_type()); +} + +template +BOOST_MATH_CUDA_ENABLED inline typename tools::promote_args::type ellint_3(T1 k, T2 v) +{ + return ellint_3(k, v, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_3_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_d.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_d.hpp new file mode 100644 index 0000000000000..f5a8491f5aaa3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_d.hpp @@ -0,0 +1,183 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_D_HPP +#define BOOST_MATH_ELLINT_D_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the second kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T ellint_d_imp(T k, const Policy& pol); + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED T ellint_d_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error("boost::math::ellint_d<%1%>(%1%,%1%)", nullptr, pol); + } + else if(phi > 1 / tools::epsilon()) + { + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + result = 2 * phi * ellint_d_imp(k, pol) / constants::pi(); + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > T(0.5)) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + } + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(m); + T sinp = sin(rphi); + T cosp = cos(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(sinp); + BOOST_MATH_INSTRUMENT_VARIABLE(cosp); + T c = 1 / (sinp * sinp); + T cm1 = cosp * cosp / (sinp * sinp); // c - 1 + T k2 = k * k; + if(k2 * sinp * sinp > 1) + { + return policies::raise_domain_error("boost::math::ellint_d<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); + } + else if(rphi == 0) + { + result = 0; + } + else + { + // http://dlmf.nist.gov/19.25#E10 + result = s * ellint_rd_imp(cm1, T(c - k2), c, pol) / 3; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + if(m != 0) + result += m * ellint_d_imp(k, pol); + } + return invert ? T(-result) : result; +} + +// Complete elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED T ellint_d_imp(T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (abs(k) >= 1) + { + return policies::raise_domain_error("boost::math::ellint_d<%1%>(%1%)", "Got k = %1%, function requires |k| <= 1", k, pol); + } + if(fabs(k) <= tools::root_epsilon()) + return constants::pi() / 4; + + T x = 0; + T t = k * k; + T y = 1 - t; + T z = 1; + T value = ellint_rd_imp(x, y, z, pol) / 3; + + return value; +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type ellint_d(T k, const Policy& pol, const boost::math::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_d_imp(static_cast(k), pol), "boost::math::ellint_d<%1%>(%1%)"); +} + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type ellint_d(T1 k, T2 phi, const boost::math::false_type&) +{ + return boost::math::ellint_d(k, phi, policies::policy<>()); +} + +} // detail + +// Complete elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type ellint_d(T k) +{ + return ellint_d(k, policies::policy<>()); +} + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type ellint_d(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_d(k, phi, tag_type()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_d_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_2<%1%>(%1%,%1%)"); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_rc.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_rc.hpp new file mode 100644 index 0000000000000..ae3c6375e52b7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_rc.hpp @@ -0,0 +1,112 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the y < 0 case. +// Updated 2015 to use Carlson's latest methods. +// + +#ifndef BOOST_MATH_ELLINT_RC_HPP +#define BOOST_MATH_ELLINT_RC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +// Carlson's degenerate elliptic integral +// R_C(x, y) = R_F(x, y, y) = 0.5 * \int_{0}^{\infty} (t+x)^{-1/2} (t+y)^{-1} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T ellint_rc_imp(T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::ellint_rc<%1%>(%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, "Argument x must be non-negative but got %1%", x, pol); + } + if(y == 0) + { + return policies::raise_domain_error(function, "Argument y must not be zero but got %1%", y, pol); + } + + // for y < 0, the integral is singular, return Cauchy principal value + T prefix, result; + if(y < 0) + { + prefix = sqrt(x / (x - y)); + x = x - y; + y = -y; + } + else + prefix = 1; + + if(x == 0) + { + result = constants::half_pi() / sqrt(y); + } + else if(x == y) + { + result = 1 / sqrt(x); + } + else if(y > x) + { + result = atan(sqrt((y - x) / x)) / sqrt(y - x); + } + else + { + if(y / x > T(0.5)) + { + T arg = sqrt((x - y) / x); + result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(x - y)); + } + else + { + result = log((sqrt(x) + sqrt(x - y)) / sqrt(y)) / sqrt(x - y); + } + } + return prefix * result; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rc(T1 x, T2 y, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rc_imp( + static_cast(x), + static_cast(y), pol), "boost::math::ellint_rc<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rc(T1 x, T2 y) +{ + return ellint_rc(x, y, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RC_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_rd.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_rd.hpp new file mode 100644 index 0000000000000..f2a33adc465ab --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_rd.hpp @@ -0,0 +1,207 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock. +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it slightly to fit into the +// Boost.Math conceptual framework better. +// Updated 2015 to use Carlson's latest methods. + +#ifndef BOOST_MATH_ELLINT_RD_HPP +#define BOOST_MATH_ELLINT_RD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the second kind +// R_D(x, y, z) = R_J(x, y, z, z) = 1.5 * \int_{0}^{\infty} [(t+x)(t+y)]^{-1/2} (t+z)^{-3/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T ellint_rd_imp(T x, T y, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::ellint_rd<%1%>(%1%,%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, "Argument x must be >= 0, but got %1%", x, pol); + } + if(y < 0) + { + return policies::raise_domain_error(function, "Argument y must be >= 0, but got %1%", y, pol); + } + if(z <= 0) + { + return policies::raise_domain_error(function, "Argument z must be > 0, but got %1%", z, pol); + } + if(x + y == 0) + { + return policies::raise_domain_error(function, "At most one argument can be zero, but got, x + y = %1%", x + y, pol); + } + // + // Special cases from http://dlmf.nist.gov/19.20#iv + // + + if(x == z) + { + BOOST_MATH_GPU_SAFE_SWAP(x, y); + } + if(y == z) + { + if(x == y) + { + return 1 / (x * sqrt(x)); + } + else if(x == 0) + { + return 3 * constants::pi() / (4 * y * sqrt(y)); + } + else + { + if(BOOST_MATH_GPU_SAFE_MAX(x, y) / BOOST_MATH_GPU_SAFE_MIN(x, y) > T(1.3)) + return 3 * (ellint_rc_imp(x, y, pol) - sqrt(x) / y) / (2 * (y - x)); + // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) + } + } + if(x == y) + { + if(BOOST_MATH_GPU_SAFE_MAX(x, z) / BOOST_MATH_GPU_SAFE_MIN(x, z) > T(1.3)) + return 3 * (ellint_rc_imp(z, x, pol) - 1 / sqrt(z)) / (z - x); + // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) + } + if(y == 0) + { + BOOST_MATH_GPU_SAFE_SWAP(x, y); + } + if(x == 0) + { + // + // Special handling for common case, from + // Numerical Computation of Real or Complex Elliptic Integrals, eq.47 + // + T xn = sqrt(y); + T yn = sqrt(z); + T x0 = xn; + T y0 = yn; + T sum = 0; + T sum_pow = 0.25f; + + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + sum_pow *= 2; + const auto temp = (xn - yn); + sum += sum_pow * temp * temp; + } + T RF = constants::pi() / (xn + yn); + // + // This following calculation suffers from serious cancellation when y ~ z + // unless we combine terms. We have: + // + // ( ((x0 + y0)/2)^2 - z ) / (z(y-z)) + // + // Substituting y = x0^2 and z = y0^2 and simplifying we get the following: + // + T pt = (x0 + 3 * y0) / (4 * z * (x0 + y0)); + // + // Since we've moved the denominator from eq.47 inside the expression, we + // need to also scale "sum" by the same value: + // + pt -= sum / (z * (y - z)); + return pt * RF * 3; + } + + T xn = x; + T yn = y; + T zn = z; + T An = (x + y + 3 * z) / 5; + T A0 = An; + // This has an extra 1.2 fudge factor which is really only needed when x, y and z are close in magnitude: + T Q = pow(tools::epsilon() / 4, -T(1) / 8) * BOOST_MATH_GPU_SAFE_MAX(BOOST_MATH_GPU_SAFE_MAX(An - x, An - y), An - z) * 1.2f; + BOOST_MATH_INSTRUMENT_VARIABLE(Q); + T lambda, rx, ry, rz; + unsigned k = 0; + T fn = 1; + T RD_sum = 0; + + for(; k < policies::get_max_series_iterations(); ++k) + { + rx = sqrt(xn); + ry = sqrt(yn); + rz = sqrt(zn); + lambda = rx * ry + rx * rz + ry * rz; + RD_sum += fn / (rz * (zn + lambda)); + An = (An + lambda) / 4; + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + fn /= 4; + Q /= 4; + BOOST_MATH_INSTRUMENT_VARIABLE(k); + BOOST_MATH_INSTRUMENT_VARIABLE(RD_sum); + BOOST_MATH_INSTRUMENT_VARIABLE(Q); + if(Q < An) + break; + } + + policies::check_series_iterations(function, k, pol); + + T X = fn * (A0 - x) / An; + T Y = fn * (A0 - y) / An; + T Z = -(X + Y) / 3; + T E2 = X * Y - 6 * Z * Z; + T E3 = (3 * X * Y - 8 * Z * Z) * Z; + T E4 = 3 * (X * Y - Z * Z) * Z * Z; + T E5 = X * Y * Z * Z * Z; + + T result = fn * pow(An, T(-3) / 2) * + (1 - 3 * E2 / 14 + E3 / 6 + 9 * E2 * E2 / 88 - 3 * E4 / 22 - 9 * E2 * E3 / 52 + 3 * E5 / 26 - E2 * E2 * E2 / 16 + + 3 * E3 * E3 / 40 + 3 * E2 * E4 / 20 + 45 * E2 * E2 * E3 / 272 - 9 * (E3 * E4 + E2 * E5) / 68); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result += 3 * RD_sum; + + return result; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rd_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rd<%1%>(%1%,%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z) +{ + return ellint_rd(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RD_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_rf.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_rf.hpp new file mode 100644 index 0000000000000..eb1c2b6e71634 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_rf.hpp @@ -0,0 +1,169 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to handle +// types longer than 80-bit reals. +// Updated 2015 to use Carlson's latest methods. +// +#ifndef BOOST_MATH_ELLINT_RF_HPP +#define BOOST_MATH_ELLINT_RF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the first kind +// R_F(x, y, z) = 0.5 * \int_{0}^{\infty} [(t+x)(t+y)(t+z)]^{-1/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + + template + BOOST_MATH_GPU_ENABLED T ellint_rf_imp(T x, T y, T z, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math; + + constexpr auto function = "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"; + + if(x < 0 || y < 0 || z < 0) + { + return policies::raise_domain_error(function, "domain error, all arguments must be non-negative, only sensible result is %1%.", boost::math::numeric_limits::quiet_NaN(), pol); + } + if(x + y == 0 || y + z == 0 || z + x == 0) + { + return policies::raise_domain_error(function, "domain error, at most one argument can be zero, only sensible result is %1%.", boost::math::numeric_limits::quiet_NaN(), pol); + } + // + // Special cases from http://dlmf.nist.gov/19.20#i + // + if(x == y) + { + if(x == z) + { + // x, y, z equal: + return 1 / sqrt(x); + } + else + { + // 2 equal, x and y: + if(z == 0) + return constants::pi() / (2 * sqrt(x)); + else + return ellint_rc_imp(z, x, pol); + } + } + if(x == z) + { + if(y == 0) + return constants::pi() / (2 * sqrt(x)); + else + return ellint_rc_imp(y, x, pol); + } + if(y == z) + { + if(x == 0) + return constants::pi() / (2 * sqrt(y)); + else + return ellint_rc_imp(x, y, pol); + } + if(x == 0) + BOOST_MATH_GPU_SAFE_SWAP(x, z); + else if(y == 0) + BOOST_MATH_GPU_SAFE_SWAP(y, z); + if(z == 0) + { + // + // Special case for one value zero: + // + T xn = sqrt(x); + T yn = sqrt(y); + + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + } + return constants::pi() / (xn + yn); + } + + T xn = x; + T yn = y; + T zn = z; + T An = (x + y + z) / 3; + T A0 = An; + T Q = pow(3 * boost::math::tools::epsilon(), T(-1) / 8) * BOOST_MATH_GPU_SAFE_MAX(BOOST_MATH_GPU_SAFE_MAX(fabs(An - xn), fabs(An - yn)), fabs(An - zn)); + T fn = 1; + + + // duplication + unsigned k = 1; + for(; k < boost::math::policies::get_max_series_iterations(); ++k) + { + T root_x = sqrt(xn); + T root_y = sqrt(yn); + T root_z = sqrt(zn); + T lambda = root_x * root_y + root_x * root_z + root_y * root_z; + An = (An + lambda) / 4; + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + Q /= 4; + fn *= 4; + if(Q < fabs(An)) + break; + } + // Check to see if we gave up too soon: + policies::check_series_iterations(function, k, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(k); + + T X = (A0 - x) / (An * fn); + T Y = (A0 - y) / (An * fn); + T Z = -X - Y; + + // Taylor series expansion to the 7th order + T E2 = X * Y - Z * Z; + T E3 = X * Y * Z; + return (1 + E3 * (T(1) / 14 + 3 * E3 / 104) + E2 * (T(-1) / 10 + E2 / 24 - (3 * E3) / 44 - 5 * E2 * E2 / 208 + E2 * E3 / 16)) / sqrt(An); + } + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rf_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z) +{ + return ellint_rf(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RF_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_rg.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_rg.hpp new file mode 100644 index 0000000000000..8a7f706ac0c7e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_rg.hpp @@ -0,0 +1,130 @@ +// Copyright (c) 2015 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) +// +#ifndef BOOST_MATH_ELLINT_RG_HPP +#define BOOST_MATH_ELLINT_RG_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail{ + + template + BOOST_MATH_GPU_ENABLED T ellint_rg_imp(T x, T y, T z, const Policy& pol) + { + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"; + + if(x < 0 || y < 0 || z < 0) + { + return policies::raise_domain_error(function, "domain error, all arguments must be non-negative, only sensible result is %1%.", boost::math::numeric_limits::quiet_NaN(), pol); + } + // + // Function is symmetric in x, y and z, but we require + // (x - z)(y - z) >= 0 to avoid cancellation error in the result + // which implies (for example) x >= z >= y + // + if(x < y) + BOOST_MATH_GPU_SAFE_SWAP(x, y); + if(x < z) + BOOST_MATH_GPU_SAFE_SWAP(x, z); + if(y > z) + BOOST_MATH_GPU_SAFE_SWAP(y, z); + + BOOST_MATH_ASSERT(x >= z); + BOOST_MATH_ASSERT(z >= y); + // + // Special cases from http://dlmf.nist.gov/19.20#ii + // + if(x == z) + { + if(y == z) + { + // x = y = z + // This also works for x = y = z = 0 presumably. + return sqrt(x); + } + else if(y == 0) + { + // x = y, z = 0 + return constants::pi() * sqrt(x) / 4; + } + else + { + // x = z, y != 0 + BOOST_MATH_GPU_SAFE_SWAP(x, y); + return (x == 0) ? T(sqrt(z) / 2) : T((z * ellint_rc_imp(x, z, pol) + sqrt(x)) / 2); + } + } + else if(y == z) + { + BOOST_MATH_ASSERT(x > 0); // Ordering of x,y,z above takes care of x == 0 case. + return (y == 0) ? T(sqrt(x) / 2) : T((y * ellint_rc_imp(x, y, pol) + sqrt(x)) / 2); + } + else if(y == 0) + { + BOOST_MATH_GPU_SAFE_SWAP(y, z); + // + // Special handling for common case, from + // Numerical Computation of Real or Complex Elliptic Integrals, eq.46 + // + T xn = sqrt(x); + T yn = sqrt(y); + T x0 = xn; + T y0 = yn; + T sum = 0; + T sum_pow = 0.25f; + + while(fabs(xn - yn) >= T(2.7) * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + sum_pow *= 2; + sum += sum_pow * boost::math::pow<2>(xn - yn); + } + T RF = constants::pi() / (xn + yn); + return ((boost::math::pow<2>((x0 + y0) / 2) - sum) * RF) / 2; + } + return (z * ellint_rf_imp(x, y, z, pol) + - (x - z) * (y - z) * ellint_rd_imp(x, y, z, pol) / 3 + + sqrt(x * y / z)) / 2; + } + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rg_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z) +{ + return ellint_rg(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RG_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/ellint_rj.hpp b/third-party/boost-math/include/boost/math/special_functions/ellint_rj.hpp new file mode 100644 index 0000000000000..8c1f93788fe46 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ellint_rj.hpp @@ -0,0 +1,299 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the p < 0 case. +// Updated 2015 to use Carlson's latest methods. +// + +#ifndef BOOST_MATH_ELLINT_RJ_HPP +#define BOOST_MATH_ELLINT_RJ_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the third kind +// R_J(x, y, z, p) = 1.5 * \int_{0}^{\infty} (t+p)^{-1} [(t+x)(t+y)(t+z)]^{-1/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T ellint_rc1p_imp(T y, const Policy& pol) +{ + using namespace boost::math; + // Calculate RC(1, 1 + x) + BOOST_MATH_STD_USING + + BOOST_MATH_ASSERT(y != -1); + + // for 1 + y < 0, the integral is singular, return Cauchy principal value + T result; + if(y < -1) + { + result = sqrt(1 / -y) * detail::ellint_rc_imp(T(-y), T(-1 - y), pol); + } + else if(y == 0) + { + result = 1; + } + else if(y > 0) + { + result = atan(sqrt(y)) / sqrt(y); + } + else + { + if(y > T(-0.5)) + { + T arg = sqrt(-y); + result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(-y)); + } + else + { + result = log((1 + sqrt(-y)) / sqrt(1 + y)) / sqrt(-y); + } + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED T ellint_rj_imp_final(T x, T y, T z, T p, const Policy& pol) +{ + BOOST_MATH_STD_USING + + // + // Special cases from http://dlmf.nist.gov/19.20#iii + // + if(x == y) + { + if(x == z) + { + if(x == p) + { + // All values equal: + return 1 / (x * sqrt(x)); + } + else + { + // x = y = z: + return 3 * (ellint_rc_imp(x, p, pol) - 1 / sqrt(x)) / (x - p); + } + } + else + { + // x = y only, permute so y = z: + BOOST_MATH_GPU_SAFE_SWAP(x, z); + if(y == p) + { + return ellint_rd_imp(x, y, y, pol); + } + else if(BOOST_MATH_GPU_SAFE_MAX(y, p) / BOOST_MATH_GPU_SAFE_MIN(y, p) > T(1.2)) + { + return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); + } + // Otherwise fall through to normal method, special case above will suffer too much cancellation... + } + } + if(y == z) + { + if(y == p) + { + // y = z = p: + return ellint_rd_imp(x, y, y, pol); + } + else if(BOOST_MATH_GPU_SAFE_MAX(y, p) / BOOST_MATH_GPU_SAFE_MIN(y, p) > T(1.2)) + { + // y = z: + return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); + } + // Otherwise fall through to normal method, special case above will suffer too much cancellation... + } + if(z == p) + { + return ellint_rd_imp(x, y, z, pol); + } + + T xn = x; + T yn = y; + T zn = z; + T pn = p; + T An = (x + y + z + 2 * p) / 5; + T A0 = An; + T delta = (p - x) * (p - y) * (p - z); + T Q = pow(tools::epsilon() / 5, -T(1) / 8) * BOOST_MATH_GPU_SAFE_MAX(BOOST_MATH_GPU_SAFE_MAX(fabs(An - x), fabs(An - y)), BOOST_MATH_GPU_SAFE_MAX(fabs(An - z), fabs(An - p))); + + unsigned n; + T lambda; + T Dn; + T En; + T rx, ry, rz, rp; + T fmn = 1; // 4^-n + T RC_sum = 0; + + for(n = 0; n < policies::get_max_series_iterations(); ++n) + { + rx = sqrt(xn); + ry = sqrt(yn); + rz = sqrt(zn); + rp = sqrt(pn); + Dn = (rp + rx) * (rp + ry) * (rp + rz); + En = delta / Dn; + En /= Dn; + if((En < T(-0.5)) && (En > T(-1.5))) + { + // + // Occasionally En ~ -1, we then have no means of calculating + // RC(1, 1+En) without terrible cancellation error, so we + // need to get to 1+En directly. By substitution we have + // + // 1+E_0 = 1 + (p-x)*(p-y)*(p-z)/((sqrt(p) + sqrt(x))*(sqrt(p)+sqrt(y))*(sqrt(p)+sqrt(z)))^2 + // = 2*sqrt(p)*(p+sqrt(x) * (sqrt(y)+sqrt(z)) + sqrt(y)*sqrt(z)) / ((sqrt(p) + sqrt(x))*(sqrt(p) + sqrt(y)*(sqrt(p)+sqrt(z)))) + // + // And since this is just an application of the duplication formula for RJ, the same + // expression works for 1+En if we use x,y,z,p_n etc. + // This branch is taken only once or twice at the start of iteration, + // after than En reverts to it's usual very small values. + // + T b = 2 * rp * (pn + rx * (ry + rz) + ry * rz) / Dn; + RC_sum += fmn / Dn * detail::ellint_rc_imp(T(1), b, pol); + } + else + { + RC_sum += fmn / Dn * ellint_rc1p_imp(En, pol); + } + lambda = rx * ry + rx * rz + ry * rz; + + // From here on we move to n+1: + An = (An + lambda) / 4; + fmn /= 4; + + if(fmn * Q < An) + break; + + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + pn = (pn + lambda) / 4; + delta /= 64; + } + + T X = fmn * (A0 - x) / An; + T Y = fmn * (A0 - y) / An; + T Z = fmn * (A0 - z) / An; + T P = (-X - Y - Z) / 2; + T E2 = X * Y + X * Z + Y * Z - 3 * P * P; + T E3 = X * Y * Z + 2 * E2 * P + 4 * P * P * P; + T E4 = (2 * X * Y * Z + E2 * P + 3 * P * P * P) * P; + T E5 = X * Y * Z * P * P; + T result = fmn * pow(An, T(-3) / 2) * + (1 - 3 * E2 / 14 + E3 / 6 + 9 * E2 * E2 / 88 - 3 * E4 / 22 - 9 * E2 * E3 / 52 + 3 * E5 / 26 - E2 * E2 * E2 / 16 + + 3 * E3 * E3 / 40 + 3 * E2 * E4 / 20 + 45 * E2 * E2 * E3 / 272 - 9 * (E3 * E4 + E2 * E5) / 68); + + result += 6 * RC_sum; + return result; +} + +template +BOOST_MATH_GPU_ENABLED T ellint_rj_imp(T x, T y, T z, T p, const Policy& pol) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::ellint_rj<%1%>(%1%,%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, "Argument x must be non-negative, but got x = %1%", x, pol); + } + if(y < 0) + { + return policies::raise_domain_error(function, "Argument y must be non-negative, but got y = %1%", y, pol); + } + if(z < 0) + { + return policies::raise_domain_error(function, "Argument z must be non-negative, but got z = %1%", z, pol); + } + if(p == 0) + { + return policies::raise_domain_error(function, "Argument p must not be zero, but got p = %1%", p, pol); + } + if(x + y == 0 || y + z == 0 || z + x == 0) + { + return policies::raise_domain_error(function, "At most one argument can be zero, only possible result is %1%.", boost::math::numeric_limits::quiet_NaN(), pol); + } + + // for p < 0, the integral is singular, return Cauchy principal value + if(p < 0) + { + // + // We must ensure that x < y < z. + // Since the integral is symmetrical in x, y and z + // we can just permute the values: + // + if(x > y) + BOOST_MATH_GPU_SAFE_SWAP(x, y); + if(y > z) + BOOST_MATH_GPU_SAFE_SWAP(y, z); + if(x > y) + BOOST_MATH_GPU_SAFE_SWAP(x, y); + + BOOST_MATH_ASSERT(x <= y); + BOOST_MATH_ASSERT(y <= z); + + T q = -p; + p = (z * (x + y + q) - x * y) / (z + q); + + BOOST_MATH_ASSERT(p >= 0); + + T value = (p - z) * ellint_rj_imp_final(x, y, z, p, pol); + value -= 3 * ellint_rf_imp(x, y, z, pol); + value += 3 * sqrt((x * y * z) / (x * y + p * q)) * ellint_rc_imp(T(x * y + p * q), T(p * q), pol); + value /= (z + q); + return value; + } + + return ellint_rj_imp_final(x, y, z, p, pol); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rj_imp( + static_cast(x), + static_cast(y), + static_cast(z), + static_cast(p), + pol), "boost::math::ellint_rj<%1%>(%1%,%1%,%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p) +{ + return ellint_rj(x, y, z, p, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RJ_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/erf.hpp b/third-party/boost-math/include/boost/math/special_functions/erf.hpp new file mode 100644 index 0000000000000..c1d9061dbab26 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/erf.hpp @@ -0,0 +1,1322 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_ERF_HPP +#define BOOST_MATH_SPECIAL_ERF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +namespace detail +{ + +// +// Asymptotic series for large z: +// +template +struct erf_asympt_series_t +{ + // LCOV_EXCL_START multiprecision case only, excluded from coverage analysis + BOOST_MATH_GPU_ENABLED erf_asympt_series_t(T z) : xx(2 * -z * z), tk(1) + { + BOOST_MATH_STD_USING + result = -exp(-z * z) / sqrt(boost::math::constants::pi()); + result /= z; + } + + typedef T result_type; + + BOOST_MATH_GPU_ENABLED T operator()() + { + BOOST_MATH_STD_USING + T r = result; + result *= tk / xx; + tk += 2; + if( fabs(r) < fabs(result)) + result = 0; + return r; + } + // LCOV_EXCL_STOP +private: + T result; + T xx; + int tk; +}; +// +// How large z has to be in order to ensure that the series converges: +// +template +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const T&) +{ + return (std::numeric_limits::max)(); +} +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 2.8F; +} +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 4.3F; +} +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 4.8F; +} +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 6.5F; +} +BOOST_MATH_GPU_ENABLED inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 6.8F; +} + +template +BOOST_MATH_GPU_ENABLED inline T erf_asymptotic_limit() +{ + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + return erf_asymptotic_limit_N(tag_type()); +} + +// LCOV_EXCL_START multiprecision case only, excluded from coverage analysis +template +struct erf_series_near_zero +{ + typedef T result_type; + T term; + T zz; + int k; + erf_series_near_zero(const T& z) : term(z), zz(-z * z), k(0) {} + + T operator()() + { + T result = term / (2 * k + 1); + term *= zz / ++k; + return result; + } +}; + +template +T erf_series_near_zero_sum(const T& x, const Policy& pol) +{ + // + // We need Kahan summation here, otherwise the errors grow fairly quickly. + // This method is *much* faster than the alternatives even so. + // + erf_series_near_zero sum(x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T result = constants::two_div_root_pi() * tools::kahan_sum_series(sum, tools::digits(), max_iter); + policies::check_series_iterations("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol); + return result; +} + +template +T erf_imp(T z, bool invert, const Policy& pol, const Tag& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("Generic erf_imp called"); + + if ((boost::math::isnan)(z)) + return policies::raise_domain_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + if(!invert && (z > detail::erf_asymptotic_limit())) + { + detail::erf_asympt_series_t s(z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, policies::get_epsilon(), max_iter, 1); + policies::check_series_iterations("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol); + } + else + { + T x = z * z; + if(z < 1.3f) + { + // Compute P: + // This is actually good for z p to 2 or so, but the cutoff given seems + // to be the best compromise. Performance wise, this is way quicker than anything else... + result = erf_series_near_zero_sum(z, pol); + } + else if(x > 1 / tools::epsilon()) + { + // http://functions.wolfram.com/06.27.06.0006.02 + invert = !invert; + result = exp(-x) / (constants::root_pi() * z); + } + else + { + // Compute Q: + invert = !invert; + result = z * exp(-x); + result /= boost::math::constants::root_pi(); + result *= upper_gamma_fraction(T(0.5f), x, policies::get_epsilon()); + } + } + if(invert) + result = 1 - result; + return result; +} +// LCOV_EXCL_STOP + +template +BOOST_MATH_GPU_ENABLED T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("53-bit precision erf_imp called"); + + if ((boost::math::isnan)(z)) + return policies::raise_domain_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol); + + int prefix_multiplier = 1; + int prefix_adder = 0; + + if(z < 0) + { + // Recursion is logically simpler here, but confuses static analyzers that need to be + // able to calculate the maximimum program stack size at compile time (ie CUDA). + z = -z; + if(!invert) + { + prefix_multiplier = -1; + // return -erf_imp(T(-z), invert, pol, t); + } + else if (z > T(0.5)) + { + prefix_adder = 2; + prefix_multiplier = -1; + // return 2 - erf_imp(T(-z), invert, pol, t); + } + else + { + invert = false; + prefix_adder = 1; + // return 1 + erf_imp(T(-z), false, pol, t); + } + } + + T result; + + // + // Big bunch of selection statements now to pick + // which implementation to use, + // try to put most likely options first: + // + if(z < T(0.5)) + { + // + // We're going to calculate erf: + // + if(z < T(1e-10)) + { + if(z == 0) + { + result = T(0); + } + else + { + BOOST_MATH_STATIC_LOCAL_VARIABLE const T c = BOOST_MATH_BIG_CONSTANT(T, 53, 0.003379167095512573896158903121545171688); // LCOV_EXCL_LINE + result = static_cast(z * 1.125f + z * c); + } + } + else + { + // Maximum Deviation Found: 1.561e-17 + // Expected Error Term: 1.561e-17 + // Maximum Relative Change in Control Points: 1.155e-04 + // Max Error found at double precision = 2.961182e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 1.044948577880859375f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0834305892146531832907), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.338165134459360935041), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0509990735146777432841), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00772758345802133288487), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000322780120964605683831), + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.455004033050794024546), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0875222600142252549554), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00858571925074406212772), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000370900071787748000569), + }; + // LCOV_EXCL_STOP + T zz = z * z; + result = z * (Y + tools::evaluate_polynomial(P, zz) / tools::evaluate_polynomial(Q, zz)); + } + } + else if(invert ? (z < 28) : (z < 5.93f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1.5f) + { + // Maximum Deviation Found: 3.702e-17 + // Expected Error Term: 3.702e-17 + // Maximum Relative Change in Control Points: 2.845e-04 + // Max Error found at double precision = 4.841816e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 0.405935764312744140625f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.098090592216281240205), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.178114665841120341155), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.191003695796775433986), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0888900368967884466578), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0195049001251218801359), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00180424538297014223957), + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.84759070983002217845), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.42628004845511324508), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.578052804889902404909), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.12385097467900864233), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0113385233577001411017), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.337511472483094676155e-5), + }; + // LCOV_EXCL_STOP + BOOST_MATH_INSTRUMENT_VARIABLE(Y); + BOOST_MATH_INSTRUMENT_VARIABLE(P[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(Q[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(z); + result = Y + tools::evaluate_polynomial(P, T(z - T(0.5))) / tools::evaluate_polynomial(Q, T(z - T(0.5))); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result *= exp(-z * z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(z < 2.5f) + { + // Max Error found at double precision = 6.599585e-18 + // Maximum Deviation Found: 3.909e-18 + // Expected Error Term: 3.909e-18 + // Maximum Relative Change in Control Points: 9.886e-05 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 0.50672817230224609375f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0243500476207698441272), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0386540375035707201728), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.04394818964209516296), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175679436311802092299), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00323962406290842133584), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000235839115596880717416), + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.53991494948552447182), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.982403709157920235114), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.325732924782444448493), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0563921837420478160373), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00410369723978904575884), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(z - T(1.5))) / tools::evaluate_polynomial(Q, z - T(1.5)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 4.5f) + { + // Maximum Deviation Found: 1.512e-17 + // Expected Error Term: 1.512e-17 + // Maximum Relative Change in Control Points: 2.222e-04 + // Max Error found at double precision = 2.062515e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 0.5405750274658203125f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00295276716530971662634), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0137384425896355332126), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00840807615555585383007), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00212825620914618649141), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000250269961544794627958), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.113212406648847561139e-4), + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.04217814166938418171), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.442597659481563127003), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0958492726301061423444), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0105982906484876531489), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000479411269521714493907), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(z - T(3.5))) / tools::evaluate_polynomial(Q, z - T(3.5)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Max Error found at double precision = 2.997958e-17 + // Maximum Deviation Found: 2.860e-17 + // Expected Error Term: 2.859e-17 + // Maximum Relative Change in Control Points: 1.357e-05 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 0.5579090118408203125f; + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00628057170626964891937), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175389834052493308818), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.212652252872804219852), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.687717681153649930619), + BOOST_MATH_BIG_CONSTANT(T, 53, -2.5518551727311523996), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.22729451764143718517), + BOOST_MATH_BIG_CONSTANT(T, 53, -2.8175401114513378771), + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.79257750980575282228), + BOOST_MATH_BIG_CONSTANT(T, 53, 11.0567237927800161565), + BOOST_MATH_BIG_CONSTANT(T, 53, 15.930646027911794143), + BOOST_MATH_BIG_CONSTANT(T, 53, 22.9367376522880577224), + BOOST_MATH_BIG_CONSTANT(T, 53, 13.5064170191802889145), + BOOST_MATH_BIG_CONSTANT(T, 53, 5.48409182238641741584), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 28 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + prefix_adder += prefix_multiplier * 1; + prefix_multiplier = -prefix_multiplier; + } + + return prefix_adder + prefix_multiplier * result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) + + +template +T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("64-bit precision erf_imp called"); + + if ((boost::math::isnan)(z)) + return policies::raise_domain_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else if(z < -0.5) + return 2 - erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + // + // Big bunch of selection statements now to pick which + // implementation to use, try to put most likely options + // first: + // + if(z < 0.5) + { + // + // We're going to calculate erf: + // + if(z == 0) + { + result = 0; + } + else if(z < 1e-10) + { + static const T c = BOOST_MATH_BIG_CONSTANT(T, 64, 0.003379167095512573896158903121545171688); // LCOV_EXCL_LINE + result = z * 1.125 + z * c; + } + else + { + // Max Error found at long double precision = 1.623299e-20 + // Maximum Deviation Found: 4.326e-22 + // Expected Error Term: -4.326e-22 + // Maximum Relative Change in Control Points: 1.474e-04 + // LCOV_EXCL_START + static const T Y = 1.044948577880859375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0834305892146531988966), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.338097283075565413695), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509602734406067204596), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00904906346158537794396), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000489468651464798669181), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.200305626366151877759e-4), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.455817300515875172439), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0916537354356241792007), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0102722652675910031202), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000650511752687851548735), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.189532519105655496778e-4), + }; + // LCOV_EXCL_STOP + result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z))); + } + } + else if(invert ? (z < 110) : (z < 6.6f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1.5) + { + // Max Error found at long double precision = 3.239590e-20 + // Maximum Deviation Found: 2.241e-20 + // Expected Error Term: -2.241e-20 + // Maximum Relative Change in Control Points: 5.110e-03 + // LCOV_EXCL_START + static const T Y = 0.405935764312744140625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0980905922162812031672), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.159989089922969141329), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.222359821619935712378), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.127303921703577362312), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0384057530342762400273), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00628431160851156719325), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000441266654514391746428), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.266689068336295642561e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.03237474985469469291), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.78355454954969405222), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.867940326293760578231), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.248025606990021698392), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0396649631833002269861), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00279220237309449026796), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 2.5) + { + // Max Error found at long double precision = 3.686211e-21 + // Maximum Deviation Found: 1.495e-21 + // Expected Error Term: -1.494e-21 + // Maximum Relative Change in Control Points: 1.793e-04 + // LCOV_EXCL_START + static const T Y = 0.50672817230224609375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.024350047620769840217), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0343522687935671451309), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0505420824305544949541), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0257479325917757388209), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00669349844190354356118), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00090807914416099524444), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.515917266698050027934e-4), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.71657861671930336344), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.26409634824280366218), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.512371437838969015941), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.120902623051120950935), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0158027197831887485261), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000897871370778031611439), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 4.5) + { + // Maximum Deviation Found: 1.107e-20 + // Expected Error Term: -1.106e-20 + // Maximum Relative Change in Control Points: 1.709e-04 + // Max Error found at long double precision = 1.446908e-20 + // LCOV_EXCL_START + static const T Y = 0.5405750274658203125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0029527671653097284033), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0141853245895495604051), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0104959584626432293901), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00343963795976100077626), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00059065441194877637899), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.523435380636174008685e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.189896043050331257262e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.19352160185285642574), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.603256964363454392857), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.165411142458540585835), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0259729870946203166468), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00221657568292893699158), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.804149464190309799804e-4), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(z - 3.5f)) / tools::evaluate_polynomial(Q, T(z - 3.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Max Error found at long double precision = 7.961166e-21 + // Maximum Deviation Found: 6.677e-21 + // Expected Error Term: 6.676e-21 + // Maximum Relative Change in Control Points: 2.319e-05 + // LCOV_EXCL_START + static const T Y = 0.55825519561767578125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00593438793008050214106), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280666231009089713937), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.141597835204583050043), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.978088201154300548842), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.47351527796012049443), + BOOST_MATH_BIG_CONSTANT(T, 64, -13.8677304660245326627), + BOOST_MATH_BIG_CONSTANT(T, 64, -27.1274948720539821722), + BOOST_MATH_BIG_CONSTANT(T, 64, -29.2545152747009461519), + BOOST_MATH_BIG_CONSTANT(T, 64, -16.8865774499799676937), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.72948911186645394541), + BOOST_MATH_BIG_CONSTANT(T, 64, 23.6750543147695749212), + BOOST_MATH_BIG_CONSTANT(T, 64, 60.0021517335693186785), + BOOST_MATH_BIG_CONSTANT(T, 64, 131.766251645149522868), + BOOST_MATH_BIG_CONSTANT(T, 64, 178.167924971283482513), + BOOST_MATH_BIG_CONSTANT(T, 64, 182.499390505915222699), + BOOST_MATH_BIG_CONSTANT(T, 64, 104.365251479578577989), + BOOST_MATH_BIG_CONSTANT(T, 64, 30.8365511891224291717), + }; + // LCOV_EXCL_STOP + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 110 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + result = 1 - result; + } + + return result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) + + +// LCOV_EXCL_START multiprecision case only, excluded from coverage analysis +template +T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called"); + + if ((boost::math::isnan)(z)) + return policies::raise_domain_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol); + + if(z < 0) + { + if (!invert) + return -erf_imp(T(-z), invert, pol, t); + else if(z < -0.5) + return 2 - erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + // + // Big bunch of selection statements now to pick which + // implementation to use, try to put most likely options + // first: + // + if(z < 0.5) + { + // + // We're going to calculate erf: + // + if(z == 0) + { + result = 0; + } + else if(z < 1e-20) + { + static const T c = BOOST_MATH_BIG_CONSTANT(T, 113, 0.003379167095512573896158903121545171688); + result = z * 1.125 + z * c; + } + else + { + // Max Error found at long double precision = 2.342380e-35 + // Maximum Deviation Found: 6.124e-36 + // Expected Error Term: -6.124e-36 + // Maximum Relative Change in Control Points: 3.492e-10 + static const T Y = 1.0841522216796875f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0442269454158250738961589031215451778), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.35549265736002144875335323556961233), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0582179564566667896225454670863270393), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0112694696904802304229950538453123925), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000805730648981801146251825329609079099), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.566304966591936566229702842075966273e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169655010425186987820201021510002265e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.344448249920445916714548295433198544e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.466542092785657604666906909196052522), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.100005087012526447295176964142107611), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0128341535890117646540050072234142603), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00107150448466867929159660677016658186), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.586168368028999183607733369248338474e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.196230608502104324965623171516808796e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.313388521582925207734229967907890146e-7), + }; + result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z))); + } + } + else if(invert ? (z < 110) : (z < 8.65f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1) + { + // Max Error found at long double precision = 3.246278e-35 + // Maximum Deviation Found: 1.388e-35 + // Expected Error Term: 1.387e-35 + // Maximum Relative Change in Control Points: 6.127e-05 + static const T Y = 0.371877193450927734375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0640320213544647969396032886581290455), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.200769874440155895637857443946706731), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.378447199873537170666487408805779826), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.30521399466465939450398642044975127), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.146890026406815277906781824723458196), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0464837937749539978247589252732769567), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00987895759019540115099100165904822903), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00137507575429025512038051025154301132), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0001144764551085935580772512359680516), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.436544865032836914773944382339900079e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.47651182872457465043733800302427977), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.78706486002517996428836400245547955), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.87295924621659627926365005293130693), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.829375825174365625428280908787261065), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.251334771307848291593780143950311514), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0522110268876176186719436765734722473), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00718332151250963182233267040106902368), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000595279058621482041084986219276392459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.226988669466501655990637599399326874e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.270666232259029102353426738909226413e-10), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 1.5) + { + // Max Error found at long double precision = 2.215785e-35 + // Maximum Deviation Found: 1.539e-35 + // Expected Error Term: 1.538e-35 + // Maximum Relative Change in Control Points: 6.104e-05 + static const T Y = 0.45658016204833984375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0289965858925328393392496555094848345), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0868181194868601184627743162571779226), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.169373435121178901746317404936356745), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13350446515949251201104889028133486), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0617447837290183627136837688446313313), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0185618495228251406703152962489700468), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00371949406491883508764162050169531013), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000485121708792921297742105775823900772), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.376494706741453489892108068231400061e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.133166058052466262415271732172490045e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.32970330146503867261275580968135126), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.46325715420422771961250513514928746), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.55307882560757679068505047390857842), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.644274289865972449441174485441409076), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.182609091063258208068606847453955649), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0354171651271241474946129665801606795), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00454060370165285246451879969534083997), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000349871943711566546821198612518656486), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.123749319840299552925421880481085392e-4), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.0f)) / tools::evaluate_polynomial(Q, T(z - 1.0f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 2.25) + { + // Maximum Deviation Found: 1.418e-35 + // Expected Error Term: 1.418e-35 + // Maximum Relative Change in Control Points: 1.316e-04 + // Max Error found at long double precision = 1.998462e-35 + static const T Y = 0.50250148773193359375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0201233630504573402185161184151016606), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0331864357574860196516686996302305002), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0716562720864787193337475444413405461), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0545835322082103985114927569724880658), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0236692635189696678976549720784989593), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00656970902163248872837262539337601845), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00120282643299089441390490459256235021), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000142123229065182650020762792081622986), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.991531438367015135346716277792989347e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.312857043762117596999398067153076051e-6), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.13506082409097783827103424943508554), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.06399257267556230937723190496806215), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.18678481279932541314830499880691109), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.447733186643051752513538142316799562), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11505680005657879437196953047542148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.020163993632192726170219663831914034), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00232708971840141388847728782209730585), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000160733201627963528519726484608224112), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.507158721790721802724402992033269266e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.18647774409821470950544212696270639e-12), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if (z < 3) + { + // Maximum Deviation Found: 3.575e-36 + // Expected Error Term: 3.575e-36 + // Maximum Relative Change in Control Points: 7.103e-05 + // Max Error found at long double precision = 5.794737e-36 + static const T Y = 0.52896785736083984375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00902152521745813634562524098263360074), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0145207142776691539346923710537580927), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0301681239582193983824211995978678571), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0215548540823305814379020678660434461), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00864683476267958365678294164340749949), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00219693096885585491739823283511049902), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000364961639163319762492184502159894371), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.388174251026723752769264051548703059e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.241918026931789436000532513553594321e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.676586625472423508158937481943649258e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.93669171363907292305550231764920001), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69468476144051356810672506101377494), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.880023580986436640372794392579985511), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.299099106711315090710836273697708402), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0690593962363545715997445583603382337), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0108427016361318921960863149875360222), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00111747247208044534520499324234317695), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.686843205749767250666787987163701209e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.192093541425429248675532015101904262e-5), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 2.25f)) / tools::evaluate_polynomial(Q, T(z - 2.25f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 3.5) + { + // Maximum Deviation Found: 8.126e-37 + // Expected Error Term: -8.126e-37 + // Maximum Relative Change in Control Points: 1.363e-04 + // Max Error found at long double precision = 1.747062e-36 + static const T Y = 0.54037380218505859375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033703486408887424921155540591370375), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0104948043110005245215286678898115811), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0148530118504000311502310457390417795), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00816693029245443090102738825536188916), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00249716579989140882491939681805594585), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0004655591010047353023978045800916647), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.531129557920045295895085236636025323e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.343526765122727069515775194111741049e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.971120407556888763695313774578711839e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.59911256167540354915906501335919317), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.136006830764025173864831382946934), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.468565867990030871678574840738423023), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.122821824954470343413956476900662236), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0209670914950115943338996513330141633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00227845718243186165620199012883547257), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000144243326443913171313947613547085553), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.407763415954267700941230249989140046e-5), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 3.0f)) / tools::evaluate_polynomial(Q, T(z - 3.0f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 5.5) + { + // Maximum Deviation Found: 5.804e-36 + // Expected Error Term: -5.803e-36 + // Maximum Relative Change in Control Points: 2.475e-05 + // Max Error found at long double precision = 1.349545e-35 + static const T Y = 0.55000019073486328125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00118142849742309772151454518093813615), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0072201822885703318172366893469382745), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0078782276276860110721875733778481505), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00418229166204362376187593976656261146), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00134198400587769200074194304298642705), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000283210387078004063264777611497435572), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.405687064094911866569295610914844928e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.39348283801568113807887364414008292e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.248798540917787001526976889284624449e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.929502490223452372919607105387474751e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.156161469668275442569286723236274457e-9), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.52955245103668419479878456656709381), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.06263944820093830054635017117417064), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.441684612681607364321013134378316463), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.121665258426166960049773715928906382), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0232134512374747691424978642874321434), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00310778180686296328582860464875562636), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000288361770756174705123674838640161693), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.177529187194133944622193191942300132e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.655068544833064069223029299070876623e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11005507545746069573608988651927452e-7), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 4.5f)) / tools::evaluate_polynomial(Q, T(z - 4.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 7.5) + { + // Maximum Deviation Found: 1.007e-36 + // Expected Error Term: 1.007e-36 + // Maximum Relative Change in Control Points: 1.027e-03 + // Max Error found at long double precision = 2.646420e-36 + static const T Y = 0.5574436187744140625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000293236907400849056269309713064107674), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00225110719535060642692275221961480162), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190984458121502831421717207849429799), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000747757733460111743833929141001680706), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000170663175280949889583158597373928096), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.246441188958013822253071608197514058e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.229818000860544644974205957895688106e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.134886977703388748488480980637704864e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.454764611880548962757125070106650958e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.673002744115866600294723141176820155e-10), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.12843690320861239631195353379313367), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.569900657061622955362493442186537259), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.169094404206844928112348730277514273), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0324887449084220415058158657252147063), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00419252877436825753042680842608219552), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00036344133176118603523976748563178578), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.204123895931375107397698245752850347e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.674128352521481412232785122943508729e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.997637501418963696542159244436245077e-8), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 6.5f)) / tools::evaluate_polynomial(Q, T(z - 6.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 11.5) + { + // Maximum Deviation Found: 8.380e-36 + // Expected Error Term: 8.380e-36 + // Maximum Relative Change in Control Points: 2.632e-06 + // Max Error found at long double precision = 9.849522e-36 + static const T Y = 0.56083202362060546875f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000282420728751494363613829834891390121), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00175387065018002823433704079355125161), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0021344978564889819420775336322920375), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00124151356560137532655039683963075661), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000423600733566948018555157026862139644), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.914030340865175237133613697319509698e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.126999927156823363353809747017945494e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110610959842869849776179749369376402e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.55075079477173482096725348704634529e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119735694018906705225870691331543806e-8), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69889613396167354566098060039549882), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.28824647372749624464956031163282674), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.572297795434934493541628008224078717), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.164157697425571712377043857240773164), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0315311145224594430281219516531649562), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00405588922155632380812945849777127458), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000336929033691445666232029762868642417), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.164033049810404773469413526427932109e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.356615210500531410114914617294694857e-6), + }; + result = Y + tools::evaluate_polynomial(P, T(z / 2 - 4.75f)) / tools::evaluate_polynomial(Q, T(z / 2 - 4.75f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Maximum Deviation Found: 1.132e-35 + // Expected Error Term: -1.132e-35 + // Maximum Relative Change in Control Points: 4.674e-04 + // Max Error found at long double precision = 1.162590e-35 + static const T Y = 0.5632686614990234375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000920922048732849448079451574171836943), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00321439044532288750501700028748922439), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.250455263029390118657884864261823431), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.906807635364090342031792404764598142), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.92233572835991735876688745989985565), + BOOST_MATH_BIG_CONSTANT(T, 113, -21.7797433494422564811782116907878495), + BOOST_MATH_BIG_CONSTANT(T, 113, -91.1451915251976354349734589601171659), + BOOST_MATH_BIG_CONSTANT(T, 113, -144.1279109655993927069052125017673), + BOOST_MATH_BIG_CONSTANT(T, 113, -313.845076581796338665519022313775589), + BOOST_MATH_BIG_CONSTANT(T, 113, -273.11378811923343424081101235736475), + BOOST_MATH_BIG_CONSTANT(T, 113, -271.651566205951067025696102600443452), + BOOST_MATH_BIG_CONSTANT(T, 113, -60.0530577077238079968843307523245547), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.49040448075464744191022350947892036), + BOOST_MATH_BIG_CONSTANT(T, 113, 34.3563592467165971295915749548313227), + BOOST_MATH_BIG_CONSTANT(T, 113, 84.4993232033879023178285731843850461), + BOOST_MATH_BIG_CONSTANT(T, 113, 376.005865281206894120659401340373818), + BOOST_MATH_BIG_CONSTANT(T, 113, 629.95369438888946233003926191755125), + BOOST_MATH_BIG_CONSTANT(T, 113, 1568.35771983533158591604513304269098), + BOOST_MATH_BIG_CONSTANT(T, 113, 1646.02452040831961063640827116581021), + BOOST_MATH_BIG_CONSTANT(T, 113, 2299.96860633240298708910425594484895), + BOOST_MATH_BIG_CONSTANT(T, 113, 1222.73204392037452750381340219906374), + BOOST_MATH_BIG_CONSTANT(T, 113, 799.359797306084372350264298361110448), + BOOST_MATH_BIG_CONSTANT(T, 113, 72.7415265778588087243442792401576737), + }; + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 110 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + result = 1 - result; + } + + return result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) +// LCOV_EXCL_STOP + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erf(T z, const Policy& /* pol */) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name()); + BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name()); + BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name()); + + typedef std::integral_constant tag_type; + + BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name()); + + return policies::checked_narrowing_cast(detail::erf_imp( + static_cast(z), + false, + forwarding_policy(), + tag_type()), "boost::math::erf<%1%>(%1%, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erfc(T z, const Policy& /* pol */) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name()); + BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name()); + BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name()); + + typedef std::integral_constant tag_type; + + BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name()); + + return policies::checked_narrowing_cast(detail::erf_imp( + static_cast(z), + true, + forwarding_policy(), + tag_type()), "boost::math::erfc<%1%>(%1%, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erf(T z) +{ + return boost::math::erf(z, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type erfc(T z) +{ + return boost::math::erfc(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#else // Special handling for NVRTC platform + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED auto erf(T x) +{ + return ::erf(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto erf(float x) +{ + return ::erff(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erf(T x, const Policy&) +{ + return ::erf(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erf(float x, const Policy&) +{ + return ::erff(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc(T x) +{ + return ::erfc(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto erfc(float x) +{ + return ::erfcf(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc(T x, const Policy&) +{ + return ::erfc(x); +} + +template +BOOST_MATH_GPU_ENABLED auto erfc(float x, const Policy&) +{ + return ::erfcf(x); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#include + +#endif // BOOST_MATH_SPECIAL_ERF_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/expint.hpp b/third-party/boost-math/include/boost/math/special_functions/expint.hpp new file mode 100644 index 0000000000000..eeec63199e33a --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/expint.hpp @@ -0,0 +1,1614 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_EXPINT_HPP +#define BOOST_MATH_EXPINT_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + expint(unsigned n, T z, const Policy& /*pol*/); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline T expint_1_rational(const T& z, const boost::math::integral_constant&) +{ + // this function is never actually called + BOOST_MATH_ASSERT(0); + return z; +} + +template +BOOST_MATH_GPU_ENABLED T expint_1_rational(const T& z, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 2.006e-18 + // Expected Error Term: 2.006e-18 + // Max error found at double precision: 2.760e-17 + // LCOV_EXCL_START + static const T Y = 0.66373538970947265625F; + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0865197248079397976498), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0320913665303559189999), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.245088216639761496153), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0368031736257943745142), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00399167106081113256961), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000111507792921197858394) + }; + static const T Q[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.37091387659397013215), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.056770677104207528384), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00427347600017103698101), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000131049900798434683324), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.528611029520217142048e-6) + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Maximum Deviation Found (interpolated): 1.444e-17 + // Max error found at double precision: 3.119e-17 + // LCOV_EXCL_START + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.121013190657725568138e-18), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.999999999999998811143), + BOOST_MATH_BIG_CONSTANT(T, 53, -43.3058660811817946037), + BOOST_MATH_BIG_CONSTANT(T, 53, -724.581482791462469795), + BOOST_MATH_BIG_CONSTANT(T, 53, -6046.8250112711035463), + BOOST_MATH_BIG_CONSTANT(T, 53, -27182.6254466733970467), + BOOST_MATH_BIG_CONSTANT(T, 53, -66598.2652345418633509), + BOOST_MATH_BIG_CONSTANT(T, 53, -86273.1567711649528784), + BOOST_MATH_BIG_CONSTANT(T, 53, -54844.4587226402067411), + BOOST_MATH_BIG_CONSTANT(T, 53, -14751.4895786128450662), + BOOST_MATH_BIG_CONSTANT(T, 53, -1185.45720315201027667) + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 45.3058660811801465927), + BOOST_MATH_BIG_CONSTANT(T, 53, 809.193214954550328455), + BOOST_MATH_BIG_CONSTANT(T, 53, 7417.37624454689546708), + BOOST_MATH_BIG_CONSTANT(T, 53, 38129.5594484818471461), + BOOST_MATH_BIG_CONSTANT(T, 53, 113057.05869159631492), + BOOST_MATH_BIG_CONSTANT(T, 53, 192104.047790227984431), + BOOST_MATH_BIG_CONSTANT(T, 53, 180329.498380501819718), + BOOST_MATH_BIG_CONSTANT(T, 53, 86722.3403467334749201), + BOOST_MATH_BIG_CONSTANT(T, 53, 18455.4124737722049515), + BOOST_MATH_BIG_CONSTANT(T, 53, 1229.20784182403048905), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.776491285282330997549) + }; + // LCOV_EXCL_STOP + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED T expint_1_rational(const T& z, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 3.807e-20 + // Expected Error Term: 3.807e-20 + // Max error found at long double precision: 6.249e-20 + // LCOV_EXCL_START + static const T Y = 0.66373538970947265625F; + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0865197248079397956816), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0275114007037026844633), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.246594388074877139824), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0237624819878732642231), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00259113319641673986276), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.30853660894346057053e-4) + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.317978365797784100273), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0393622602554758722511), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00204062029115966323229), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.732512107100088047854e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.202872781770207871975e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.52779248094603709945e-7) + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Maximum Deviation Found (interpolated): 2.220e-20 + // Max error found at long double precision: 1.346e-19 + // LCOV_EXCL_START + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.534401189080684443046e-23), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.999999999999999999905), + BOOST_MATH_BIG_CONSTANT(T, 64, -62.1517806091379402505), + BOOST_MATH_BIG_CONSTANT(T, 64, -1568.45688271895145277), + BOOST_MATH_BIG_CONSTANT(T, 64, -21015.3431990874009619), + BOOST_MATH_BIG_CONSTANT(T, 64, -164333.011755931661949), + BOOST_MATH_BIG_CONSTANT(T, 64, -777917.270775426696103), + BOOST_MATH_BIG_CONSTANT(T, 64, -2244188.56195255112937), + BOOST_MATH_BIG_CONSTANT(T, 64, -3888702.98145335643429), + BOOST_MATH_BIG_CONSTANT(T, 64, -3909822.65621952648353), + BOOST_MATH_BIG_CONSTANT(T, 64, -2149033.9538897398457), + BOOST_MATH_BIG_CONSTANT(T, 64, -584705.537139793925189), + BOOST_MATH_BIG_CONSTANT(T, 64, -65815.2605361889477244), + BOOST_MATH_BIG_CONSTANT(T, 64, -2038.82870680427258038) + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 64.1517806091379399478), + BOOST_MATH_BIG_CONSTANT(T, 64, 1690.76044393722763785), + BOOST_MATH_BIG_CONSTANT(T, 64, 24035.9534033068949426), + BOOST_MATH_BIG_CONSTANT(T, 64, 203679.998633572361706), + BOOST_MATH_BIG_CONSTANT(T, 64, 1074661.58459976978285), + BOOST_MATH_BIG_CONSTANT(T, 64, 3586552.65020899358773), + BOOST_MATH_BIG_CONSTANT(T, 64, 7552186.84989547621411), + BOOST_MATH_BIG_CONSTANT(T, 64, 9853333.79353054111434), + BOOST_MATH_BIG_CONSTANT(T, 64, 7689642.74550683631258), + BOOST_MATH_BIG_CONSTANT(T, 64, 3385553.35146759180739), + BOOST_MATH_BIG_CONSTANT(T, 64, 763218.072732396428725), + BOOST_MATH_BIG_CONSTANT(T, 64, 73930.2995984054930821), + BOOST_MATH_BIG_CONSTANT(T, 64, 2063.86994219629165937) + }; + // LCOV_EXCL_STOP + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED T expint_1_rational(const T& z, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 2.477e-35 + // Expected Error Term: 2.477e-35 + // Max error found at long double precision: 6.810e-35 + // LCOV_EXCL_START + static const T Y = 0.66373538970947265625F; + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0865197248079397956434879099175975937), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0369066175910795772830865304506087759), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.24272036838415474665971599314725545), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0502166331248948515282379137550178307), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00768384138547489410285101483730424919), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000612574337702109683505224915484717162), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.380207107950635046971492617061708534e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.136528159460768830763009294683628406e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.346839106212658259681029388908658618e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.340500302777838063940402160594523429e-9) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.426568827778942588160423015589537302), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0841384046470893490592450881447510148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0100557215850668029618957359471132995), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000799334870474627021737357294799839363), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.434452090903862735242423068552687688e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15829674748799079874182885081231252e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.354406206738023762100882270033082198e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.369373328141051577845488477377890236e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.274149801370933606409282434677600112e-12) + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z <= 4) + { + // Max error in interpolated form: 5.614e-35 + // Max error found at long double precision: 7.979e-35 + // LCOV_EXCL_START + static const T Y = 0.70190334320068359375F; + + static const T P[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.298096656795020369955077350585959794), + BOOST_MATH_BIG_CONSTANT(T, 113, 12.9314045995266142913135497455971247), + BOOST_MATH_BIG_CONSTANT(T, 113, 226.144334921582637462526628217345501), + BOOST_MATH_BIG_CONSTANT(T, 113, 2070.83670924261732722117682067381405), + BOOST_MATH_BIG_CONSTANT(T, 113, 10715.1115684330959908244769731347186), + BOOST_MATH_BIG_CONSTANT(T, 113, 30728.7876355542048019664777316053311), + BOOST_MATH_BIG_CONSTANT(T, 113, 38520.6078609349855436936232610875297), + BOOST_MATH_BIG_CONSTANT(T, 113, -27606.0780981527583168728339620565165), + BOOST_MATH_BIG_CONSTANT(T, 113, -169026.485055785605958655247592604835), + BOOST_MATH_BIG_CONSTANT(T, 113, -254361.919204983608659069868035092282), + BOOST_MATH_BIG_CONSTANT(T, 113, -195765.706874132267953259272028679935), + BOOST_MATH_BIG_CONSTANT(T, 113, -83352.6826013533205474990119962408675), + BOOST_MATH_BIG_CONSTANT(T, 113, -19251.6828496869586415162597993050194), + BOOST_MATH_BIG_CONSTANT(T, 113, -2226.64251774578542836725386936102339), + BOOST_MATH_BIG_CONSTANT(T, 113, -109.009437301400845902228611986479816), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.51492042209561411434644938098833499) + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 46.734521442032505570517810766704587), + BOOST_MATH_BIG_CONSTANT(T, 113, 908.694714348462269000247450058595655), + BOOST_MATH_BIG_CONSTANT(T, 113, 9701.76053033673927362784882748513195), + BOOST_MATH_BIG_CONSTANT(T, 113, 63254.2815292641314236625196594947774), + BOOST_MATH_BIG_CONSTANT(T, 113, 265115.641285880437335106541757711092), + BOOST_MATH_BIG_CONSTANT(T, 113, 732707.841188071900498536533086567735), + BOOST_MATH_BIG_CONSTANT(T, 113, 1348514.02492635723327306628712057794), + BOOST_MATH_BIG_CONSTANT(T, 113, 1649986.81455283047769673308781585991), + BOOST_MATH_BIG_CONSTANT(T, 113, 1326000.828522976970116271208812099), + BOOST_MATH_BIG_CONSTANT(T, 113, 683643.09490612171772350481773951341), + BOOST_MATH_BIG_CONSTANT(T, 113, 217640.505137263607952365685653352229), + BOOST_MATH_BIG_CONSTANT(T, 113, 40288.3467237411710881822569476155485), + BOOST_MATH_BIG_CONSTANT(T, 113, 3932.89353979531632559232883283175754), + BOOST_MATH_BIG_CONSTANT(T, 113, 169.845369689596739824177412096477219), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.17607292280092201170768401876895354) + }; + // LCOV_EXCL_STOP + T recip = 1 / z; + result = Y + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Max error in interpolated form: 4.413e-35 + // Max error found at long double precision: 8.928e-35 + // LCOV_EXCL_START + static const T P[19] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.559148411832951463689610809550083986e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999999999999999999999997), + BOOST_MATH_BIG_CONSTANT(T, 113, -166.542326331163836642960118190147367), + BOOST_MATH_BIG_CONSTANT(T, 113, -12204.639128796330005065904675153652), + BOOST_MATH_BIG_CONSTANT(T, 113, -520807.069767086071806275022036146855), + BOOST_MATH_BIG_CONSTANT(T, 113, -14435981.5242137970691490903863125326), + BOOST_MATH_BIG_CONSTANT(T, 113, -274574945.737064301247496460758654196), + BOOST_MATH_BIG_CONSTANT(T, 113, -3691611582.99810039356254671781473079), + BOOST_MATH_BIG_CONSTANT(T, 113, -35622515944.8255047299363690814678763), + BOOST_MATH_BIG_CONSTANT(T, 113, -248040014774.502043161750715548451142), + BOOST_MATH_BIG_CONSTANT(T, 113, -1243190389769.53458416330946622607913), + BOOST_MATH_BIG_CONSTANT(T, 113, -4441730126135.54739052731990368425339), + BOOST_MATH_BIG_CONSTANT(T, 113, -11117043181899.7388524310281751971366), + BOOST_MATH_BIG_CONSTANT(T, 113, -18976497615396.9717776601813519498961), + BOOST_MATH_BIG_CONSTANT(T, 113, -21237496819711.1011661104761906067131), + BOOST_MATH_BIG_CONSTANT(T, 113, -14695899122092.5161620333466757812848), + BOOST_MATH_BIG_CONSTANT(T, 113, -5737221535080.30569711574295785864903), + BOOST_MATH_BIG_CONSTANT(T, 113, -1077042281708.42654526404581272546244), + BOOST_MATH_BIG_CONSTANT(T, 113, -68028222642.1941480871395695677675137) + }; + static const T Q[20] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 168.542326331163836642960118190147311), + BOOST_MATH_BIG_CONSTANT(T, 113, 12535.7237814586576783518249115343619), + BOOST_MATH_BIG_CONSTANT(T, 113, 544891.263372016404143120911148640627), + BOOST_MATH_BIG_CONSTANT(T, 113, 15454474.7241010258634446523045237762), + BOOST_MATH_BIG_CONSTANT(T, 113, 302495899.896629522673410325891717381), + BOOST_MATH_BIG_CONSTANT(T, 113, 4215565948.38886507646911672693270307), + BOOST_MATH_BIG_CONSTANT(T, 113, 42552409471.7951815668506556705733344), + BOOST_MATH_BIG_CONSTANT(T, 113, 313592377066.753173979584098301610186), + BOOST_MATH_BIG_CONSTANT(T, 113, 1688763640223.4541980740597514904542), + BOOST_MATH_BIG_CONSTANT(T, 113, 6610992294901.59589748057620192145704), + BOOST_MATH_BIG_CONSTANT(T, 113, 18601637235659.6059890851321772682606), + BOOST_MATH_BIG_CONSTANT(T, 113, 36944278231087.2571020964163402941583), + BOOST_MATH_BIG_CONSTANT(T, 113, 50425858518481.7497071917028793820058), + BOOST_MATH_BIG_CONSTANT(T, 113, 45508060902865.0899967797848815980644), + BOOST_MATH_BIG_CONSTANT(T, 113, 25649955002765.3817331501988304758142), + BOOST_MATH_BIG_CONSTANT(T, 113, 8259575619094.6518520988612711292331), + BOOST_MATH_BIG_CONSTANT(T, 113, 1299981487496.12607474362723586264515), + BOOST_MATH_BIG_CONSTANT(T, 113, 70242279152.8241187845178443118302693), + BOOST_MATH_BIG_CONSTANT(T, 113, -37633302.9409263839042721539363416685) + }; + // LCOV_EXCL_STOP + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + + +template +struct expint_fraction +{ + typedef boost::math::pair result_type; + BOOST_MATH_GPU_ENABLED expint_fraction(unsigned n_, T z_) : b(n_ + z_), i(-1), n(n_){} + BOOST_MATH_GPU_ENABLED boost::math::pair operator()() + { + boost::math::pair result = boost::math::make_pair(-static_cast((i+1) * (n+i)), b); + b += 2; + ++i; + return result; + } +private: + T b; + int i; + unsigned n; +}; + +template +BOOST_MATH_GPU_ENABLED inline T expint_as_fraction(unsigned n, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + BOOST_MATH_INSTRUMENT_VARIABLE(z) + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + expint_fraction f(n, z); + T result = tools::continued_fraction_b( + f, + boost::math::policies::get_epsilon(), + max_iter); + policies::check_series_iterations("boost::math::expint_continued_fraction<%1%>(unsigned,%1%)", max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + BOOST_MATH_INSTRUMENT_VARIABLE(max_iter) + result = exp(-z) / result; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + return result; +} + +template +struct expint_series +{ + typedef T result_type; + BOOST_MATH_GPU_ENABLED expint_series(unsigned k_, T z_, T x_k_, T denom_, T fact_) + : k(k_), z(z_), x_k(x_k_), denom(denom_), fact(fact_){} + BOOST_MATH_GPU_ENABLED T operator()() + { + x_k *= -z; + denom += 1; + fact *= ++k; + return x_k / (denom * fact); + } +private: + unsigned k; + T z; + T x_k; + T denom; + T fact; +}; + +template +BOOST_MATH_GPU_ENABLED inline T expint_as_series(unsigned n, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + BOOST_MATH_INSTRUMENT_VARIABLE(z) + + T result = 0; + T x_k = -1; + T denom = T(1) - n; + T fact = 1; + unsigned k = 0; + for(; k < n - 1;) + { + result += x_k / (denom * fact); + denom += 1; + x_k *= -z; + fact *= ++k; + } + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += pow(-z, static_cast(n - 1)) + * (boost::math::digamma(static_cast(n), pol) - log(z)) / fact; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + + expint_series s(k, z, x_k, denom, fact); + result = tools::sum_series(s, policies::get_epsilon(), max_iter, result); + policies::check_series_iterations("boost::math::expint_series<%1%>(unsigned,%1%)", max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + BOOST_MATH_INSTRUMENT_VARIABLE(max_iter) + return result; +} + +template +BOOST_MATH_GPU_ENABLED T expint_imp(unsigned n, T z, const Policy& pol, const Tag& tag) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::expint<%1%>(unsigned, %1%)"; + if(z < 0) + return policies::raise_domain_error(function, "Function requires z >= 0 but got %1%.", z, pol); + if(z == 0) + return n == 1 ? policies::raise_overflow_error(function, nullptr, pol) : T(1 / (static_cast(n - 1))); + + T result; + + bool f; + if(n < 3) + { + f = z < T(0.5); + } + else + { + f = z < (static_cast(n - 2) / static_cast(n - 1)); + } +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) // conditional expression is constant +#endif + if(n == 0) + { + result = exp(-z) / z; + } + else if((n == 1) && (Tag::value)) + { + result = expint_1_rational(z, tag); + } + else if(f) + { + result = expint_as_series(n, z, pol); + } + else + { + result = expint_as_fraction(n, z, pol); + } +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + return result; +} + +template +struct expint_i_series +{ + typedef T result_type; + BOOST_MATH_GPU_ENABLED expint_i_series(T z_) : k(0), z_k(1), z(z_){} + BOOST_MATH_GPU_ENABLED T operator()() + { + z_k *= z / ++k; + return z_k / k; + } +private: + unsigned k; + T z_k; + T z; +}; + +template +BOOST_MATH_GPU_ENABLED T expint_i_as_series(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + T result = log(z); // (log(z) - log(1 / z)) / 2; + result += constants::euler(); + expint_i_series s(z); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + result = tools::sum_series(s, policies::get_epsilon(), max_iter, result); + policies::check_series_iterations("boost::math::expint_i_series<%1%>(%1%)", max_iter, pol); + return result; +} + +template +BOOST_MATH_GPU_ENABLED T expint_i_imp(T z, const Policy& pol, const Tag& tag) +{ + constexpr auto function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE confirmed covered by real_concept tests + return expint_i_as_series(z, pol); +} + +template +BOOST_MATH_GPU_ENABLED T expint_i_imp(T z, const Policy& pol, const boost::math::integral_constant& tag) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + // Maximum Deviation Found: 2.852e-18 + // Expected Error Term: 2.852e-18 + // Max Error found at double precision = Poly: 2.636335e-16 Cheb: 4.187027e-16 + // LCOV_EXCL_START + BOOST_MATH_STATIC const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 2.98677224343598593013), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.356343618769377415068), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.780836076283730801839), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.114670926327032002811), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0499434773576515260534), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00726224593341228159561), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00115478237227804306827), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000116419523609765200999), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.798296365679269702435e-5), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.2777056254402008721e-6) + }; + BOOST_MATH_STATIC const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, -1.17090412365413911947), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.62215109846016746276), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.195114782069495403315), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0391523431392967238166), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00504800158663705747345), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000389034007436065401822), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.138972589601781706598e-4) + }; + + BOOST_MATH_STATIC_LOCAL_VARIABLE const T c1 = BOOST_MATH_BIG_CONSTANT(T, 53, 1677624236387711.0); + BOOST_MATH_STATIC_LOCAL_VARIABLE const T c2 = BOOST_MATH_BIG_CONSTANT(T, 53, 4503599627370496.0); + BOOST_MATH_STATIC_LOCAL_VARIABLE const T r1 = static_cast(c1 / c2); + BOOST_MATH_STATIC_LOCAL_VARIABLE const T r2 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.131401834143860282009280387409357165515556574352422001206362e-16); + BOOST_MATH_STATIC_LOCAL_VARIABLE const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 53, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + // LCOV_EXCL_STOP + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = (z - r1) - r2; + result *= t; + if(fabs(t) < T(0.1)) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } + } + else if (z <= 10) + { + // Maximum Deviation Found: 6.546e-17 + // Expected Error Term: 6.546e-17 + // Max Error found at double precision = Poly: 6.890169e-17 Cheb: 6.772128e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 1.158985137939453125F; + BOOST_MATH_STATIC const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00139324086199402804173), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0349921221823888744966), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0264095520754134848538), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00761224003005476438412), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00247496209592143627977), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000374885917942100256775), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.554086272024881826253e-4), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.396487648924804510056e-5) + }; + BOOST_MATH_STATIC const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.744625566823272107711), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.329061095011767059236), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.100128624977313872323), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0223851099128506347278), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00365334190742316650106), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000402453408512476836472), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.263649630720255691787e-4) + }; + // LCOV_EXCL_STOP + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 20) + { + // Maximum Deviation Found: 1.843e-17 + // Expected Error Term: -1.842e-17 + // Max Error found at double precision = Poly: 4.375868e-17 Cheb: 5.860967e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 1.0869731903076171875F; + BOOST_MATH_STATIC const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00893891094356945667451), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0484607730127134045806), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0652810444222236895772), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0478447572647309671455), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0226059218923777094596), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00720603636917482065907), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00155941947035972031334), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000209750022660200888349), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.138652200349182596186e-4) + }; + BOOST_MATH_STATIC const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.97017214039061194971), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.86232465043073157508), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.09601437090337519977), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.438873285773088870812), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.122537731979686102756), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0233458478275769288159), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00278170769163303669021), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000159150281166108755531) + }; + // LCOV_EXCL_STOP + T t = z / 5 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 40) + { + // Maximum Deviation Found: 5.102e-18 + // Expected Error Term: 5.101e-18 + // Max Error found at double precision = Poly: 1.441088e-16 Cheb: 1.864792e-16 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y = 1.03937530517578125F; + BOOST_MATH_STATIC const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00356165148914447597995), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0229930320357982333406), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0449814350482277917716), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0453759383048193402336), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0272050837209380717069), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00994403059883350813295), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00207592267812291726961), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000192178045857733706044), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.113161784705911400295e-9) + }; + BOOST_MATH_STATIC const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.84354408840148561131), + BOOST_MATH_BIG_CONSTANT(T, 53, 3.6599610090072393012), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.75088464344293083595), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.2985244073998398643), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.383213198510794507409), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0651165455496281337831), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00488071077519227853585) + }; + // LCOV_EXCL_STOP + T t = z / 10 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else + { + // Max Error found at double precision = 3.381886e-17 + // LCOV_EXCL_START + BOOST_MATH_STATIC_LOCAL_VARIABLE const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 53, 2.35385266837019985407899910749034804508871617254555467236651e17)); + BOOST_MATH_STATIC_LOCAL_VARIABLE const T Y= 1.013065338134765625F; + BOOST_MATH_STATIC const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0130653381347656243849), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.19029710559486576682), + BOOST_MATH_BIG_CONSTANT(T, 53, 94.7365094537197236011), + BOOST_MATH_BIG_CONSTANT(T, 53, -2516.35323679844256203), + BOOST_MATH_BIG_CONSTANT(T, 53, 18932.0850014925993025), + BOOST_MATH_BIG_CONSTANT(T, 53, -38703.1431362056714134) + }; + BOOST_MATH_STATIC const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 61.9733592849439884145), + BOOST_MATH_BIG_CONSTANT(T, 53, -2354.56211323420194283), + BOOST_MATH_BIG_CONSTANT(T, 53, 22329.1459489893079041), + BOOST_MATH_BIG_CONSTANT(T, 53, -70126.245140396567133), + BOOST_MATH_BIG_CONSTANT(T, 53, 54738.2833147775537106), + BOOST_MATH_BIG_CONSTANT(T, 53, 8297.16296356518409347) + }; + // LCOV_EXCL_STOP + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED T expint_i_imp(T z, const Policy& pol, const boost::math::integral_constant& tag) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + // Maximum Deviation Found: 3.883e-21 + // Expected Error Term: 3.883e-21 + // Max Error found at long double precision = Poly: 3.344801e-19 Cheb: 4.989937e-19 + + // LCOV_EXCL_START + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 2.98677224343598593764), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.25891613550886736592), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.789323584998672832285), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.092432587824602399339), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0514236978728625906656), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00658477469745132977921), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00124914538197086254233), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000131429679565472408551), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.11293331317982763165e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.629499283139417444244e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.177833045143692498221e-7) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.20352377969742325748), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.66707904942606479811), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.223014531629140771914), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0493340022262908008636), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00741934273050807310677), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00074353567782087939294), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.455861727069603367656e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.131515429329812837701e-5) + }; + + static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 64, 1677624236387711.0); + static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 64, 4503599627370496.0); + static const T r1 = c1 / c2; + static const T r2 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.131401834143860282009280387409357165515556574352422001206362e-16); + static const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + // LCOV_EXCL_STOP + + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = (z - r1) - r2; + result *= t; + if(fabs(t) < T(0.1)) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } + } + else if (z <= 10) + { + // Maximum Deviation Found: 2.622e-21 + // Expected Error Term: -2.622e-21 + // Max Error found at long double precision = Poly: 1.208328e-20 Cheb: 1.073723e-20 + // LCOV_EXCL_START + static const T Y = 1.158985137939453125F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00139324086199409049399), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0345238388952337563247), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0382065278072592940767), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0156117003070560727392), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00383276012430495387102), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000697070540945496497992), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.877310384591205930343e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.623067256376494930067e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.377246883283337141444e-6) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.08073635708902053767), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.553681133533942532909), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.176763647137553797451), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0387891748253869928121), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0060603004848394727017), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000670519492939992806051), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.4947357050100855646e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.204339282037446434827e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.146951181174930425744e-7) + }; + // LCOV_EXCL_STOP + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 20) + { + // Maximum Deviation Found: 3.220e-20 + // Expected Error Term: 3.220e-20 + // Max Error found at long double precision = Poly: 7.696841e-20 Cheb: 6.205163e-20 + + // LCOV_EXCL_START + static const T Y = 1.0869731903076171875F; + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00893891094356946995368), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0487562980088748775943), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0670568657950041926085), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509577352851442932713), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.02551800927409034206), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00892913759760086687083), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00224469630207344379888), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000392477245911296982776), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.44424044184395578775e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252788029251437017959e-5) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.00323265503572414261), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.94688958187256383178), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.19733638134417472296), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.513137726038353385661), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.159135395578007264547), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0358233587351620919881), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0056716655597009417875), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000577048986213535829925), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.290976943033493216793e-4) + }; + // LCOV_EXCL_STOP + T t = z / 5 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 40) + { + // Maximum Deviation Found: 2.940e-21 + // Expected Error Term: -2.938e-21 + // Max Error found at long double precision = Poly: 3.419893e-19 Cheb: 3.359874e-19 + // LCOV_EXCL_START + static const T Y = 1.03937530517578125F; + static const T P[12] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00356165148914447278177), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0240235006148610849678), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0516699967278057976119), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0586603078706856245674), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0409960120868776180825), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0185485073689590665153), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00537842101034123222417), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000920988084778273760609), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.716742618812210980263e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.504623302166487346677e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.712662196671896837736e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.533769629702262072175e-11) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.13286733695729715455), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.49281223045653491929), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.84900294427622911374), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.15205199043580378211), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.802912186540269232424), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.194793170017818925388), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280128013584653182994), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00182034930799902922549) + }; + // LCOV_EXCL_STOP + T t = z / 10 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + } + else + { + // Maximum Deviation Found: 3.536e-20 + // Max Error found at long double precision = Poly: 1.310671e-19 Cheb: 8.630943e-11 + // LCOV_EXCL_START + static const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.35385266837019985407899910749034804508871617254555467236651e17)); + static const T Y= 1.013065338134765625F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0130653381347656250004), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.644487780349757303739), + BOOST_MATH_BIG_CONSTANT(T, 64, 143.995670348227433964), + BOOST_MATH_BIG_CONSTANT(T, 64, -13918.9322758014173709), + BOOST_MATH_BIG_CONSTANT(T, 64, 476260.975133624194484), + BOOST_MATH_BIG_CONSTANT(T, 64, -7437102.15135982802122), + BOOST_MATH_BIG_CONSTANT(T, 64, 53732298.8764767916542), + BOOST_MATH_BIG_CONSTANT(T, 64, -160695051.957997452509), + BOOST_MATH_BIG_CONSTANT(T, 64, 137839271.592778020028) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 27.2103343964943718802), + BOOST_MATH_BIG_CONSTANT(T, 64, -8785.48528692879413676), + BOOST_MATH_BIG_CONSTANT(T, 64, 397530.290000322626766), + BOOST_MATH_BIG_CONSTANT(T, 64, -7356441.34957799368252), + BOOST_MATH_BIG_CONSTANT(T, 64, 63050914.5343400957524), + BOOST_MATH_BIG_CONSTANT(T, 64, -246143779.638307701369), + BOOST_MATH_BIG_CONSTANT(T, 64, 384647824.678554961174), + BOOST_MATH_BIG_CONSTANT(T, 64, -166288297.874583961493) + }; + // LCOV_EXCL_STOP + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_imp_113a(T& result, const T& z, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 1.230e-36 + // Expected Error Term: -1.230e-36 + // Max Error found at long double precision = Poly: 4.355299e-34 Cheb: 7.512581e-34 + + // LCOV_EXCL_START + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 2.98677224343598593765287235997328555), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.333256034674702967028780537349334037), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.851831522798101228384971644036708463), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0657854833494646206186773614110374948), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0630065662557284456000060708977935073), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00311759191425309373327784154659649232), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00176213568201493949664478471656026771), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.491548660404172089488535218163952295e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.207764227621061706075562107748176592e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.225445398156913584846374273379402765e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.996939977231410319761273881672601592e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.212546902052178643330520878928100847e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.154646053060262871360159325115980023e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.143971277122049197323415503594302307e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.306243138978114692252817805327426657e-13) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.40178870313943798705491944989231793), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.943810968269701047641218856758605284), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.405026631534345064600850391026113165), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.123924153524614086482627660399122762), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0286364505373369439591132549624317707), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00516148845910606985396596845494015963), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000738330799456364820380739850924783649), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.843737760991856114061953265870882637e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.767957673431982543213661388914587589e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.549136847313854595809952100614840031e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.299801381513743676764008325949325404e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.118419479055346106118129130945423483e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.30372295663095470359211949045344607e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.382742953753485333207877784720070523e-12) + }; + + static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 113, 1677624236387711.0); + static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T c3 = BOOST_MATH_BIG_CONSTANT(T, 113, 266514582277687.0); + static const T c4 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T c5 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T r1 = c1 / c2; + static const T r2 = c3 / c4 / c5; + static const T r3 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.283806480836357377069325311780969887585024578164571984232357e-31)); + static const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + // LCOV_EXCL_STOP + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = ((z - r1) - r2) - r3; + result *= t; + if(fabs(t) < 0.1) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113b(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 7.779e-36 + // Expected Error Term: -7.779e-36 + // Max Error found at long double precision = Poly: 2.576723e-35 Cheb: 1.236001e-34 + // LCOV_EXCL_START + static const T Y = 1.158985137939453125F; + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139324086199409049282472239613554817), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0338173111691991289178779840307998955), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0555972290794371306259684845277620556), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0378677976003456171563136909186202177), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0152221583517528358782902783914356667), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00428283334203873035104248217403126905), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000922782631491644846511553601323435286), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000155513428088853161562660696055496696), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.205756580255359882813545261519317096e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.220327406578552089820753181821115181e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.189483157545587592043421445645377439e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.122426571518570587750898968123803867e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.635187358949437991465353268374523944e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.203015132965870311935118337194860863e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.384276705503357655108096065452950822e-12) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.58784732785354597996617046880946257), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.18550755302279446339364262338114098), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.55598993549661368604527040349702836), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.184290888380564236919107835030984453), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0459658051803613282360464632326866113), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089505064268613225167835599456014705), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139042673882987693424772855926289077), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000174210708041584097450805790176479012), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.176324034009707558089086875136647376e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.142935845999505649273084545313710581e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.907502324487057260675816233312747784e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.431044337808893270797934621235918418e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.139007266881450521776529705677086902e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234715286125516430792452741830364672e-11) + }; + // LCOV_EXCL_STOP + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113c(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 1.082e-34 + // Expected Error Term: 1.080e-34 + // Max Error found at long double precision = Poly: 1.958294e-34 Cheb: 2.472261e-34 + + // LCOV_EXCL_START + static const T Y = 1.091579437255859375F; + static const T P[17] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00685089599550151282724924894258520532), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0443313550253580053324487059748497467), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.071538561252424027443296958795814874), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0622923153354102682285444067843300583), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0361631270264607478205393775461208794), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0153192826839624850298106509601033261), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00496967904961260031539602977748408242), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126989079663425780800919171538920589), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000258933143097125199914724875206326698), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.422110326689204794443002330541441956e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.546004547590412661451073996127115221e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.546775260262202177131068692199272241e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.404157632825805803833379568956559215e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.200612596196561323832327013027419284e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.502538501472133913417609379765434153e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.326283053716799774936661568391296584e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.869226483473172853557775877908693647e-15) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.23227220874479061894038229141871087), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.40221000361027971895657505660959863), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.65476320985936174728238416007084214), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.816828602963895720369875535001248227), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.306337922909446903672123418670921066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0902400121654409267774593230720600752), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0212708882169429206498765100993228086), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00404442626252467471957713495828165491), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0006195601618842253612635241404054589), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.755930932686543009521454653994321843e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.716004532773778954193609582677482803e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500881663076471627699290821742924233e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233593219218823384508105943657387644e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.554900353169148897444104962034267682e-9) + }; + // LCOV_EXCL_STOP + T t = z / 4 - 3.5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113d(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 3.163e-35 + // Expected Error Term: 3.163e-35 + // Max Error found at long double precision = Poly: 4.158110e-35 Cheb: 5.385532e-35 + // LCOV_EXCL_START + static const T Y = 1.051731109619140625F; + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00144552494420652573815404828020593565), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0126747451594545338365684731262912741), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.01757394877502366717526779263438073), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0126838952395506921945756139424722588), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0060045057928894974954756789352443522), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00205349237147226126653803455793107903), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000532606040579654887676082220195624207), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107344687098019891474772069139014662), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169536802705805811859089949943435152e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.20863311729206543881826553010120078e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.195670358542116256713560296776654385e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.133291168587253145439184028259772437e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.595500337089495614285777067722823397e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.133141358866324100955927979606981328e-10) + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.72490783907582654629537013560044682), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.44524329516800613088375685659759765), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.778241785539308257585068744978050181), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.300520486589206605184097270225725584), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0879346899691339661394537806057953957), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0200802415843802892793583043470125006), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00362842049172586254520256100538273214), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000519731362862955132062751246769469957), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.584092147914050999895178697392282665e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.501851497707855358002773398333542337e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.313085677467921096644895738538865537e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.127552010539733113371132321521204458e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.25737310826983451144405899970774587e-9) + }; + // LCOV_EXCL_STOP + T t = z / 4 - 5.5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113e(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 7.972e-36 + // Expected Error Term: 7.962e-36 + // Max Error found at long double precision = Poly: 1.711721e-34 Cheb: 3.100018e-34 + // LCOV_EXCL_START + static const T Y = 1.032726287841796875F; + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00141056919297307534690895009969373233), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0123384175302540291339020257071411437), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0298127270706864057791526083667396115), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0390686759471630584626293670260768098), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0338226792912607409822059922949035589), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0211659736179834946452561197559654582), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0100428887460879377373158821400070313), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00370717396015165148484022792801682932), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0010768667551001624764329000496561659), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000246127328761027039347584096573123531), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.437318110527818613580613051861991198e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.587532682329299591501065482317771497e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.565697065670893984610852937110819467e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.350233957364028523971768887437839573e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105428907085424234504608142258423505e-8) + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.17261315255467581204685605414005525), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.85267952971640525245338392887217426), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.74341914912439861451492872946725151), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.31108463283559911602405970817931801), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.74657006336994649386607925179848899), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.718255607416072737965933040353653244), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234037553177354542791975767960643864), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0607470145906491602476833515412605389), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0125048143774226921434854172947548724), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00201034366420433762935768458656609163), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000244823338417452367656368849303165721), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.213511655166983177960471085462540807e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119323998465870686327170541547982932e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.322153582559488797803027773591727565e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.161635525318683508633792845159942312e-16) + }; + // LCOV_EXCL_STOP + T t = z / 8 - 4.25; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113f(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 4.469e-36 + // Expected Error Term: 4.468e-36 + // Max Error found at long double precision = Poly: 1.288958e-35 Cheb: 2.304586e-35 + // LCOV_EXCL_START + static const T Y = 1.0216197967529296875F; + static const T P[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000322999116096627043476023926572650045), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00385606067447365187909164609294113346), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00686514524727568176735949971985244415), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00606260649593050194602676772589601799), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00334382362017147544335054575436194357), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126108534260253075708625583630318043), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000337881489347846058951220431209276776), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.648480902304640018785370650254018022e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.87652644082970492211455290209092766e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.794712243338068631557849449519994144e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.434084023639508143975983454830954835e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.107839681938752337160494412638656696e-8) + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.09913805456661084097134805151524958), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.07041755535439919593503171320431849), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.26406517226052371320416108604874734), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.529689923703770353961553223973435569), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.159578150879536711042269658656115746), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0351720877642000691155202082629857131), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00565313621289648752407123620997063122), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000646920278540515480093843570291218295), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.499904084850091676776993523323213591e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233740058688179614344680531486267142e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.498800627828842754845418576305379469e-7) + }; + // LCOV_EXCL_STOP + T t = z / 7 - 7; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113g(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 5.588e-35 + // Expected Error Term: -5.566e-35 + // Max Error found at long double precision = Poly: 9.976345e-35 Cheb: 8.358865e-35 + // LCOV_EXCL_START + static const T Y = 1.015148162841796875F; + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000435714784725086961464589957142615216), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00432114324353830636009453048419094314), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0100740363285526177522819204820582424), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0116744115827059174392383504427640362), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00816145387784261141360062395898644652), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00371380272673500791322744465394211508), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00112958263488611536502153195005736563), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000228316462389404645183269923754256664), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29462181955852860250359064291292577e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.21972450610957417963227028788460299e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.720558173805289167524715527536874694e-7) + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.95918362458402597039366979529287095), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.96472247520659077944638411856748924), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.15563251550528513747923714884142131), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.64674612007093983894215359287448334), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.58695020129846594405856226787156424), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.144358385319329396231755457772362793), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.024146911506411684815134916238348063), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026257132337460784266874572001650153), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000167479843750859222348869769094711093), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.475673638665358075556452220192497036e-5) + }; + // LCOV_EXCL_STOP + T t = z / 14 - 5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +BOOST_MATH_GPU_ENABLED void expint_i_113h(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 4.448e-36 + // Expected Error Term: 4.445e-36 + // Max Error found at long double precision = Poly: 2.058532e-35 Cheb: 2.165465e-27 + // LCOV_EXCL_START + static const T Y= 1.00849151611328125F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0084915161132812500000001440233607358), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.84479378737716028341394223076147872), + BOOST_MATH_BIG_CONSTANT(T, 113, -130.431146923726715674081563022115568), + BOOST_MATH_BIG_CONSTANT(T, 113, 4336.26945491571504885214176203512015), + BOOST_MATH_BIG_CONSTANT(T, 113, -76279.0031974974730095170437591004177), + BOOST_MATH_BIG_CONSTANT(T, 113, 729577.956271997673695191455111727774), + BOOST_MATH_BIG_CONSTANT(T, 113, -3661928.69330208734947103004900349266), + BOOST_MATH_BIG_CONSTANT(T, 113, 8570600.041606912735872059184527855), + BOOST_MATH_BIG_CONSTANT(T, 113, -6758379.93672362080947905580906028645) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -99.4868026047611434569541483506091713), + BOOST_MATH_BIG_CONSTANT(T, 113, 3879.67753690517114249705089803055473), + BOOST_MATH_BIG_CONSTANT(T, 113, -76495.82413252517165830203774900806), + BOOST_MATH_BIG_CONSTANT(T, 113, 820773.726408311894342553758526282667), + BOOST_MATH_BIG_CONSTANT(T, 113, -4803087.64956923577571031564909646579), + BOOST_MATH_BIG_CONSTANT(T, 113, 14521246.227703545012713173740895477), + BOOST_MATH_BIG_CONSTANT(T, 113, -19762752.0196769712258527849159393044), + BOOST_MATH_BIG_CONSTANT(T, 113, 8354144.67882768405803322344185185517), + BOOST_MATH_BIG_CONSTANT(T, 113, 355076.853106511136734454134915432571) + }; + // LCOV_EXCL_STOP + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +BOOST_MATH_GPU_ENABLED T expint_i_imp(T z, const Policy& pol, const boost::math::integral_constant& tag) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + expint_i_imp_113a(result, z, pol); + } + else if (z <= 10) + { + expint_i_113b(result, z); + } + else if(z <= 18) + { + expint_i_113c(result, z); + } + else if(z <= 26) + { + expint_i_113d(result, z); + } + else if(z <= 42) + { + expint_i_113e(result, z); + } + else if(z <= 56) + { + expint_i_113f(result, z); + } + else if(z <= 84) + { + expint_i_113g(result, z); + } + else if(z <= 210) + { + expint_i_113h(result, z); + } + else // z > 210 + { + // Maximum Deviation Found: 3.963e-37 + // Expected Error Term: 3.963e-37 + // Max Error found at long double precision = Poly: 1.248049e-36 Cheb: 2.843486e-29 + + static const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2.35385266837019985407899910749034804508871617254555467236651e17)); + static const T Y= 1.00252532958984375F; + static const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00252532958984375000000000000000000085), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.16591386866059087390621952073890359), + BOOST_MATH_BIG_CONSTANT(T, 113, -67.8483431314018462417456828499277579), + BOOST_MATH_BIG_CONSTANT(T, 113, 1567.68688154683822956359536287575892), + BOOST_MATH_BIG_CONSTANT(T, 113, -17335.4683325819116482498725687644986), + BOOST_MATH_BIG_CONSTANT(T, 113, 93632.6567462673524739954389166550069), + BOOST_MATH_BIG_CONSTANT(T, 113, -225025.189335919133214440347510936787), + BOOST_MATH_BIG_CONSTANT(T, 113, 175864.614717440010942804684741336853) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -65.6998869881600212224652719706425129), + BOOST_MATH_BIG_CONSTANT(T, 113, 1642.73850032324014781607859416890077), + BOOST_MATH_BIG_CONSTANT(T, 113, -19937.2610222467322481947237312818575), + BOOST_MATH_BIG_CONSTANT(T, 113, 124136.267326632742667972126625064538), + BOOST_MATH_BIG_CONSTANT(T, 113, -384614.251466704550678760562965502293), + BOOST_MATH_BIG_CONSTANT(T, 113, 523355.035910385688578278384032026998), + BOOST_MATH_BIG_CONSTANT(T, 113, -217809.552260834025885677791936351294), + BOOST_MATH_BIG_CONSTANT(T, 113, -8555.81719551123640677261226549550872) + }; + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + expint_forwarder(T z, const Policy& /*pol*/, boost::math::true_type const&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef boost::math::integral_constant tag_type; + + return policies::checked_narrowing_cast(detail::expint_i_imp(static_cast(z), forwarding_policy(), tag_type()), "boost::math::expint<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type +expint_forwarder(unsigned n, T z, const boost::math::false_type&) +{ + return boost::math::expint(n, z, policies::policy<>()); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + expint(unsigned n, T z, const Policy& /*pol*/) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef boost::math::integral_constant tag_type; + + return policies::checked_narrowing_cast(detail::expint_imp( + n, + static_cast(z), + forwarding_policy(), + tag_type()), "boost::math::expint<%1%>(unsigned, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::expint_result::type + expint(T const z, U const u) +{ + typedef typename policies::is_policy::type tag_type; + return detail::expint_forwarder(z, u, tag_type()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + expint(T z) +{ + return expint(z, policies::policy<>()); +} + +}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_EXPINT_HPP + + diff --git a/third-party/boost-math/include/boost/math/special_functions/expm1.hpp b/third-party/boost-math/include/boost/math/special_functions/expm1.hpp new file mode 100644 index 0000000000000..7635c6471ef02 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/expm1.hpp @@ -0,0 +1,416 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_EXPM1_INCLUDED +#define BOOST_MATH_EXPM1_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#if defined __has_include +# if ((__cplusplus > 202002L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 202002L))) +# if __has_include () +# include +# endif +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost { + namespace math { + + namespace detail + { + // Functor expm1_series returns the next term in the Taylor series + // x^k / k! + // each time that operator() is invoked. + // + // LCOV_EXCL_START multiprecision case only, excluded from coverage analysis + template + struct expm1_series + { + typedef T result_type; + + BOOST_MATH_GPU_ENABLED expm1_series(T x) + : k(0), m_x(x), m_term(1) { + } + + BOOST_MATH_GPU_ENABLED T operator()() + { + ++k; + m_term *= m_x; + m_term /= k; + return m_term; + } + + BOOST_MATH_GPU_ENABLED int count()const + { + return k; + } + + private: + int k; + const T m_x; + T m_term; + expm1_series(const expm1_series&) = delete; + expm1_series& operator=(const expm1_series&) = delete; + }; + + // + // Algorithm expm1 is part of C99, but is not yet provided by many compilers. + // + // This version uses a Taylor series expansion for 0.5 > |x| > epsilon. + // + template + T expm1_imp(T x, const boost::math::integral_constant&, const Policy& pol) + { + BOOST_MATH_STD_USING + + T a = fabs(x); + if ((boost::math::isnan)(a)) + { + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol); + } + if (a > T(0.5f)) + { + if (a >= tools::log_max_value()) + { + if (x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if (a < tools::epsilon()) + return x; + detail::expm1_series s(x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::expm1<%1%>(%1%)", max_iter, pol); + return result; + } + // LCOV_EXCL_STOP + + template + BOOST_MATH_GPU_ENABLED T expm1_imp(T x, const boost::math::integral_constant&, const P& pol) + { + BOOST_MATH_STD_USING + + T a = fabs(x); + if ((boost::math::isnan)(a)) + { + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol); + } + if (a > T(0.5L)) + { + if (a >= tools::log_max_value()) + { + if (x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if (a < tools::epsilon()) + return x; + + BOOST_MATH_STATIC const float Y = 0.10281276702880859e1f; + BOOST_MATH_STATIC const T n[] = { static_cast(-0.28127670288085937e-1), static_cast(0.51278186299064534e0), static_cast(-0.6310029069350198e-1), static_cast(0.11638457975729296e-1), static_cast(-0.52143390687521003e-3), static_cast(0.21491399776965688e-4) }; + BOOST_MATH_STATIC const T d[] = { 1, static_cast(-0.45442309511354755e0), static_cast(0.90850389570911714e-1), static_cast(-0.10088963629815502e-1), static_cast(0.63003407478692265e-3), static_cast(-0.17976570003654402e-4) }; + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; + } + + template + BOOST_MATH_GPU_ENABLED T expm1_imp(T x, const boost::math::integral_constant&, const P& pol) + { + BOOST_MATH_STD_USING + + T a = fabs(x); + if ((boost::math::isnan)(a)) + { + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol); + } + if (a > T(0.5L)) + { + if (a >= tools::log_max_value()) + { + if (x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if (a < tools::epsilon()) + return x; + + // LCOV_EXCL_START + BOOST_MATH_STATIC const float Y = 0.10281276702880859375e1f; + BOOST_MATH_STATIC const T n[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.281276702880859375e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.512980290285154286358e0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.667758794592881019644e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.131432469658444745835e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.72303795326880286965e-3), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.447441185192951335042e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.714539134024984593011e-6) + }; + BOOST_MATH_STATIC const T d[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.461477618025562520389e0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.961237488025708540713e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.116483957658204450739e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.873308008461557544458e-3), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.387922804997682392562e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.807473180049193557294e-6) + }; + // LCOV_EXCL_STOP + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; + } + + template + BOOST_MATH_GPU_ENABLED T expm1_imp(T x, const boost::math::integral_constant&, const P& pol) + { + BOOST_MATH_STD_USING + + T a = fabs(x); + if ((boost::math::isnan)(a)) + { + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol); + } + if (a > T(0.5L)) + { + if (a >= tools::log_max_value()) + { + if (x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if (a < tools::epsilon()) + return x; + + // LCOV_EXCL_START + static const float Y = 0.10281276702880859375e1f; + static const T n[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.28127670288085937499999999999999999854e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.51278156911210477556524452177540792214e0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.63263178520747096729500254678819588223e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14703285606874250425508446801230572252e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.8675686051689527802425310407898459386e-3), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.88126359618291165384647080266133492399e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.25963087867706310844432390015463138953e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14226691087800461778631773363204081194e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.15995603306536496772374181066765665596e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.45261820069007790520447958280473183582e-10) + }; + static const T d[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.45441264709074310514348137469214538853e0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.96827131936192217313133611655555298106e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.12745248725908178612540554584374876219e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11473613871583259821612766907781095472e-2), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.73704168477258911962046591907690764416e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.34087499397791555759285503797256103259e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11114024704296196166272091230695179724e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.23987051614110848595909588343223896577e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29477341859111589208776402638429026517e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13222065991022301420255904060628100924e-12) + }; + // LCOV_EXCL_STOP + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; + } + + } // namespace detail + + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type expm1(T x, const Policy& /* pol */) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef boost::math::integral_constant tag_type; + + return policies::checked_narrowing_cast(detail::expm1_imp( + static_cast(x), + tag_type(), forwarding_policy()), "boost::math::expm1<%1%>(%1%)"); + } + + // + // Since we now live in a post C++11 world, we can always defer to std::expm1 when appropriate: + // + template + BOOST_MATH_GPU_ENABLED inline float expm1(float x, const Policy&) + { + BOOST_MATH_IF_CONSTEXPR(Policy::domain_error_type::value != boost::math::policies::ignore_error && Policy::domain_error_type::value != boost::math::policies::errno_on_error) + { + if ((boost::math::isnan)(x)) + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", x, Policy()); + } + BOOST_MATH_IF_CONSTEXPR(Policy::overflow_error_type::value != boost::math::policies::ignore_error && Policy::overflow_error_type::value != boost::math::policies::errno_on_error) + { + if (x >= tools::log_max_value()) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, Policy()); + } + return std::expm1(x); + } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + template + inline long double expm1(long double x, const Policy&) + { + BOOST_MATH_IF_CONSTEXPR(Policy::domain_error_type::value != boost::math::policies::ignore_error && Policy::domain_error_type::value != boost::math::policies::errno_on_error) + { + if ((boost::math::isnan)(x)) + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", x, Policy()); + } + BOOST_MATH_IF_CONSTEXPR(Policy::overflow_error_type::value != boost::math::policies::ignore_error && Policy::overflow_error_type::value != boost::math::policies::errno_on_error) + { + if (x >= tools::log_max_value()) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, Policy()); + } + return std::expm1(x); + } +#endif + template + BOOST_MATH_GPU_ENABLED inline double expm1(double x, const Policy&) + { + BOOST_MATH_IF_CONSTEXPR(Policy::domain_error_type::value != boost::math::policies::ignore_error && Policy::domain_error_type::value != boost::math::policies::errno_on_error) + { + if ((boost::math::isnan)(x)) + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", x, Policy()); + } + BOOST_MATH_IF_CONSTEXPR(Policy::overflow_error_type::value != boost::math::policies::ignore_error && Policy::overflow_error_type::value != boost::math::policies::errno_on_error) + { + if (x >= tools::log_max_value()) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, Policy()); + } + return std::expm1(x); + } + + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type expm1(T x) + { + return expm1(x, policies::policy<>()); + } + // + // Specific width floating point types: + // +#ifdef __STDCPP_FLOAT32_T__ + template + BOOST_MATH_GPU_ENABLED inline std::float32_t expm1(std::float32_t x, const Policy& pol) + { + return boost::math::expm1(static_cast(x), pol); + } +#endif +#ifdef __STDCPP_FLOAT64_T__ + template + BOOST_MATH_GPU_ENABLED inline std::float64_t expm1(std::float64_t x, const Policy& pol) + { + return boost::math::expm1(static_cast(x), pol); + } +#endif +#ifdef __STDCPP_FLOAT128_T__ + template + BOOST_MATH_GPU_ENABLED inline std::float128_t expm1(std::float128_t x, const Policy& pol) + { + if constexpr (std::numeric_limits::digits == std::numeric_limits::digits) + { + return boost::math::expm1(static_cast(x), pol); + } + else + { + return boost::math::detail::expm1_imp(x, boost::math::integral_constant(), pol); + } + } +#endif +} // namespace math +} // namespace boost + +#else // Special handling for NVRTC + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED auto expm1(T x) +{ + return ::expm1(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto expm1(float x) +{ + return ::expm1f(x); +} + +template +BOOST_MATH_GPU_ENABLED auto expm1(T x, const Policy&) +{ + return ::expm1(x); +} + +template +BOOST_MATH_GPU_ENABLED auto expm1(float x, const Policy&) +{ + return ::expm1f(x); +} + +} // Namespace math +} // Namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif // BOOST_MATH_HYPOT_INCLUDED + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/factorials.hpp b/third-party/boost-math/include/boost/math/special_functions/factorials.hpp new file mode 100644 index 0000000000000..ec6978bdc5aa6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/factorials.hpp @@ -0,0 +1,276 @@ +// Copyright John Maddock 2006, 2010. +// 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) + +#ifndef BOOST_MATH_SP_FACTORIALS_HPP +#define BOOST_MATH_SP_FACTORIALS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) // Temporary until lexical cast fixed. +#pragma warning(disable: 4127 4701) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +namespace boost { namespace math +{ + +template +BOOST_MATH_GPU_ENABLED inline T factorial(unsigned i, const Policy& pol) +{ + static_assert(!boost::math::is_integral::value, "Type T must not be an integral type"); + // factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + + BOOST_MATH_STD_USING // Aid ADL for floor. + + if(i <= max_factorial::value) + return unchecked_factorial(i); + T result = boost::math::tgamma(static_cast(i+1), pol); + if(result > tools::max_value()) + return result; // Overflowed value! (But tgamma will have signalled the error already). + return floor(result + 0.5f); +} + +template +BOOST_MATH_GPU_ENABLED inline T factorial(unsigned i) +{ + return factorial(i, policies::policy<>()); +} +/* +// Can't have these in a policy enabled world? +template<> +inline float factorial(unsigned i) +{ + if(i <= max_factorial::value) + return unchecked_factorial(i); + return tools::overflow_error(BOOST_CURRENT_FUNCTION); +} + +template<> +inline double factorial(unsigned i) +{ + if(i <= max_factorial::value) + return unchecked_factorial(i); + return tools::overflow_error(BOOST_CURRENT_FUNCTION); +} +*/ +template +BOOST_MATH_GPU_ENABLED T double_factorial(unsigned i, const Policy& pol) +{ + static_assert(!boost::math::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING // ADL lookup of std names + if(i & 1) + { + // odd i: + if(i < max_factorial::value) + { + unsigned n = (i - 1) / 2; + return ceil(unchecked_factorial(i) / (ldexp(T(1), (int)n) * unchecked_factorial(n)) - 0.5f); + } + // + // Fallthrough: i is too large to use table lookup, try the + // gamma function instead. + // + T result = boost::math::tgamma(static_cast(i) / 2 + 1, pol) / sqrt(constants::pi()); + if(ldexp(tools::max_value(), -static_cast(i+1) / 2) > result) + return ceil(result * ldexp(T(1), static_cast(i+1) / 2) - 0.5f); + } + else + { + // even i: + unsigned n = i / 2; + T result = factorial(n, pol); + if(ldexp(tools::max_value(), -(int)n) > result) + return result * ldexp(T(1), (int)n); + } + // + // If we fall through to here then the result is infinite: + // + return policies::raise_overflow_error("boost::math::double_factorial<%1%>(unsigned)", 0, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline T double_factorial(unsigned i) +{ + return double_factorial(i, policies::policy<>()); +} + +// TODO(mborland): We do not currently have support for tgamma_delta_ratio +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +namespace detail{ + +template +T rising_factorial_imp(T x, int n, const Policy& pol) +{ + static_assert(!boost::math::is_integral::value, "Type T must not be an integral type"); + if(x < 0) + { + // + // For x less than zero, we really have a falling + // factorial, modulo a possible change of sign. + // + // Note that the falling factorial isn't defined + // for negative n, so we'll get rid of that case + // first: + // + bool inv = false; + if(n < 0) + { + x += n; + n = -n; + inv = true; + } + T result = ((n&1) ? -1 : 1) * falling_factorial(-x, n, pol); + if(inv) + result = 1 / result; + return result; + } + if(n == 0) + return 1; + if(x == 0) + { + if(n < 0) + return static_cast(-boost::math::tgamma_delta_ratio(x + 1, static_cast(-n), pol)); + else + return 0; + } + if((x < 1) && (x + n < 0)) + { + const auto val = static_cast(boost::math::tgamma_delta_ratio(1 - x, static_cast(-n), pol)); + return (n & 1) ? T(-val) : val; + } + // + // We don't optimise this for small n, because + // tgamma_delta_ratio is already optimised for that + // use case: + // + return 1 / static_cast(boost::math::tgamma_delta_ratio(x, static_cast(n), pol)); +} + +template +inline T falling_factorial_imp(T x, unsigned n, const Policy& pol) +{ + static_assert(!boost::math::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING // ADL of std names + if(x == 0) + return 0; + if(x < 0) + { + // + // For x < 0 we really have a rising factorial + // modulo a possible change of sign: + // + return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol); + } + if(n == 0) + return 1; + if(x < 0.5f) + { + // + // 1 + x below will throw away digits, so split up calculation: + // + if(n > max_factorial::value - 2) + { + // If the two end of the range are far apart we have a ratio of two very large + // numbers, split the calculation up into two blocks: + T t1 = x * boost::math::falling_factorial(x - 1, max_factorial::value - 2, pol); + T t2 = boost::math::falling_factorial(x - max_factorial::value + 1, n - max_factorial::value + 1, pol); + if(tools::max_value() / fabs(t1) < fabs(t2)) + return boost::math::sign(t1) * boost::math::sign(t2) * policies::raise_overflow_error("boost::math::falling_factorial<%1%>", 0, pol); + return t1 * t2; + } + return x * boost::math::falling_factorial(x - 1, n - 1, pol); + } + if(x <= n - 1) + { + // + // x+1-n will be negative and tgamma_delta_ratio won't + // handle it, split the product up into three parts: + // + T xp1 = x + 1; + unsigned n2 = itrunc((T)floor(xp1), pol); + if(n2 == xp1) + return 0; + auto result = static_cast(boost::math::tgamma_delta_ratio(xp1, -static_cast(n2), pol)); + x -= n2; + result *= x; + ++n2; + if(n2 < n) + result *= falling_factorial(x - 1, n - n2, pol); + return result; + } + // + // Simple case: just the ratio of two + // (positive argument) gamma functions. + // Note that we don't optimise this for small n, + // because tgamma_delta_ratio is already optimised + // for that use case: + // + return static_cast(boost::math::tgamma_delta_ratio(x + 1, -static_cast(n), pol)); +} + +} // namespace detail + +template +inline typename tools::promote_args::type + falling_factorial(RT x, unsigned n) +{ + typedef typename tools::promote_args::type result_type; + return detail::falling_factorial_imp( + static_cast(x), n, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + falling_factorial(RT x, unsigned n, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::falling_factorial_imp( + static_cast(x), n, pol); +} + +template +inline typename tools::promote_args::type + rising_factorial(RT x, int n) +{ + typedef typename tools::promote_args::type result_type; + return detail::rising_factorial_imp( + static_cast(x), n, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + rising_factorial(RT x, int n, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::rising_factorial_imp( + static_cast(x), n, pol); +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_FACTORIALS_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/fibonacci.hpp b/third-party/boost-math/include/boost/math/special_functions/fibonacci.hpp new file mode 100644 index 0000000000000..e62fa892811b2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/fibonacci.hpp @@ -0,0 +1,92 @@ +// Copyright 2020, Madhur Chauhan + +// 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) + +#ifndef BOOST_MATH_SPECIAL_FIBO_HPP +#define BOOST_MATH_SPECIAL_FIBO_HPP + +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost { +namespace math { + +namespace detail { + constexpr double fib_bits_phi = 0.69424191363061730173879026; + constexpr double fib_bits_deno = 1.1609640474436811739351597; +} // namespace detail + +template +inline BOOST_MATH_CXX14_CONSTEXPR T unchecked_fibonacci(unsigned long long n) noexcept(std::is_fundamental::value) { + // This function is called by the rest and computes the actual nth fibonacci number + // First few fibonacci numbers: 0 (0th), 1 (1st), 1 (2nd), 2 (3rd), ... + if (n <= 2) return n == 0 ? 0 : 1; + /* + * This is based on the following identities by Dijkstra: + * F(2*n-1) = F(n-1)^2 + F(n)^2 + * F(2*n) = (2*F(n-1) + F(n)) * F(n) + * The implementation is iterative and is unrolled version of trivial recursive implementation. + */ + unsigned long long mask = 1; + for (int ct = 1; ct != std::numeric_limits::digits && (mask << 1) <= n; ++ct, mask <<= 1) + ; + T a{1}, b{1}; + for (mask >>= 1; mask; mask >>= 1) { + T t1 = a * a; + a = 2 * a * b - t1, b = b * b + t1; + if (mask & n) + t1 = b, b = b + a, a = t1; // equivalent to: swap(a,b), b += a; + } + return a; +} + +template +T inline BOOST_MATH_CXX14_CONSTEXPR fibonacci(unsigned long long n, const Policy &pol) { + // check for overflow using approximation to binet's formula: F_n ~ phi^n / sqrt(5) + if (n > 20 && n * detail::fib_bits_phi - detail::fib_bits_deno > std::numeric_limits::digits) + return policies::raise_overflow_error("boost::math::fibonacci<%1%>(unsigned long long)", "Possible overflow detected.", pol); + return unchecked_fibonacci(n); +} + +template +T inline BOOST_MATH_CXX14_CONSTEXPR fibonacci(unsigned long long n) { + return fibonacci(n, policies::policy<>()); +} + +// generator for next fibonacci number (see examples/reciprocal_fibonacci_constant.hpp) +template +class fibonacci_generator { + public: + // return next fibonacci number + T operator()() noexcept(std::is_fundamental::value) { + T ret = a; + a = b, b = b + ret; // could've simply: swap(a, b), b += a; + return ret; + } + + // after set(nth), subsequent calls to the generator returns consecutive + // fibonacci numbers starting with the nth fibonacci number + void set(unsigned long long nth) noexcept(std::is_fundamental::value) { + n = nth; + a = unchecked_fibonacci(n); + b = unchecked_fibonacci(n + 1); + } + + private: + unsigned long long n = 0; + T a = 0, b = 1; +}; + +} // namespace math +} // namespace boost + +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/fourier_transform_daubechies.hpp b/third-party/boost-math/include/boost/math/special_functions/fourier_transform_daubechies.hpp new file mode 100644 index 0000000000000..982e740233b96 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/fourier_transform_daubechies.hpp @@ -0,0 +1,248 @@ +// boost-no-inspect +/* + * Copyright Nick Thompson, Matt Borland, 2023 + * 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) + */ + +#ifndef BOOST_MATH_SPECIAL_FOURIER_TRANSFORM_DAUBECHIES_HPP +#define BOOST_MATH_SPECIAL_FOURIER_TRANSFORM_DAUBECHIES_HPP +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math { + +namespace detail { + +// See the Table 6.2 of Daubechies, Ten Lectures on Wavelets. +// These constants are precisely those divided by 1/sqrt(2), because otherwise +// we'd immediately just have to divide through by 1/sqrt(2). +// These numbers agree with Table 6.2, but are generated via example/calculate_fourier_transform_daubechies_constants.cpp +template constexpr std::array ft_daubechies_scaling_polynomial_coefficients() { + static_assert(N >= 1 && N <= 10, "Scaling function only implemented for 1-10 vanishing moments."); + if constexpr (N == 1) { + return std::array{static_cast(1)}; + } + if constexpr (N == 2) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 1.36602540378443864676372317075293618347140262690519031402790348972596650842632007803393058), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.366025403784438646763723170752936183471402626905190314027903489725966508441952115116994061)}; + } + if constexpr (N == 3) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 1.88186883113665472301331643028468183320710177910151845853383427363197699204347143889269703), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -1.08113883008418966599944677221635926685977756966260841342875242639629721931484516409937898), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.199269998947534942986130341931677433652675790561089954894918152764320227250084833874126086)}; + } + if constexpr (N == 4) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 2.60642742441038678619616138456320274846457112268350230103083547418823666924354637907021821), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -2.33814397690691624172277875654682595239896411009843420976312905955518655953831321619717516), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.851612467139421235087502761217605775743179492713667860409024360383174560120738199344383827), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.119895914642891779560885389233982571808786505298735951676730775016224669960397338539830347)}; + } + if constexpr (N == 5) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 3.62270372133693372237431371824382790538377237674943454540758419371854887218301659611796287), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -4.45042192340421529271926241961545172940077367856833333571968270791760393243895360839974479), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 2.41430351179889241160444590912469777504146155873489898274561148139247721271772284677196254), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.662064156756696785656360678859372223233256033099757083735935493062448802216759690564503751), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.0754788470250859443968634711062982722087957761837568913024225258690266500301041274151679859)}; + } + if constexpr (N == 6) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 5.04775782409284533508504459282823265081102702143912881539214595513121059428213452194161891), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -7.90242489414953082292172067801361411066690749603940036372954720647258482521355701761199), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 5.69062231972011992229557724635729642828799628244009852056657089766265949751788181912632318), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -2.29591465417352749013350971621495843275025605194376564457120763045109729714936982561585742), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.508712486289373262241383448555327418882885930043157873517278143590549199629822225076344289), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.0487530817792802065667748935122839545647456859392192011752401594607371693280512344274717466)}; + } + if constexpr (N == 7) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 7.0463635677199166580912954330590360004554457287730448872409828895500755049108034478397642), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -13.4339028220058085795120274851204982381087988043552711869584397724404274044947626280185946), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 12.0571882966390397563079887516068140052534768286900467252199152570563053103366694003818755), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -6.39124482303930285525880162640679389779540687632321120940980371544051534690730897661850842), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 2.07674879424918331569327229402057948161936796436510457676789758815816492768386639712643599), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.387167532162867697386347232520843525988806810788254462365009860280979111139408537312553398), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.0320145185998394020646198653617061745647219696385406695044576133973761206215673170563538)}; + } + if constexpr (N == 8) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 9.85031962984351656604584909868313752909650830419035084214249929687665775818153930511533915), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -22.1667494032601530437943449172929277733925779301673358406203340024653233856852379126537395), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 23.8272728452144265698978643079553442578633838793866258585693705776047828901217069807060715), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -15.6065825916019064469551268429136774427686552695820632173344334583910793479437661751737998), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 6.63923943761238270605338141020386331691362835005178161341935720370310013774320917891051914), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -1.81462830704498058848677549516134095104668450780318379608495409574150643627578462439190617), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.292393958692487086036895445298600849998803161432207979583488595754566344585039785927586499), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.0212655694557728487977430067729997866644059875083834396749941173411979591559303697954912042)}; + } + if constexpr (N == 9) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 13.7856894948673536752299497816200874595462540239049618127984616645562437295073582057283235), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -35.79362367743347676734569335180426263053917566987500206688713345532850076082533131311371), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 44.8271517576868325408174336351944130389504383168376658969692365144162452669941793147313), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -34.9081281226625998193992072777004811412863069972654446089639166067029872995118090115016879), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 18.2858070519930071738884732413420775324549836290768317032298177553411077249931094333824682), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -6.53714271572640296907117142447372145396492988681610221640307755553450246302777187366825001), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 1.5454286423270706293059630490222623728433659436325762803842722481655127844136128434034519), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.219427682644567750633335191213222483839627852234602683427115193605056655384931679751929029), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.0142452515927832872075875380128473058349984927391158822994546286919376896668596927857450578)}; + } + if constexpr (N == 10) { + return std::array{ + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 19.3111846872275854185286532829110292444580572106276740012656292351880418629976266671349603), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -56.8572892818288577904562616825768121532988312416110097001327598719988644787442373891037268), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 81.3040184941182201969442916535886223134891624078921290339772790298979750863332417443823932), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -73.3067370305702272426402835488383512315892354877130132060680994033122368453226804355121917), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 45.5029913577892585869595005785056707790215969761054467083138479721524945862678794713356742), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -20.0048938122958245128650205249242185678760602333821352917865992073643758821417211689052482), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 6.18674372398711325312495154772282340531430890354257911422818567803548535981484584999007723), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -1.29022235346655645559407302793903682217361613280994725979138999393113139183198020070701239), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + 0.16380852384056875506684562409582514726612462486206657238854671180228210790016298829595125), + BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, + -0.00960430880128020906860390254555211461150702751378997239464015046967050703218076318595987803)}; + } +} + +} // namespace detail + +/* + * Given ω∈ℝ, computes a numerical approximation to 𝓕[𝜙](ω), + * where 𝜙 is the Daubechies scaling function. + * Fast and accurate evaluation of these function seems to me to be a rather involved research project, + * which I have not endeavored to complete. + * In particular, recovering ~1ULP evaluation is not possible using the techniques + * employed here-you should use this with the understanding it is good enough for almost + * all uses with empirical data, but probably doesn't recover enough accuracy + * for pure mathematical uses (other than graphing-in which case it's fine). + * The implementation uses an infinite product of trigonometric polynomials. + * See Daubechies, 10 Lectures on Wavelets, equation 5.1.17, 5.1.18. + * It uses the factorization of m₀ shown in Corollary 5.5.4 and equation 5.5.5. + * See more discusion near equation 6.1.1, + * as well as efficiency gains from equation 7.1.4. + */ +template std::complex fourier_transform_daubechies_scaling(Real omega) { + // This arg promotion is kinda sad, but IMO the accuracy is not good enough in + // float precision using this method. Requesting a better algorithm! + if constexpr (std::is_same_v) { + return static_cast>(fourier_transform_daubechies_scaling(static_cast(omega))); + } + using boost::math::constants::one_div_root_two_pi; + using std::abs; + using std::exp; + using std::norm; + using std::pow; + using std::sqrt; + using std::cbrt; + // Equation 7.1.4 of 10 Lectures on Wavelets is singular at ω=0: + if (omega == 0) { + return std::complex(one_div_root_two_pi(), 0); + } + // For whatever reason, this starts returning NaNs rather than zero for |ω|≫1. + // But we know that this function decays rather quickly with |ω|, + // and hence it is "numerically zero", even if in actuality the function does not have compact support. + // Now, should we probably do a fairly involved, exhaustive calculation to see where exactly we should set this threshold + // and store them in a table? .... yes. + if (abs(omega) >= sqrt(std::numeric_limits::max())) { + return std::complex(0, 0); + } + auto const constexpr lxi = detail::ft_daubechies_scaling_polynomial_coefficients(); + auto xi = -omega / 2; + std::complex phi{one_div_root_two_pi(), 0}; + do { + std::complex arg{0, xi}; + auto z = exp(arg); + phi *= boost::math::tools::evaluate_polynomial_estrin(lxi, z); + xi /= 2; + } while (abs(xi) > std::numeric_limits::epsilon()); + std::complex arg{0, omega}; + // There is no std::expm1 for complex numbers. + // We may therefore be leaving accuracy gains on the table for small |ω|: + std::complex prefactor = (Real(1) - exp(-arg))/arg; + return phi * static_cast>(pow(prefactor, p)); +} + +template std::complex fourier_transform_daubechies_wavelet(Real omega) { + // See Daubechies, 10 Lectures on Wavelets, page 193, unlabelled equation in Theorem 6.3.6: + // 𝓕[ψ](ω) = -exp(-iω/2)m₀(ω/2 + π)^{*}𝓕[𝜙](ω/2) + if constexpr (std::is_same_v) { + return static_cast>(fourier_transform_daubechies_wavelet(static_cast(omega))); + } + + using std::exp; + using std::pow; + auto Fphi = fourier_transform_daubechies_scaling(omega/2); + auto phase = -exp(std::complex(0, -omega/2)); + // See Section 6.4 for the sign convention on the argument, + // as well as Table 6.2: + auto z = phase; // strange coincidence. + //auto z = exp(std::complex(0, -omega/2 - boost::math::constants::pi())); + auto constexpr lxi = detail::ft_daubechies_scaling_polynomial_coefficients(); + auto m0 = std::complex(pow((Real(1) + z)/Real(2), p))*boost::math::tools::evaluate_polynomial_estrin(lxi, z); + return Fphi*std::conj(m0)*phase; +} + +} // namespace boost::math +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/fpclassify.hpp b/third-party/boost-math/include/boost/math/special_functions/fpclassify.hpp new file mode 100644 index 0000000000000..c17b4a3a0b6aa --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/fpclassify.hpp @@ -0,0 +1,797 @@ +// Copyright John Maddock 2005-2008. +// Copyright (c) 2006-2008 Johan Rade +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_FPCLASSIFY_HPP +#define BOOST_MATH_FPCLASSIFY_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include + +/*! + \file fpclassify.hpp + \brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN. + \version 1.0 + \author John Maddock + */ + +/* + +1. If the platform is C99 compliant, then the native floating point +classification functions are used. However, note that we must only +define the functions which call std::fpclassify etc if that function +really does exist: otherwise a compiler may reject the code even though +the template is never instantiated. + +2. If the platform is not C99 compliant, and the binary format for +a floating point type (float, double or long double) can be determined +at compile time, then the following algorithm is used: + + If all exponent bits, the flag bit (if there is one), + and all significand bits are 0, then the number is zero. + + If all exponent bits and the flag bit (if there is one) are 0, + and at least one significand bit is 1, then the number is subnormal. + + If all exponent bits are 1 and all significand bits are 0, + then the number is infinity. + + If all exponent bits are 1 and at least one significand bit is 1, + then the number is a not-a-number. + + Otherwise the number is normal. + + This algorithm works for the IEEE 754 representation, + and also for several non IEEE 754 formats. + + Most formats have the structure + sign bit + exponent bits + significand bits. + + A few have the structure + sign bit + exponent bits + flag bit + significand bits. + The flag bit is 0 for zero and subnormal numbers, + and 1 for normal numbers and NaN. + It is 0 (Motorola 68K) or 1 (Intel) for infinity. + + To get the bits, the four or eight most significant bytes are copied + into an uint32_t or uint64_t and bit masks are applied. + This covers all the exponent bits and the flag bit (if there is one), + but not always all the significand bits. + Some of the functions below have two implementations, + depending on whether all the significand bits are copied or not. + +3. If the platform is not C99 compliant, and the binary format for +a floating point type (float, double or long double) can not be determined +at compile time, then comparison with std::numeric_limits values +is used. + +*/ + +#ifdef BOOST_MATH_HAS_GPU_SUPPORT + +namespace boost { namespace math { + +template<> BOOST_MATH_GPU_ENABLED inline bool (isnan)(float x) { return x != x; } +template<> BOOST_MATH_GPU_ENABLED inline bool (isnan)(double x) { return x != x; } + +template<> BOOST_MATH_GPU_ENABLED inline bool (isinf)(float x) { return x > FLT_MAX || x < -FLT_MAX; } +template<> BOOST_MATH_GPU_ENABLED inline bool (isinf)(double x) { return x > DBL_MAX || x < -DBL_MAX; } + +template<> BOOST_MATH_GPU_ENABLED inline bool (isfinite)(float x) { return !isnan(x) && !isinf(x); } +template<> BOOST_MATH_GPU_ENABLED inline bool (isfinite)(double x) { return !isnan(x) && !isinf(x); } + +template<> BOOST_MATH_GPU_ENABLED inline bool (isnormal)(float x) +{ + if(x < 0) x = -x; + return (x >= FLT_MIN) && (x <= FLT_MAX); +} +template<> BOOST_MATH_GPU_ENABLED inline bool (isnormal)(double x) +{ + if(x < 0) x = -x; + return (x >= DBL_MIN) && (x <= DBL_MAX); +} + +template<> BOOST_MATH_GPU_ENABLED inline int (fpclassify)(float t) +{ + if((boost::math::isnan)(t)) + return FP_NAN; + // std::fabs broken on a few systems especially for long long!!!! + float at = (t < 0.0f) ? -t : t; + + // Use a process of exclusion to figure out + // what kind of type we have, this relies on + // IEEE conforming reals that will treat + // Nan's as unordered. Some compilers + // don't do this once optimisations are + // turned on, hence the check for nan's above. + if(at <= FLT_MAX) + { + if(at >= FLT_MIN) + return FP_NORMAL; + return (at != 0) ? FP_SUBNORMAL : FP_ZERO; + } + else if(at > FLT_MAX) + return FP_INFINITE; + return FP_NAN; // LCOV_EXCL_LINE should not normally be reachable. +} + +template<> BOOST_MATH_GPU_ENABLED inline int (fpclassify)(double t) +{ + if((boost::math::isnan)(t)) + return FP_NAN; + // std::fabs broken on a few systems especially for long long!!!! + double at = (t < 0.0) ? -t : t; + + // Use a process of exclusion to figure out + // what kind of type we have, this relies on + // IEEE conforming reals that will treat + // Nan's as unordered. Some compilers + // don't do this once optimisations are + // turned on, hence the check for nan's above. + if(at <= DBL_MAX) + { + if(at >= DBL_MIN) + return FP_NORMAL; + return (at != 0) ? FP_SUBNORMAL : FP_ZERO; + } + else if(at > DBL_MAX) + return FP_INFINITE; + return FP_NAN; +} + +#else + +#if defined(_MSC_VER) || defined(BOOST_BORLANDC) +#include +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +#ifdef __has_include +#if __has_include("quadmath.h") +#include "quadmath.h" +#define BOOST_MATH_HAS_QUADMATH_H +#endif +#endif +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE + namespace std{ using ::abs; using ::fabs; } +#endif + +namespace boost{ + +// +// This must not be located in any namespace under boost::math +// otherwise we can get into an infinite loop if isnan is +// a #define for "isnan" ! +// +namespace math_detail{ + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4800) +#endif + +template +inline bool is_nan_helper(T t, const std::true_type&) +{ +#ifdef isnan + return isnan(t); +#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY) + (void)t; + return false; +#else // BOOST_HAS_FPCLASSIFY + return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +inline bool is_nan_helper(T, const std::false_type&) +{ + return false; +} +#if defined(BOOST_MATH_USE_FLOAT128) +#if defined(BOOST_MATH_HAS_QUADMATH_H) +inline bool is_nan_helper(__float128 f, const std::true_type&) { return ::isnanq(f); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return ::isnanq(f); } +#elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \ + _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +inline bool is_nan_helper(__float128 f, const std::true_type&) { return std::isnan(static_cast(f)); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return std::isnan(static_cast(f)); } +#else +inline bool is_nan_helper(__float128 f, const std::true_type&) { return boost::math::isnan(static_cast(f)); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return boost::math::isnan(static_cast(f)); } +#endif +#endif +} + +namespace math{ + +namespace detail{ + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&) +{ + return (std::fpclassify)(t); +} +#endif + +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) +{ + BOOST_MATH_INSTRUMENT_VARIABLE(t); + + // whenever possible check for Nan's first: +#if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) + if(::boost::math_detail::is_nan_helper(t, typename std::is_floating_point::type())) + return FP_NAN; // LCOV_EXCL_LINE only called in UDT contexts (excluded from coverage checks). +#elif defined(isnan) + if(boost::math_detail::is_nan_helper(t, typename std::is_floating_point::type())) + return FP_NAN; +#elif defined(_MSC_VER) || defined(BOOST_BORLANDC) + if(::_isnan(boost::math::tools::real_cast(t))) + return FP_NAN; +#endif + // std::fabs broken on a few systems especially for long long!!!! + T at = (t < T(0)) ? -t : t; + + // Use a process of exclusion to figure out + // what kind of type we have, this relies on + // IEEE conforming reals that will treat + // Nan's as unordered. Some compilers + // don't do this once optimisations are + // turned on, hence the check for nan's above. + if(at <= (std::numeric_limits::max)()) + { + if(at >= (std::numeric_limits::min)()) + return FP_NORMAL; + return (at != 0) ? FP_SUBNORMAL : FP_ZERO; + } + else if(at > (std::numeric_limits::max)()) + return FP_INFINITE; + return FP_NAN; +} + +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) +{ +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return fpclassify_imp(t, generic_tag()); +#endif + // + // An unknown type with no numeric_limits support, + // so what are we supposed to do we do here? + // + BOOST_MATH_INSTRUMENT_VARIABLE(t); + + return t == 0 ? FP_ZERO : FP_NORMAL; +} + +template +int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag) +{ + typedef typename fp_traits::type traits; + + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + typename traits::bits a; + traits::get_bits(x,a); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + a &= traits::exponent | traits::flag | traits::significand; + BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand)); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + + if(a <= traits::significand) { + if(a == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if(a < traits::exponent) return FP_NORMAL; + + a &= traits::significand; + if(a == 0) return FP_INFINITE; + + return FP_NAN; +} + +template +int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag) +{ + typedef typename fp_traits::type traits; + + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::flag | traits::significand; + + if(a <= traits::significand) { + if(x == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if(a < traits::exponent) return FP_NORMAL; + + a &= traits::significand; + traits::set_bits(x,a); + if(x == 0) return FP_INFINITE; + + return FP_NAN; +} + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)) +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::fpclassify_imp(t, generic_tag()); +} +#endif + +} // namespace detail + +template +inline int fpclassify BOOST_NO_MACRO_EXPAND(T t) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + typedef typename tools::promote_args_permissive::type value_type; +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(nullptr))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); +#else + return detail::fpclassify_imp(static_cast(t), method()); +#endif +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template <> +inline int fpclassify BOOST_NO_MACRO_EXPAND(long double t) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef long double value_type; +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(nullptr))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); +#else + return detail::fpclassify_imp(static_cast(t), method()); +#endif +} +#endif + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isfinite_impl(T x, native_tag const&) + { + return (std::isfinite)(x); + } +#endif + + template + inline bool isfinite_impl(T x, generic_tag const&) + { + return x >= -(std::numeric_limits::max)() + && x <= (std::numeric_limits::max)(); + } + + template + inline bool isfinite_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isfinite_impl(x, generic_tag()); +#endif + (void)x; // warning suppression. + return true; + } + + template + inline bool isfinite_impl(T x, ieee_tag const&) + { + typedef typename detail::fp_traits::type traits; + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent; + return a != traits::exponent; + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isfinite_impl(t, generic_tag()); +} +#endif + +} + +template +inline bool (isfinite)(T x) +{ //!< \brief return true if floating-point type t is finite. + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isfinite_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isfinite)(long double x) +{ //!< \brief return true if floating-point type t is finite. + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isfinite_impl(static_cast(x), method()); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isnormal_impl(T x, native_tag const&) + { + return (std::isnormal)(x); + } +#endif + + template + inline bool isnormal_impl(T x, generic_tag const&) + { + if(x < 0) x = -x; + return x >= (std::numeric_limits::min)() + && x <= (std::numeric_limits::max)(); + } + + template + inline bool isnormal_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isnormal_impl(x, generic_tag()); +#endif + return !(x == 0); + } + + template + inline bool isnormal_impl(T x, ieee_tag const&) + { + typedef typename detail::fp_traits::type traits; + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::flag; + return (a != 0) && (a < traits::exponent); + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isnormal_impl(t, generic_tag()); +} +#endif + +} + +template +inline bool (isnormal)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + //typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isnormal_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isnormal)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isnormal_impl(static_cast(x), method()); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isinf_impl(T x, native_tag const&) + { + return (std::isinf)(x); + } +#endif + + template + inline bool isinf_impl(T x, generic_tag const&) + { + (void)x; // in case the compiler thinks that x is unused because std::numeric_limits::has_infinity is false + return std::numeric_limits::has_infinity + && ( x == std::numeric_limits::infinity() + || x == -std::numeric_limits::infinity()); + } + + template + inline bool isinf_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isinf_impl(x, generic_tag()); +#endif + (void)x; // warning suppression. + return false; + } + + template + inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + return a == traits::exponent; + } + + template + inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + if(a != traits::exponent) + return false; + + traits::set_bits(x,0); + return x == 0; + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isinf_impl(t, generic_tag()); +} +#endif + +} // namespace detail + +template +inline bool (isinf)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isinf_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isinf)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isinf_impl(static_cast(x), method()); +} +#endif +#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H) +template<> +inline bool (isinf)(__float128 x) +{ + return ::isinfq(x); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isnan_impl(T x, native_tag const&) + { + return (std::isnan)(x); + } +#endif + + template + inline bool isnan_impl(T x, generic_tag const&) + { + return std::numeric_limits::has_infinity + ? !(x <= std::numeric_limits::infinity()) + : x != x; + } + + template + inline bool isnan_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isnan_impl(x, generic_tag()); +#endif + (void)x; // warning suppression + return false; + } + + template + inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + return a > traits::exponent; + } + + template + inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + + a &= traits::exponent | traits::significand; + if(a < traits::exponent) + return false; + + a &= traits::significand; + traits::set_bits(x,a); + return x != 0; + } + +} // namespace detail + +template +inline bool (isnan)(T x) +{ //!< \brief return true if floating-point type t is NaN (Not A Number). + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + return detail::isnan_impl(x, method()); +} + +#ifdef isnan +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(float t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(long double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +template<> +inline bool (isnan)(long double x) +{ //!< \brief return true if floating-point type t is NaN (Not A Number). + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + return detail::isnan_impl(x, method()); +} +#endif +#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H) +template<> +inline bool (isnan)(__float128 x) +{ + return ::isnanq(x); +} +#endif + +#endif + +} // namespace math +} // namespace boost + +#else // Special handling generally using the CUDA library + +#include + +namespace boost { +namespace math { + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isnan(T x) +{ + return false; +} + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isnan(T x) +{ + return ::isnan(x); +} + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isinf(T x) +{ + return false; +} + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isinf(T x) +{ + return ::isinf(x); +} + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isfinite(T x) +{ + return true; +} + +template , bool> = true> +BOOST_MATH_GPU_ENABLED inline bool isfinite(T x) +{ + return ::isfinite(x); +} + +template +BOOST_MATH_GPU_ENABLED inline bool isnormal(T x) +{ + return x != static_cast(0) && x != static_cast(-0) && + !boost::math::isnan(x) && + !boost::math::isinf(x); +} + +// We skip the check for FP_SUBNORMAL since they are not supported on these platforms +template +BOOST_MATH_GPU_ENABLED inline int fpclassify(T x) +{ + if (boost::math::isnan(x)) + { + return BOOST_MATH_FP_NAN; + } + else if (boost::math::isinf(x)) + { + return BOOST_MATH_FP_INFINITE; + } + else if (x == static_cast(0) || x == static_cast(-0)) + { + return BOOST_MATH_FP_ZERO; + } + + return BOOST_MATH_FP_NORMAL; +} + +} // Namespace math +} // Namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif // BOOST_MATH_FPCLASSIFY_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/gamma.hpp b/third-party/boost-math/include/boost/math/special_functions/gamma.hpp new file mode 100644 index 0000000000000..47b4f3d68defe --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/gamma.hpp @@ -0,0 +1,2502 @@ +// Copyright John Maddock 2006-7, 2013-20. +// Copyright Paul A. Bristow 2007, 2013-14. +// Copyright Nikhar Agrawal 2013-14 +// Copyright Christopher Kormanyos 2013-14, 2020, 2024 +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SF_GAMMA_HPP +#define BOOST_MATH_SF_GAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Only needed for types larger than double +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +#include +#include +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +# pragma warning(disable: 4127) // conditional expression is constant. +# pragma warning(disable: 4100) // unreferenced formal parameter. +# pragma warning(disable: 6326) // potential comparison of a constant with another constant +// Several variables made comments, +// but some difficulty as whether referenced on not may depend on macro values. +// So to be safe, 4100 warnings suppressed. +// TODO - revisit this? +#endif + +namespace boost{ namespace math{ + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const boost::math::true_type&) +{ + int i = static_cast(v); + return i&1; +} +template +BOOST_MATH_GPU_ENABLED inline bool is_odd(T v, const boost::math::false_type&) +{ + // Oh dear can't cast T to int! + BOOST_MATH_STD_USING + T modulus = v - 2 * floor(v/2); + return static_cast(modulus != 0); +} +template +BOOST_MATH_GPU_ENABLED inline bool is_odd(T v) +{ + return is_odd(v, ::boost::math::is_convertible()); +} + +template +BOOST_MATH_GPU_ENABLED T sinpx(T z) +{ + // Ad hoc function calculates x * sin(pi * x), + // taking extra care near when x is near a whole number. + BOOST_MATH_STD_USING + int sign = 1; + if(z < 0) + { + z = -z; + } + T fl = floor(z); + T dist; // LCOV_EXCL_LINE + if(is_odd(fl)) + { + fl += 1; + dist = fl - z; + sign = -sign; + } + else + { + dist = z - fl; + } + BOOST_MATH_ASSERT(fl >= 0); + if(dist > T(0.5)) + dist = 1 - dist; + T result = sin(dist*boost::math::constants::pi()); + return sign*z*result; +} // template T sinpx(T z) +// +// tgamma(z), with Lanczos support: +// +template +BOOST_MATH_GPU_ENABLED T gamma_imp_final(T z, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + (void)l; // Suppresses unused variable warning when BOOST_MATH_INSTRUMENT is not defined + + T result = 1; + +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if(!b) + { + std::cout << "tgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl; + b = true; + } +#endif + constexpr auto function = "boost::math::tgamma<%1%>(%1%)"; + + if(z <= 0) + { + // shift z to > 1: + while(z < 0) + { + result /= z; + z += 1; + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if((floor(z) == z) && (z < max_factorial::value)) + { + result *= unchecked_factorial(static_cast(itrunc(z, pol) - 1)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (z < tools::root_epsilon()) + { + if (z < 1 / tools::max_value()) + result = policies::raise_overflow_error(function, nullptr, pol); + result *= 1 / z - constants::euler(); + } + else + { + result *= Lanczos::lanczos_sum(z); + T zgh = (z + static_cast(Lanczos::g()) - boost::math::constants::half()); + T lzgh = log(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + BOOST_MATH_INSTRUMENT_VARIABLE(tools::log_max_value()); + if(z * lzgh > tools::log_max_value()) + { + // we're going to overflow unless this is done with care: + BOOST_MATH_INSTRUMENT_VARIABLE(zgh); + if(lzgh * z / 2 > tools::log_max_value()) + return boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + T hp = pow(zgh, T((z / 2) - T(0.25))); + BOOST_MATH_INSTRUMENT_VARIABLE(hp); + result *= hp / exp(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(tools::max_value() / hp < result) + return boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + result *= hp; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + BOOST_MATH_INSTRUMENT_VARIABLE(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, T(z - boost::math::constants::half()))); + BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh)); + result *= pow(zgh, T(z - boost::math::constants::half())) / exp(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + return result; +} + +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_suppress 2190 +#endif + +// SYCL compilers can not support recursion so we extract it into a dispatch function +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T gamma_imp(T z, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + T result = 1; + constexpr auto function = "boost::math::tgamma<%1%>(%1%)"; + + if(z <= 0) + { + if(floor(z) == z) + return policies::raise_pole_error(function, "Evaluation of tgamma at a negative integer %1%.", z, pol); + if(z <= -20) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + result = gamma_imp_final(T(-z), pol, l) * sinpx(z); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::overflow_error&) + { + return policies::raise_underflow_error(function, "Result of tgamma is too small to represent.", pol); + } +#endif + BOOST_MATH_INSTRUMENT_VARIABLE(result); + BOOST_MATH_IF_CONSTEXPR(!boost::math::numeric_limits::is_specialized || (boost::math::numeric_limits::digits > 64)) + { + if ((fabs(result) < 1) && (tools::max_value() * fabs(result) < boost::math::constants::pi())) + { + return policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE MP only. + + } + } + else + { + // Result can never be small: tgamma[-z] is always larger than sinpx[z] is small. + // Specifically, sinpx can never be larger than 1 / epsilon which is too small to + // ever generate a value less than one for `result`, unless T has a truely + // exceptional number of digits precision. + BOOST_MATH_ASSERT((fabs(result) > 1) || (tools::max_value() * fabs(result) > boost::math::constants::pi())); + } + result = -boost::math::constants::pi() / result; + if (result == 0) + return policies::raise_underflow_error(function, "Result of tgamma is too small to represent.", pol); + /* + * Result can never be subnormal as we have a value > 1 in the numerator: + if((boost::math::fpclassify)(result) == (int)FP_SUBNORMAL) + return policies::raise_denorm_error(function, "Result of tgamma is denormalized.", result, pol); + */ + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result; + } + } + + return gamma_imp_final(T(z), pol, l); +} + +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_default 2190 +#endif + +// +// lgamma(z) with Lanczos support: +// +template +BOOST_MATH_GPU_ENABLED T lgamma_imp_final(T z, const Policy& pol, const Lanczos& l, int* sign = nullptr) +{ +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if(!b) + { + std::cout << "lgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl; + b = true; + } +#endif + + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::lgamma<%1%>(%1%)"; + + T result = 0; + int sresult = 1; + + if (z < tools::root_epsilon()) + { + if (0 == z) + return policies::raise_pole_error(function, "Evaluation of lgamma at %1%.", z, pol); + if (4 * fabs(z) < tools::epsilon()) + result = -log(fabs(z)); + else + result = log(fabs(1 / z - constants::euler())); + if (z < 0) + sresult = -1; + } + else if(z < 15) + { + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + + result = lgamma_small_imp(z, T(z - 1), T(z - 2), tag_type(), pol, l); + } + else if((z >= 3) && (z < 100) && (boost::math::numeric_limits::max_exponent >= 1024)) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, l)); + } + else + { + // regular evaluation: + T zgh = static_cast(z + T(Lanczos::g()) - boost::math::constants::half()); + result = log(zgh) - 1; + result *= z - 0.5f; + // + // Only add on the lanczos sum part if we're going to need it: + // + if(result * tools::epsilon() < 20) + result += log(Lanczos::lanczos_sum_expG_scaled(z)); + } + + if(sign) + *sign = sresult; + return result; +} + +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_suppress 2190 +#endif + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = nullptr) +{ + BOOST_MATH_STD_USING + + if(z <= -tools::root_epsilon()) + { + constexpr auto function = "boost::math::lgamma<%1%>(%1%)"; + + T result = 0; + int sresult = 1; + + // reflection formula: + if(floor(z) == z) + return policies::raise_pole_error(function, "Evaluation of lgamma at a negative integer %1%.", z, pol); + + T t = sinpx(z); + z = -z; + if(t < 0) + { + t = -t; + } + else + { + sresult = -sresult; + } + result = log(boost::math::constants::pi()) - lgamma_imp_final(T(z), pol, l) - log(t); + + if(sign) + { + *sign = sresult; + } + + return result; + } + else + { + return lgamma_imp_final(T(z), pol, l, sign); + } +} + +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_default 2190 +#endif + +// +// Incomplete gamma functions follow: +// +template +struct upper_incomplete_gamma_fract +{ +private: + T z, a; + int k; +public: + typedef boost::math::pair result_type; + + BOOST_MATH_GPU_ENABLED upper_incomplete_gamma_fract(T a1, T z1) + : z(z1-a1+1), a(a1), k(0) + { + } + + BOOST_MATH_GPU_ENABLED result_type operator()() + { + ++k; + z += 2; + return result_type(k * (a - k), z); + } +}; + +template +BOOST_MATH_GPU_ENABLED inline T upper_gamma_fraction(T a, T z, T eps) +{ + // Multiply result by z^a * e^-z to get the full + // upper incomplete integral. Divide by tgamma(z) + // to normalise. + upper_incomplete_gamma_fract f(a, z); + return 1 / (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps)); +} + +template +struct lower_incomplete_gamma_series +{ +private: + T a, z, result; +public: + typedef T result_type; + BOOST_MATH_GPU_ENABLED lower_incomplete_gamma_series(T a1, T z1) : a(a1), z(z1), result(1){} + + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = result; + a += 1; + result *= z/a; + return r; + } +}; + +template +BOOST_MATH_GPU_ENABLED inline T lower_gamma_series(T a, T z, const Policy& pol, T init_value = 0) +{ + // Multiply result by ((z^a) * (e^-z) / a) to get the full + // lower incomplete integral. Then divide by tgamma(a) + // to get the normalised value. + lower_incomplete_gamma_series s(a, z); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + T factor = policies::get_epsilon(); + T result = boost::math::tools::sum_series(s, factor, max_iter, init_value); + policies::check_series_iterations("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol); + return result; +} + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +// +// Fully generic tgamma and lgamma use Stirling's approximation +// with Bernoulli numbers. +// +template +boost::math::size_t highest_bernoulli_index() +{ + const float digits10_of_type = (boost::math::numeric_limits::is_specialized + ? static_cast(boost::math::numeric_limits::digits10) + : static_cast(boost::math::tools::digits() * 0.301F)); + + // Find the high index n for Bn to produce the desired precision in Stirling's calculation. + return static_cast(18.0F + (0.6F * digits10_of_type)); +} + +template +int minimum_argument_for_bernoulli_recursion() +{ + BOOST_MATH_STD_USING + + const float digits10_of_type = (boost::math::numeric_limits::is_specialized + ? (float) boost::math::numeric_limits::digits10 + : (float) (boost::math::tools::digits() * 0.301F)); + + int min_arg = (int) (digits10_of_type * 1.7F); + + if(digits10_of_type < 50.0F) + { + // The following code sequence has been modified + // within the context of issue 396. + + // The calculation of the test-variable limit has now + // been protected against overflow/underflow dangers. + + // The previous line looked like this and did, in fact, + // underflow ldexp when using certain multiprecision types. + + // const float limit = std::ceil(std::pow(1.0f / std::ldexp(1.0f, 1-boost::math::tools::digits()), 1.0f / 20.0f)); + + // The new safe version of the limit check is now here. + const float d2_minus_one = ((digits10_of_type / 0.301F) - 1.0F); + const float limit = ceil(exp((d2_minus_one * log(2.0F)) / 20.0F)); + + min_arg = (int) (BOOST_MATH_GPU_SAFE_MIN(digits10_of_type * 1.7F, limit)); + } + + return min_arg; +} + +template +T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false) +{ + BOOST_MATH_STD_USING + // + // Calculates tgamma(z) / (z/e)^z + // Requires that our argument is large enough for Sterling's approximation to hold. + // Used internally when combining gamma's of similar magnitude without logarithms. + // + BOOST_MATH_ASSERT(minimum_argument_for_bernoulli_recursion() <= z); + + // Perform the Bernoulli series expansion of Stirling's approximation. + + const boost::math::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations(); + + T one_over_x_pow_two_n_minus_one = 1 / z; + const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one; + T sum = (boost::math::bernoulli_b2n(1) / 2) * one_over_x_pow_two_n_minus_one; + const T target_epsilon_to_break_loop = sum * boost::math::tools::epsilon(); + const T half_ln_two_pi_over_z = sqrt(boost::math::constants::two_pi() / z); + T last_term = 2 * sum; + + for (boost::math::size_t n = 2U;; ++n) + { + one_over_x_pow_two_n_minus_one *= one_over_x2; + + const boost::math::size_t n2 = static_cast(n * 2U); + + const T term = (boost::math::bernoulli_b2n(static_cast(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U)); + + if ((n >= 3U) && (abs(term) < target_epsilon_to_break_loop)) + { + // We have reached the desired precision in Stirling's expansion. + // Adding additional terms to the sum of this divergent asymptotic + // expansion will not improve the result. + + // Break from the loop. + break; + } + if (n > number_of_bernoullis_b2n) + // Safety net, we hope to never get here: + return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Exceeded maximum series iterations without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol); // LCOV_EXCL_LINE + + sum += term; + + // Sanity check for divergence: + T fterm = fabs(term); + if(fterm > last_term) + // Safety net, we hope to never get here: + return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Series became divergent without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol); // LCOV_EXCL_LINE + last_term = fterm; + } + + // Complete Stirling's approximation. + T scaled_gamma_value = islog ? T(sum + log(half_ln_two_pi_over_z)) : T(exp(sum) * half_ln_two_pi_over_z); + return scaled_gamma_value; +} + +// Forward declaration of the lgamma_imp template specialization. +template +T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign = nullptr); + +template +T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::tgamma<%1%>(%1%)"; + + // Check if the argument of tgamma is identically zero. + const bool is_at_zero = (z == 0); + + if((boost::math::isnan)(z) || (is_at_zero) || ((boost::math::isinf)(z) && (z < 0))) + return policies::raise_domain_error(function, "Evaluation of tgamma at %1%.", z, pol); + + const bool b_neg = (z < 0); + + const bool floor_of_z_is_equal_to_z = (floor(z) == z); + + // Special case handling of small factorials: + if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial::value)) + { + return boost::math::unchecked_factorial(static_cast(itrunc(z) - 1)); + } + + // Make a local, unsigned copy of the input argument. + T zz((!b_neg) ? z : -z); + + // Special case for ultra-small z: + if(zz < tools::cbrt_epsilon()) + { + const T a0(1); + const T a1(boost::math::constants::euler()); + const T six_euler_squared((boost::math::constants::euler() * boost::math::constants::euler()) * 6); + const T a2((six_euler_squared - boost::math::constants::pi_sqr()) / 12); + + const T inverse_tgamma_series = z * ((a2 * z + a1) * z + a0); + + return 1 / inverse_tgamma_series; + } + + // Scale the argument up for the calculation of lgamma, + // and use downward recursion later for the final result. + const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion(); + + int n_recur; + + if(zz < min_arg_for_recursion) + { + n_recur = boost::math::itrunc(min_arg_for_recursion - zz) + 1; + + zz += n_recur; + } + else + { + n_recur = 0; + } + if (!n_recur) + { + if (zz > tools::log_max_value()) + return b_neg ? policies::raise_underflow_error(function, nullptr, pol) : policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE MP only + if (log(zz) * zz / 2 > tools::log_max_value()) + return b_neg ? policies::raise_underflow_error(function, nullptr, pol) : policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE MP only + } + T gamma_value = scaled_tgamma_no_lanczos(zz, pol); + T power_term = pow(zz, zz / 2); + T exp_term = exp(-zz); + gamma_value *= (power_term * exp_term); + if (!n_recur && (tools::max_value() / power_term < gamma_value)) + return b_neg ? policies::raise_underflow_error(function, nullptr, pol) : policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE MP only + gamma_value *= power_term; + + // Rescale the result using downward recursion if necessary. + if(n_recur) + { + // The order of divides is important, if we keep subtracting 1 from zz + // we DO NOT get back to z (cancellation error). Further if z < epsilon + // we would end up dividing by zero. Also in order to prevent spurious + // overflow with the first division, we must save dividing by |z| till last, + // so the optimal order of divides is z+1, z+2, z+3...z+n_recur-1,z. + zz = fabs(z) + 1; + for(int k = 1; k < n_recur; ++k) + { + gamma_value /= zz; + zz += 1; + } + gamma_value /= fabs(z); + } + + // Return the result, accounting for possible negative arguments. + if(b_neg) + { + // Provide special error analysis for: + // * arguments in the neighborhood of a negative integer + // * arguments exactly equal to a negative integer. + + // Check if the argument of tgamma is exactly equal to a negative integer. + if(floor_of_z_is_equal_to_z) + return policies::raise_pole_error(function, "Evaluation of tgamma at a negative integer %1%.", z, pol); // LCOV_EXCL_LINE MP only + + T s = sinpx(z); + if ((gamma_value > 1) && (tools::max_value() / gamma_value < fabs(s))) + return policies::raise_underflow_error(function, nullptr, pol); // LCOV_EXCL_LINE MP only + gamma_value *= s; // LCOV_EXCL_LINE MP only + + BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value); + // + // Result can never overflow, since sinpx(z) can never be smaller than machine epsilon and gamma_value > 1. + // + BOOST_MATH_ASSERT( (abs(gamma_value) > 1) || ((tools::max_value() * abs(gamma_value)) > boost::math::constants::pi())); // LCOV_EXCL_LINE MP only + + gamma_value = -boost::math::constants::pi() / gamma_value; + + BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value); // LCOV_EXCL_LINE MP only + // + // We can never underflow since the numerator > 1 above and denominator is not infinite: + // + BOOST_MATH_ASSERT(gamma_value != 0); // LCOV_EXCL_LINE MP only + } + + return gamma_value; +} + +template +inline T log_gamma_near_1(const T& z, Policy const& pol) +{ + // + // This is for the multiprecision case where there is + // no lanczos support, use a taylor series at z = 1, + // see https://www.wolframalpha.com/input/?i=taylor+series+lgamma(x)+at+x+%3D+1 + // + BOOST_MATH_STD_USING // ADL of std names + + // For some reason, several lines aren't triggered for coverage even though + // adjacent lines are... weird! + + BOOST_MATH_ASSERT(fabs(z) < 1); // LCOV_EXCL_LINE + + T result = -constants::euler() * z; + + T power_term = z * z / 2; + int n = 2; // LCOV_EXCL_LINE + T term = 0; // LCOV_EXCL_LINE + + do + { + term = power_term * boost::math::polygamma(n - 1, T(1), pol); + result += term; // LCOV_EXCL_LINE + ++n; + power_term *= z / n; + } while (fabs(result) * tools::epsilon() < fabs(term)); + + return result; +} + +template +T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::lgamma<%1%>(%1%)"; + + // Check if the argument of lgamma is identically zero. + const bool is_at_zero = (z == 0); + + if(is_at_zero) + return policies::raise_domain_error(function, "Evaluation of lgamma at zero %1%.", z, pol); + if((boost::math::isnan)(z)) + return policies::raise_domain_error(function, "Evaluation of lgamma at %1%.", z, pol); + if((boost::math::isinf)(z)) + return policies::raise_overflow_error(function, nullptr, pol); + + const bool b_neg = (z < 0); + + const bool floor_of_z_is_equal_to_z = (floor(z) == z); + + // Special case handling of small factorials: + if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial::value)) + { + if (sign) + *sign = 1; // LCOV_EXCL_LINE + return log(boost::math::unchecked_factorial(itrunc(z) - 1)); + } + + // Make a local, unsigned copy of the input argument. + T zz((!b_neg) ? z : -z); + + const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion(); + + T log_gamma_value; + + if (zz < min_arg_for_recursion) + { + // Here we simply take the logarithm of tgamma(). This is somewhat + // inefficient, but simple. The rationale is that the argument here + // is relatively small and overflow is not expected to be likely. + if (sign) + * sign = 1; // // LCOV_EXCL_LINE + if(fabs(z - 1) < 0.25) + { + log_gamma_value = log_gamma_near_1(T(zz - 1), pol); + } + else if(fabs(z - 2) < 0.25) + { + log_gamma_value = log_gamma_near_1(T(zz - 2), pol) + log(zz - 1); + } + else if (z > -tools::root_epsilon()) + { + // Reflection formula may fail if z is very close to zero, let the series + // expansion for tgamma close to zero do the work: + if (sign) + *sign = z < 0 ? -1 : 1; // LCOV_EXCL_LINE + return log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos()))); + } + else + { + // No issue with spurious overflow in reflection formula, + // just fall through to regular code: + T g = gamma_imp(zz, pol, lanczos::undefined_lanczos()); + if (sign) + { + *sign = g < 0 ? -1 : 1; // LCOV_EXCL_LINE MP only + } + log_gamma_value = log(abs(g)); + } + } + else + { + // Perform the Bernoulli series expansion of Stirling's approximation. + T sum = scaled_tgamma_no_lanczos(zz, pol, true); + log_gamma_value = zz * (log(zz) - 1) + sum; + } + + int sign_of_result = 1; + + if(b_neg) + { + // Provide special error analysis if the argument is exactly + // equal to a negative integer. + + // Check if the argument of lgamma is exactly equal to a negative integer. + if(floor_of_z_is_equal_to_z) + return policies::raise_pole_error(function, "Evaluation of lgamma at a negative integer %1%.", z, pol); // LCOV_EXCL_LINE MP only + + T t = sinpx(z); + + if(t < 0) + { + t = -t; + } + else + { + sign_of_result = -sign_of_result; // LCOV_EXCL_LINE MP only + } + + log_gamma_value = - log_gamma_value + log(boost::math::constants::pi()) - log(t); + } + + if(sign != static_cast(nullptr)) { *sign = sign_of_result; } + + return log_gamma_value; +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +// In order for tgammap1m1_imp to compile we need a forward decl of boost::math::tgamma +// The rub is that we can't just use math_fwd so we provide one here only in that circumstance +#ifdef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT z); + +template +BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT1 a, RT2 z); + +template +BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT1 a, RT2 z, const Policy& pol); +#endif + +// +// This helper calculates tgamma(dz+1)-1 without cancellation errors, +// used by the upper incomplete gamma with z < 1: +// +template +BOOST_MATH_GPU_ENABLED T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + typedef typename policies::precision::type precision_type; + + typedef boost::math::integral_constant tag_type; + + T result{}; + if(dz < 0) + { + if(dz < T(-0.5)) + { + // Best method is simply to subtract 1 from tgamma: + #ifdef BOOST_MATH_HAS_NVRTC + result = ::tgamma(1+dz); + #else + result = boost::math::tgamma(1+dz, pol) - 1; + #endif + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // Use expm1 on lgamma: + result = boost::math::expm1(-boost::math::log1p(dz, pol) + + lgamma_small_imp(dz+2, dz + 1, dz, tag_type(), pol, l), pol); + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + else + { + if(dz < 2) + { + // Use expm1 on lgamma: + result = boost::math::expm1(lgamma_small_imp(dz+1, dz, dz-1, tag_type(), pol, l), pol); + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // Best method is simply to subtract 1 from tgamma: + #ifdef BOOST_MATH_HAS_NVRTC + result = ::tgamma(1+dz); + #else + result = boost::math::tgamma(1+dz, pol) - 1; + #endif + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + + return result; +} + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +inline T tgammap1m1_imp(T z, Policy const& pol, + const ::boost::math::lanczos::undefined_lanczos&) +{ + BOOST_MATH_STD_USING // ADL of std names + + if(fabs(z) < T(0.55)) + { + return boost::math::expm1(log_gamma_near_1(z, pol)); + } + return boost::math::expm1(boost::math::lgamma(1 + z, pol)); +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +// +// Series representation for upper fraction when z is small: +// +template +struct small_gamma2_series +{ + typedef T result_type; + + BOOST_MATH_GPU_ENABLED small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){} + + BOOST_MATH_GPU_ENABLED T operator()() + { + T r = result / (apn); + result *= x; + result /= ++n; + apn += 1; + return r; + } + +private: + T result, x, apn; + int n; +}; +// +// calculate power term prefix (z^a)(e^-z) used in the non-normalised +// incomplete gammas: +// +template +BOOST_MATH_GPU_ENABLED T full_igamma_prefix(T a, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if (z > tools::max_value() || (a > 0 && z == 0)) + return 0; + + T alz = a * log(z); + + T prefix { }; + + if(z >= 1) + { + if((alz < tools::log_max_value()) && (-z > tools::log_min_value())) + { + prefix = pow(z, a) * exp(-z); + } + else if(a >= 1) + { + prefix = pow(T(z / exp(z/a)), a); + } + else + { + prefix = exp(alz - z); // LCOV_EXCL_LINE defensive programming, can probably never get here? + } + } + else + { + if(alz > tools::log_min_value()) + { + prefix = pow(z, a) * exp(-z); + } + // LCOV_EXCL_START + // Defensive programming, can probably never get here, very hard to prove though! + else if(z/a < tools::log_max_value()) + { + prefix = pow(T(z / exp(z/a)), a); + } + else + { + prefix = exp(alz - z); + } + // LCOV_EXCL_STOP + } + // + // This error handling isn't very good: it happens after the fact + // rather than before it... + // Typically though this method is used when the result is small, we should probably not overflow here... + // + if((boost::math::fpclassify)(prefix) == (int)BOOST_MATH_FP_INFINITE) + return policies::raise_overflow_error("boost::math::detail::full_igamma_prefix<%1%>(%1%, %1%)", "Result of incomplete gamma function is too large to represent.", pol); // LCOV_EXCL_LINE + + return prefix; +} +// +// Compute (z^a)(e^-z)/tgamma(a) +// most if the error occurs in this function: +// +template +BOOST_MATH_GPU_ENABLED T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + if (z >= tools::max_value() || (a > 0 && z == 0)) + return 0; + T agh = a + static_cast(Lanczos::g()) - T(0.5); + T prefix{}; + T d = ((z - a) - static_cast(Lanczos::g()) + T(0.5)) / agh; + + if(a < 1) + { + // + // We have to treat a < 1 as a special case because our Lanczos + // approximations are optimised against the factorials with a > 1, + // and for high precision types especially (128-bit reals for example) + // very small values of a can give rather erroneous results for gamma + // unless we do this: + // + // TODO: is this still required? Lanczos approx should be better now? + // + if((z <= tools::log_min_value()) || (a < 1 / tools::max_value())) + { + // Oh dear, have to use logs, should be free of cancellation errors though: + return exp(a * log(z) - z - lgamma_imp(a, pol, l)); + } + else + { + // direct calculation, no danger of overflow as gamma(a) < 1/a + // for small a. + return pow(z, a) * exp(-z) / gamma_imp(a, pol, l); + } + } + else if((fabs(d*d*a) <= 100) && (a > 150)) + { + // special case for large a and a ~ z. + prefix = a * boost::math::log1pmx(d, pol) + z * static_cast(0.5 - Lanczos::g()) / agh; + prefix = exp(prefix); + } + else + { + // + // general case. + // direct computation is most accurate, but use various fallbacks + // for different parts of the problem domain: + // + T alz = a * log(z / agh); + T amz = a - z; + if((BOOST_MATH_GPU_SAFE_MIN(alz, amz) <= tools::log_min_value()) || (BOOST_MATH_GPU_SAFE_MAX(alz, amz) >= tools::log_max_value())) + { + T amza = amz / a; + if((BOOST_MATH_GPU_SAFE_MIN(alz, amz)/2 > tools::log_min_value()) && (BOOST_MATH_GPU_SAFE_MAX(alz, amz)/2 < tools::log_max_value())) + { + // compute square root of the result and then square it: + T sq = pow(z / agh, a / 2) * exp(amz / 2); + prefix = sq * sq; + } + else if((BOOST_MATH_GPU_SAFE_MIN(alz, amz)/4 > tools::log_min_value()) && (BOOST_MATH_GPU_SAFE_MAX(alz, amz)/4 < tools::log_max_value()) && (z > a)) + { + // compute the 4th root of the result then square it twice: + T sq = pow(z / agh, a / 4) * exp(amz / 4); + prefix = sq * sq; + prefix *= prefix; + } + else if((amza > tools::log_min_value()) && (amza < tools::log_max_value())) + { + prefix = pow(T((z * exp(amza)) / agh), a); + } + else + { + prefix = exp(alz + amz); + } + } + else + { + prefix = pow(T(z / agh), a) * exp(amz); + } + } + prefix *= sqrt(agh / boost::math::constants::e()) / Lanczos::lanczos_sum_expG_scaled(a); + return prefix; +} + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +// +// And again, without Lanczos support: +// +template +T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos& l) +{ + BOOST_MATH_STD_USING + + if((a < 1) && (z < 1)) + { + // No overflow possible since the power terms tend to unity as a,z -> 0 + return pow(z, a) * exp(-z) / boost::math::tgamma(a, pol); + } + else if(a > minimum_argument_for_bernoulli_recursion()) + { + T scaled_gamma = scaled_tgamma_no_lanczos(a, pol); + T power_term = pow(z / a, a / 2); + T a_minus_z = a - z; + if ((0 == power_term) || (fabs(a_minus_z) > tools::log_max_value())) + { + // The result is probably zero, but we need to be sure: + return exp(a * log(z / a) + a_minus_z - log(scaled_gamma)); + } + return (power_term * exp(a_minus_z)) * (power_term / scaled_gamma); + } + else + { + // + // Usual case is to calculate the prefix at a+shift and recurse down + // to the value we want: + // + const int min_z = minimum_argument_for_bernoulli_recursion(); + long shift = 1 + ltrunc(min_z - a); + T result = regularised_gamma_prefix(T(a + shift), z, pol, l); + if (result != 0) + { + for (long i = 0; i < shift; ++i) + { + result /= z; + result *= a + i; + } + return result; + } + else + { + // + // We failed, most probably we have z << 1, try again, this time + // we calculate z^a e^-z / tgamma(a+shift), combining power terms + // as we go. And again recurse down to the result. + // + T scaled_gamma = scaled_tgamma_no_lanczos(T(a + shift), pol); + T power_term_1 = pow(T(z / (a + shift)), a); + T power_term_2 = pow(T(a + shift), T(-shift)); + T power_term_3 = exp(a + shift - z); + if ((0 == power_term_1) || (0 == power_term_2) || (0 == power_term_3) || (fabs(a + shift - z) > tools::log_max_value())) + { + // We have no test case that gets here, most likely the type T + // has a high precision but low exponent range: + return exp(a * log(z) - z - boost::math::lgamma(a, pol)); + } + result = power_term_1 * power_term_2 * power_term_3 / scaled_gamma; + for (long i = 0; i < shift; ++i) + { + result *= a + i; + } + return result; + } + } +} + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +// +// Upper gamma fraction for very small a: +// +template +BOOST_MATH_GPU_ENABLED inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0) +{ + BOOST_MATH_STD_USING // ADL of std functions. + // + // Compute the full upper fraction (Q) when a is very small: + // + + #ifdef BOOST_MATH_HAS_NVRTC + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + T result {detail::tgammap1m1_imp(static_cast(a), pol, evaluation_type())}; + #else + T result { boost::math::tgamma1pm1(a, pol) }; + #endif + + if(pgam) + *pgam = (result + 1) / a; + T p = boost::math::powm1(x, a, pol); + result -= p; + result /= a; + detail::small_gamma2_series s(a, x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations() - 10; + p += 1; + if(pderivative) + *pderivative = p / (*pgam * exp(x)); + T init_value = invert ? *pgam : 0; + result = -p * tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, (init_value - result) / p); + policies::check_series_iterations("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol); + if(invert) + result = -result; + return result; +} +// +// Upper gamma fraction for integer a: +// +template +BOOST_MATH_GPU_ENABLED inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0) +{ + // + // Calculates normalised Q when a is an integer: + // + BOOST_MATH_STD_USING + T e = exp(-x); + T sum = e; + if(sum != 0) + { + T term = sum; + for(unsigned n = 1; n < a; ++n) + { + term /= n; + term *= x; + sum += term; + } + } + if(pderivative) + { + *pderivative = e * pow(x, a) / boost::math::unchecked_factorial(itrunc(T(a - 1), pol)); + } + return sum; +} +// +// Upper gamma fraction for half integer a: +// +template +BOOST_MATH_GPU_ENABLED T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol) +{ + // + // Calculates normalised Q when a is a half-integer: + // + BOOST_MATH_STD_USING + + #ifdef BOOST_MATH_HAS_NVRTC + T e; + if (boost::math::is_same_v) + { + e = ::erfcf(::sqrtf(x)); + } + else + { + e = ::erfc(::sqrt(x)); + } + #else + T e = boost::math::erfc(sqrt(x), pol); + #endif + + if((e != 0) && (a > 1)) + { + T term = exp(-x) / sqrt(constants::pi() * x); + term *= x; + static const T half = T(1) / 2; // LCOV_EXCL_LINE + term /= half; + T sum = term; + for(unsigned n = 2; n < a; ++n) + { + term /= n - half; + term *= x; + sum += term; + } + e += sum; + if(p_derivative) + { + *p_derivative = 0; + } + } + else if(p_derivative) + { + // We'll be dividing by x later, so calculate derivative * x: + *p_derivative = sqrt(x) * exp(-x) / constants::root_pi(); + } + return e; +} +// +// Asymptotic approximation for large argument, see: https://dlmf.nist.gov/8.11#E2 +// +template +struct incomplete_tgamma_large_x_series +{ + typedef T result_type; + BOOST_MATH_GPU_ENABLED incomplete_tgamma_large_x_series(const T& a, const T& x) + : a_poch(a - 1), z(x), term(1) {} + BOOST_MATH_GPU_ENABLED T operator()() + { + T result = term; + term *= a_poch / z; + a_poch -= 1; + return result; + } + T a_poch, z, term; +}; + +template +BOOST_MATH_GPU_ENABLED T incomplete_tgamma_large_x(const T& a, const T& x, const Policy& pol) +{ + BOOST_MATH_STD_USING + incomplete_tgamma_large_x_series s(a, x); + boost::math::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol); + return result; +} + + +// +// Main incomplete gamma entry point, handles all four incomplete gamma's: +// +template +BOOST_MATH_GPU_ENABLED T gamma_incomplete_imp_final(T a, T x, bool normalised, bool invert, + const Policy& pol, T* p_derivative) +{ + BOOST_MATH_STD_USING + + typedef typename lanczos::lanczos::type lanczos_type; + + T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used + + BOOST_MATH_ASSERT((p_derivative == nullptr) || normalised); + + bool is_int, is_half_int; + bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value()); + if(is_small_a) + { + T fa = floor(a); + is_int = (fa == a); + is_half_int = is_int ? false : (fabs(fa - a) == 0.5f); + } + else + { + is_int = is_half_int = false; + } + + int eval_method; + + if (x == 0) + { + eval_method = 2; + } + else if(is_int && (x > 0.6)) + { + // calculate Q via finite sum: + invert = !invert; + eval_method = 0; + } + else if(is_half_int && (x > 0.2)) + { + // calculate Q via finite sum for half integer a: + invert = !invert; + eval_method = 1; + } + else if((x < tools::root_epsilon()) && (a > 1)) + { + eval_method = 6; + } + else if ((x > 1000) && ((a < x) || (fabs(a - 50) / x < 1))) + { + // calculate Q via asymptotic approximation: + invert = !invert; + eval_method = 7; + } + else if(x < T(0.5)) + { + // + // Changeover criterion chosen to give a changeover at Q ~ 0.33 + // + if(T(-0.4) / log(x) < a) + { + eval_method = 2; + } + else + { + eval_method = 3; + } + } + else if(x < T(1.1)) + { + // + // Changeover here occurs when P ~ 0.75 or Q ~ 0.25: + // + if(x * 0.75f < a) + { + eval_method = 2; + } + else + { + eval_method = 3; + } + } + else + { + // + // Begin by testing whether we're in the "bad" zone + // where the result will be near 0.5 and the usual + // series and continued fractions are slow to converge: + // + bool use_temme = false; + if(normalised && boost::math::numeric_limits::is_specialized && (a > 20)) + { + T sigma = fabs((x-a)/a); + if((a > 200) && (policies::digits() <= 113)) + { + // + // This limit is chosen so that we use Temme's expansion + // only if the result would be larger than about 10^-6. + // Below that the regular series and continued fractions + // converge OK, and if we use Temme's method we get increasing + // errors from the dominant erfc term as it's (inexact) argument + // increases in magnitude. + // + if(20 / a > sigma * sigma) + use_temme = true; + } + else if(policies::digits() <= 64) + { + // Note in this zone we can't use Temme's expansion for + // types longer than an 80-bit real: + // it would require too many terms in the polynomials. + if(sigma < 0.4) + use_temme = true; + } + } + if(use_temme) + { + eval_method = 5; + } + else + { + // + // Regular case where the result will not be too close to 0.5. + // + // Changeover here occurs at P ~ Q ~ 0.5 + // Note that series computation of P is about x2 faster than continued fraction + // calculation of Q, so try and use the CF only when really necessary, especially + // for small x. + // + if(x - (1 / (3 * x)) < a) + { + eval_method = 2; + } + else + { + eval_method = 4; + invert = !invert; + } + } + } + + switch(eval_method) + { + case 0: + { + result = finite_gamma_q(a, x, pol, p_derivative); + if(!normalised) + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result *= ::tgammaf(a); + } + else + { + result *= ::tgamma(a); + } + #else + result *= boost::math::tgamma(a, pol); + #endif + } + break; + } + case 1: + { + result = finite_half_gamma_q(a, x, p_derivative, pol); + if(!normalised) + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result *= ::tgammaf(a); + } + else + { + result *= ::tgamma(a); + } + #else + result *= boost::math::tgamma(a, pol); + #endif + } + if(p_derivative && (*p_derivative == 0)) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 2: + { + // Compute P: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if(p_derivative) + *p_derivative = result; + if(result != 0) + { + // + // If we're going to be inverting the result then we can + // reduce the number of series evaluations by quite + // a few iterations if we set an initial value for the + // series sum based on what we'll end up subtracting it from + // at the end. + // Have to be careful though that this optimization doesn't + // lead to spurious numeric overflow. Note that the + // scary/expensive overflow checks below are more often + // than not bypassed in practice for "sensible" input + // values: + // + T init_value = 0; + bool optimised_invert = false; + if(invert) + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + init_value = (normalised ? T(1) : ::tgammaf(a)); + } + else + { + init_value = (normalised ? T(1) : ::tgamma(a)); + } + #else + init_value = (normalised ? T(1) : boost::math::tgamma(a, pol)); + #endif + + if(normalised || (result >= 1) || (tools::max_value() * result > init_value)) + { + init_value /= result; + if(normalised || (a < 1) || (tools::max_value() / a > init_value)) + { + init_value *= -a; + optimised_invert = true; + } + else + init_value = 0; // LCOV_EXCL_LINE Unreachable for any "sensible" floating point type. + } + else + init_value = 0; + } + result *= detail::lower_gamma_series(a, x, pol, init_value) / a; + if(optimised_invert) + { + invert = false; + result = -result; + } + } + break; + } + case 3: + { + // Compute Q: + invert = !invert; + T g{}; + result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative); + invert = false; + if(normalised) + result /= g; + break; + } + case 4: + { + // Compute Q: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if(p_derivative) + *p_derivative = result; + if(result != 0) + result *= upper_gamma_fraction(a, x, policies::get_epsilon()); + break; + } + case 5: + { + // + // Use compile time dispatch to the appropriate + // Temme asymptotic expansion. This may be dead code + // if T does not have numeric limits support, or has + // too many digits for the most precise version of + // these expansions, in that case we'll be calling + // an empty function. + // + typedef typename policies::precision::type precision_type; + + typedef boost::math::integral_constant tag_type; + + result = igamma_temme_large(a, x, pol, tag_type()); + if(x >= a) + invert = !invert; + if(p_derivative) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 6: + { + // x is so small that P is necessarily very small too, + // use http://functions.wolfram.com/GammaBetaErf/GammaRegularized/06/01/05/01/01/ + if(!normalised) + result = pow(x, a) / (a); + else + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result = ::powf(x, a) / ::tgammaf(a + 1); + } + else + { + result = ::pow(x, a) / ::tgamma(a + 1); + } + #else + result = pow(x, a) / boost::math::tgamma(a + 1, pol); + #endif +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch (const std::overflow_error&) + { + result = 0; + } +#endif + } + result *= 1 - a * x / (a + 1); + if (p_derivative) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 7: + { + // x is large, + // Compute Q: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if (p_derivative) + *p_derivative = result; + result /= x; + if (result != 0) + result *= incomplete_tgamma_large_x(a, x, pol); + break; + } + } + + if(normalised && (result > 1)) + result = 1; + if(invert) + { + #ifdef BOOST_MATH_HAS_NVRTC + T gam; + if (boost::math::is_same_v) + { + gam = normalised ? T(1) : ::tgammaf(a); + } + else + { + gam = normalised ? T(1) : ::tgamma(a); + } + #else + T gam = normalised ? T(1) : boost::math::tgamma(a, pol); + #endif + result = gam - result; + } + if(p_derivative) + { + if((x == 0) || ((x < 1) && (tools::max_value() * x < *p_derivative))) + { + // overflow, just return an arbitrarily large value: + *p_derivative = tools::max_value() / 2; + } + else + *p_derivative /= x; + } + + return result; +} + +// Need to implement this dispatch to avoid recursion for device compilers +template +BOOST_MATH_GPU_ENABLED T gamma_incomplete_imp(T a, T x, bool normalised, bool invert, + const Policy& pol, T* p_derivative) +{ + constexpr auto function = "boost::math::gamma_p<%1%>(%1%, %1%)"; + if(a <= 0) + return policies::raise_domain_error(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol); + if(x < 0) + return policies::raise_domain_error(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol); + + BOOST_MATH_STD_USING + + + T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used + + if(x > 0 && a >= max_factorial::value && !normalised) + { + // + // When we're computing the non-normalized incomplete gamma + // and a is large the result is rather hard to compute unless + // we use logs. There are really two options - if x is a long + // way from a in value then we can reliably use methods 2 and 4 + // below in logarithmic form and go straight to the result. + // Otherwise we let the regularized gamma take the strain + // (the result is unlikely to underflow in the central region anyway) + // and combine with lgamma in the hopes that we get a finite result. + // + if(invert && (a * 4 < x)) + { + // This is method 4 below, done in logs: + result = a * log(x) - x; + BOOST_MATH_ASSERT(p_derivative == nullptr); + // Not currently used for non-normalized igamma: + //if(p_derivative) + // *p_derivative = exp(result); + result += log(upper_gamma_fraction(a, x, policies::get_epsilon())); + } + else if(!invert && (a > 4 * x)) + { + // This is method 2 below, done in logs: + result = a * log(x) - x; + BOOST_MATH_ASSERT(p_derivative == nullptr); + // Not currently used for non-normalized igamma: + //if(p_derivative) + // *p_derivative = exp(result); + T init_value = 0; + result += log(detail::lower_gamma_series(a, x, pol, init_value) / a); + } + else + { + result = gamma_incomplete_imp_final(T(a), T(x), true, invert, pol, p_derivative); + if(result == 0) + { + if(invert) + { + // Try http://functions.wolfram.com/06.06.06.0039.01 + result = 1 + 1 / (12 * a) + 1 / (288 * a * a); + result = log(result) - a + (a - 0.5f) * log(a) + log(boost::math::constants::root_two_pi()); + BOOST_MATH_ASSERT(p_derivative == nullptr); + // Not currently used for non-normalized igamma: + //if(p_derivative) + // *p_derivative = exp(a * log(x) - x); + } + else + { + // This is method 2 below, done in logs, we're really outside the + // range of this method, but since the result is almost certainly + // infinite, we should probably be OK: + result = a * log(x) - x; + BOOST_MATH_ASSERT(p_derivative == nullptr); + // Not currently used for non-normalized igamma: + //if(p_derivative) + // *p_derivative = exp(result); + T init_value = 0; + result += log(detail::lower_gamma_series(a, x, pol, init_value) / a); + } + } + else + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + result = ::logf(result) + ::lgammaf(a); + } + else + { + result = ::log(result) + ::lgamma(a); + } + #else + result = log(result) + boost::math::lgamma(a, pol); + #endif + } + } + if(result > tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + return exp(result); + } + + // If no special handling is required then we proceeds as normal + return gamma_incomplete_imp_final(T(a), T(x), normalised, invert, pol, p_derivative); +} + +// +// Ratios of two gamma functions: +// +template +BOOST_MATH_GPU_ENABLED T tgamma_delta_ratio_imp_lanczos_final(T z, T delta, const Policy& pol, const Lanczos&) +{ + BOOST_MATH_STD_USING + + T zgh = static_cast(z + T(Lanczos::g()) - constants::half()); + T result{}; + if(z + delta == z) + { + // Given delta < z * eps + // and zgh > z + // Then this must follow: + BOOST_MATH_ASSERT(fabs(delta / zgh) < boost::math::tools::epsilon()); + // We have: + // result = exp((constants::half() - z) * boost::math::log1p(delta / zgh, pol)); + // 0.5 - z == -z + // log1p(delta / zgh) = delta / zgh = delta / z + // multiplying we get -delta. + result = exp(-delta); + } + else + { + if(fabs(delta) < 10) + { + result = exp((constants::half() - z) * boost::math::log1p(delta / zgh, pol)); + } + else + { + result = pow(T(zgh / (zgh + delta)), T(z - constants::half())); + } + // Split the calculation up to avoid spurious overflow: + result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta)); + } + result *= pow(T(constants::e() / (zgh + delta)), delta); + return result; +} + +template +BOOST_MATH_GPU_ENABLED T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + if(z < tools::epsilon()) + { + // + // We get spurious numeric overflow unless we're very careful, this + // can occur either inside Lanczos::lanczos_sum(z) or in the + // final combination of terms, to avoid this, split the product up + // into 2 (or 3) parts: + // + // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta + // z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial + // + if(boost::math::max_factorial::value < delta) + { + T ratio = tgamma_delta_ratio_imp_lanczos_final(T(delta), T(boost::math::max_factorial::value - delta), pol, l); + ratio *= z; + ratio *= boost::math::unchecked_factorial(boost::math::max_factorial::value - 1); + return 1 / ratio; + } + else + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return 1 / (z * ::tgammaf(z + delta)); + } + else + { + return 1 / (z * ::tgamma(z + delta)); + } + #else + return 1 / (z * boost::math::tgamma(z + delta, pol)); + #endif + } + } + + return tgamma_delta_ratio_imp_lanczos_final(T(z), T(delta), pol, l); +} + +// +// And again without Lanczos support this time: +// +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +template +T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos& l) +{ + BOOST_MATH_STD_USING + + // + // We adjust z and delta so that both z and z+delta are large enough for + // Sterling's approximation to hold. We can then calculate the ratio + // for the adjusted values, and rescale back down to z and z+delta. + // + // Get the required shifts first: + // + long numerator_shift = 0; + long denominator_shift = 0; + const int min_z = minimum_argument_for_bernoulli_recursion(); + + if (min_z > z) + numerator_shift = 1 + ltrunc(min_z - z); + if (min_z > z + delta) + denominator_shift = 1 + ltrunc(min_z - z - delta); + // + // If the shifts are zero, then we can just combine scaled tgamma's + // and combine the remaining terms: + // + if (numerator_shift == 0 && denominator_shift == 0) + { + T scaled_tgamma_num = scaled_tgamma_no_lanczos(z, pol); + T scaled_tgamma_denom = scaled_tgamma_no_lanczos(T(z + delta), pol); + T result = scaled_tgamma_num / scaled_tgamma_denom; + result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow(T((delta + z) / constants::e()), -delta); + return result; + } + // + // We're going to have to rescale first, get the adjusted z and delta values, + // plus the ratio for the adjusted values: + // + T zz = z + numerator_shift; + T dd = delta - (numerator_shift - denominator_shift); + T ratio = tgamma_delta_ratio_imp_lanczos(zz, dd, pol, l); + // + // Use gamma recurrence relations to get back to the original + // z and z+delta: + // + for (long long i = 0; i < numerator_shift; ++i) + { + ratio /= (z + i); + if (i < denominator_shift) + ratio *= (z + delta + i); + } + for (long long i = numerator_shift; i < denominator_shift; ++i) + { + ratio *= (z + delta + i); + } + return ratio; +} + +#endif + +template +BOOST_MATH_GPU_ENABLED T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if((z <= 0) || (z + delta <= 0)) + { + // This isn't very sophisticated, or accurate, but it does work: + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return ::tgammaf(z) / ::tgammaf(z + delta); + } + else + { + return ::tgamma(z) / ::tgamma(z + delta); + } + #else + return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol); + #endif + } + + if(floor(delta) == delta) + { + if(floor(z) == z) + { + // + // Both z and delta are integers, see if we can just use table lookup + // of the factorials to get the result: + // + if((z <= max_factorial::value) && (z + delta <= max_factorial::value)) + { + return unchecked_factorial((unsigned)itrunc(z, pol) - 1) / unchecked_factorial((unsigned)itrunc(T(z + delta), pol) - 1); + } + } + if(fabs(delta) < 20) + { + // + // delta is a small integer, we can use a finite product: + // + if(delta == 0) + return 1; + if(delta < 0) + { + z -= 1; + T result = z; + while(0 != (delta += 1)) + { + z -= 1; + result *= z; + } + return result; + } + else + { + T result = 1 / z; + while(0 != (delta -= 1)) + { + z += 1; + result /= z; + } + return result; + } + } + } + typedef typename lanczos::lanczos::type lanczos_type; + return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type()); +} + +template +BOOST_MATH_GPU_ENABLED T tgamma_ratio_imp(T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if((x <= 0) || (boost::math::isinf)(x)) + return policies::raise_domain_error("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got a=%1%).", x, pol); + if((y <= 0) || (boost::math::isinf)(y)) + return policies::raise_domain_error("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got b=%1%).", y, pol); + + // We don't need to worry about the denorm case on device + // And this has the added bonus of removing recursion + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + if(x <= tools::min_value()) + { + // Special case for denorms...Ugh. + T shift = ldexp(T(1), tools::digits()); + return shift * tgamma_ratio_imp(T(x * shift), y, pol); + } + #endif + + if((x < max_factorial::value) && (y < max_factorial::value)) + { + // Rather than subtracting values, lets just call the gamma functions directly: + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return ::tgammaf(x) / ::tgammaf(y); + } + else + { + return ::tgamma(x) / ::tgamma(y); + } + #else + return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + #endif + } + T prefix = 1; + if(x < 1) + { + if(y < 2 * max_factorial::value) + { + // We need to sidestep on x as well, otherwise we'll underflow + // before we get to factor in the prefix term: + prefix /= x; + x += 1; + while(y >= max_factorial::value) + { + y -= 1; + prefix /= y; + } + + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return prefix * ::tgammaf(x) / ::tgammaf(y); + } + else + { + return prefix * ::tgamma(x) / ::tgamma(y); + } + #else + return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + #endif + } + // + // result is almost certainly going to underflow to zero, try logs just in case: + // + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return ::expf(::lgammaf(x) - ::lgammaf(y)); + } + else + { + return ::exp(::lgamma(x) - ::lgamma(y)); + } + #else + return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol)); + #endif + } + if(y < 1) + { + if(x < 2 * max_factorial::value) + { + // We need to sidestep on y as well, otherwise we'll overflow + // before we get to factor in the prefix term: + prefix *= y; + y += 1; + while(x >= max_factorial::value) + { + x -= 1; + prefix *= x; + } + + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + return prefix * ::tgammaf(x) / ::tgammaf(y); + } + else + { + return prefix * ::tgamma(x) / ::tgamma(y); + } + #else + return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + #endif + } + // + // Result will almost certainly overflow, try logs just in case: + // + BOOST_MATH_IF_CONSTEXPR(boost::math::is_same::value || boost::math::is_same::value) + { + // straight to the scene of the accident, since the result is larger than max_factorial: + return policies::raise_overflow_error("tgamma_ratio", nullptr, pol); + } + else + { + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + prefix = ::lgammaf(x) - ::lgammaf(y); + } + else + { + prefix = ::lgamma(x) - ::lgamma(y); + } + #else + prefix = boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol); + #endif + if (prefix > boost::math::tools::log_max_value()) + return policies::raise_overflow_error("tgamma_ratio", nullptr, pol); + // + // This is unreachable, unless max_factorial is small compared to the exponent + // range of the type, ie multiprecision types only here... + // + return exp(prefix); // LCOV_EXCL_LINE + } + } + // + // Regular case, x and y both large and similar in magnitude: + // + #ifdef BOOST_MATH_HAS_NVRTC + return detail::tgamma_delta_ratio_imp(x, y - x, pol); + #else + return boost::math::tgamma_delta_ratio(x, y - x, pol); + #endif +} + +template +BOOST_MATH_GPU_ENABLED T gamma_p_derivative_imp(T a, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Usual error checks first: + // + if(a <= 0) + return policies::raise_domain_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol); + if(x < 0) + return policies::raise_domain_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol); + // + // Now special cases: + // + if(x == 0) + { + return (a > 1) ? T(0) : + (a == 1) ? T(1) : policies::raise_overflow_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol); + } + // + // Normal case: + // + typedef typename lanczos::lanczos::type lanczos_type; + T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type()); + /* + * Derivative goes to zero as x -> 0, this should be unreachable: + * + if((x < 1) && (tools::max_value() * x < f1)) + { + // overflow: + return policies::raise_overflow_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol); + } + */ + if(f1 == 0) + { + // Underflow in calculation, use logs instead: + #ifdef BOOST_MATH_HAS_NVRTC + if (boost::math::is_same_v) + { + f1 = a * ::logf(x) - x - ::lgammaf(a) - ::logf(x); + } + else + { + f1 = a * ::log(x) - x - ::lgamma(a) - ::log(x); + } + #else + f1 = a * log(x) - x - lgamma(a, pol) - log(x); + #endif + f1 = exp(f1); + } + else + f1 /= x; + + return f1; +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + tgamma(T z, const Policy& /* pol */, const boost::math::true_type) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::gamma_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma(T1 a, T2 z, const Policy&, const boost::math::false_type) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), false, true, + forwarding_policy(), static_cast(nullptr)), "boost::math::tgamma<%1%>(%1%, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma(T1 a, T2 z, const boost::math::false_type& tag) +{ + return tgamma(a, z, policies::policy<>(), tag); +} + + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + lgamma(T z, int* sign, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::lgamma_imp(static_cast(z), forwarding_policy(), evaluation_type(), sign), "boost::math::lgamma<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + lgamma(T z, int* sign) +{ + return lgamma(z, sign, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + lgamma(T x, const Policy& pol) +{ + return ::boost::math::lgamma(x, nullptr, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + lgamma(T x) +{ + return ::boost::math::lgamma(x, nullptr, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + tgamma1pm1(T z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + tgamma1pm1(T z) +{ + return tgamma1pm1(z, policies::policy<>()); +} + +// +// Full upper incomplete gamma: +// +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma(T1 a, T2 z) +{ + // + // Type T2 could be a policy object, or a value, select the + // right overload based on T2: + // + using maybe_policy = typename policies::is_policy::type; + using result_type = tools::promote_args_t; + return static_cast(detail::tgamma(a, z, maybe_policy())); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma(T1 a, T2 z, const Policy& pol) +{ + using result_type = tools::promote_args_t; + return static_cast(detail::tgamma(a, z, pol, boost::math::false_type())); +} +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + tgamma(T z) +{ + return tgamma(z, policies::policy<>()); +} +// +// Full lower incomplete gamma: +// +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_lower(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), false, false, + forwarding_policy(), static_cast(nullptr)), "tgamma_lower<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_lower(T1 a, T2 z) +{ + return tgamma_lower(a, z, policies::policy<>()); +} +// +// Regularised upper incomplete gamma: +// +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_q(T1 a, T2 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), true, true, + forwarding_policy(), static_cast(nullptr)), "gamma_q<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_q(T1 a, T2 z) +{ + return gamma_q(a, z, policies::policy<>()); +} +// +// Regularised lower incomplete gamma: +// +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_p(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), true, false, + forwarding_policy(), static_cast(nullptr)), "gamma_p<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_p(T1 a, T2 z) +{ + return gamma_p(a, z, policies::policy<>()); +} + +// ratios of gamma functions: +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::tgamma_delta_ratio_imp(static_cast(z), static_cast(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_delta_ratio(T1 z, T2 delta) +{ + return tgamma_delta_ratio(z, delta, policies::policy<>()); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_ratio(T1 a, T2 b, const Policy&) +{ + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::tgamma_ratio_imp(static_cast(a), static_cast(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + tgamma_ratio(T1 a, T2 b) +{ + return tgamma_ratio(a, b, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_p_derivative(T1 a, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef tools::promote_args_t result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::gamma_p_derivative_imp(static_cast(a), static_cast(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)"); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t + gamma_p_derivative(T1 a, T2 x) +{ + return gamma_p_derivative(a, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#include +#include +#include + +#endif // BOOST_MATH_SF_GAMMA_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/gegenbauer.hpp b/third-party/boost-math/include/boost/math/special_functions/gegenbauer.hpp new file mode 100644 index 0000000000000..70324cf6562df --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/gegenbauer.hpp @@ -0,0 +1,84 @@ +// (C) Copyright Nick Thompson 2019. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_GEGENBAUER_HPP +#define BOOST_MATH_SPECIAL_GEGENBAUER_HPP + +#include +#include +#include + +#ifndef BOOST_MATH_NO_EXCEPTIONS +#include +#endif + +namespace boost { namespace math { + +template +BOOST_MATH_GPU_ENABLED Real gegenbauer(unsigned n, Real lambda, Real x) +{ + static_assert(!boost::math::is_integral::value, "Gegenbauer polynomials required floating point arguments."); + if (lambda <= -1/Real(2)) { +#ifndef BOOST_MATH_NO_EXCEPTIONS + throw std::domain_error("lambda > -1/2 is required."); +#else + return boost::math::numeric_limits::quiet_NaN(); +#endif + } + // The only reason to do this is because of some instability that could be present for x < 0 that is not present for x > 0. + // I haven't observed this, but then again, I haven't managed to test an exhaustive number of parameters. + // In any case, the routine is distinctly faster without this test: + //if (x < 0) { + // if (n&1) { + // return -gegenbauer(n, lambda, -x); + // } + // return gegenbauer(n, lambda, -x); + //} + + if (n == 0) { + return Real(1); + } + Real y0 = 1; + Real y1 = 2*lambda*x; + + Real yk = y1; + Real k = 2; + Real k_max = n*(1+boost::math::numeric_limits::epsilon()); + Real gamma = 2*(lambda - 1); + while(k < k_max) + { + yk = ( (2 + gamma/k)*x*y1 - (1+gamma/k)*y0); + y0 = y1; + y1 = yk; + k += 1; + } + return yk; +} + + +template +BOOST_MATH_GPU_ENABLED Real gegenbauer_derivative(unsigned n, Real lambda, Real x, unsigned k) +{ + if (k > n) { + return Real(0); + } + Real gegen = gegenbauer(n-k, lambda + k, x); + Real scale = 1; + for (unsigned j = 0; j < k; ++j) { + scale *= 2*lambda; + lambda += 1; + } + return scale*gegen; +} + +template +BOOST_MATH_GPU_ENABLED Real gegenbauer_prime(unsigned n, Real lambda, Real x) { + return gegenbauer_derivative(n, lambda, x, 1); +} + + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/hankel.hpp b/third-party/boost-math/include/boost/math/special_functions/hankel.hpp new file mode 100644 index 0000000000000..730c7afa03c72 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hankel.hpp @@ -0,0 +1,186 @@ +// Copyright John Maddock 2012. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_HANKEL_HPP +#define BOOST_MATH_HANKEL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED boost::math::complex hankel_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"; + + if(x < 0) + { + bool isint_v = floor(v) == v; + T j, y; + bessel_jy(v, -x, &j, &y, need_j | need_y, pol); + boost::math::complex cx(x), cv(v); + boost::math::complex j_result, y_result; + if(isint_v) + { + int s = (iround(v) & 1) ? -1 : 1; + j_result = j * s; + y_result = T(s) * (y - (2 / constants::pi()) * (log(-x) - log(cx)) * j); + } + else + { + j_result = pow(cx, v) * pow(-cx, -v) * j; + T p1 = pow(-x, v); + boost::math::complex p2 = pow(cx, v); + y_result = p1 * y / p2 + + (p2 / p1 - p1 / p2) * j / tan(constants::pi() * v); + } + // multiply y_result by i: + y_result = boost::math::complex(-sign * y_result.imag(), sign * y_result.real()); + return j_result + y_result; + } + + if(x == 0) + { + if(v == 0) + { + // J is 1, Y is -INF + return boost::math::complex(1, sign * -policies::raise_overflow_error(function, nullptr, pol)); + } + else + { + // At least one of J and Y is complex infinity: + return boost::math::complex(policies::raise_overflow_error(function, nullptr, pol), sign * policies::raise_overflow_error(function, nullptr, pol)); + } + } + + T j, y; + bessel_jy(v, x, &j, &y, need_j | need_y, pol); + return boost::math::complex(j, sign * y); +} + +template +BOOST_MATH_GPU_ENABLED boost::math::complex hankel_imp(int v, T x, const bessel_int_tag&, const Policy& pol, int sign); + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex hankel_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING // ADL of std names. + int ival = detail::iconv(v, pol); + if(0 == v - ival) + { + return hankel_imp(ival, x, bessel_int_tag(), pol, sign); + } + return hankel_imp(v, x, bessel_no_int_tag(), pol, sign); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex hankel_imp(int v, T x, const bessel_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + if((abs(v) < 200) && (x > 0)) + return boost::math::complex(bessel_jn(v, x, pol), sign * bessel_yn(v, x, pol)); + return hankel_imp(static_cast(v), x, bessel_no_int_tag(), pol, sign); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex sph_hankel_imp(T v, T x, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + return constants::root_half_pi() * hankel_imp(v + 0.5f, x, bessel_no_int_tag(), pol, sign) / sqrt(boost::math::complex(x)); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> cyl_hankel_1(T1 v, T2 x, const Policy& pol) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast, Policy>(detail::hankel_imp(v, static_cast(x), tag_type(), pol, 1), "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex >::result_type> cyl_hankel_1(T1 v, T2 x) +{ + return cyl_hankel_1(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> cyl_hankel_2(T1 v, T2 x, const Policy& pol) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast, Policy>(detail::hankel_imp(v, static_cast(x), tag_type(), pol, -1), "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex >::result_type> cyl_hankel_2(T1 v, T2 x) +{ + return cyl_hankel_2(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> sph_hankel_1(T1 v, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast, Policy>(detail::sph_hankel_imp(static_cast(v), static_cast(x), forwarding_policy(), 1), "boost::math::sph_hankel_1<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex >::result_type> sph_hankel_1(T1 v, T2 x) +{ + return sph_hankel_1(v, x, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> sph_hankel_2(T1 v, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast, Policy>(detail::sph_hankel_imp(static_cast(v), static_cast(x), forwarding_policy(), -1), "boost::math::sph_hankel_1<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::complex >::result_type> sph_hankel_2(T1 v, T2 x) +{ + return sph_hankel_2(v, x, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_HANKEL_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/hermite.hpp b/third-party/boost-math/include/boost/math/special_functions/hermite.hpp new file mode 100644 index 0000000000000..3d77fc03e39af --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hermite.hpp @@ -0,0 +1,79 @@ + +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SPECIAL_HERMITE_HPP +#define BOOST_MATH_SPECIAL_HERMITE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for Hermite polynomials: +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1) +{ + using promoted_type = tools::promote_args_t; + return (2 * promoted_type(x) * promoted_type(Hn) - 2 * n * promoted_type(Hnm1)); +} + +namespace detail{ + +// Implement Hermite polynomials via recurrence: +template +BOOST_MATH_GPU_ENABLED T hermite_imp(unsigned n, T x) +{ + T p0 = 1; + T p1 = 2 * x; + + if(n == 0) + return p0; + + unsigned c = 1; + + while(c < n) + { + BOOST_MATH_GPU_SAFE_SWAP(p0, p1); + p1 = static_cast(hermite_next(c, x, p0, p1)); + ++c; + } + return p1; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + hermite(unsigned n, T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::hermite_imp(n, static_cast(x)), "boost::math::hermite<%1%>(unsigned, %1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + hermite(unsigned n, T x) +{ + return boost::math::hermite(n, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_HERMITE_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/heuman_lambda.hpp b/third-party/boost-math/include/boost/math/special_functions/heuman_lambda.hpp new file mode 100644 index 0000000000000..05002725f2ba2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/heuman_lambda.hpp @@ -0,0 +1,97 @@ +// Copyright (c) 2015 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_ELLINT_HL_HPP +#define BOOST_MATH_ELLINT_HL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integral the Jacobi Zeta function. + +namespace boost { namespace math { + +namespace detail{ + +// Elliptic integral - Jacobi Zeta +template +BOOST_MATH_GPU_ENABLED T heuman_lambda_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + constexpr auto function = "boost::math::heuman_lambda<%1%>(%1%, %1%)"; + + if(fabs(k) > 1) + return policies::raise_domain_error(function, "We require |k| <= 1 but got k = %1%", k, pol); + + T result; + T sinp = sin(phi); + T cosp = cos(phi); + T s2 = sinp * sinp; + T k2 = k * k; + T kp = 1 - k2; + T delta = sqrt(1 - (kp * s2)); + if(fabs(phi) <= constants::half_pi()) + { + result = kp * sinp * cosp / (delta * constants::half_pi()); + result *= ellint_rf_imp(T(0), kp, T(1), pol) + k2 * ellint_rj(T(0), kp, T(1), T(1 - k2 / (delta * delta)), pol) / (3 * delta * delta); + } + else + { + typedef boost::math::integral_constant::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 54) ? 0 : + boost::math::is_floating_point::value && boost::math::numeric_limits::digits && (boost::math::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + + T rkp = sqrt(kp); + T ratio; + if(rkp == 1) + { + return policies::raise_domain_error(function, "When 1-k^2 == 1 then phi must be < Pi/2, but got phi = %1%", phi, pol); + } + else + { + ratio = ellint_f_imp(phi, rkp, pol, k2) / ellint_k_imp(rkp, pol, k2); + } + result = ratio + ellint_k_imp(k, pol, precision_tag_type()) * jacobi_zeta_imp(phi, rkp, pol, k2) / constants::half_pi(); + } + return result; +} + +} // detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type heuman_lambda(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::heuman_lambda_imp(static_cast(phi), static_cast(k), pol), "boost::math::heuman_lambda<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type heuman_lambda(T1 k, T2 phi) +{ + return boost::math::heuman_lambda(k, phi, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/hypergeometric_0F1.hpp b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_0F1.hpp new file mode 100644 index 0000000000000..a721e7e462e95 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_0F1.hpp @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) + +#ifndef BOOST_MATH_HYPERGEOMETRIC_0F1_HPP +#define BOOST_MATH_HYPERGEOMETRIC_0F1_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + + template + struct hypergeometric_0F1_cf + { + // + // We start this continued fraction at b on index -1 + // and treat the -1 and 0 cases as special cases. + // We do this to avoid adding the continued fraction result + // to 1 so that we can accurately evaluate for small results + // as well as large ones. See http://functions.wolfram.com/07.17.10.0002.01 + // + T b, z; + int k; + hypergeometric_0F1_cf(T b_, T z_) : b(b_), z(z_), k(-2) {} + typedef std::pair result_type; + + result_type operator()() + { + ++k; + if (k <= 0) + return std::make_pair(z / b, 1); + return std::make_pair(-z / ((k + 1) * (b + k)), 1 + z / ((k + 1) * (b + k))); + } + }; + + template + T hypergeometric_0F1_cf_imp(T b, T z, const Policy& pol, const char* function) + { + hypergeometric_0F1_cf evaluator(b, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T cf = tools::continued_fraction_b(evaluator, policies::get_epsilon(), max_iter); + policies::check_series_iterations(function, max_iter, pol); + return cf; + } + + + template + inline T hypergeometric_0F1_imp(const T& b, const T& z, const Policy& pol) + { + const char* function = "boost::math::hypergeometric_0f1<%1%,%1%>(%1%, %1%)"; + BOOST_MATH_STD_USING + + // some special cases + if (z == 0) + return T(1); + + if ((b <= 0) && (b == floor(b))) + return policies::raise_pole_error(function, "Evaluation of 0f1 with nonpositive integer b = %1%.", b, pol); + + if (z < -5 && b > -5) + { + // Series is alternating and divergent, need to do something else here, + // Bessel function relation is much more accurate, unless |b| is similarly + // large to |z|, otherwise the CF formula suffers from cancellation when + // the result would be very small. + if (fabs(z / b) > 4) + return hypergeometric_0F1_bessel(b, z, pol); + return hypergeometric_0F1_cf_imp(b, z, pol, function); + } + // evaluation through Taylor series looks + // more precisious than Bessel relation: + // detail::hypergeometric_0f1_bessel(b, z, pol); + return detail::hypergeometric_0F1_generic_series(b, z, pol); + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_0F1_imp( + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_0F1<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z) +{ + return hypergeometric_0F1(b, z, policies::policy<>()); +} + + +} } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F0.hpp b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F0.hpp new file mode 100644 index 0000000000000..3fbf81ba8d79c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F0.hpp @@ -0,0 +1,69 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) + +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F0_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F0_HPP + +#include +#include +#include + + +namespace boost { namespace math { namespace detail { + +template +inline T hypergeometric_1F0_imp(const T& a, const T& z, const Policy& pol) +{ + static const char* function = "boost::math::hypergeometric_1F0<%1%,%1%>(%1%, %1%)"; + BOOST_MATH_STD_USING // pow + + if (z == 1) + return policies::raise_pole_error(function, "Evaluation of 1F0 with z = %1%.", z, pol); + if (1 - z < 0) + { + if (floor(a) != a) + return policies::raise_domain_error(function, "Result is complex when a is non-integral and z > 1, but got z = %1%", z, pol); + } + // more naive and convergent method than series + return pow(T(1 - z), T(-a)); +} + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F0_imp( + static_cast(a), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F0<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z) +{ + return hypergeometric_1F0(a, z, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F0_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F1.hpp b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F1.hpp new file mode 100644 index 0000000000000..21e25670c82a2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_1F1.hpp @@ -0,0 +1,822 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) + +#ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + // check when 1F1 series can't decay to polynom + template + inline bool check_hypergeometric_1F1_parameters(const T& a, const T& b) + { + BOOST_MATH_STD_USING + + if ((b <= 0) && (b == floor(b))) + { + if ((a >= 0) || (a < b) || (a != floor(a))) + return false; + } + + return true; + } + + template + T hypergeometric_1F1_divergent_fallback(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + const char* function = "hypergeometric_1F1_divergent_fallback<%1%>(%1%,%1%,%1%)"; + // + // We get here if either: + // 1) We decide up front that Tricomi's method won't work, or: + // 2) We've called Tricomi's method and it's failed. + // + if (b > 0) + { + // Commented out since recurrence seems to always be better? +#if 0 + if ((z < b) && (a > -50)) + // Might as well use a recurrence in preference to z-recurrence: + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + int k = 1 + itrunc(z - z_limit); + // If k is too large we destroy all the digits in the result: + T convergence_at_50 = (b - a + 50) * k / (z * 50); + if ((k > 0) && (k < 50) && (fabs(convergence_at_50) < 1) && (z > z_limit)) + { + return boost::math::detail::hypergeometric_1f1_recurrence_on_z_minus_zero(a, b, T(z - k), k, pol, log_scaling); + } +#endif + if (z < b) + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + else + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + } + else // b < 0 + { + if (a < 0) + { + if ((b < a) && (z < -b / 4)) + // Defensive programming: it is *almost* certain that we can never get here, proving that is hard though... + return hypergeometric_1F1_from_function_ratio_negative_ab(a, b, z, pol, log_scaling); // LCOV_EXCL_LINE + else + { + // + // Solve (a+n)z/((b+n)n) == 1 for n, the number of iterations till the series starts to converge. + // If this is well away from the origin then it's probably better to use the series to evaluate this. + // Note that if sqr is negative then we have no solution, so assign an arbitrarily large value to the + // number of iterations. + // + bool can_use_recursion = (z - b + 100 < boost::math::policies::get_max_series_iterations()) && (100 - a < boost::math::policies::get_max_series_iterations()); + T sqr = 4 * a * z + b * b - 2 * b * z + z * z; + T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a - b); + if(can_use_recursion && ((std::max)(a, b) + iterations_to_convergence > -300)) + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + // + // When a < b and if we fall through to the series, then we get divergent behaviour when b crosses the origin + // so ideally we would pick another method. Otherwise the terms immediately after b crosses the origin may + // suffer catastrophic cancellation.... + // + if((a < b) && can_use_recursion) + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + } + } + else + { + // + // Start by getting the domain of the recurrence relations, we get either: + // -1 Backwards recursion is stable and the CF will converge to double precision. + // +1 Forwards recursion is stable and the CF will converge to double precision. + // 0 No man's land, we're not far enough away from the crossover point to get double precision from either CF. + // + // At higher than double precision we need to be further away from the crossover location to + // get full converge, but it's not clear how much further - indeed at quad precision it's + // basically impossible to ever get forwards iteration to work. Backwards seems to work + // OK as long as a > 1 whatever the precision though. + // + int domain = hypergeometric_1F1_negative_b_recurrence_region(a, b, z); + if ((domain < 0) && ((a > 1) || (boost::math::policies::digits() <= 64))) + return hypergeometric_1F1_from_function_ratio_negative_b(a, b, z, pol, log_scaling); + else if (domain > 0) + { + if (boost::math::policies::digits() <= 64) + return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling); + // LCOV_EXCL_START, what follows is multiprecision only +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const evaluation_error&) + { + // + // The series failed, try the recursions instead and hope we get at least double precision: + // + return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling); + } +#endif + // LCOV_EXCL_STOP + } + // + // We could fall back to Tricomi's approximation if we're in the transition zone + // between the above two regions. However, I've been unable to find any examples + // where this is better than the series, and there are many cases where it leads to + // quite grievous errors. + /* + else if (allow_tricomi) + { + T aa = a < 1 ? T(1) : a; + if (z < fabs((2 * aa - b) / (sqrt(fabs(aa * b))))) + return hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + */ + } + } + + // If we get here, then we've run out of methods to try, use the checked series which will + // raise an error if the result is garbage: + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + +#if 0 + // Archived, not used, see comments at call site. + template + bool is_convergent_negative_z_series(const T& a, const T& b, const T& z, const T& b_minus_a) + { + BOOST_MATH_STD_USING + // + // Filter out some cases we don't want first: + // + if((b_minus_a > 0) && (b > 0)) + { + if (a < 0) + return false; + } + // + // Generic check: we have small initial divergence and are convergent after 10 terms: + // + if ((fabs(z * a / b) < 2) && (fabs(z * (a + 10) / ((b + 10) * 10)) < 1)) + { + // Double check for divergence when we cross the origin on a and b: + if (a < 0) + { + T n = 3 - floor(a); + if (fabs((a + n) * z / ((b + n) * n)) < 1) + { + if (b < 0) + { + T m = 3 - floor(b); + if (fabs((a + m) * z / ((b + m) * m)) < 1) + return true; + } + else + return true; + } + } + else if (b < 0) + { + T n = 3 - floor(b); + if (fabs((a + n) * z / ((b + n) * n)) < 1) + return true; + } + } + if ((b > 0) && (a < 0)) + { + // + // For a and z both negative, we're OK with some initial divergence as long as + // it occurs before we hit the origin, as to start with all the terms have the + // same sign. + // + // https://www.wolframalpha.com/input/?i=solve+(a%2Bn)z+%2F+((b%2Bn)n)+%3D%3D+1+for+n + // + T sqr = 4 * a * z + b * b - 2 * b * z + z * z; + T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a + b); + if (iterations_to_convergence < 0) + iterations_to_convergence = 0.5f * (sqrt(sqr) - b + z); + if (a + iterations_to_convergence < -50) + { + // Need to check for divergence when we cross the origin on a: + if (a > -1) + return true; + T n = 300 - floor(a); + if(fabs((a + n) * z / ((b + n) * n)) < 1) + return true; + } + } + return false; + } +#endif + template + inline T cyl_bessel_i_shrinkage_rate(const T& z) + { + // Approximately the ratio I_10.5(z/2) / I_9.5(z/2), this gives us an idea of how quickly + // the Bessel terms in A&S 13.6.4 are converging: + if (z < -160) + return 1; + if (z < -40) + return 0.75f; + if (z < -20) + return 0.5f; + if (z < -7) + return 0.25f; + if (z < -2) + return 0.1f; + return 0.05f; + } + + template + inline bool hypergeometric_1F1_is_13_3_6_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if(fabs(a) == 0.5) + return false; + if ((z < 0) && (fabs(10 * a / b) < 1) && (fabs(a) < 50)) + { + T shrinkage = cyl_bessel_i_shrinkage_rate(z); + // We want the first term not too divergent, and convergence by term 10: + if ((fabs((2 * a - 1) * (2 * a - b) / b) < 2) && (fabs(shrinkage * (2 * a + 9) * (2 * a - b + 10) / (10 * (b + 10))) < 0.75)) + return true; + } + return false; + } + + template + inline bool hypergeometric_1F1_need_kummer_reflection(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + // + // Check to see if we should apply Kummer's relation or not: + // + if (z > 0) + return false; + if (z < -1) + return true; + // + // When z is small and negative, things get more complex. + // More often than not we do not need apply Kummer's relation and the + // series is convergent as is, but we do need to check: + // + if (a > 0) + { + if (b > 0) + { + return fabs((a + 10) * z / (10 * (b + 10))) < 1; // Is the 10'th term convergent? + } + else + { + return true; // Likely to be divergent as b crosses the origin + } + } + else // a < 0 + { + if (b > 0) + { + return false; // Terms start off all positive and then by the time a crosses the origin we *must* be convergent. + } + else + { + return true; // Likely to be divergent as b crosses the origin, but hard to rationalise about! + } + } + } + + + template + T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + + static const char* const function = "boost::math::hypergeometric_1F1<%1%,%1%,%1%>(%1%,%1%,%1%)"; + + if ((z == 0) || (a == 0)) + return T(1); + + // undefined result: + if (!detail::check_hypergeometric_1F1_parameters(a, b)) + return policies::raise_domain_error(function, "Function is indeterminate for negative integer b = %1%.", b, pol); + + // other checks: + if (a == -1) + { + T r = 1 - (z / b); + if (fabs(r) < 0.5) + r = (b - z) / b; + return r; + } + + const T b_minus_a = b - a; + + // 0f0 a == b case; + if (b_minus_a == 0) + { + if ((a < 0) && (floor(a) == a)) + { + // Special case, use the truncated series to match what Mathematica does. + if ((a < -20) && (z > 0) && (z < 1)) + { + // https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/03/01/04/02/0002/ + return exp(z) * boost::math::gamma_q(1 - a, z, pol); + } + // https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/03/01/04/02/0003/ + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + long long scale = lltrunc(z, pol); + log_scaling += scale; + return exp(z - scale); + } + // Special case for b-a = -1, we don't use for small a as it throws the digits of a away and leads to large errors: + if ((b_minus_a == -1) && (fabs(a) > 0.5)) + { + // for negative small integer a it is reasonable to use truncated series - polynomial + if ((a < 0) && (a == ceil(a)) && (a > -50)) + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function); + + log_scaling = lltrunc(floor(z)); + T local_z = z - log_scaling; + return (b + z) * exp(local_z) / b; + } + + if ((a == 1) && (b == 2)) + return boost::math::expm1(z, pol) / z; + + if ((b - a == b) && (fabs(z / b) < policies::get_epsilon())) + return 1; + // + // Special case for A&S 13.3.6: + // + if (z < 0) + { + if (hypergeometric_1F1_is_13_3_6_region(a, b, z)) + { + // a is tiny compared to b, and z < 0 + // 13.3.6 appears to be the most efficient and often the most accurate method. + T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling); + long long scale = lltrunc(z, pol); + log_scaling += scale; + return r * exp(z - scale); + } + if ((b < 0) && (fabs(a) < 1e-2)) + { + // + // This is a tricky area, potentially we have no good method at all: + // + if (b - ceil(b) == a) + { + // Fractional parts of a and b are genuinely equal, we might as well + // apply Kummer's relation and get a truncated series: + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_imp(b_minus_a, b, -z, pol, log_scaling); + log_scaling += scaling; + return r; + } + if ((b < -1) && (max_b_for_1F1_small_a_negative_b_by_ratio(z) < b)) + return hypergeometric_1F1_small_a_negative_b_by_ratio(a, b, z, pol, log_scaling); + if ((b > -1) && (b < -0.5f)) + { + // Recursion is meta-stable: + T first = hypergeometric_1F1_imp(a, T(b + 2), z, pol); + T second = hypergeometric_1F1_imp(a, T(b + 1), z, pol); + return tools::apply_recurrence_relation_backward(hypergeometric_1F1_recurrence_small_b_coefficients(a, b, z, 1), 1, first, second); + } + // + // We've got nothing left but 13.3.6, even though it may be initially divergent: + // + T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling); + long long scale = lltrunc(z, pol); + log_scaling += scale; + return r * exp(z - scale); + } + } + // + // Asymptotic expansion for large z + // TODO: check region for higher precision types. + // Use recurrence relations to move to this region when a and b are also large. + // + if (detail::hypergeometric_1F1_asym_region(a, b, z, pol)) + { + long long saved_scale = log_scaling; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + return hypergeometric_1F1_asym_large_z_series(a, b, z, pol, log_scaling); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const evaluation_error&) + { + } +#endif + // + // Very occasionally our convergence criteria don't quite go to full precision + // and we have to try another method: + // + log_scaling = saved_scale; + } + + if ((fabs(a * z / b) < 3.5) && (fabs(z * 100) < fabs(b)) && ((fabs(a) > 1e-2) || (b < -5))) + return detail::hypergeometric_1F1_rational(a, b, z, pol); + + if (hypergeometric_1F1_need_kummer_reflection(a, b, z)) + { + if (a == 1) + return detail::hypergeometric_1F1_pade(b, z, pol); +#if 0 + // + // Commented out: is_convergent_negative_z_series is fine so far as it goes + // but there appear to be no cases that use it, and in extremis, we will + // fall through to the series evaluation anyway. + // + if (is_convergent_negative_z_series(a, b, z, b_minus_a)) + { + if ((boost::math::sign(b_minus_a) == boost::math::sign(b)) && ((b > 0) || (b < -200))) + { + // Series is close enough to convergent that we should be OK, + // In this domain b - a ~ b and since 1F1[a, a, z] = e^z 1F1[b-a, b, -z] + // and 1F1[a, a, -z] = e^-z the result must necessarily be somewhere near unity. + // We have to rule out b small and negative because if b crosses the origin early + // in the series (before we're pretty much converged) then all bets are off. + // Note that this can go badly wrong when b and z are both large and negative, + // in that situation the series goes in waves of large and small values which + // may or may not cancel out. Likewise the initial part of the series may or may + // not converge, and even if it does may or may not give a correct answer! + // For example 1F1[-small, -1252.5, -1043.7] can loose up to ~800 digits due to + // cancellation and is basically incalculable via this method. + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + } +#endif + if ((b < 0) && (floor(b) == b)) + { + // Negative integer b, so a must be a negative integer too. + // Kummer's transformation fails here! + if(a > -50) + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function); + // Is there anything better than this?? + return hypergeometric_1F1_imp(a, float_next(b), z, pol, log_scaling); + } + else + { + // Let's otherwise make z positive (almost always) + // by Kummer's transformation + // (we also don't transform if z belongs to [-1,0]) + // Also note that Kummer's transformation fails when b is + // a negative integer, although this seems to be unmentioned + // in the literature... + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_imp(b_minus_a, b, -z, pol, log_scaling); + log_scaling += scaling; + return r; + } + } + // + // Check for initial divergence: + // + bool series_is_divergent = (a + 1) * z / (b + 1) < -1; + if (series_is_divergent && (a < 0) && (b < 0) && (a > -1)) + series_is_divergent = false; // Best off taking the series in this situation + // + // If series starts off non-divergent, and becomes divergent later + // then it's because both a and b are negative, so check for later + // divergence as well: + // + if (!series_is_divergent && (a < 0) && (b < 0) && (b > a)) + { + // + // We need to exclude situations where we're over the initial "hump" + // in the series terms (ie series has already converged by the time + // b crosses the origin: + // + //T fa = fabs(a); + //T fb = fabs(b); + T convergence_point = sqrt((a - 1) * (a - b)) - a; + if (-b < convergence_point) + { + T n = -floor(b); + series_is_divergent = (a + n) * z / ((b + n) * n) < -1; + } + } + else if (!series_is_divergent && (b < 0) && (a > 0)) + { + // Series almost always become divergent as b crosses the origin: + series_is_divergent = true; + } + if (series_is_divergent && (b < -1) && (b > -5) && (a > b)) + series_is_divergent = false; // don't bother with divergence, series will be OK + + // + // Test for alternating series due to negative a, + // in particular, see if the series is initially divergent + // If so use the recurrence relation on a: + // + if (series_is_divergent) + { + if((a < 0) && (floor(a) == a) && (-a < policies::get_max_series_iterations())) + // This works amazingly well for negative integer a: + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + // + // In what follows we have to set limits on how large z can be otherwise + // the Bessel series become large and divergent and all the digits cancel out. + // The criteria are distinctly empiracle rather than based on a firm analysis + // of the terms in the series. + // + if (b > 0) + { + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + if ((z < z_limit) && hypergeometric_1F1_is_tricomi_viable_positive_b(a, b, z)) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + else // b < 0 + { + if (a < 0) + { + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + // + // I hate these hard limits, but they're about the best we can do to try and avoid + // Bessel function internal failures: these will be caught and handled + // but up the expense of this function call: + // + if (((z < z_limit) || (a > -500)) && ((b > -500) || (b - 2 * a > 0)) && (z < -a)) + { + // + // Outside this domain we will probably get better accuracy from the recursive methods. + // + if(!(((a < b) && (z > -b)) || (z > z_limit))) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + // + // When b and z are both very small, we get large errors from the recurrence methods + // in the fallbacks. Tricomi seems to work well here, as does direct series evaluation + // at least some of the time. Picking the right method is not easy, and sometimes this + // is much worse than the fallback. Overall though, it's a reasonable choice that keeps + // the very worst errors under control. + // + if(b > -1) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + } + // + // We previously used Tricomi here, but it appears to be worse than + // the recurrence-based algorithms in hypergeometric_1F1_divergent_fallback. + /* + else + { + T aa = a < 1 ? T(1) : a; + if (z < fabs((2 * aa - b) / (sqrt(fabs(aa * b))))) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + }*/ + } + + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scaling); + } + + if (hypergeometric_1F1_is_13_3_6_region(b_minus_a, b, T(-z))) + { + // b_minus_a is tiny compared to b, and -z < 0 + // 13.3.6 appears to be the most efficient and often the most accurate method. + return boost::math::detail::hypergeometric_1F1_AS_13_3_6(a, b, z, b_minus_a, pol, log_scaling); + } +#if 0 + if ((a > 0) && (b > 0) && (a * z / b > 2)) + { + // + // Series is initially divergent and slow to converge, see if applying + // Kummer's relation can improve things: + // + if (is_convergent_negative_z_series(b_minus_a, b, T(-z), b_minus_a)) + { + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_checked_series_impl(b_minus_a, b, T(-z), pol, log_scaling); + log_scaling += scaling; + return r; + } + + } +#endif + if ((a > 0) && (b > 0) && (a * z > 50)) + return detail::hypergeometric_1F1_large_abz(a, b, z, pol, log_scaling); + + if (b < 0) + return detail::hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function); + } + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + // + // Actual result will be result * e^log_scaling. + // + static const thread_local long long max_scaling = lltrunc(boost::math::tools::log_max_value()) - 2; + static const thread_local T max_scale_factor = exp(T(max_scaling)); + + while (log_scaling > max_scaling) + { + result *= max_scale_factor; + log_scaling -= max_scaling; + } + while (log_scaling < -max_scaling) + { + result /= max_scale_factor; + log_scaling += max_scaling; + } + if (log_scaling) + result *= exp(T(log_scaling)); + return result; + } + + template + inline T log_hypergeometric_1F1_imp(const T& a, const T& b, const T& z, int* sign, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + if (sign) + *sign = result < 0 ? -1 : 1; + result = log(fabs(result)) + log_scaling; + return result; + } + + template + inline T hypergeometric_1F1_regularized_imp(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + // + // Actual result will be result * e^log_scaling / tgamma(b). + // + int result_sign = 1; + T scale = log_scaling - boost::math::lgamma(b, &result_sign, pol); + + static const thread_local T max_scaling = boost::math::tools::log_max_value() - 2; + static const thread_local T max_scale_factor = exp(max_scaling); + + while (scale > max_scaling) + { + if((fabs(result) > 1) && (fabs(tools::max_value()) / result <= max_scale_factor)) + return policies::raise_overflow_error("hypergeometric_1F1_regularized", nullptr, pol); + // This is *probably* unreachable: + // LCOV_EXCL_START + result *= max_scale_factor; + scale -= max_scaling; + // LCOV_EXCL_STOP + } + while (scale < -max_scaling) + { + result /= max_scale_factor; + scale += max_scaling; + } + if (scale != 0) + { + scale = exp(scale); + if ((scale > 1) && (fabs(result) > 1) && (fabs(tools::max_value() / result) <= scale)) + return policies::raise_overflow_error("hypergeometric_1F1_regularized", nullptr, pol); + result *= scale; + } + return result * result_sign; + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z) +{ + return hypergeometric_1F1(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F1_regularized_imp( + static_cast(a), + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z) +{ + return hypergeometric_1F1_regularized(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::log_hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + 0, + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z) +{ + return log_hypergeometric_1F1(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::log_hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + sign, + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign) +{ + return log_hypergeometric_1F1(a, b, z, sign, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/hypergeometric_2F0.hpp b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_2F0.hpp new file mode 100644 index 0000000000000..d22e6a029d8f8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_2F0.hpp @@ -0,0 +1,163 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// 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) + +#ifndef BOOST_MATH_HYPERGEOMETRIC_2F0_HPP +#define BOOST_MATH_HYPERGEOMETRIC_2F0_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + template + struct hypergeometric_2F0_cf + { + // + // We start this continued fraction at b on index -1 + // and treat the -1 and 0 cases as special cases. + // We do this to avoid adding the continued fraction result + // to 1 so that we can accurately evaluate for small results + // as well as large ones. See http://functions.wolfram.com/07.31.10.0002.01 + // + T a1, a2, z; + int k; + hypergeometric_2F0_cf(T a1_, T a2_, T z_) : a1(a1_), a2(a2_), z(z_), k(-2) {} + typedef std::pair result_type; + + result_type operator()() + { + ++k; + if (k <= 0) + return std::make_pair(z * a1 * a2, 1); + return std::make_pair(-z * (a1 + k) * (a2 + k) / (k + 1), 1 + z * (a1 + k) * (a2 + k) / (k + 1)); + } + }; + + template + T hypergeometric_2F0_cf_imp(T a1, T a2, T z, const Policy& pol, const char* function) + { + using namespace boost::math; + hypergeometric_2F0_cf evaluator(a1, a2, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T cf = tools::continued_fraction_b(evaluator, policies::get_epsilon(), max_iter); + policies::check_series_iterations(function, max_iter, pol); + return cf; + } + + + template + inline T hypergeometric_2F0_imp(T a1, T a2, const T& z, const Policy& pol, bool asymptotic = false) + { + // + // The terms in this series go to infinity unless one of a1 and a2 is a negative integer. + // + using std::swap; + BOOST_MATH_STD_USING + + static const char* const function = "boost::math::hypergeometric_2F0<%1%,%1%,%1%>(%1%,%1%,%1%)"; + + if (z == 0) + return 1; + + bool is_a1_integer = (a1 == floor(a1)); + bool is_a2_integer = (a2 == floor(a2)); + + if (!asymptotic && !is_a1_integer && !is_a2_integer) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + if (!is_a1_integer || (a1 > 0)) + { + swap(a1, a2); + swap(is_a1_integer, is_a2_integer); + } + // + // At this point a1 must be a negative integer: + // + if(!asymptotic && (!is_a1_integer || (a1 > 0))) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + // + // Special cases first: + // + if (a1 == 0) + return 1; + if ((a1 == a2 - 0.5f) && (z < 0)) + { + // http://functions.wolfram.com/07.31.03.0083.01 + int n = static_cast(static_cast(boost::math::lltrunc(-2 * a1))); + T smz = sqrt(-z); + return static_cast(pow(2 / smz, T(-n)) * boost::math::hermite(n, 1 / smz, pol)); // Warning suppression: integer power returns at least a double + } + + if (is_a1_integer && is_a2_integer) + { + if ((a1 < 1) && (a2 <= a1)) + { + const unsigned int n = static_cast(static_cast(boost::math::lltrunc(-a1))); + const unsigned int m = static_cast(static_cast(boost::math::lltrunc(-a2 - n))); + + return (pow(z, T(n)) * boost::math::factorial(n, pol)) * + boost::math::laguerre(n, m, -(1 / z), pol); + } + else if ((a2 < 1) && (a1 <= a2)) + { + // function is symmetric for a1 and a2 + const unsigned int n = static_cast(static_cast(boost::math::lltrunc(-a2))); + const unsigned int m = static_cast(static_cast(boost::math::lltrunc(-a1 - n))); + + return (pow(z, T(n)) * boost::math::factorial(n, pol)) * + boost::math::laguerre(n, m, -(1 / z), pol); + } + } + + if ((a1 * a2 * z < 0) && (a2 < -5) && (fabs(a1 * a2 * z) > 0.5)) + { + // Series is alternating and maybe divergent at least for the first few terms + // (until a2 goes positive), try the continued fraction: + return hypergeometric_2F0_cf_imp(a1, a2, z, pol, function); + } + + return detail::hypergeometric_2F0_generic_series(a1, a2, z, pol); + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_2F0_imp( + static_cast(a1), + static_cast(a2), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_2F0<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z) +{ + return hypergeometric_2F0(a1, a2, z, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/hypergeometric_pFq.hpp b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_pFq.hpp new file mode 100644 index 0000000000000..070b852dd2f9f --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypergeometric_pFq.hpp @@ -0,0 +1,195 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// 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) + +#ifndef BOOST_MATH_HYPERGEOMETRIC_PFQ_HPP +#define BOOST_MATH_HYPERGEOMETRIC_PFQ_HPP + +#include +#include +#include +#include + +namespace boost { + namespace math { + + namespace detail { + + struct pFq_termination_exception : public std::runtime_error + { + pFq_termination_exception(const char* p) : std::runtime_error(p) {} + }; + + struct timed_iteration_terminator + { + timed_iteration_terminator(std::uintmax_t i, double t) : max_iter(i), max_time(t), start_time(std::chrono::system_clock::now()) {} + + bool operator()(std::uintmax_t iter)const + { + if (iter > max_iter) + BOOST_MATH_THROW_EXCEPTION(boost::math::detail::pFq_termination_exception("pFq exceeded maximum permitted iterations.")); + if (std::chrono::duration(std::chrono::system_clock::now() - start_time).count() > max_time) + BOOST_MATH_THROW_EXCEPTION(boost::math::detail::pFq_termination_exception("pFq exceeded maximum permitted evaluation time.")); + return false; + } + + std::uintmax_t max_iter; + double max_time; + std::chrono::system_clock::time_point start_time; + }; + + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const Seq& aj, const Seq& bj, const Real& z, Real* p_abs_error, const Policy& pol) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + + long long scale = 0; + std::pair r = boost::math::detail::hypergeometric_pFq_checked_series_impl(aj, bj, value_type(z), pol, boost::math::detail::iteration_terminator(boost::math::policies::get_max_series_iterations()), scale); + r.first *= exp(Real(scale)); + r.second *= exp(Real(scale)); + if (p_abs_error) + *p_abs_error = static_cast(r.second) * boost::math::tools::epsilon(); + return policies::checked_narrowing_cast(r.first, "boost::math::hypergeometric_pFq<%1%>(%1%,%1%,%1%)"); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const Seq& aj, const Seq& bj, const Real& z, Real* p_abs_error = 0) + { + return hypergeometric_pFq(aj, bj, z, p_abs_error, boost::math::policies::policy<>()); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, Real* p_abs_error, const Policy& pol) + { + return hypergeometric_pFq, Real, Policy>(aj, bj, z, p_abs_error, pol); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, Real* p_abs_error = nullptr) + { + return hypergeometric_pFq, Real>(aj, bj, z, p_abs_error); + } + +#ifndef BOOST_MATH_NO_EXCEPTIONS + template + struct scoped_precision + { + scoped_precision(unsigned p) + { + old_p = T::default_precision(); + T::default_precision(p); + } + ~scoped_precision() + { + T::default_precision(old_p); + } + unsigned old_p; + }; + + template + Real hypergeometric_pFq_precision(const Seq& aj, const Seq& bj, Real z, unsigned digits10, double timeout, const Policy& pol) + { + unsigned current_precision = digits10 + 5; + + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + current_precision = (std::max)(current_precision, ai->precision()); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + current_precision = (std::max)(current_precision, bi->precision()); + } + current_precision = (std::max)(current_precision, z.precision()); + + Real r, norm; + std::vector aa(aj), bb(bj); + do + { + scoped_precision p(current_precision); + for (auto ai = aa.begin(); ai != aa.end(); ++ai) + ai->precision(current_precision); + for (auto bi = bb.begin(); bi != bb.end(); ++bi) + bi->precision(current_precision); + z.precision(current_precision); + try + { + long long scale = 0; + std::pair rp = boost::math::detail::hypergeometric_pFq_checked_series_impl(aa, bb, z, pol, boost::math::detail::timed_iteration_terminator(boost::math::policies::get_max_series_iterations(), timeout), scale); + rp.first *= exp(Real(scale)); + rp.second *= exp(Real(scale)); + + r = rp.first; + norm = rp.second; + + unsigned cancellation; + try { + cancellation = itrunc(log10(abs(norm / r))); + } + catch (const boost::math::rounding_error&) + { + // Happens when r is near enough zero: + cancellation = UINT_MAX; + } + if (cancellation >= current_precision - 1) + { + current_precision *= 2; + continue; + } + unsigned precision_obtained = current_precision - 1 - cancellation; + if (precision_obtained < digits10) + { + current_precision += digits10 - precision_obtained + 5; + } + else + break; + } + catch (const boost::math::evaluation_error&) + { + current_precision *= 2; + } + catch (const detail::pFq_termination_exception& e) + { + // + // Either we have exhausted the number of series iterations, or the timeout. + // Either way we quit now. + throw boost::math::evaluation_error(e.what()); + } + } while (true); + + return r; + } + template + Real hypergeometric_pFq_precision(const Seq& aj, const Seq& bj, const Real& z, unsigned digits10, double timeout = 0.5) + { + return hypergeometric_pFq_precision(aj, bj, z, digits10, timeout, boost::math::policies::policy<>()); + } + + template + Real hypergeometric_pFq_precision(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, unsigned digits10, double timeout, const Policy& pol) + { + return hypergeometric_pFq_precision< std::initializer_list, Real>(aj, bj, z, digits10, timeout, pol); + } + template + Real hypergeometric_pFq_precision(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, unsigned digits10, double timeout = 0.5) + { + return hypergeometric_pFq_precision< std::initializer_list, Real>(aj, bj, z, digits10, timeout, boost::math::policies::policy<>()); + } +#endif + } +} // namespaces + +#endif // BOOST_MATH_BESSEL_ITERATORS_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/hypot.hpp b/third-party/boost-math/include/boost/math/special_functions/hypot.hpp new file mode 100644 index 0000000000000..f38e37e872b33 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/hypot.hpp @@ -0,0 +1,82 @@ +// (C) Copyright John Maddock 2005-2006. +// 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) + +#ifndef BOOST_MATH_HYPOT_INCLUDED +#define BOOST_MATH_HYPOT_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED T hypot_imp(T x, T y, const Policy& pol) +{ + // + // Normalize x and y, so that both are positive and x >= y: + // + BOOST_MATH_STD_USING + + x = fabs(x); + y = fabs(y); + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4127) +#endif + // special case, see C99 Annex F: + if(boost::math::numeric_limits::has_infinity + && ((x == boost::math::numeric_limits::infinity()) + || (y == boost::math::numeric_limits::infinity()))) + return policies::raise_overflow_error("boost::math::hypot<%1%>(%1%,%1%)", nullptr, pol); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + if(y > x) + BOOST_MATH_GPU_SAFE_SWAP(x, y); + + if(x * tools::epsilon() >= y) + return x; + + T rat = y / x; + return x * sqrt(1 + rat*rat); +} // template T hypot(T x, T y) + +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + hypot(T1 x, T2 y) +{ + typedef typename tools::promote_args::type result_type; + return detail::hypot_imp( + static_cast(x), static_cast(y), policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + hypot(T1 x, T2 y, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::hypot_imp( + static_cast(x), static_cast(y), pol); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HYPOT_INCLUDED + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/jacobi.hpp b/third-party/boost-math/include/boost/math/special_functions/jacobi.hpp new file mode 100644 index 0000000000000..e4703be307953 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/jacobi.hpp @@ -0,0 +1,69 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_SPECIAL_JACOBI_HPP +#define BOOST_MATH_SPECIAL_JACOBI_HPP + +#include +#include + +namespace boost { namespace math { + +template +Real jacobi(unsigned n, Real alpha, Real beta, Real x) +{ + static_assert(!std::is_integral::value, "Jacobi polynomials do not work with integer arguments."); + + if (n == 0) { + return Real(1); + } + Real y0 = 1; + Real y1 = (alpha+1) + (alpha+beta+2)*(x-1)/Real(2); + + Real yk = y1; + Real k = 2; + Real k_max = n*(1+std::numeric_limits::epsilon()); + while(k < k_max) + { + // Hoping for lots of common subexpression elimination by the compiler: + Real denom = 2*k*(k+alpha+beta)*(2*k+alpha+beta-2); + Real gamma1 = (2*k+alpha+beta-1)*( (2*k+alpha+beta)*(2*k+alpha+beta-2)*x + alpha*alpha -beta*beta); + Real gamma0 = -2*(k+alpha-1)*(k+beta-1)*(2*k+alpha+beta); + yk = (gamma1*y1 + gamma0*y0)/denom; + y0 = y1; + y1 = yk; + k += 1; + } + return yk; +} + +template +Real jacobi_derivative(unsigned n, Real alpha, Real beta, Real x, unsigned k) +{ + if (k > n) { + return Real(0); + } + Real scale = 1; + for(unsigned j = 1; j <= k; ++j) { + scale *= (alpha + beta + n + j)/2; + } + + return scale*jacobi(n-k, alpha + k, beta+k, x); +} + +template +Real jacobi_prime(unsigned n, Real alpha, Real beta, Real x) +{ + return jacobi_derivative(n, alpha, beta, x, 1); +} + +template +Real jacobi_double_prime(unsigned n, Real alpha, Real beta, Real x) +{ + return jacobi_derivative(n, alpha, beta, x, 2); +} + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/jacobi_elliptic.hpp b/third-party/boost-math/include/boost/math/special_functions/jacobi_elliptic.hpp new file mode 100644 index 0000000000000..149e9fb1cade8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/jacobi_elliptic.hpp @@ -0,0 +1,319 @@ +// Copyright John Maddock 2012. +// 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) + +#ifndef BOOST_MATH_JACOBI_ELLIPTIC_HPP +#define BOOST_MATH_JACOBI_ELLIPTIC_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +T jacobi_recurse(const T& x, const T& k, T anm1, T bnm1, unsigned N, T* pTn, const Policy& pol) +{ + BOOST_MATH_STD_USING + ++N; + T Tn; + T cn = (anm1 - bnm1) / 2; + T an = (anm1 + bnm1) / 2; + if(cn < policies::get_epsilon()) + { + Tn = ldexp(T(1), (int)N) * x * an; + } + else + Tn = jacobi_recurse(x, k, an, sqrt(anm1 * bnm1), N, 0, pol); + if(pTn) + *pTn = Tn; + return (Tn + asin((cn / an) * sin(Tn))) / 2; +} + +template +T jacobi_imp(const T& x, const T& k, T* cn, T* dn, const Policy& pol, const char* function) +{ + BOOST_MATH_STD_USING + if(k < 0) + { + return *dn = *cn = policies::raise_domain_error(function, "Modulus k must be positive but got %1%.", k, pol); + } + if(k > 1) + { + T xp = x * k; + T kp = 1 / k; + T snp, cnp, dnp; + snp = jacobi_imp(xp, kp, &cnp, &dnp, pol, function); + *cn = dnp; + *dn = cnp; + return snp * kp; + } + // + // Special cases first: + // + if(x == 0) + { + *cn = *dn = 1; + return 0; + } + if(k == 0) + { + *cn = cos(x); + *dn = 1; + return sin(x); + } + if(k == 1) + { + *cn = *dn = 1 / cosh(x); + return tanh(x); + } + // + // Asymptotic forms from A&S 16.13: + // + if(k < tools::forth_root_epsilon()) + { + T su = sin(x); + T cu = cos(x); + T m = k * k; + *dn = 1 - m * su * su / 2; + *cn = cu + m * (x - su * cu) * su / 4; + return su - m * (x - su * cu) * cu / 4; + } + /* Can't get this to work to adequate precision - disabled for now... + // + // Asymptotic forms from A&S 16.15: + // + if(k > 1 - tools::root_epsilon()) + { + T tu = tanh(x); + T su = sinh(x); + T cu = cosh(x); + T sec = 1 / cu; + T kp = 1 - k; + T m1 = 2 * kp - kp * kp; + *dn = sec + m1 * (su * cu + x) * tu * sec / 4; + *cn = sec - m1 * (su * cu - x) * tu * sec / 4; + T sn = tu; + T sn2 = m1 * (x * sec * sec - tu) / 4; + T sn3 = (72 * x * cu + 4 * (8 * x * x - 5) * su - 19 * sinh(3 * x) + sinh(5 * x)) * sec * sec * sec * m1 * m1 / 512; + return sn + sn2 - sn3; + }*/ + T T1; + T kc = 1 - k; + T k_prime = k < T(0.5) ? T(sqrt(1 - k * k)) : T(sqrt(2 * kc - kc * kc)); + T T0 = jacobi_recurse(x, k, T(1), k_prime, 0, &T1, pol); + *cn = cos(T0); + *dn = cos(T0) / cos(T1 - T0); + return sin(T0); +} + +} // namespace detail + +template +inline typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_elliptic<%1%>(%1%)"; + + value_type sn, cn, dn; + sn = detail::jacobi_imp(static_cast(theta), static_cast(k), &cn, &dn, forwarding_policy(), function); + if(pcn) + *pcn = policies::checked_narrowing_cast(cn, function); + if(pdn) + *pdn = policies::checked_narrowing_cast(dn, function); + return policies::checked_narrowing_cast(sn, function); +} + +template +inline typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn) +{ + return jacobi_elliptic(k, theta, pcn, pdn, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sn(U k, T theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), static_cast(nullptr), pol); +} + +template +inline typename tools::promote_args::type jacobi_sn(U k, T theta) +{ + return jacobi_sn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cn(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return cn; +} + +template +inline typename tools::promote_args::type jacobi_cn(T k, U theta) +{ + return jacobi_cn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_dn(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type dn; + jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return dn; +} + +template +inline typename tools::promote_args::type jacobi_dn(T k, U theta) +{ + return jacobi_dn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cd(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn, dn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, &dn, pol); + return cn / dn; +} + +template +inline typename tools::promote_args::type jacobi_cd(T k, U theta) +{ + return jacobi_cd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_dc(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn, dn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, &dn, pol); + return dn / cn; +} + +template +inline typename tools::promote_args::type jacobi_dc(T k, U theta) +{ + return jacobi_dc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_ns(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return 1 / jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), static_cast(nullptr), pol); +} + +template +inline typename tools::promote_args::type jacobi_ns(T k, U theta) +{ + return jacobi_ns(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sd(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, dn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return sn / dn; +} + +template +inline typename tools::promote_args::type jacobi_sd(T k, U theta) +{ + return jacobi_sd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_ds(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, dn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return dn / sn; +} + +template +inline typename tools::promote_args::type jacobi_ds(T k, U theta) +{ + return jacobi_ds(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_nc(T k, U theta, const Policy& pol) +{ + return 1 / jacobi_cn(k, theta, pol); +} + +template +inline typename tools::promote_args::type jacobi_nc(T k, U theta) +{ + return jacobi_nc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_nd(T k, U theta, const Policy& pol) +{ + return 1 / jacobi_dn(k, theta, pol); +} + +template +inline typename tools::promote_args::type jacobi_nd(T k, U theta) +{ + return jacobi_nd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sc(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, cn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return sn / cn; +} + +template +inline typename tools::promote_args::type jacobi_sc(T k, U theta) +{ + return jacobi_sc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cs(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, cn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return cn / sn; +} + +template +inline typename tools::promote_args::type jacobi_cs(T k, U theta) +{ + return jacobi_cs(k, theta, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_JACOBI_ELLIPTIC_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/jacobi_theta.hpp b/third-party/boost-math/include/boost/math/special_functions/jacobi_theta.hpp new file mode 100644 index 0000000000000..e3e17e7e03487 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/jacobi_theta.hpp @@ -0,0 +1,802 @@ +// Jacobi theta functions +// Copyright Evan Miller 2020 +// +// 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) +// +// Four main theta functions with various flavors of parameterization, +// floating-point policies, and bonus "minus 1" versions of functions 3 and 4 +// designed to preserve accuracy for small q. Twenty-four C++ functions are +// provided in all. +// +// The functions take a real argument z and a parameter known as q, or its close +// relative tau. +// +// The mathematical functions are best understood in terms of their Fourier +// series. Using the q parameterization, and summing from n = 0 to INF: +// +// theta_1(z,q) = 2 SUM (-1)^n * q^(n+1/2)^2 * sin((2n+1)z) +// theta_2(z,q) = 2 SUM q^(n+1/2)^2 * cos((2n+1)z) +// theta_3(z,q) = 1 + 2 SUM q^n^2 * cos(2nz) +// theta_4(z,q) = 1 + 2 SUM (-1)^n * q^n^2 * cos(2nz) +// +// Appropriately multiplied and divided, these four theta functions can be used +// to implement the famous Jacabi elliptic functions - but this is not really +// recommended, as the existing Boost implementations are likely faster and +// more accurate. More saliently, setting z = 0 on the fourth theta function +// will produce the limiting CDF of the Kolmogorov-Smirnov distribution, which +// is this particular implementation's raison d'etre. +// +// Separate C++ functions are provided for q and for tau. The main q functions are: +// +// template inline T jacobi_theta1(T z, T q); +// template inline T jacobi_theta2(T z, T q); +// template inline T jacobi_theta3(T z, T q); +// template inline T jacobi_theta4(T z, T q); +// +// The parameter q, also known as the nome, is restricted to the domain (0, 1), +// and will throw a domain error otherwise. +// +// The equivalent functions that use tau instead of q are: +// +// template inline T jacobi_theta1tau(T z, T tau); +// template inline T jacobi_theta2tau(T z, T tau); +// template inline T jacobi_theta3tau(T z, T tau); +// template inline T jacobi_theta4tau(T z, T tau); +// +// Mathematically, q and tau are related by: +// +// q = exp(i PI*Tau) +// +// However, the tau in the equation above is *not* identical to the tau in the function +// signature. Instead, `tau` is the imaginary component of tau. Mathematically, tau can +// be complex - but practically, most applications call for a purely imaginary tau. +// Rather than provide a full complex-number API, the author decided to treat the +// parameter `tau` as an imaginary number. So in computational terms, the +// relationship between `q` and `tau` is given by: +// +// q = exp(-constants::pi() * tau) +// +// The tau versions are provided for the sake of accuracy, as well as conformance +// with common notation. If your q is an exponential, you are better off using +// the tau versions, e.g. +// +// jacobi_theta1(z, exp(-a)); // rather poor accuracy +// jacobi_theta1tau(z, a / constants::pi()); // better accuracy +// +// Similarly, if you have a precise (small positive) value for the complement +// of q, you can obtain a more precise answer overall by passing the result of +// `log1p` to the tau parameter: +// +// jacobi_theta1(z, 1-q_complement); // precision lost in subtraction +// jacobi_theta1tau(z, -log1p(-q_complement) / constants::pi()); // better! +// +// A third quartet of functions are provided for improving accuracy in cases +// where q is small, specifically |q| < exp(-PI) = 0.04 (or, equivalently, tau +// greater than unity). In this domain of q values, the third and fourth theta +// functions always return values close to 1. So the following "m1" functions +// are provided, similar in spirit to `expm1`, which return one less than their +// regular counterparts: +// +// template inline T jacobi_theta3m1(T z, T q); +// template inline T jacobi_theta4m1(T z, T q); +// template inline T jacobi_theta3m1tau(T z, T tau); +// template inline T jacobi_theta4m1tau(T z, T tau); +// +// Note that "m1" versions of the first and second theta would not be useful, +// as their ranges are not confined to a neighborhood around 1 (see the Fourier +// transform representations above). +// +// Finally, the twelve functions above are each available with a third Policy +// argument, which can be used to define a custom epsilon value. These Policy +// versions bring the total number of functions provided by jacobi_theta.hpp +// to twenty-four. +// +// See: +// https://mathworld.wolfram.com/JacobiThetaFunctions.html +// https://dlmf.nist.gov/20 + +#ifndef BOOST_MATH_JACOBI_THETA_HPP +#define BOOST_MATH_JACOBI_THETA_HPP + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +// Simple functions - parameterized by q +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q); + +// Simple functions - parameterized by tau (assumed imaginary) +// q = exp(i*PI*TAU) +// tau = -log(q)/PI +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau); + +// Minus one versions for small q / large tau +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau); + +// Policied versions - parameterized by q +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy& pol); + +// Policied versions - parameterized by tau +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy& pol); + +// Policied m1 functions +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy& pol); + +// Compare the non-oscillating component of the delta to the previous delta. +// Both are assumed to be non-negative. +template +inline bool +_jacobi_theta_converged(RealType last_delta, RealType delta, RealType eps) { + return delta == 0.0 || delta < eps*last_delta; +} + +template +inline RealType +_jacobi_theta_sum(RealType tau, RealType z_n, RealType z_increment, RealType eps) { + BOOST_MATH_STD_USING + RealType delta = 0, partial_result = 0; + RealType last_delta = 0; + + do { + last_delta = delta; + delta = exp(-tau*z_n*z_n/constants::pi()); + partial_result += delta; + z_n += z_increment; + } while (!_jacobi_theta_converged(last_delta, delta, eps)); + + return partial_result; +} + +// The following _IMAGINARY theta functions assume imaginary z and are for +// internal use only. They are designed to increase accuracy and reduce the +// number of iterations required for convergence for large |q|. The z argument +// is scaled by tau, and the summations are rewritten to be double-sided +// following DLMF 20.13.4 and 20.13.5. The return values are scaled by +// exp(-tau*z^2/Pi)/sqrt(tau). +// +// These functions are triggered when tau < 1, i.e. |q| > exp(-Pi) = 0.043 +// +// Note that jacobi_theta4 uses the imaginary version of jacobi_theta2 (and +// vice-versa). jacobi_theta1 and jacobi_theta3 use the imaginary versions of +// themselves, following DLMF 20.7.30 - 20.7.33. +template +inline RealType +_IMAGINARY_jacobi_theta1tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = RealType(0); + + // n>=0 even + result -= _jacobi_theta_sum(tau, RealType(z + constants::half_pi()), constants::two_pi(), eps); + // n>0 odd + result += _jacobi_theta_sum(tau, RealType(z + constants::half_pi() + constants::pi()), constants::two_pi(), eps); + // n<0 odd + result += _jacobi_theta_sum(tau, RealType(z - constants::half_pi()), RealType (-constants::two_pi()), eps); + // n<0 even + result -= _jacobi_theta_sum(tau, RealType(z - constants::half_pi() - constants::pi()), RealType (-constants::two_pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta2tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = RealType(0); + + // n>=0 + result += _jacobi_theta_sum(tau, RealType(z + constants::half_pi()), constants::pi(), eps); + // n<0 + result += _jacobi_theta_sum(tau, RealType(z - constants::half_pi()), RealType (-constants::pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta3tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = 0; + + // n=0 + result += exp(-z*z*tau/constants::pi()); + // n>0 + result += _jacobi_theta_sum(tau, RealType(z + constants::pi()), constants::pi(), eps); + // n<0 + result += _jacobi_theta_sum(tau, RealType(z - constants::pi()), RealType(-constants::pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta4tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = 0; + + // n = 0 + result += exp(-z*z*tau/constants::pi()); + + // n > 0 odd + result -= _jacobi_theta_sum(tau, RealType(z + constants::pi()), constants::two_pi(), eps); + // n < 0 odd + result -= _jacobi_theta_sum(tau, RealType(z - constants::pi()), RealType (-constants::two_pi()), eps); + // n > 0 even + result += _jacobi_theta_sum(tau, RealType(z + constants::two_pi()), constants::two_pi(), eps); + // n < 0 even + result += _jacobi_theta_sum(tau, RealType(z - constants::two_pi()), RealType (-constants::two_pi()), eps); + + return result * sqrt(tau); +} + +// First Jacobi theta function (Parameterized by tau - assumed imaginary) +// = 2 * SUM (-1)^n * exp(i*Pi*Tau*(n+1/2)^2) * sin((2n+1)z) +template +inline RealType +jacobi_theta1tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + unsigned n = 0; + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + + if (tau <= 0.0) + return policies::raise_domain_error(function, "tau must be greater than 0 but got %1%.", tau, pol); + + if (abs(z) == 0.0) + return result; + + if (tau < 1.0) { + z = fmod(z, constants::two_pi()); + while (z > constants::pi()) { + z -= constants::two_pi(); + } + while (z < -constants::pi()) { + z += constants::two_pi(); + } + + return _IMAGINARY_jacobi_theta1tau(z, RealType(1/tau), pol); + } + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n + 0.5)*RealType(n + 0.5) ); + delta = q_n * sin(RealType(2*n+1)*z); + if (n%2) + delta = -delta; + + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// First Jacobi theta function (Parameterized by q) +// = 2 * SUM (-1)^n * q^(n+1/2)^2 * sin((2n+1)z) +template +inline RealType +jacobi_theta1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta1tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Second Jacobi theta function (Parameterized by tau - assumed imaginary) +// = 2 * SUM exp(i*Pi*Tau*(n+1/2)^2) * cos((2n+1)z) +template +inline RealType +jacobi_theta2tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + unsigned n = 0; + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + + if (tau <= 0.0) { + return policies::raise_domain_error(function, "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta4tau(z, 1/tau, pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.31 + z = fmod(z, constants::two_pi()); + while (z > constants::pi()) { + z -= constants::two_pi(); + } + while (z < -constants::pi()) { + z += constants::two_pi(); + } + + return _IMAGINARY_jacobi_theta4tau(z, RealType(1/tau), pol); + } + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n + 0.5)*RealType(n + 0.5)); + delta = q_n * cos(RealType(2*n+1)*z); + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Second Jacobi theta function, parameterized by q +// = 2 * SUM q^(n+1/2)^2 * cos((2n+1)z) +template +inline RealType +jacobi_theta2_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta2tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Third Jacobi theta function, minus one (Parameterized by tau - assumed imaginary) +// This function preserves accuracy for small values of q (i.e. |q| < exp(-Pi) = 0.043) +// For larger values of q, the minus one version usually won't help. +// = 2 * SUM exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta3m1tau_imp(RealType z, RealType tau, const Policy& pol) +{ + BOOST_MATH_STD_USING + + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + unsigned n = 1; + + if (tau < 1.0) + return jacobi_theta3tau(z, tau, pol) - RealType(1); + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n)*RealType(n)); + delta = q_n * cos(RealType(2*n)*z); + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Third Jacobi theta function, parameterized by tau +// = 1 + 2 * SUM exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta3tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + if (tau <= 0.0) { + return policies::raise_domain_error(function, "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta3tau(z, RealType(1/tau), pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.32 + z = fmod(z, constants::pi()); + while (z > constants::half_pi()) { + z -= constants::pi(); + } + while (z < -constants::half_pi()) { + z += constants::pi(); + } + return _IMAGINARY_jacobi_theta3tau(z, RealType(1/tau), pol); + } + return RealType(1) + jacobi_theta3m1tau_imp(z, tau, pol); +} + +// Third Jacobi theta function, minus one (parameterized by q) +// = 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta3m1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta3m1tau_imp(z, RealType (-log(q)/constants::pi()), pol); +} + +// Third Jacobi theta function (parameterized by q) +// = 1 + 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta3_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta3tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Fourth Jacobi theta function, minus one (Parameterized by tau) +// This function preserves accuracy for small values of q (i.e. tau > 1) +// = 2 * SUM (-1)^n exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta4m1tau_imp(RealType z, RealType tau, const Policy& pol) +{ + BOOST_MATH_STD_USING + + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + unsigned n = 1; + + if (tau < 1.0) + return jacobi_theta4tau(z, tau, pol) - RealType(1); + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n)*RealType(n)); + delta = q_n * cos(RealType(2*n)*z); + if (n%2) + delta = -delta; + + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Fourth Jacobi theta function (Parameterized by tau) +// = 1 + 2 * SUM (-1)^n exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta4tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + if (tau <= 0.0) { + return policies::raise_domain_error(function, "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta2tau(z, 1/tau, pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.33 + z = fmod(z, constants::pi()); + while (z > constants::half_pi()) { + z -= constants::pi(); + } + while (z < -constants::half_pi()) { + z += constants::pi(); + } + return _IMAGINARY_jacobi_theta2tau(z, RealType(1/tau), pol); + } + + return RealType(1) + jacobi_theta4m1tau_imp(z, tau, pol); +} + +// Fourth Jacobi theta function, minus one (Parameterized by q) +// This function preserves accuracy for small values of q +// = 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta4m1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta4m1tau_imp(z, RealType (-log(q)/constants::pi()), pol); +} + +// Fourth Jacobi theta function, parameterized by q +// = 1 + 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta4_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, "|q| must be greater than zero and less than 1, but got %1%.", q, pol); + } + return jacobi_theta4tau_imp(z, RealType(-log(q)/constants::pi()), pol, function); +} + +// Begin public API + +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta1tau_imp(static_cast(z), static_cast(tau), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau) { + return jacobi_theta1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta1<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta1_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q) { + return jacobi_theta1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta2tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta2tau_imp(static_cast(z), static_cast(tau), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau) { + return jacobi_theta2tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta2<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta2_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q) { + return jacobi_theta2(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3m1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta3m1tau_imp(static_cast(z), static_cast(tau), forwarding_policy()), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau) { + return jacobi_theta3m1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta3tau_imp(static_cast(z), static_cast(tau), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau) { + return jacobi_theta3tau(z, tau, policies::policy<>()); +} + + +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3m1<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta3m1_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q) { + return jacobi_theta3m1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta3_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q) { + return jacobi_theta3(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4m1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta4m1tau_imp(static_cast(z), static_cast(tau), forwarding_policy()), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau) { + return jacobi_theta4m1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta4tau_imp(static_cast(z), static_cast(tau), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau) { + return jacobi_theta4tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4m1<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta4m1_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q) { + return jacobi_theta4m1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4<%1%>(%1%)"; + + return policies::checked_narrowing_cast(jacobi_theta4_imp(static_cast(z), static_cast(q), forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q) { + return jacobi_theta4(z, q, policies::policy<>()); +} + +}} + +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/jacobi_zeta.hpp b/third-party/boost-math/include/boost/math/special_functions/jacobi_zeta.hpp new file mode 100644 index 0000000000000..8b6f80912d6ad --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/jacobi_zeta.hpp @@ -0,0 +1,83 @@ +// Copyright (c) 2015 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) +// + +#ifndef BOOST_MATH_ELLINT_JZ_HPP +#define BOOST_MATH_ELLINT_JZ_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integral the Jacobi Zeta function. + +namespace boost { namespace math { + +namespace detail{ + +// Elliptic integral - Jacobi Zeta +template +BOOST_MATH_GPU_ENABLED T jacobi_zeta_imp(T phi, T k, const Policy& pol, T kp) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + T sinp = sin(phi); + T cosp = cos(phi); + T c2 = cosp * cosp; + T one_minus_ks2 = kp + c2 - kp * c2; + T k2 = k * k; + if(k == 1) + result = sinp * (boost::math::sign)(cosp); // We get here by simplifying JacobiZeta[w, 1] in Mathematica, and the fact that 0 <= phi. + else + { + result = k2 * sinp * cosp * sqrt(one_minus_ks2) * ellint_rj_imp(T(0), kp, T(1), one_minus_ks2, pol) / (3 * ellint_k_imp(k, pol, kp)); + } + return invert ? T(-result) : result; +} +template +BOOST_MATH_GPU_ENABLED inline T jacobi_zeta_imp(T phi, T k, const Policy& pol) +{ + return jacobi_zeta_imp(phi, k, pol, T(1 - k * k)); +} +} // detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::jacobi_zeta_imp(static_cast(phi), static_cast(k), pol), "boost::math::jacobi_zeta<%1%>(%1%,%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi) +{ + return boost::math::jacobi_zeta(k, phi, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/laguerre.hpp b/third-party/boost-math/include/boost/math/special_functions/laguerre.hpp new file mode 100644 index 0000000000000..d747274536997 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/laguerre.hpp @@ -0,0 +1,139 @@ + +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SPECIAL_LAGUERRE_HPP +#define BOOST_MATH_SPECIAL_LAGUERRE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for Laguerre polynomials: +template +inline typename tools::promote_args::type + laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * n + 1 - result_type(x)) * result_type(Ln) - n * result_type(Lnm1)) / (n + 1); +} + +namespace detail{ + +// Implement Laguerre polynomials via recurrence: +template +T laguerre_imp(unsigned n, T x) +{ + T p0 = 1; + T p1 = 1 - x; + + if(n == 0) + return p0; + + unsigned c = 1; + + while(c < n) + { + std::swap(p0, p1); + p1 = laguerre_next(c, x, p0, p1); + ++c; + } + return p1; +} + +template +inline typename tools::promote_args::type +laguerre(unsigned n, T x, const Policy&, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::laguerre_imp(n, static_cast(x)), "boost::math::laguerre<%1%>(unsigned, %1%)"); +} + +template +inline typename tools::promote_args::type + laguerre(unsigned n, unsigned m, T x, const std::false_type&) +{ + return boost::math::laguerre(n, m, x, policies::policy<>()); +} + +} // namespace detail + +template +inline typename tools::promote_args::type + laguerre(unsigned n, T x) +{ + return laguerre(n, x, policies::policy<>()); +} + +// Recurrence for associated polynomials: +template +inline typename tools::promote_args::type + laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * n + l + 1 - result_type(x)) * result_type(Pl) - (n + l) * result_type(Plm1)) / (n+1); +} + +namespace detail{ +// Laguerre Associated Polynomial: +template +T laguerre_imp(unsigned n, unsigned m, T x, const Policy& pol) +{ + // Special cases: + if(m == 0) + return boost::math::laguerre(n, x, pol); + + T p0 = 1; + + if(n == 0) + return p0; + + T p1 = m + 1 - x; + + unsigned c = 1; + + while(c < n) + { + std::swap(p0, p1); + p1 = static_cast(laguerre_next(c, m, x, p0, p1)); + ++c; + } + return p1; +} + +} + +template +inline typename tools::promote_args::type + laguerre(unsigned n, unsigned m, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::laguerre_imp(n, m, static_cast(x), pol), "boost::math::laguerre<%1%>(unsigned, unsigned, %1%)"); +} + +template +inline typename laguerre_result::type + laguerre(unsigned n, T1 m, T2 x) +{ + typedef typename policies::is_policy::type tag_type; + return detail::laguerre(n, m, x, tag_type()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_LAGUERRE_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/lambert_w.hpp b/third-party/boost-math/include/boost/math/special_functions/lambert_w.hpp new file mode 100644 index 0000000000000..671432c6794b3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/lambert_w.hpp @@ -0,0 +1,2171 @@ +// Copyright John Maddock 2017. +// Copyright Paul A. Bristow 2016, 2017, 2018. +// Copyright Nicholas Thompson 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). + +#ifndef BOOST_MATH_SF_LAMBERT_W_HPP +#define BOOST_MATH_SF_LAMBERT_W_HPP + +#ifdef _MSC_VER +#pragma warning(disable : 4127) +#endif + +/* +Implementation of an algorithm for the Lambert W0 and W-1 real-only functions. + +This code is based in part on the algorithm by +Toshio Fukushima, +"Precise and fast computation of Lambert W-functions without transcendental function evaluations", +J.Comp.Appl.Math. 244 (2013) 77-89, +and on a C/C++ version by Darko Veberic, darko.veberic@ijs.si +based on the Fukushima algorithm and Toshio Fukushima's FORTRAN version of his algorithm. + +First derivative of Lambert_w is derived from +Princeton Companion to Applied Mathematics, 'The Lambert-W function', Section 1.3: Series and Generating Functions. + +*/ + +/* +TODO revise this list of macros. +Some macros that will show some (or much) diagnostic values if #defined. +//[boost_math_instrument_lambert_w_macros + +// #define-able macros +BOOST_MATH_INSTRUMENT_LAMBERT_W_HALLEY // Halley refinement diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_W_PRECISION // Precision. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1 // W1 branch diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_HALLEY // Halley refinement diagnostics only for W-1 branch. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY // K > 64, z > -1.0264389699511303e-26 +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP // Show results from W-1 lookup table. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER // Schroeder refinement diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS // Number of terms used for near-singularity series. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES // Show evaluation of series near branch singularity. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES +BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS // Show evaluation of series for small z. +//] [/boost_math_instrument_lambert_w_macros] +*/ + +#include +#include +#include +#include +#include +#include // for log (1 + x) +#include // For exp_minus_one == 3.67879441171442321595523770161460867e-01. +#include // for has_denorm_now +#include // powers with compile time exponent, used in arbitrary precision code. +#include // series functor. +//#include // polynomial. +#include // evaluate_polynomial. +#include // boost::math::tools::max_value(). +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +#include +#include +#include +#include + +// Needed for testing and diagnostics only. +//#include +//#include +#include // For float_distance. + +using lookup_t = double; // Type for lookup table (double or float, or even long double?) + +//#include "J:\Cpp\Misc\lambert_w_lookup_table_generator\lambert_w_lookup_table.ipp" +// #include "lambert_w_lookup_table.ipp" // Boost.Math version. +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost { +namespace math { +namespace lambert_w_detail { + +//! \brief Applies a single Halley step to make a better estimate of Lambert W. +//! \details Used the simplified formulae obtained from +//! http://www.wolframalpha.com/input/?i=%5B2(z+exp(z)-w)+d%2Fdx+(z+exp(z)-w)%5D+%2F+%5B2+(d%2Fdx+(z+exp(z)-w))%5E2+-+(z+exp(z)-w)+d%5E2%2Fdx%5E2+(z+exp(z)-w)%5D +//! [2(z exp(z)-w) d/dx (z exp(z)-w)] / [2 (d/dx (z exp(z)-w))^2 - (z exp(z)-w) d^2/dx^2 (z exp(z)-w)] + +//! \tparam T floating-point (or fixed-point) type. +//! \param w_est Lambert W estimate. +//! \param z Argument z for Lambert_w function. +//! \returns New estimate of Lambert W, hopefully improved. +//! +template +inline T lambert_w_halley_step(T w_est, const T z) +{ + BOOST_MATH_STD_USING + T e = exp(w_est); + w_est -= 2 * (w_est + 1) * (e * w_est - z) / (z * (w_est + 2) + e * (w_est * (w_est + 2) + 2)); + return w_est; +} // template lambert_w_halley_step(T w_est, T z) + +//! \brief Halley iterate to refine Lambert_w estimate, +//! taking at least one Halley_step. +//! Repeat Halley steps until the *last step* had fewer than half the digits wrong, +//! the step we've just taken should have been sufficient to have completed the iteration. + +//! \tparam T floating-point (or fixed-point) type. +//! \param z Argument z for Lambert_w function. +//! \param w_est Lambert w estimate. +template +inline T lambert_w_halley_iterate(T w_est, const T z) +{ + BOOST_MATH_STD_USING + static const T max_diff = boost::math::tools::root_epsilon() * fabs(w_est); + + T w_new = lambert_w_halley_step(w_est, z); + T diff = fabs(w_est - w_new); + while (diff > max_diff) + { + w_est = w_new; + w_new = lambert_w_halley_step(w_est, z); + diff = fabs(w_est - w_new); + } + return w_new; +} // template lambert_w_halley_iterate(T w_est, T z) + +// Two Halley function versions that either +// single step (if std::false_type) or iterate (if std::true_type). +// Selected at compile-time using parameter 3. +template +inline T lambert_w_maybe_halley_iterate(T z, T w, std::false_type const&) +{ + return lambert_w_halley_step(z, w); // Single step. +} + +template +inline T lambert_w_maybe_halley_iterate(T z, T w, std::true_type const&) +{ + return lambert_w_halley_iterate(z, w); // Iterate steps. +} + +//! maybe_reduce_to_double function, +//! Two versions that have a compile-time option to +//! reduce argument z to double precision (if true_type). +//! Version is selected at compile-time using parameter 2. + +template +inline double maybe_reduce_to_double(const T& z, const std::true_type&) +{ + return static_cast(z); // Reduce to double precision. +} + +template +inline T maybe_reduce_to_double(const T& z, const std::false_type&) +{ // Don't reduce to double. + return z; +} + +template +inline double must_reduce_to_double(const T& z, const std::true_type&) +{ + return static_cast(z); // Reduce to double precision. +} + +template +inline double must_reduce_to_double(const T& z, const std::false_type&) +{ // try a lexical_cast and hope for the best: +#ifndef BOOST_MATH_STANDALONE + + #ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION + + // Catches the C++23 floating point types + if constexpr (std::is_arithmetic_v) + { + return static_cast(z); + } + else + { + return boost::lexical_cast(z); + } + + #else + + return boost::lexical_cast(z); + + #endif + +#else + static_assert(sizeof(T) == 0, "Unsupported in standalone mode: don't know how to cast your number type to a double."); + return 0.0; +#endif +} + +//! \brief Schroeder method, fifth-order update formula, +//! \details See T. Fukushima page 80-81, and +//! A. Householder, The Numerical Treatment of a Single Nonlinear Equation, +//! McGraw-Hill, New York, 1970, section 4.4. +//! Fukushima algorithm switches to @c schroeder_update after pre-computed bisections, +//! chosen to ensure that the result will be achieve the +/- 10 epsilon target. +//! \param w Lambert w estimate from bisection or series. +//! \param y bracketing value from bisection. +//! \returns Refined estimate of Lambert w. + +// Schroeder refinement, called unless NOT required by precision policy. +template +inline T schroeder_update(const T w, const T y) +{ + // Compute derivatives using 5th order Schroeder refinement. + // Since this is the final step, it will always use the highest precision type T. + // Example of Call: + // result = schroeder_update(w, y); + //where + // w is estimate of Lambert W (from bisection or series). + // y is z * e^-w. + + BOOST_MATH_STD_USING // Aid argument dependent lookup of abs. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + using boost::math::float_distance; + T fd = float_distance(w, y); + std::cout << "Schroder "; + if (abs(fd) < 214748000.) + { + std::cout << " Distance = "<< static_cast(fd); + } + else + { + std::cout << "Difference w - y = " << (w - y) << "."; + } + std::cout << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + // Fukushima equation 18, page 6. + const T f0 = w - y; // f0 = w - y. + const T f1 = 1 + y; // f1 = df/dW + const T f00 = f0 * f0; + const T f11 = f1 * f1; + const T f0y = f0 * y; + const T result = + w - 4 * f0 * (6 * f1 * (f11 + f0y) + f00 * y) / + (f11 * (24 * f11 + 36 * f0y) + + f00 * (6 * y * y + 8 * f1 * y + f0y)); // Fukushima Page 81, equation 21 from equation 20. + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + std::cout << "Schroeder refined " << w << " " << y << ", difference " << w-y << ", change " << w - result << ", to result " << result << std::endl; + std::cout.precision(saved_precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + + return result; +} // template T schroeder_update(const T w, const T y) + + //! \brief Series expansion used near the singularity/branch point z = -exp(-1) = -3.6787944. + //! Wolfram InverseSeries[Series[sqrt[2(p Exp[1 + p] + 1)], {p,-1, 20}]] + //! Wolfram command used to obtain 40 series terms at 50 decimal digit precision was + //! N[InverseSeries[Series[Sqrt[2(p Exp[1 + p] + 1)], { p,-1,40 }]], 50] + //! -1+p-p^2/3+(11 p^3)/72-(43 p^4)/540+(769 p^5)/17280-(221 p^6)/8505+(680863 p^7)/43545600 ... + //! Decimal values of specifications for built-in floating-point types below + //! are at least 21 digits precision == max_digits10 for long double. + //! Longer decimal digits strings are rationals evaluated using Wolfram. + +template +T lambert_w_singularity_series(const T p) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES + std::size_t saved_precision = std::cout.precision(3); + std::cout << "Singularity_series Lambert_w p argument = " << p << std::endl; + std::cout + //<< "Argument Type = " << typeid(T).name() + //<< ", max_digits10 = " << std::numeric_limits::max_digits10 + //<< ", epsilon = " << std::numeric_limits::epsilon() + << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES + + static const T q[] = + { + -static_cast(1), // j0 + +T(1), // j1 + -T(1) / 3, // 1/3 j2 + +T(11) / 72, // 0.152777777777777778, // 11/72 j3 + -T(43) / 540, // 0.0796296296296296296, // 43/540 j4 + +T(769) / 17280, // 0.0445023148148148148, j5 + -T(221) / 8505, // 0.0259847148736037625, j6 + //+T(0.0156356325323339212L), // j7 + //+T(0.015635632532333921222810111699000587889476778365667L), // j7 from Wolfram N[680863/43545600, 50] + +T(680863uLL) / 43545600uLL, // +0.0156356325323339212, j7 + //-T(0.00961689202429943171L), // j8 + -T(1963uLL) / 204120uLL, // 0.00961689202429943171, j8 + //-T(0.0096168920242994317068391142465216539290613364687439L), // j8 from Wolfram N[1963/204120, 50] + +T(226287557uLL) / 37623398400uLL, // 0.00601454325295611786, j9 + -T(5776369uLL) / 1515591000uLL, // 0.00381129803489199923, j10 + //+T(0.00244087799114398267L), j11 0.0024408779911439826658968585286437530215699919795550 + +T(169709463197uLL) / 69528040243200uLL, // j11 + // -T(0.00157693034468678425L), // j12 -0.0015769303446867842539234095399314115973161850314723 + -T(1118511313uLL) / 709296588000uLL, // j12 + +T(667874164916771uLL) / 650782456676352000uLL, // j13 + //+T(0.00102626332050760715L), // j13 0.0010262633205076071544375481533906861056468041465973 + -T(500525573uLL) / 744761417400uLL, // j14 + // -T(0.000672061631156136204L), j14 + //+T(1003663334225097487uLL) / 234281684403486720000uLL, // j15 0.00044247306181462090993020760858473726479232802068800 error C2177: constant too big + //+T(0.000442473061814620910L, // j15 + BOOST_MATH_BIG_CONSTANT(T, 64, +0.000442473061814620910), // j15 + // -T(0.000292677224729627445L), // j16 + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000292677224729627445), // j16 + //+T(0.000194387276054539318L), // j17 + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000194387276054539318), // j17 + //-T(0.000129574266852748819L), // j18 + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000129574266852748819), // j18 + //+T(0.0000866503580520812717L), // j19 N[+1150497127780071399782389/13277465363600276402995200000, 50] 0.000086650358052081271660451590462390293190597827783288 + BOOST_MATH_BIG_CONSTANT(T, 64, +0.0000866503580520812717), // j19 + //-T(0.0000581136075044138168L) // j20 N[2853534237182741069/49102686267859224000000, 50] 0.000058113607504413816772205464778828177256611844221913 + // -T(2853534237182741069uLL) / 49102686267859224000000uLL // j20 // error C2177: constant too big, + // so must use BOOST_MATH_BIG_CONSTANT(T, ) format in hope of using suffix Q for quad or decimal digits string for others. + //-T(0.000058113607504413816772205464778828177256611844221913L), // j20 N[2853534237182741069/49102686267859224000000, 50] 0.000058113607504413816772205464778828177256611844221913 + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000058113607504413816772205464778828177256611844221913) // j20 - last used by Fukushima + // More terms don't seem to give any improvement (worse in fact) and are not use for many z values. + //BOOST_MATH_BIG_CONSTANT(T, +0.000039076684867439051635395583044527492132109160553593), // j21 + //BOOST_MATH_BIG_CONSTANT(T, -0.000026338064747231098738584082718649443078703982217219), // j22 + //BOOST_MATH_BIG_CONSTANT(T, +0.000017790345805079585400736282075184540383274460464169), // j23 + //BOOST_MATH_BIG_CONSTANT(T, -0.000012040352739559976942274116578992585158113153190354), // j24 + //BOOST_MATH_BIG_CONSTANT(T, +8.1635319824966121713827512573558687050675701559448E-6), // j25 + //BOOST_MATH_BIG_CONSTANT(T, -5.5442032085673591366657251660804575198155559225316E-6) // j26 + // -T(5.5442032085673591366657251660804575198155559225316E-6L) // j26 + // 21 to 26 Added for long double. + }; // static const T q[] + + /* + // Temporary copy of original double values for comparison; these are reproduced well. + static const T q[] = + { + -1L, // j0 + +1L, // j1 + -0.333333333333333333L, // 1/3 j2 + +0.152777777777777778L, // 11/72 j3 + -0.0796296296296296296L, // 43/540 + +0.0445023148148148148L, + -0.0259847148736037625L, + +0.0156356325323339212L, + -0.00961689202429943171L, + +0.00601454325295611786L, + -0.00381129803489199923L, + +0.00244087799114398267L, + -0.00157693034468678425L, + +0.00102626332050760715L, + -0.000672061631156136204L, + +0.000442473061814620910L, + -0.000292677224729627445L, + +0.000194387276054539318L, + -0.000129574266852748819L, + +0.0000866503580520812717L, + -0.0000581136075044138168L // j20 + }; + */ + + // Decide how many series terms to use, increasing as z approaches the singularity, + // balancing run-time versus computational noise from round-off. + // In practice, we truncate the series expansion at a certain order. + // If the order is too large, not only does the amount of computation increase, + // but also the round-off errors accumulate. + // See Fukushima equation 35, page 85 for logic of choice of number of series terms. + + BOOST_MATH_STD_USING // Aid argument dependent lookup (ADL) of abs. + + const T absp = abs(p); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS + { + int terms = 20; // Default to using all terms. + if (absp < 0.01159) + { // Very near singularity. + terms = 6; + } + else if (absp < 0.0766) + { // Near singularity. + terms = 10; + } + std::streamsize saved_precision = std::cout.precision(3); + std::cout << "abs(p) = " << absp << ", terms = " << terms << std::endl; + std::cout.precision(saved_precision); + } +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS + + if (absp < T(0.01159)) + { // Only 6 near-singularity series terms are useful. + return -1 + p * (1 + p * (q[2] + p * (q[3] + p * (q[4] + p * (q[5] + p * q[6]))))); + } + else if (absp < T(0.0766)) // Use 10 near-singularity series terms. + { // Use 10 near-singularity series terms. + return -1 + p * (1 + p * (q[2] + p * (q[3] + p * (q[4] + p * (q[5] + p * (q[6] + p * (q[7] + p * (q[8] + p * (q[9] + p * q[10]))))))))); + } + // Use all 20 near-singularity series terms. + return -1 + p * (1 + p * (q[2] + p * (q[3] + p * (q[4] + p * (q[5] + p * (q[6] + p * (q[7] + p * (q[8] + p * (q[9] + p * (q[10] + p * (q[11] + p * (q[12] + p * (q[13] + p * (q[14] + p * (q[15] + p * (q[16] + p * (q[17] + p * (q[18] + p * (q[19] + p * q[20] /* Last Fukushima term.*/))))))))))))))))))); + // + // more terms for more precise T: long double ... + //// but makes almost no difference, so don't use more terms? + // p*q[21] + + // p*q[22] + + // p*q[23] + + // p*q[24] + + // p*q[25] + // ))))))))))))))))))); + +} // template T lambert_w_singularity_series(const T p) + + + ///////////////////////////////////////////////////////////////////////////////////////////// + + //! \brief Series expansion used near zero (abs(z) < 0.05). + //! \details + //! Coefficients of the inverted series expansion of the Lambert W function around z = 0. + //! Tosio Fukushima always uses all 17 terms of a Taylor series computed using Wolfram with + //! InverseSeries[Series[z Exp[z],{z,0,17}]] + //! Tosio Fukushima / Journal of Computational and Applied Mathematics 244 (2013) page 86. + + //! Decimal values of specifications for built-in floating-point types below + //! are 21 digits precision == max_digits10 for long double. + //! Care! Some coefficients might overflow some fixed_point types. + + //! This version is intended to allow use by user-defined types + //! like Boost.Multiprecision quad and cpp_dec_float types. + //! The three specializations below for built-in float, double + //! (and perhaps long double) will be chosen in preference for these types. + + //! This version uses rationals computed by Wolfram as far as possible, + //! limited by maximum size of uLL integers. + //! For higher term, uses decimal digit strings computed by Wolfram up to the maximum possible using uLL rationals, + //! and then higher coefficients are computed as necessary using function lambert_w0_small_z_series_term + //! until the precision required by the policy is achieved. + //! InverseSeries[Series[z Exp[z],{z,0,34}]] also computed. + + // Series evaluation for LambertW(z) as z -> 0. + // See http://functions.wolfram.com/ElementaryFunctions/ProductLog/06/01/01/0003/ + // http://functions.wolfram.com/ElementaryFunctions/ProductLog/06/01/01/0003/MainEq1.L.gif + + //! \brief lambert_w0_small_z uses a tag_type to select a variant depending on the size of the type. + //! The Lambert W is computed by lambert_w0_small_z for small z. + //! The cutoff for z smallness determined by Tosio Fukushima by trial and error is (abs(z) < 0.05), + //! but the optimum might be a function of the size of the type of z. + + //! \details + //! The tag_type selection is based on the value @c std::numeric_limits::max_digits10. + //! This allows distinguishing between long double types that commonly vary between 64 and 80-bits, + //! and also compilers that have a float type using 64 bits and/or long double using 128-bits. + //! It assumes that max_digits10 is defined correctly or this might fail to make the correct selection. + //! causing very small differences in computing lambert_w that would be very difficult to detect and diagnose. + //! Cannot switch on @c std::numeric_limits<>::max() because comparison values may overflow the compiler limit. + //! Cannot switch on @c std::numeric_limits::max_exponent10() + //! because both 80 and 128 bit floating-point implementations use 11 bits for the exponent. + //! So must rely on @c std::numeric_limits::max_digits10. + + //! Specialization of float zero series expansion used for small z (abs(z) < 0.05). + //! Specializations of lambert_w0_small_z for built-in types. + //! These specializations should be chosen in preference to T version. + //! For example: lambert_w0_small_z(0.001F) should use the float version. + //! (Parameter Policy is not used by built-in types when all terms are used during an inline computation, + //! but for the tag_type selection to work, they all must include Policy in their signature. + + // Forward declaration of variants of lambert_w0_small_z. +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for float (32-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for double (64-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for long double (double extended 80-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for long double (128-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for float128 quadmath Q type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // Generic multiprecision T. + // Set tag_type depending on max_digits10. +template +T lambert_w0_small_z(T x, const Policy& pol) +{ //std::numeric_limits::max_digits10 == 36 ? 3 : // 128-bit long double. + using tag_type = std::integral_constant::is_specialized == 0 ? 5 : +#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS + std::numeric_limits::max_digits10 <= 9 ? 0 : // for float 32-bit. + std::numeric_limits::max_digits10 <= 17 ? 1 : // for double 64-bit. + std::numeric_limits::max_digits10 <= 22 ? 2 : // for 80-bit double extended. + std::numeric_limits::max_digits10 < 37 ? 4 // for both 128-bit long double (3) and 128-bit quad suffix Q type (4). +#else + std::numeric_limits::radix != 2 ? 5 : + std::numeric_limits::digits <= 24 ? 0 : // for float 32-bit. + std::numeric_limits::digits <= 53 ? 1 : // for double 64-bit. + std::numeric_limits::digits <= 64 ? 2 : // for 80-bit double extended. + std::numeric_limits::digits <= 113 ? 4 // for both 128-bit long double (3) and 128-bit quad suffix Q type (4). +#endif + : 5>; // All Generic multiprecision types. + // std::cout << "\ntag type = " << tag_type << std::endl; // error C2275: 'tag_type': illegal use of this type as an expression. + return lambert_w0_small_z(x, pol, tag_type()); +} // template T lambert_w0_small_z(T x) + + //! Specialization of float (32-bit) series expansion used for small z (abs(z) < 0.05). + // Only 9 Coefficients are computed to 21 decimal digits precision, ample for 32-bit float used by most platforms. + // Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction + // N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], + // as proposed by Tosio Fukushima and implemented by Darko Veberic. + +template +T lambert_w0_small_z(T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize prec = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 0 float lambert_w0_small_z called with z = " << z << " using " << 9 << " terms of precision " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1 - // j1 z^1 term = 1 + z * (1 - // j2 z^2 term = -1 + z * (static_cast(3uLL) / 2uLL - // 3/2 // j3 z^3 term = 1.5. + z * (2.6666666666666666667F - // 8/3 // j4 + z * (5.2083333333333333333F - // -125/24 // j5 + z * (10.8F - // j6 + z * (23.343055555555555556F - // j7 + z * (52.012698412698412698F - // j8 + z * 118.62522321428571429F)))))))); // j9 + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // template T lambert_w0_small_z(T x, std::integral_constant const&) + + //! Specialization of double (64-bit double) series expansion used for small z (abs(z) < 0.05). + // 17 Coefficients are computed to 21 decimal digits precision suitable for 64-bit double used by most platforms. + // Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction + // N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], as proposed by Tosio Fukushima and implemented by Veberic. + +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize prec = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 1 double lambert_w0_small_z called with z = " << z << " using " << 17 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1. - // j1 z^1 + z * (1. - // j2 z^2 + z * (1.5 - // 3/2 // j3 z^3 + z * (2.6666666666666666667 - // 8/3 // j4 + z * (5.2083333333333333333 - // -125/24 // j5 + z * (10.8 - // j6 + z * (23.343055555555555556 - // j7 + z * (52.012698412698412698 - // j8 + z * (118.62522321428571429 - // j9 + z * (275.57319223985890653 - // j10 + z * (649.78717234347442681 - // j11 + z * (1551.1605194805194805 - // j12 + z * (3741.4497029592385495 - // j13 + z * (9104.5002411580189358 - // j14 + z * (22324.308512706601434 - // j15 + z * (55103.621972903835338 - // j16 + z * 136808.86090394293563)))))))))))))))); // j17 z^17 + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) + + //! Specialization of long double (80-bit double extended) series expansion used for small z (abs(z) < 0.05). + // 21 Coefficients are computed to 21 decimal digits precision suitable for 80-bit long double used by some + // platforms including GCC and Clang when generating for Intel X86 floating-point processors with 80-bit operations enabled (the default). + // (This is NOT used by Microsoft Visual Studio where double and long always both use only 64-bit type. + // Nor used for 128-bit float128.) +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 2 long double (80-bit double extended) lambert_w0_small_z called with z = " << z << " using " << 21 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES +// T result = +// z * (1.L - // j1 z^1 +// z * (1.L - // j2 z^2 +// z * (1.5L - // 3/2 // j3 +// z * (2.6666666666666666667L - // 8/3 // j4 +// z * (5.2083333333333333333L - // -125/24 // j5 +// z * (10.800000000000000000L - // j6 +// z * (23.343055555555555556L - // j7 +// z * (52.012698412698412698L - // j8 +// z * (118.62522321428571429L - // j9 +// z * (275.57319223985890653L - // j10 +// z * (649.78717234347442681L - // j11 +// z * (1551.1605194805194805L - // j12 +// z * (3741.4497029592385495L - // j13 +// z * (9104.5002411580189358L - // j14 +// z * (22324.308512706601434L - // j15 +// z * (55103.621972903835338L - // j16 +// z * (136808.86090394293563L - // j17 z^17 last term used by Fukushima double. +// z * (341422.050665838363317L - // z^18 +// z * (855992.9659966075514633L - // z^19 +// z * (2.154990206091088289321e6L - // z^20 +// z * 5.4455529223144624316423e6L // z^21 +// )))))))))))))))))))); +// + + T result = +z * (1.L - // z j1 +z * (1.L - // z^2 +z * (1.500000000000000000000000000000000L - // z^3 +z * (2.666666666666666666666666666666666L - // z ^ 4 +z * (5.208333333333333333333333333333333L - // z ^ 5 +z * (10.80000000000000000000000000000000L - // z ^ 6 +z * (23.34305555555555555555555555555555L - // z ^ 7 +z * (52.01269841269841269841269841269841L - // z ^ 8 +z * (118.6252232142857142857142857142857L - // z ^ 9 +z * (275.5731922398589065255731922398589L - // z ^ 10 +z * (649.7871723434744268077601410934744L - // z ^ 11 +z * (1551.160519480519480519480519480519L - // z ^ 12 +z * (3741.449702959238549516327294105071L - //z ^ 13 +z * (9104.500241158018935796713574491352L - // z ^ 14 +z * (22324.308512706601434280005708577137L - // z ^ 15 +z * (55103.621972903835337697771560205422L - // z ^ 16 +z * (136808.86090394293563342215789305736L - // z ^ 17 +z * (341422.05066583836331735491399356945L - // z^18 +z * (855992.9659966075514633630250633224L - // z^19 +z * (2.154990206091088289321708745358647e6L // z^20 distance -5 without term 20 +)))))))))))))))))))); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + return result; +} // long double lambert_w0_small_z(const T z, std::integral_constant const&) + +//! Specialization of 128-bit long double series expansion used for small z (abs(z) < 0.05). +// 34 Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction +// N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], +// and are suffixed by L as they are assumed of type long double. +// (This is NOT used for 128-bit quad boost::multiprecision::float128 type which required a suffix Q +// nor multiprecision type cpp_bin_float_quad that can only be initialized at full precision of the type +// constructed with a decimal digit string like "2.6666666666666666666666666666666666666666666666667".) + +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 3 long double (128-bit) lambert_w0_small_z called with z = " << z << " using " << 17 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1.L - // j1 + z * (1.L - // j2 + z * (1.5L - // 3/2 // j3 + z * (2.6666666666666666666666666666666666L - // 8/3 // j4 + z * (5.2052083333333333333333333333333333L - // -125/24 // j5 + z * (10.800000000000000000000000000000000L - // j6 + z * (23.343055555555555555555555555555555L - // j7 + z * (52.0126984126984126984126984126984126L - // j8 + z * (118.625223214285714285714285714285714L - // j9 + z * (275.57319223985890652557319223985890L - // * z ^ 10 - // j10 + z * (649.78717234347442680776014109347442680776014109347L - // j11 + z * (1551.1605194805194805194805194805194805194805194805L - // j12 + z * (3741.4497029592385495163272941050718828496606274384L - // j13 + z * (9104.5002411580189357967135744913522691300469078247L - // j14 + z * (22324.308512706601434280005708577137148565719994291L - // j15 + z * (55103.621972903835337697771560205422639285073147507L - // j16 + z * 136808.86090394293563342215789305736395683485630576L // j17 + )))))))))))))))); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) + +//! Specialization of 128-bit quad series expansion used for small z (abs(z) < 0.05). +// 34 Taylor series coefficients used were computed by Wolfram to 50 decimal digits using instruction +// N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], +// and are suffixed by Q as they are assumed of type quad. +// This could be used for 128-bit quad (which requires a suffix Q for full precision). +// But experiments with GCC 7.2.0 show that while this gives full 128-bit precision +// when the -f-ext-numeric-literals option is in force and the libquadmath library available, +// over the range -0.049 to +0.049, +// it is slightly slower than getting a double approximation followed by a single Halley step. + +#ifdef BOOST_HAS_FLOAT128 +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 4 128-bit quad float128 lambert_w0_small_z called with z = " << z << " using " << 34 << " terms of precision, " + << std::numeric_limits::max_digits10 << " max decimal digits." << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1.Q - // z j1 + z * (1.Q - // z^2 + z * (1.500000000000000000000000000000000Q - // z^3 + z * (2.666666666666666666666666666666666Q - // z ^ 4 + z * (5.208333333333333333333333333333333Q - // z ^ 5 + z * (10.80000000000000000000000000000000Q - // z ^ 6 + z * (23.34305555555555555555555555555555Q - // z ^ 7 + z * (52.01269841269841269841269841269841Q - // z ^ 8 + z * (118.6252232142857142857142857142857Q - // z ^ 9 + z * (275.5731922398589065255731922398589Q - // z ^ 10 + z * (649.7871723434744268077601410934744Q - // z ^ 11 + z * (1551.160519480519480519480519480519Q - // z ^ 12 + z * (3741.449702959238549516327294105071Q - //z ^ 13 + z * (9104.500241158018935796713574491352Q - // z ^ 14 + z * (22324.308512706601434280005708577137Q - // z ^ 15 + z * (55103.621972903835337697771560205422Q - // z ^ 16 + z * (136808.86090394293563342215789305736Q - // z ^ 17 + z * (341422.05066583836331735491399356945Q - // z^18 + z * (855992.9659966075514633630250633224Q - // z^19 + z * (2.154990206091088289321708745358647e6Q - // 20 + z * (5.445552922314462431642316420035073e6Q - // 21 + z * (1.380733000216662949061923813184508e7Q - // 22 + z * (3.511704498513923292853869855945334e7Q - // 23 + z * (8.956800256102797693072819557780090e7Q - // 24 + z * (2.290416846187949813964782641734774e8Q - // 25 + z * (5.871035041171798492020292225245235e8Q - // 26 + z * (1.508256053857792919641317138812957e9Q - // 27 + z * (3.882630161293188940385873468413841e9Q - // 28 + z * (1.001394313665482968013913601565723e10Q - // 29 + z * (2.587356736265760638992878359024929e10Q - // 30 + z * (6.696209709358073856946120522333454e10Q - // 31 + z * (1.735711659599198077777078238043644e11Q - // 32 + z * (4.505680465642353886756098108484670e11Q - // 33 + z * (1.171223178256487391904047636564823e12Q //z^34 + )))))))))))))))))))))))))))))))))); + + + #ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) float128 + +#else + +template +inline T lambert_w0_small_z(const T z, const Policy& pol, std::integral_constant const&) // LCOV_EXCL_LINE body is covered, strangley this line is not. +{ + return lambert_w0_small_z(z, pol, std::integral_constant()); +} + +#endif // BOOST_HAS_FLOAT128 + +//! Series functor to compute series term using pow and factorial. +//! \details Functor is called after evaluating polynomial with the coefficients as rationals below. +template +struct lambert_w0_small_z_series_term +{ + using result_type = T; + //! \param _z Lambert W argument z. + //! \param -term -pow<18>(z) / 6402373705728000uLL + //! \param _k number of terms == initially 18 + + // Note *after* evaluating N terms, its internal state has k = N and term = (-1)^N z^N. + + lambert_w0_small_z_series_term(T _z, T _term, int _k) + : k(_k), z(_z), term(_term) { } + + T operator()() + { // Called by sum_series until needs precision set by factor (policy::get_epsilon). + using std::pow; + ++k; + term *= -z / k; + //T t = pow(z, k) * pow(T(k), -1 + k) / factorial(k); // (z^k * k(k-1)^k) / k! + T result = term * pow(T(k), T(-1 + k)); // term * k^(k-1) + // std::cout << " k = " << k << ", term = " << term << ", result = " << result << std::endl; + return result; // + } +private: + int k; + T z; + T term; +}; // template struct lambert_w0_small_z_series_term + + //! Generic variant for T a User-defined types like Boost.Multiprecision. +template +inline T lambert_w0_small_z(T z, const Policy& pol, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "Generic lambert_w0_small_z called with z = " << z << " using as many terms needed for precision." << std::endl; + std::cout << "Argument z is of type " << typeid(T).name() << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + // First several terms of the series are tabulated and evaluated as a polynomial: + // this will save us a bunch of expensive calls to pow. + // Then our series functor is initialized "as if" it had already reached term 18, + // enough evaluation of built-in 64-bit double and float (and 80-bit long double?) types. + + // Coefficients should be stored such that the coefficients for the x^i terms are in poly[i]. + static const T coeff[] = + { + 0, // z^0 Care: zeroth term needed by tools::evaluate_polynomial, but not in the Wolfram equation, so indexes are one different! + 1, // z^1 term. + -1, // z^2 term + static_cast(3uLL) / 2uLL, // z^3 term. + -static_cast(8uLL) / 3uLL, // z^4 + static_cast(125uLL) / 24uLL, // z^5 + -static_cast(54uLL) / 5uLL, // z^6 + static_cast(16807uLL) / 720uLL, // z^7 + -static_cast(16384uLL) / 315uLL, // z^8 + static_cast(531441uLL) / 4480uLL, // z^9 + -static_cast(156250uLL) / 567uLL, // z^10 + static_cast(2357947691uLL) / 3628800uLL, // z^11 + -static_cast(2985984uLL) / 1925uLL, // z^12 + static_cast(1792160394037uLL) / 479001600uLL, // z^13 + -static_cast(7909306972uLL) / 868725uLL, // z^14 + static_cast(320361328125uLL) / 14350336uLL, // z^15 + -static_cast(35184372088832uLL) / 638512875uLL, // z^16 + static_cast(2862423051509815793uLL) / 20922789888000uLL, // z^17 term + -static_cast(5083731656658uLL) / 14889875uLL, + // z^18 term. = 136808.86090394293563342215789305735851647769682393 + + // z^18 is biggest that can be computed as rational using the largest possible uLL integers, + // so higher terms cannot be potentially compiler-computed as uLL rationals. + // Wolfram (5083731656658 z ^ 18) / 14889875 or + // -341422.05066583836331735491399356945575432970390954 z^18 + + // See note below calling the functor to compute another term, + // sufficient for 80-bit long double precision. + // Wolfram -341422.05066583836331735491399356945575432970390954 z^19 term. + // (5480386857784802185939 z^19)/6402373705728000 + // But now this variant is not used to compute long double + // as specializations are provided above. + }; // static const T coeff[] + + /* + Table of 19 computed coefficients: + + #0 0 + #1 1 + #2 -1 + #3 1.5 + #4 -2.6666666666666666666666666666666665382713370408509 + #5 5.2083333333333333333333333333333330765426740817019 + #6 -10.800000000000000000000000000000000616297582203915 + #7 23.343055555555555555555555555555555076212991619177 + #8 -52.012698412698412698412698412698412659282693193402 + #9 118.62522321428571428571428571428571146835390992496 + #10 -275.57319223985890652557319223985891400375196748314 + #11 649.7871723434744268077601410934743969785223845882 + #12 -1551.1605194805194805194805194805194947599566007429 + #13 3741.4497029592385495163272941050719510009019331763 + #14 -9104.5002411580189357967135744913524243896052869184 + #15 22324.308512706601434280005708577137322392070452582 + #16 -55103.621972903835337697771560205423203318720697224 + #17 136808.86090394293563342215789305735851647769682393 + 136808.86090394293563342215789305735851647769682393 == Exactly same as Wolfram computed value. + #18 -341422.05066583836331735491399356947486381600607416 + 341422.05066583836331735491399356945575432970390954 z^19 Wolfram value differs at 36 decimal digit, as expected. + */ + + using boost::math::policies::get_epsilon; // for type T. + using boost::math::tools::sum_series; + using boost::math::tools::evaluate_polynomial; + // http://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/roots/rational.html + + // std::streamsize prec = std::cout.precision(std::numeric_limits ::max_digits10); + + T result = evaluate_polynomial(coeff, z); // LCOV_EXCL_LINE next line covered but not this one strangely - GCOV SNAFU? + // template + // V evaluate_polynomial(const T(&poly)[N], const V& val); + // Size of coeff found from N + //std::cout << "evaluate_polynomial(coeff, z); == " << result << std::endl; + //std::cout << "result = " << result << std::endl; + // It's an artefact of the way I wrote the functor: *after* evaluating N + // terms, its internal state has k = N and term = (-1)^N z^N. So after + // evaluating 18 terms, we initialize the functor to the term we've just + // evaluated, and then when it's called, it increments itself to the next term. + // So 18!is 6402373705728000, which is where that comes from. + + // The 19th coefficient of the polynomial is actually, 19 ^ 18 / 19!= + // 104127350297911241532841 / 121645100408832000 which after removing GCDs + // reduces down to Wolfram rational 5480386857784802185939 / 6402373705728000. + // Wolfram z^19 term +(5480386857784802185939 z^19) /6402373705728000 + // +855992.96599660755146336302506332246623424823099755 z^19 + + //! Evaluate Functor. + lambert_w0_small_z_series_term s(z, -pow<18>(z) / 6402373705728000uLL, 18); + + // Temporary to list the coefficients. + //std::cout << " Table of coefficients" << std::endl; + //std::streamsize saved_precision = std::cout.precision(50); + //for (size_t i = 0; i != 19; i++) + //{ + // std::cout << "#" << i << " " << coeff[i] << std::endl; + //} + //std::cout.precision(saved_precision); + + std::uintmax_t max_iter = policies::get_max_series_iterations(); // Max iterations from policy. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "max iter from policy = " << max_iter << std::endl; + // // max iter from policy = 1000000 is default. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + result = sum_series(s, get_epsilon(), max_iter, result); + // result == evaluate_polynomial. + //sum_series(Functor& func, int bits, std::uintmax_t& max_terms, const U& init_value) + // std::cout << "sum_series(s, get_epsilon(), max_iter, result); = " << result << std::endl; + + //T epsilon = get_epsilon(); + //std::cout << "epsilon from policy = " << epsilon << std::endl; + // epsilon from policy = 1.93e-34 for T == quad + // 5.35e-51 for t = cpp_bin_float_50 + + // std::cout << " get eps = " << get_epsilon() << std::endl; // quad eps = 1.93e-34, bin_float_50 eps = 5.35e-51 + policies::check_series_iterations("boost::math::lambert_w0_small_z<%1%>(%1%)", max_iter, pol); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS + std::cout << "z = " << z << " needed " << max_iter << " iterations." << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS + return result; +} // template inline T lambert_w0_small_z_series(T z, const Policy& pol) + +// Approximate lambert_w0 (used for z values that are outside range of lookup table or rational functions) +// Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. +template +inline T lambert_w0_approx(T z) +{ + BOOST_MATH_STD_USING + T lz = log(z); + T llz = log(lz); + T w = lz - llz + (llz / lz); // Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. + return w; + // std::cout << "w max " << max_w << std::endl; // double 703.227 +} + + ////////////////////////////////////////////////////////////////////////////////////////// + +//! \brief Lambert_w0 implementations for float, double and higher precisions. +//! 3rd parameter used to select which version is used. + +//! /details Rational polynomials are provided for several range of argument z. +//! For very small values of z, and for z very near the branch singularity at -e^-1 (~= -0.367879), +//! two other series functions are used. + +//! float precision polynomials are used for 32-bit (usually float) precision (for speed) +//! double precision polynomials are used for 64-bit (usually double) precision. +//! For higher precisions, a 64-bit double approximation is computed first, +//! and then refined using Halley iterations. + +template +inline T do_get_near_singularity_param(T z) +{ + BOOST_MATH_STD_USING + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + return p; +} +template +inline T get_near_singularity_param(T z, const Policy) +{ + using value_type = typename policies::evaluation::type; + return static_cast(do_get_near_singularity_param(static_cast(z))); +} + +// Forward declarations: + +//template T lambert_w0_small_z(T z, const Policy& pol); +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 32 bit usually float. +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 64 bit usually double. +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 80-bit long double. + +template +T lambert_w_positive_rational_float(T z) +{ + BOOST_MATH_STD_USING + if (z < 2) + { + if (z < T(0.5)) + { // 0.05 < z < 0.5 + // Maximum Deviation Found: 2.993e-08 + // Expected Error Term : 2.993e-08 + // Maximum Relative Change in Control Points : 7.555e-04 Y offset : -8.196592331e-01 + // LCOV_EXCL_START + static const T Y = 8.196592331e-01f; + static const T P[] = { + 1.803388345e-01f, + -4.820256838e-01f, + -1.068349741e+00f, + -3.506624319e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.871703469e+00f, + 1.690949264e+00f, + }; + // LCOV_EXCL_STOP + return z * (Y + boost::math::tools::evaluate_polynomial(P, z) / boost::math::tools::evaluate_polynomial(Q, z)); + } + else + { // 0.5 < z < 2 + // Max error in interpolated form: 1.018e-08 + // LCOV_EXCL_START + static const T Y = 5.503368378e-01f; + static const T P[] = { + 4.493332766e-01f, + 2.543432707e-01f, + -4.808788799e-01f, + -1.244425316e-01f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.780661241e+00f, + 1.830840318e+00f, + 2.407221031e-01f, + }; + // LCOV_EXCL_STOP + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + } + else if (z < 6) + { + // 2 < z < 6 + // Max error in interpolated form: 2.944e-08 + // LCOV_EXCL_START + static const T Y = 1.162393570e+00f; + static const T P[] = { + -1.144183394e+00f, + -4.712732855e-01f, + 1.563162512e-01f, + 1.434010911e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 1.192626340e+00f, + 2.295580708e-01f, + 5.477869455e-03f, + }; + // LCOV_EXCL_STOP + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 18) + { + // 6 < z < 18 + // Max error in interpolated form: 5.893e-08 + // LCOV_EXCL_START + static const T Y = 1.809371948e+00f; + static const T P[] = { + -1.689291769e+00f, + -3.337812742e-01f, + 3.151434873e-02f, + 1.134178734e-03f, + }; + static const T Q[] = { + 1.000000000e+00f, + 5.716915685e-01f, + 4.489521292e-02f, + 4.076716763e-04f, + }; + // LCOV_EXCL_STOP + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < T(9897.12905874)) // 2.8 < log(z) < 9.2 + { + // Max error in interpolated form: 1.771e-08 + // LCOV_EXCL_START + static const T Y = -1.402973175e+00f; + static const T P[] = { + 1.966174312e+00f, + 2.350864728e-01f, + -5.098074353e-02f, + -1.054818339e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 4.388208264e-01f, + 8.316639634e-02f, + 3.397187918e-03f, + -1.321489743e-05f, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } + else if (z < T(7.896296e+13)) // 9.2 < log(z) <= 32 + { + // Max error in interpolated form: 5.821e-08 + // LCOV_EXCL_START + static const T Y = -2.735729218e+00f; + static const T P[] = { + 3.424903470e+00f, + 7.525631787e-02f, + -1.427309584e-02f, + -1.435974178e-05f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.514005579e-01f, + 6.118994652e-03f, + -1.357889535e-05f, + 7.312865624e-08f, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } + + // Max error in interpolated form: 1.491e-08 + // LCOV_EXCL_START + static const T Y = -4.012863159e+00f; + static const T P[] = { + 4.431629226e+00f, + 2.756690487e-01f, + -2.992956930e-03f, + -4.912259384e-05f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.015434591e-01f, + 4.949426142e-03f, + 1.609659944e-05f, + -5.111523436e-09f, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + +} + +template +T lambert_w_negative_rational_float(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + if (z > T(-0.27)) + { + if (z < T(-0.051)) + { + // -0.27 < z < -0.051 + // Max error in interpolated form: 5.080e-08 + // LCOV_EXCL_START + static const T Y = 1.255809784e+00f; + static const T P[] = { + -2.558083412e-01f, + -2.306524098e+00f, + -5.630887033e+00f, + -3.803974556e+00f, + }; + static const T Q[] = { + 1.000000000e+00f, + 5.107680783e+00f, + 7.914062868e+00f, + 3.501498501e+00f, + }; + // LCOV_EXCL_STOP + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else + { + // Very small z so use a series function. + return lambert_w0_small_z(z, pol); + } + } + else if (z > T(-0.3578794411714423215955237701)) + { // Very close to branch singularity. + // Max error in interpolated form: 5.269e-08 + // LCOV_EXCL_START + static const T Y = 1.220928431e-01f; + static const T P[] = { + -1.221787446e-01f, + -6.816155875e+00f, + 7.144582035e+01f, + 1.128444390e+03f, + }; + static const T Q[] = { + 1.000000000e+00f, + 6.480326790e+01f, + 1.869145243e+02f, + -1.361804274e+03f, + 1.117826726e+03f, + }; + // LCOV_EXCL_STOP + T d = z + 0.367879441171442321595523770161460867445811f; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + + return lambert_w_singularity_series(get_near_singularity_param(z, pol)); +} + +//! Lambert_w0 @b 'float' implementation, selected when T is 32-bit precision. +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; // For error messages. + BOOST_MATH_STD_USING // Aid ADL of std functions. + + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected a value > -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if ((boost::math::isinf)(z)) + { + return boost::math::policies::raise_overflow_error(function, "Expected a finite value but got %1%.", z, pol); + } + + if (z >= T(0.05)) // Fukushima switch point. + // if (z >= 0.045) // 34 terms makes 128-bit 'exact' below 0.045. + { // Normal ranges using several rational polynomials. + return lambert_w_positive_rational_float(z); + } + else if (z <= -0.3678794411714423215955237701614608674458111310f) + { + if (z < -0.3678794411714423215955237701614608674458111310f) + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + return -1; + } + + return lambert_w_negative_rational_float(z, pol); +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) for 32-bit usually float. + +template +T lambert_w_positive_rational_double(T z) +{ + BOOST_MATH_STD_USING + if (z < 2) + { + if (z < 0.5) + { + // Max error in interpolated form: 2.255e-17 + // LCOV_EXCL_START + static const T offset = 8.19659233093261719e-01; + static const T P[] = { + 1.80340766906685177e-01, + 3.28178241493119307e-01, + -2.19153620687139706e+00, + -7.24750929074563990e+00, + -7.28395876262524204e+00, + -2.57417169492512916e+00, + -2.31606948888704503e-01 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 7.36482529307436604e+00, + 2.03686007856430677e+01, + 2.62864592096657307e+01, + 1.59742041380858333e+01, + 4.03760534788374589e+00, + 2.91327346750475362e-01 + }; + // LCOV_EXCL_STOP + return z * (offset + boost::math::tools::evaluate_polynomial(P, z) / boost::math::tools::evaluate_polynomial(Q, z)); + } + else + { + // Max error in interpolated form: 3.806e-18 + // LCOV_EXCL_START + static const T offset = 5.50335884094238281e-01; + static const T P[] = { + 4.49664083944098322e-01, + 1.90417666196776909e+00, + 1.99951368798255994e+00, + -6.91217310299270265e-01, + -1.88533935998617058e+00, + -7.96743968047750836e-01, + -1.02891726031055254e-01, + -3.09156013592636568e-03 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 6.45854489419584014e+00, + 1.54739232422116048e+01, + 1.72606164253337843e+01, + 9.29427055609544096e+00, + 2.29040824649748117e+00, + 2.21610620995418981e-01, + 5.70597669908194213e-03 + };// LCOV_EXCL_STOP + return z * (offset + boost::math::tools::evaluate_rational(P, Q, z)); + } + } + else if (z < 6) + { + // 2 < z < 6 + // Max error in interpolated form: 1.216e-17 + // LCOV_EXCL_START + static const T Y = 1.16239356994628906e+00; + static const T P[] = { + -1.16230494982099475e+00, + -3.38528144432561136e+00, + -2.55653717293161565e+00, + -3.06755172989214189e-01, + 1.73149743765268289e-01, + 3.76906042860014206e-02, + 1.84552217624706666e-03, + 1.69434126904822116e-05, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 3.77187616711220819e+00, + 4.58799960260143701e+00, + 2.24101228462292447e+00, + 4.54794195426212385e-01, + 3.60761772095963982e-02, + 9.25176499518388571e-04, + 4.43611344705509378e-06, + }; + // LCOV_EXCL_STOP + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 18) + { + // 6 < z < 18 + // Max error in interpolated form: 1.985e-19 + // LCOV_EXCL_START + static const T offset = 1.80937194824218750e+00; + static const T P[] = + { + -1.80690935424793635e+00, + -3.66995929380314602e+00, + -1.93842957940149781e+00, + -2.94269984375794040e-01, + 1.81224710627677778e-03, + 2.48166798603547447e-03, + 1.15806592415397245e-04, + 1.43105573216815533e-06, + 3.47281483428369604e-09 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 2.57319080723908597e+00, + 1.96724528442680658e+00, + 5.84501352882650722e-01, + 7.37152837939206240e-02, + 3.97368430940416778e-03, + 8.54941838187085088e-05, + 6.05713225608426678e-07, + 8.17517283816615732e-10 + }; + // LCOV_EXCL_STOP + return offset + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 9897.12905874) // 2.8 < log(z) < 9.2 + { + // Max error in interpolated form: 1.195e-18 + // LCOV_EXCL_START + static const T Y = -1.40297317504882812e+00; + static const T P[] = { + 1.97011826279311924e+00, + 1.05639945701546704e+00, + 3.33434529073196304e-01, + 3.34619153200386816e-02, + -5.36238353781326675e-03, + -2.43901294871308604e-03, + -2.13762095619085404e-04, + -4.85531936495542274e-06, + -2.02473518491905386e-08, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 8.60107275833921618e-01, + 4.10420467985504373e-01, + 1.18444884081994841e-01, + 2.16966505556021046e-02, + 2.24529766630769097e-03, + 9.82045090226437614e-05, + 1.36363515125489502e-06, + 3.44200749053237945e-09, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else if (z < 7.896296e+13) // 9.2 < log(z) <= 32 + { + // Max error in interpolated form: 6.529e-18 + // LCOV_EXCL_START + static const T Y = -2.73572921752929688e+00; + static const T P[] = { + 3.30547638424076217e+00, + 1.64050071277550167e+00, + 4.57149576470736039e-01, + 4.03821227745424840e-02, + -4.99664976882514362e-04, + -1.28527893803052956e-04, + -2.95470325373338738e-06, + -1.76662025550202762e-08, + -1.98721972463709290e-11, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 6.91472559412458759e-01, + 2.48154578891676774e-01, + 4.60893578284335263e-02, + 3.60207838982301946e-03, + 1.13001153242430471e-04, + 1.33690948263488455e-06, + 4.97253225968548872e-09, + 3.39460723731970550e-12, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else if (z < 2.6881171e+43) // 32 < log(z) < 100 + { + // Max error in interpolated form: 2.015e-18 + // LCOV_EXCL_START + static const T Y = -4.01286315917968750e+00; + static const T P[] = { + 5.07714858354309672e+00, + -3.32994414518701458e+00, + -8.61170416909864451e-01, + -4.01139705309486142e-02, + -1.85374201771834585e-04, + 1.08824145844270666e-05, + 1.17216905810452396e-07, + 2.97998248101385990e-10, + 1.42294856434176682e-13, + }; + static const T Q[] = { + 1.00000000000000000e+00, + -4.85840770639861485e-01, + -3.18714850604827580e-01, + -3.20966129264610534e-02, + -1.06276178044267895e-03, + -1.33597828642644955e-05, + -6.27900905346219472e-08, + -9.35271498075378319e-11, + -2.60648331090076845e-14, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else // 100 < log(z) < 710 + { + // Max error in interpolated form: 5.277e-18 + // LCOV_EXCL_START + static const T Y = -5.70115661621093750e+00; + static const T P[] = { + 6.42275660145116698e+00, + 1.33047964073367945e+00, + 6.72008923401652816e-02, + 1.16444069958125895e-03, + 7.06966760237470501e-06, + 5.48974896149039165e-09, + -7.00379652018853621e-11, + -1.89247635913659556e-13, + -1.55898770790170598e-16, + -4.06109208815303157e-20, + -2.21552699006496737e-24, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 3.34498588416632854e-01, + 2.51519862456384983e-02, + 6.81223810622416254e-04, + 7.94450897106903537e-06, + 4.30675039872881342e-08, + 1.10667669458467617e-10, + 1.31012240694192289e-13, + 6.53282047177727125e-17, + 1.11775518708172009e-20, + 3.78250395617836059e-25, + }; + // LCOV_EXCL_STOP + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } +} + +template +T lambert_w_negative_rational_double(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + if (z > -0.1) + { + if (z < -0.051) + { + // -0.1 < z < -0.051 + // Maximum Deviation Found: 4.402e-22 + // Expected Error Term : 4.240e-22 + // Maximum Relative Change in Control Points : 4.115e-03 + // LCOV_EXCL_START + static const T Y = 1.08633995056152344e+00; + static const T P[] = { + -8.63399505615014331e-02, + -1.64303871814816464e+00, + -7.71247913918273738e+00, + -1.41014495545382454e+01, + -1.02269079949257616e+01, + -2.17236002836306691e+00, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 7.44775406945739243e+00, + 2.04392643087266541e+01, + 2.51001961077774193e+01, + 1.31256080849023319e+01, + 2.11640324843601588e+00, + }; + // LCOV_EXCL_STOP + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else + { + // Very small z > 0.051: + return lambert_w0_small_z(z, pol); + } + } + else if (z > -0.2) + { + // -0.2 < z < -0.1 + // Maximum Deviation Found: 2.898e-20 + // Expected Error Term : 2.873e-20 + // Maximum Relative Change in Control Points : 3.779e-04 + // LCOV_EXCL_START + static const T Y = 1.20359611511230469e+00; + static const T P[] = { + -2.03596115108465635e-01, + -2.95029082937201859e+00, + -1.54287922188671648e+01, + -3.81185809571116965e+01, + -4.66384358235575985e+01, + -2.59282069989642468e+01, + -4.70140451266553279e+00, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 9.57921436074599929e+00, + 3.60988119290234377e+01, + 6.73977699505546007e+01, + 6.41104992068148823e+01, + 2.82060127225153607e+01, + 4.10677610657724330e+00, + }; + // LCOV_EXCL_STOP + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else if (z > -0.3178794411714423215955237) + { + // Max error in interpolated form: 6.996e-18 + // LCOV_EXCL_START + static const T Y = 3.49680423736572266e-01; + static const T P[] = { + -3.49729841718749014e-01, + -6.28207407760709028e+01, + -2.57226178029669171e+03, + -2.50271008623093747e+04, + 1.11949239154711388e+05, + 1.85684566607844318e+06, + 4.80802490427638643e+06, + 2.76624752134636406e+06, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 1.82717661215113000e+02, + 8.00121119810280100e+03, + 1.06073266717010129e+05, + 3.22848993926057721e+05, + -8.05684814514171256e+05, + -2.59223192927265737e+06, + -5.61719645211570871e+05, + 6.27765369292636844e+04, + }; + // LCOV_EXCL_STOP + T d = z + 0.367879441171442321595523770161460867445811; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + else if (z > -0.3578794411714423215955237701) + { + // Max error in interpolated form: 1.404e-17 + // LCOV_EXCL_START + static const T Y = 5.00126481056213379e-02; + static const T P[] = { + -5.00173570682372162e-02, + -4.44242461870072044e+01, + -9.51185533619946042e+03, + -5.88605699015429386e+05, + -1.90760843597427751e+06, + 5.79797663818311404e+08, + 1.11383352508459134e+10, + 5.67791253678716467e+10, + 6.32694500716584572e+10, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 9.08910517489981551e+02, + 2.10170163753340133e+05, + 1.67858612416470327e+07, + 4.90435561733227953e+08, + 4.54978142622939917e+09, + 2.87716585708739168e+09, + -4.59414247951143131e+10, + -1.72845216404874299e+10, + }; + // LCOV_EXCL_STOP + T d = z + 0.36787944117144232159552377016146086744581113103176804; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + else + { // z is very close (within 0.01) of the singularity at -e^-1, + // so use a series expansion from R. M. Corless et al. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + return lambert_w_detail::lambert_w_singularity_series(p); + } +} + +//! Lambert_w0 @b 'double' implementation, selected when T is 64-bit precision. +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; + BOOST_MATH_STD_USING // Aid ADL of std functions. + + // Detect unusual case of 32-bit double with a wider/64-bit long double + static_assert(std::numeric_limits::digits >= 53, + "Our double precision coefficients will be truncated, " + "please file a bug report with details of your platform's floating point types " + "- or possibly edit the coefficients to have " + "an appropriate size-suffix for 64-bit floats on your platform - L?"); + + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected a value > -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if ((boost::math::isinf)(z)) + { + return boost::math::policies::raise_overflow_error(function, "Expected a finite value but got %1%.", z, pol); + } + + if (z >= 0.05) + { + return lambert_w_positive_rational_double(z); + } + else if (z <= -0.36787944117144232159552377016146086744581113103176804) // Precision is max_digits10(cpp_bin_float_50). + { + if (z < -0.36787944117144232159552377016146086744581113103176804) + { + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + return -1; + } + else + { + return lambert_w_negative_rational_double(z, pol); + } +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) 64-bit precision, usually double. + +//! lambert_W0 implementation for extended precision types including +//! long double (80-bit and 128-bit), ??? +//! quad float128, Boost.Multiprecision types like cpp_bin_float_quad, cpp_bin_float_50... + +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; + BOOST_MATH_STD_USING // Aid ADL of std functions. + + // Filter out special cases first: + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if (fabs(z) <= 0.05f) + { + // Very small z: + return lambert_w0_small_z(z, pol); + } + if (z > (std::numeric_limits::max)()) + { + if ((boost::math::isinf)(z)) + { + return policies::raise_overflow_error(function, nullptr, pol); + // Or might return infinity if available else max_value, + // but other Boost.Math special functions raise overflow. + } + // z is larger than the largest double, so cannot use the polynomial to get an approximation, + // so use the asymptotic approximation and Halley iterate: + + T w = lambert_w0_approx(z); // Make an inline function as also used elsewhere. + //T lz = log(z); + //T llz = log(lz); + //T w = lz - llz + (llz / lz); // Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. + return lambert_w_halley_iterate(w, z); + } + if (z < -0.3578794411714423215955237701) + { // Very close to branch point so rational polynomials are not usable. + if (z <= -boost::math::constants::exp_minus_one()) + { + if (z == -boost::math::constants::exp_minus_one()) + { // Exactly at the branch point singularity. + return -1; + } + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + // z is very close (within 0.01) of the branch singularity at -e^-1 + // so use a series approximation proposed by Corless et al. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + T w = lambert_w_detail::lambert_w_singularity_series(p); + return lambert_w_halley_iterate(w, z); + } + + // Phew! If we get here we are in the normal range of the function, + // so get a double precision approximation first, then iterate to full precision of T. + // We define a tag_type that is: + // true_type if there are so many digits precision wanted that iteration is necessary. + // false_type if a single Halley step is sufficient. + + using precision_type = typename policies::precision::type; + using tag_type = std::integral_constant 113) ? + true // Unknown at compile-time, variable/arbitrary, or more than float128 or cpp_bin_quad 128-bit precision. + : false // float, double, float128, cpp_bin_quad 128-bit, so single Halley step. + >; + + // For speed, we also cast z to type double when that is possible + // if (std::is_constructible() == true). + T w = lambert_w0_imp(maybe_reduce_to_double(z, std::is_constructible()), pol, std::integral_constant()); + + return lambert_w_maybe_halley_iterate(w, z, tag_type()); + +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) all extended precision types. + + // Lambert w-1 implementation +// ============================================================================================== + + //! Lambert W for W-1 branch, -max(z) < z <= -1/e. + // TODO is -max(z) allowed? +template +T lambert_wm1_imp(const T z, const Policy& pol) +{ + // Catch providing an integer value as parameter x to lambert_w, for example, lambert_w(1). + // Need to ensure it is a floating-point type (of the desired type, float 1.F, double 1., or long double 1.L), + // or static_casted integer, for example: static_cast(1) or static_cast(1). + // Want to allow fixed_point types too, so do not just test for floating-point. + // Integral types should be promoted to double by user Lambert w functions. + // If integral type provided to user function lambert_w0 or lambert_wm1, + // then should already have been promoted to double. + static_assert(!std::is_integral::value, + "Must be floating-point or fixed type (not integer type), for example: lambert_wm1(1.), not lambert_wm1(1)!"); + + BOOST_MATH_STD_USING // Aid argument dependent lookup (ADL) of abs. + + const char* function = "boost::math::lambert_wm1()"; // Used for error messages. + + // Check for edge and corner cases first: + if ((boost::math::isnan)(z)) + { + return policies::raise_domain_error(function, "Argument z is NaN!", z, pol); + } // isnan + + if ((boost::math::isinf)(z)) + { + return policies::raise_domain_error(function, "Argument z is infinite!", z, pol); + } // isinf + + if (z == static_cast(0)) + { // z is exactly zero so return -std::numeric_limits::infinity(); + return -policies::raise_overflow_error(function, nullptr, z, pol); + } + if (boost::math::detail::has_denorm_now()) + { // All real types except arbitrary precision. + if (!(boost::math::isnormal)(z)) + { // Almost zero - might also just return infinity like z == 0 or max_value? + return -policies::raise_overflow_error(function, "Argument z = %1% is denormalized! (must be z > (std::numeric_limits::min)() or z == 0)", z, pol); + } + } + + if (z > static_cast(0)) + { // + return policies::raise_domain_error(function, "Argument z = %1% is out of range (z <= 0) for Lambert W-1 branch! (Try Lambert W0 branch?)", z, pol); + } + if (z == -boost::math::constants::exp_minus_one()) // == singularity/branch point z = -exp(-1) = -0.36787944. + { // At singularity, so return exactly -1. + return -static_cast(1); + } + // z is too negative for the W-1 (or W0) branch. + if (z < -boost::math::constants::exp_minus_one()) // > singularity/branch point z = -exp(-1) = -0.36787944. + { + return policies::raise_domain_error(function, "Argument z = %1% is out of range (require -exp(-1) = -0.36787944... < z <= 0) for Lambert W-1 (or W0) branch!", z, pol); + } + if (z < static_cast(-0.35)) + { // Close to singularity/branch point z = -0.3678794411714423215955237701614608727 but on W-1 branch. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + // Commented out, requires z = -1 / 2e which is greater than -0.35 so this whole branch is not taken. + //if (p2 == 0) + //{ // At the singularity at branch point. + // return -1; + // } + BOOST_MATH_ASSERT(p2 > 0); + T w_series = lambert_w_singularity_series(T(-sqrt(p2))); + if (boost::math::tools::digits() > 53) + { // Multiprecision, so try a Halley refinement. + w_series = lambert_w_detail::lambert_w_halley_iterate(w_series, z); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Lambert W-1 Halley updated to " << w_series << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + } + return w_series; + } // if (z < -0.35) + + using lambert_w_lookup::wm1es; + using lambert_w_lookup::wm1zs; + using lambert_w_lookup::noof_wm1zs; // size == 64 + + // std::cout <<" Wm1zs[63] (== G[64]) = " << " " << wm1zs[63] << std::endl; // Wm1zs[63] (== G[64]) = -1.0264389699511283e-26 + // Check that z argument value is not smaller than lookup_table G[64] + // std::cout << "(z > wm1zs[63]) = " << std::boolalpha << (z > wm1zs[63]) << std::endl; + + if (z >= T(wm1zs[63])) // wm1zs[63] = -1.0264389699511282259046957018510946438e-26L W = 64.00000000000000000 + { // z >= -1.0264389699511303e-26 (but z != 0 and z >= std::numeric_limits::min() and so NOT denormalized). + + // Some info on Lambert W-1 values for extreme values of z. + // std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + // std::cout << "-std::numeric_limits::min() = " << -(std::numeric_limits::min)() << std::endl; + // std::cout << "-std::numeric_limits::min() = " << -(std::numeric_limits::min)() << std::endl; + // -std::numeric_limits::min() = -1.1754943508222875e-38 + // -std::numeric_limits::min() = -2.2250738585072014e-308 + // N[productlog(-1, -1.1754943508222875 * 10^-38 ), 50] = -91.856775324595479509567756730093823993834155027858 + // N[productlog(-1, -2.2250738585072014e-308 * 10^-308 ), 50] = -1424.8544521230553853558132180518404363617968042942 + // N[productlog(-1, -1.4325445274604020119111357113179868158* 10^-27), 37] = -65.99999999999999999999999999999999955 + + // R.M.Corless, G.H.Gonnet, D.E.G.Hare, D.J.Jeffrey, and D.E.Knuth, + // On the Lambert W function, Adv.Comput.Math., vol. 5, pp. 329, 1996. + // Francois Chapeau-Blondeau and Abdelilah Monir + // Numerical Evaluation of the Lambert W Function + // IEEE Transactions On Signal Processing, VOL. 50, NO. 9, Sep 2002 + // https://pdfs.semanticscholar.org/7a5a/76a9369586dd0dd34dda156d8f2779d1fd59.pdf + // Estimate Lambert W using ln(-z) ... + // This is roughly the power of ten * ln(10) ~= 2.3. n ~= 10^n + // and improve by adding a second term -ln(ln(-z)) + T guess; // bisect lowest possible Gk[=64] (for lookup_t type) + T lz = log(-z); + T llz = log(-lz); + guess = lz - llz + (llz / lz); // Chapeau-Blondeau equation 20, page 2162. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "z = " << z << ", guess = " << guess << ", ln(-z) = " << lz << ", ln(-ln(-z) = " << llz << ", llz/lz = " << (llz / lz) << std::endl; + // z = -1.0000000000000001e-30, guess = -73.312782616731482, ln(-z) = -69.077552789821368, ln(-ln(-z) = 4.2352298269101114, llz/lz = -0.061311231447304194 + // z = -9.9999999999999999e-91, guess = -212.56650048504233, ln(-z) = -207.23265836946410, ln(-ln(-z) = 5.3338421155782205, llz/lz = -0.025738424423764311 + // >z = -2.2250738585072014e-308, guess = -714.95942238244606, ln(-z) = -708.39641853226408, ln(-ln(-z) = 6.5630038501819854, llz/lz = -0.0092645920821846622 + int d10 = policies::digits_base10(); // policy template parameter digits10 + int d2 = policies::digits(); // digits base 2 from policy. + std::cout << "digits10 = " << d10 << ", digits2 = " << d2 // For example: digits10 = 1, digits2 = 5 + << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY + if (policies::digits() < 12) + { // For the worst case near w = 64, the error in the 'guess' is ~0.008, ratio ~ 0.0001 or 1 in 10,000 digits 10 ~= 4, or digits2 ~= 12. + return guess; // LCOV_EXCL_LINE We don't have a test type with few enough digits to trigger this. + } + T result = lambert_w_detail::lambert_w_halley_iterate(guess, z); + return result; + + // Was Fukushima + // G[k=64] == g[63] == -1.02643897e-26 + //return policies::raise_domain_error(function, + // "Argument z = %1% is too small (< -1.02643897e-26) ! (Should not occur, please report.", + // z, pol); + } // Z too small so use approximation and Halley. + // Else Use a lookup table to find the nearest integer part of Lambert W-1 as starting point for Bisection. + + if (boost::math::tools::digits() > 53) + { // T is more precise than 64-bit double (or long double, or ?), + // so compute an approximate value using only one Schroeder refinement, + // (avoiding any double-precision Halley refinement from policy double_digits2<50> 53 - 3 = 50 + // because are next going to use Halley refinement at full/high precision using this as an approximation). + using boost::math::policies::precision; + using boost::math::policies::digits10; + using boost::math::policies::digits2; + using boost::math::policies::policy; + // Compute a 50-bit precision approximate W0 in a double (no Halley refinement). + T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_constructible()), policy>()))); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Lambert_wm1 Argument Type " << typeid(T).name() << " approximation double = " << double_approx << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + // Perform additional Halley refinement(s) to ensure that + // get a near as possible to correct result (usually +/- one epsilon). + T result = lambert_w_halley_iterate(double_approx, z); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Result " << typeid(T).name() << " precision Halley refinement = " << result << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + return result; + } // digits > 53 - higher precision than double. + else // T is double or less precision. + { // Use a lookup table to find the nearest integer part of Lambert W as starting point for Bisection. + using namespace boost::math::lambert_w_detail::lambert_w_lookup; + // Bracketing sequence n = (2, 4, 8, 16, 32, 64) for W-1 branch. (0 is -infinity) + // Since z is probably quite small, start with lowest n (=2). + int n = 2; + if (T(wm1zs[n - 1]) > z) + { + goto bisect; + } + for (int j = 1; j <= 5; ++j) + { + n *= 2; + if (T(wm1zs[n - 1]) > z) + { + goto overshot; + } + } + // else z < g[63] == -1.0264389699511303e-26, so Lambert W-1 integer part > 64. + // This should not now occur (should be caught by test and code above) so should be a logic_error? + return policies::raise_evaluation_error(function, "Argument z = %1% is too small (< -1.026439e-26) (logic error - please report!)", z, pol); // LCOV_EXCL_LINE + overshot: + { + int nh = n / 2; + for (int j = 1; j <= 5; ++j) + { + nh /= 2; // halve step size. + if (nh <= 0) + { + break; // goto bisect; + } + if (T(wm1zs[n - nh - 1]) > z) + { + n -= nh; + } + } + } + bisect: + --n; + // g[n] now holds lambert W of floor integer n and g[n+1] the ceil part; + // these are used as initial values for bisection. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Result lookup W-1(" << z << ") bisection between wm1zs[" << n - 1 << "] = " << wm1zs[n - 1] << " and wm1zs[" << n << "] = " << wm1zs[n] + << ", bisect mean = " << (wm1zs[n - 1] + wm1zs[n]) / 2 << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP + + // Compute bisections is the number of bisections computed from n, + // such that a single application of the fifth-order Schroeder update formula + // after the bisections is enough to evaluate Lambert W-1 with (near?) 53-bit accuracy. + // Fukushima established these by trial and error? + int bisections = 11; // Assume maximum number of bisections will be needed (most common case). + if (n >= 8) + { + bisections = 8; + } + else if (n >= 3) + { + bisections = 9; + } + else if (n >= 2) + { + bisections = 10; + } + // Bracketing, Fukushima section 2.3, page 82: + // (Avoiding using exponential function for speed). + // Only use @c lookup_t precision, default double, for bisection (again for speed), + // and use later Halley refinement for higher precisions. + using lambert_w_lookup::halves; + using lambert_w_lookup::sqrtwm1s; + + using calc_type = typename std::conditional::value, lookup_t, T>::type; + + calc_type w = -static_cast(n); // Equation 25, + calc_type y = static_cast(z * T(wm1es[n - 1])); // Equation 26, + // Perform the bisections fractional bisections for necessary precision. + for (int j = 0; j < bisections; ++j) + { // Equation 27. + calc_type wj = w - halves[j]; // Subtract 1/2, 1/4, 1/8 ... + calc_type yj = y * sqrtwm1s[j]; // Multiply by sqrt(1/e), ... + if (wj < yj) + { + w = wj; + y = yj; + } + } // for j + return static_cast(schroeder_update(w, y)); // Schroeder 5th order method refinement. + +// else // Perform additional Halley refinement(s) to ensure that +// // get a near as possible to correct result (usually +/- epsilon). +// { +// // result = lambert_w_halley_iterate(result, z); +// result = lambert_w_halley_step(result, z); // Just one Halley step should be enough. +//#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_HALLEY +// std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); +// std::cout << "Halley refinement estimate = " << result << std::endl; +// std::cout.precision(saved_precision); +//#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W1_HALLEY +// return result; // Halley +// } // Schroeder or Schroeder and Halley. + } + } // template T lambert_wm1_imp(const T z) +} // namespace lambert_w_detail + +///////////////////////////// User Lambert w functions. ////////////////////////////// + +//! Lambert W0 using User-defined policy. + template + inline + typename boost::math::tools::promote_args::type + lambert_w0(T z, const Policy& pol) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + + // Work out what precision has been selected, + // based on the Policy and the number type. + using precision_type = typename policies::precision::type; + // and then select the correct implementation based on that precision (not the type T): + using tag_type = std::integral_constant 53) ? + 0 // either variable precision (0), or greater than 64-bit precision. + : (precision_type::value <= 24) ? 1 // 32-bit (probably float) precision. + : 2 // 64-bit (probably double) precision. + >; + + return lambert_w_detail::lambert_w0_imp(result_type(z), pol, tag_type()); // + } // lambert_w0(T z, const Policy& pol) + + //! Lambert W0 using default policy. + template + inline + typename tools::promote_args::type + lambert_w0(T z) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + + // Work out what precision has been selected, based on the Policy and the number type. + // For the default policy version, we want the *default policy* precision for T. + using precision_type = typename policies::precision>::type; + // and then select the correct implementation based on that (not the type T): + using tag_type = std::integral_constant 53) ? + 0 // either variable precision (0), or greater than 64-bit precision. + : (precision_type::value <= 24) ? 1 // 32-bit (probably float) precision. + : 2 // 64-bit (probably double) precision. + >; + return lambert_w_detail::lambert_w0_imp(result_type(z), policies::policy<>(), tag_type()); + } // lambert_w0(T z) using default policy. + + //! W-1 branch (-max(z) < z <= -1/e). + + //! Lambert W-1 using User-defined policy. + template + inline + typename tools::promote_args::type + lambert_wm1(T z, const Policy& pol) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + return lambert_w_detail::lambert_wm1_imp(result_type(z), pol); // + } + + //! Lambert W-1 using default policy. + template + inline + typename tools::promote_args::type + lambert_wm1(T z) + { + using result_type = typename tools::promote_args::type; + return lambert_w_detail::lambert_wm1_imp(result_type(z), policies::policy<>()); + } // lambert_wm1(T z) + + // First derivative of Lambert W0 and W-1. + namespace lambert_w_detail { + template + inline typename tools::promote_args::type + lambert_w0_prime(T z, const Policy& pol) + { + using result_type = typename tools::promote_args::type; + using std::numeric_limits; + if (z == 0) + { + return static_cast(1); + } + // This is the sensible choice if we regard the Lambert-W function as complex analytic. + // Of course on the real line, it's just undefined. + if (z == -boost::math::constants::exp_minus_one()) + { + return boost::math::policies::raise_overflow_error("lambert_w0_prime", nullptr, z, pol); + } + // if z < -1/e, we'll let lambert_w0 do the error handling: + result_type w = lambert_w0(result_type(z), pol); + // If w ~ -1, then presumably this can get inaccurate. + // Is there an accurate way to evaluate 1 + W(-1/e + eps)? + // Yes: This is discussed in the Princeton Companion to Applied Mathematics, + // 'The Lambert-W function', Section 1.3: Series and Generating Functions. + // 1 + W(-1/e + x) ~ sqrt(2ex). + // Nick is not convinced this formula is more accurate than the naive one. + // However, for z != -1/e, we never get rounded to w = -1 in any precision I've tested (up to cpp_bin_float_100). + return w / (z * (1 + w)); + } // lambert_w0_prime(T z) + } + // First derivative of Lambert W0 and W-1. + template + inline typename tools::promote_args::type + lambert_w0_prime(T z, const Policy& pol) + { + using result_type = typename tools::promote_args::type; + return lambert_w_detail::lambert_w0_prime(static_cast(z), pol); + } + + template + inline typename tools::promote_args::type + lambert_w0_prime(T z) + { + return lambert_w0_prime(z, policies::policy<>()); + } + + template + inline typename tools::promote_args::type + lambert_wm1_prime(T z, const Policy& pol) + { + using std::numeric_limits; + using result_type = typename tools::promote_args::type; + //if (z == 0) + //{ + // return static_cast(1); + //} + //if (z == - boost::math::constants::exp_minus_one()) + if (z == 0 || z == - boost::math::constants::exp_minus_one()) + { + return -boost::math::policies::raise_overflow_error("lambert_wm1_prime", nullptr, z, pol); + } + + result_type w = lambert_wm1(z, pol); + return w/(z*(1+w)); + } // lambert_wm1_prime(T z) + + template + inline typename tools::promote_args::type + lambert_wm1_prime(T z) + { + return lambert_wm1_prime(z, policies::policy<>()); + } + +}} //boost::math namespaces + +#endif // #ifdef BOOST_MATH_SF_LAMBERT_W_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/lanczos.hpp b/third-party/boost-math/include/boost/math/special_functions/lanczos.hpp new file mode 100644 index 0000000000000..0ec24bddbf000 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/lanczos.hpp @@ -0,0 +1,2760 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS +#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace lanczos{ + +// +// Individual lanczos approximations start here. +// +// Optimal values for G for each N are taken from +// http://web.mala.bc.ca/pughg/phdThesis/phdThesis.pdf, +// as are the theoretical error bounds. +// +// Constants calculated using the method described by Godfrey +// http://my.fit.edu/~gabdo/gamma.txt and elaborated by Toth at +// http://www.rskey.org/gamma.htm using NTL::RR at 1000 bit precision. +// +// +// Non-member helper which allows us to have a different g() value for the +// near_1 and near_2 approximations. This is a big help in reducing error +// rates for multiprecision types at large digit counts. +// Default version assumes all g() values are the same. +// +template +BOOST_MATH_GPU_ENABLED inline double lanczos_g_near_1_and_2(const L&) +{ + return L::g(); +} + + +// +// Lanczos Coefficients for N=6 G=5.581 +// Max experimental error (with arbitrary precision arithmetic) 9.516e-12 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos6 : public boost::math::integral_constant +{ + // + // Produces slightly better than float precision when evaluated at + // double precision: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[6] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 8706.349592549009182288174442774377925882)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 8523.650341121874633477483696775067709735)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 3338.029219476423550899999750161289306564)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 653.6424994294008795995653541449610986791)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 63.99951844938187085666201263218840287667)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.506628274631006311133031631822390264407)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[6] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 32.81244541029783471623665933780748627823)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 32.12388941444332003446077108933558534361)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 12.58034729455216106950851080138931470954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.463444478353241423633780693218408889251)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.2412010548258800231126240760264822486599)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.009446967704539249494420221613134244048319)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[5] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.044879010930422922760429926121241330235)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -2.751366405578505366591317846728753993668)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 1.02282965224225004296750609604264824677)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -0.09786124911582813985028889636665335893627)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.0009829742267506615183144364420540766510112)), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[5] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 5.748142489536043490764289256167080091892)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -7.734074268282457156081021756682138251825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.875167944990511006997713242805893543947)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -0.2750873773533504542306766137703788781776)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.002763134585812698552178368447708846850353)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 5.581000000000000405009359383257105946541; } +}; + +// +// Lanczos Coefficients for N=11 G=10.900511 +// Max experimental error (with arbitrary precision arithmetic) 2.16676e-19 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos11 : public boost::math::integral_constant +{ + // + // Produces slightly better than double precision when evaluated at + // extended-double precision: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[11] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 38474670393.31776828316099004518914832218)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 36857665043.51950660081971227404959150474)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 15889202453.72942008945006665994637853242)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4059208354.298834770194507810788393801607)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 680547661.1834733286087695557084801366446)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 78239755.00312005289816041245285376206263)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 6246580.776401795264013335510453568106366)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 341986.3488721347032223777872763188768288)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 12287.19451182455120096222044424100527629)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 261.6140441641668190791708576058805625502)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 2.506628274631000502415573855452633787834)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[11] = { + static_cast(0u), + static_cast(362880u), + static_cast(1026576u), + static_cast(1172700u), + static_cast(723680u), + static_cast(269325u), + static_cast(63273u), + static_cast(9450u), + static_cast(870u), + static_cast(45u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[11] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 709811.662581657956893540610814842699825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 679979.847415722640161734319823103390728)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 293136.785721159725251629480984140341656)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 74887.5403291467179935942448101441897121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 12555.29058241386295096255111537516768137)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 1443.42992444170669746078056942194198252)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 115.2419459613734722083208906727972935065)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 6.30923920573262762719523981992008976989)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.2266840463022436475495508977579735223818)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.004826466289237661857584712046231435101741)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.4624429436045378766270459638520555557321e-4)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[11] = { + static_cast(0u), + static_cast(362880u), + static_cast(1026576u), + static_cast(1172700u), + static_cast(723680u), + static_cast(269325u), + static_cast(63273u), + static_cast(9450u), + static_cast(870u), + static_cast(45u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[10] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4.005853070677940377969080796551266387954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -13.17044315127646469834125159673527183164)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 17.19146865350790353683895137079288129318)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -11.36446409067666626185701599196274701126)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4.024801119349323770107694133829772634737)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.7445703262078094128346501724255463005006)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.06513861351917497265045550019547857713172)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.00217899958561830354633560009312512312758)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.17655204574495137651670832229571934738e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.1036282091079938047775645941885460820853e-7)), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[10] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 19.05889633808148715159575716844556056056)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -62.66183664701721716960978577959655644762)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 81.7929198065004751699057192860287512027)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -54.06941772964234828416072865069196553015)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 19.14904664790693019642068229478769661515)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -3.542488556926667589704590409095331790317)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.3099140334815639910894627700232804503017)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.01036716187296241640634252431913030440825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.8399926504443119927673843789048514017761e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.493038376656195010308610694048822561263e-7)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 10.90051099999999983936049829935654997826; } +}; + +// +// Lanczos Coefficients for N=13 G=13.144565 +// Max experimental error (with arbitrary precision arithmetic) 9.2213e-23 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos13 : public boost::math::integral_constant +{ + // + // Produces slightly better than extended-double precision when evaluated at + // higher precision: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[13] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 44012138428004.60895436261759919070125699)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 41590453358593.20051581730723108131357995)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 18013842787117.99677796276038389462742949)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 4728736263475.388896889723995205703970787)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 837910083628.4046470415724300225777912264)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 105583707273.4299344907359855510105321192)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 9701363618.494999493386608345339104922694)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 654914397.5482052641016767125048538245644)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 32238322.94213356530668889463945849409184)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1128514.219497091438040721811544858643121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 26665.79378459858944762533958798805525125)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 381.8801248632926870394389468349331394196)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 2.506628274631000502415763426076722427007)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[13] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 86091529.53418537217994842267760536134841)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 81354505.17858011242874285785316135398567)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 35236626.38815461910817650960734605416521)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 9249814.988024471294683815872977672237195)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1639024.216687146960253839656643518985826)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 206530.8157641225032631778026076868855623)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 18976.70193530288915698282139308582105936)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1281.068909912559479885759622791374106059)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 63.06093343420234536146194868906771599354)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 2.207470909792527638222674678171050209691)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.05216058694613505427476207805814960742102)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.0007469903808915448316510079585999893674101)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.4903180573459871862552197089738373164184e-5)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[12] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 4.832115561461656947793029596285626840312)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -19.86441536140337740383120735104359034688)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 33.9927422807443239927197864963170585331)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -31.41520692249765980987427413991250886138)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 17.0270866009599345679868972409543597821)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -5.5077216950865501362506920516723682167)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1.037811741948214855286817963800439373362)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.106640468537356182313660880481398642811)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.005276450526660653288757565778182586742831)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0001000935625597121545867453746252064770029)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.462590910138598083940803704521211569234e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.1735307814426389420248044907765671743012e-9)), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[12] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 26.96979819614830698367887026728396466395)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -110.8705424709385114023884328797900204863)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 189.7258846119231466417015694690434770085)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -175.3397202971107486383321670769397356553)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 95.03437648691551457087250340903980824948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -30.7406022781665264273675797983497141978)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 5.792405601630517993355102578874590410552)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.5951993240669148697377539518639997795831)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.02944979359164017509944724739946255067671)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0005586586555377030921194246330399163602684)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.2581888478270733025288922038673392636029e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.9685385411006641478305219367315965391289e-9)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 13.1445650000000000545696821063756942749; } +}; + +// +// Lanczos Coefficients for N=6 G=1.428456135094165802001953125 +// Max experimental error (with arbitrary precision arithmetic) 8.111667e-8 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos6m24 : public boost::math::integral_constant +{ + // + // Use for float precision, when evaluated as a float: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[6] = { + static_cast(58.52061591769095910314047740215847630266L), + static_cast(182.5248962595894264831189414768236280862L), + static_cast(211.0971093028510041839168287718170827259L), + static_cast(112.2526547883668146736465390902227161763L), + static_cast(27.5192015197455403062503721613097825345L), + static_cast(2.50662858515256974113978724717473206342L) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[6] = { + static_cast(14.0261432874996476619570577285003839357L), + static_cast(43.74732405540314316089531289293124360129L), + static_cast(50.59547402616588964511581430025589038612L), + static_cast(26.90456680562548195593733429204228910299L), + static_cast(6.595765571169314946316366571954421695196L), + static_cast(0.6007854010515290065101128585795542383721L) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[5] = { + static_cast(0.4922488055204602807654354732674868442106L), + static_cast(0.004954497451132152436631238060933905650346L), + static_cast(-0.003374784572167105840686977985330859371848L), + static_cast(0.001924276018962061937026396537786414831385L), + static_cast(-0.00056533046336427583708166383712907694434L), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[5] = { + static_cast(0.6534966888520080645505805298901130485464L), + static_cast(0.006577461728560758362509168026049182707101L), + static_cast(-0.004480276069269967207178373559014835978161L), + static_cast(0.00255461870648818292376982818026706528842L), + static_cast(-0.000750517993690428370380996157470900204524L), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 1.428456135094165802001953125; } +}; + +// +// Lanczos Coefficients for N=13 G=6.024680040776729583740234375 +// Max experimental error (with arbitrary precision arithmetic) 1.196214e-17 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos13m53 : public boost::math::integral_constant +{ + // + // Use for double precision, when evaluated as a double: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[13] = { + static_cast(23531376880.41075968857200767445163675473L), + static_cast(42919803642.64909876895789904700198885093L), + static_cast(35711959237.35566804944018545154716670596L), + static_cast(17921034426.03720969991975575445893111267L), + static_cast(6039542586.35202800506429164430729792107L), + static_cast(1439720407.311721673663223072794912393972L), + static_cast(248874557.8620541565114603864132294232163L), + static_cast(31426415.58540019438061423162831820536287L), + static_cast(2876370.628935372441225409051620849613599L), + static_cast(186056.2653952234950402949897160456992822L), + static_cast(8071.672002365816210638002902272250613822L), + static_cast(210.8242777515793458725097339207133627117L), + static_cast(2.506628274631000270164908177133837338626L) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[13] = { + static_cast(56906521.91347156388090791033559122686859L), + static_cast(103794043.1163445451906271053616070238554L), + static_cast(86363131.28813859145546927288977868422342L), + static_cast(43338889.32467613834773723740590533316085L), + static_cast(14605578.08768506808414169982791359218571L), + static_cast(3481712.15498064590882071018964774556468L), + static_cast(601859.6171681098786670226533699352302507L), + static_cast(75999.29304014542649875303443598909137092L), + static_cast(6955.999602515376140356310115515198987526L), + static_cast(449.9445569063168119446858607650988409623L), + static_cast(19.51992788247617482847860966235652136208L), + static_cast(0.5098416655656676188125178644804694509993L), + static_cast(0.006061842346248906525783753964555936883222L) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[12] = { + static_cast(2.208709979316623790862569924861841433016L), + static_cast(-3.327150580651624233553677113928873034916L), + static_cast(1.483082862367253753040442933770164111678L), + static_cast(-0.1993758927614728757314233026257810172008L), + static_cast(0.004785200610085071473880915854204301886437L), + static_cast(-0.1515973019871092388943437623825208095123e-5L), + static_cast(-0.2752907702903126466004207345038327818713e-7L), + static_cast(0.3075580174791348492737947340039992829546e-7L), + static_cast(-0.1933117898880828348692541394841204288047e-7L), + static_cast(0.8690926181038057039526127422002498960172e-8L), + static_cast(-0.2499505151487868335680273909354071938387e-8L), + static_cast(0.3394643171893132535170101292240837927725e-9L), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[12] = { + static_cast(6.565936202082889535528455955485877361223L), + static_cast(-9.8907772644920670589288081640128194231L), + static_cast(4.408830289125943377923077727900630927902L), + static_cast(-0.5926941084905061794445733628891024027949L), + static_cast(0.01422519127192419234315002746252160965831L), + static_cast(-0.4506604409707170077136555010018549819192e-5L), + static_cast(-0.8183698410724358930823737982119474130069e-7L), + static_cast(0.9142922068165324132060550591210267992072e-7L), + static_cast(-0.5746670642147041587497159649318454348117e-7L), + static_cast(0.2583592566524439230844378948704262291927e-7L), + static_cast(-0.7430396708998719707642735577238449585822e-8L), + static_cast(0.1009141566987569892221439918230042368112e-8L), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 6.024680040776729583740234375; } +}; + +// +// Lanczos Coefficients for N=17 G=12.2252227365970611572265625 +// Max experimental error (with arbitrary precision arithmetic) 2.7699e-26 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos17m64 : public boost::math::integral_constant +{ + // + // Use for extended-double precision, when evaluated as an extended-double: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[17] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 553681095419291969.2230556393350368550504)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 731918863887667017.2511276782146694632234)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 453393234285807339.4627124634539085143364)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 174701893724452790.3546219631779712198035)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 46866125995234723.82897281620357050883077)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9281280675933215.169109622777099699054272)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1403600894156674.551057997617468721789536)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 165345984157572.7305349809894046783973837)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 15333629842677.31531822808737907246817024)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1123152927963.956626161137169462874517318)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 64763127437.92329018717775593533620578237)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2908830362.657527782848828237106640944457)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 99764700.56999856729959383751710026787811)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2525791.604886139959837791244686290089331)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 44516.94034970167828580039370201346554872)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 488.0063567520005730476791712814838113252)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.50662827463100050241576877135758834683)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint64_t) denom[17] = { + BOOST_MATH_INT_VALUE_SUFFIX(0, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(120, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1, uLL) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[17] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2715894658327.717377557655133124376674911)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3590179526097.912105038525528721129550434)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2223966599737.814969312127353235818710172)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 856940834518.9562481809925866825485883417)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 229885871668.749072933597446453399395469)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 45526171687.54610815813502794395753410032)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6884887713.165178784550917647709216424823)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 811048596.1407531864760282453852372777439)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 75213915.96540822314499613623119501704812)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5509245.417224265151697527957954952830126)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 317673.5368435419126714931842182369574221)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 14268.27989845035520147014373320337523596)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 489.3618720403263670213909083601787814792)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 12.38941330038454449295883217865458609584)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2183627389504614963941574507281683147897)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.002393749522058449186690627996063983095463)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1229541408909435212800785616808830746135e-4)) + }; + BOOST_MATH_STATIC const BOOST_MATH_INT_TABLE_TYPE(T, boost::math::uint64_t) denom[17] = { + BOOST_MATH_INT_VALUE_SUFFIX(0, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(120, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1, uLL) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[16] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.493645054286536365763334986866616581265)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -16.95716370392468543800733966378143997694)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 26.19196892983737527836811770970479846644)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -21.3659076437988814488356323758179283908)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.913992596774556590710751047594507535764)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.62888300018780199210536267080940382158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.3807056693542503606384861890663080735588)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.02714647489697685807340312061034730486958)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0007815484715461206757220527133967191796747)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.6108630817371501052576880554048972272435e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.5037380238864836824167713635482801545086e-8)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1483232144262638814568926925964858237006e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1346609158752142460943888149156716841693e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.660492688923978805315914918995410340796e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1472114697343266749193617793755763792681e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1410901942033374651613542904678399264447e-16)), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[16] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 23.56409085052261327114594781581930373708)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -88.92116338946308797946237246006238652361)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 137.3472822086847596961177383569603988797)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -112.0400438263562152489272966461114852861)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 51.98768915202973863076166956576777843805)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -13.78552090862799358221343319574970124948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.996371068830872830250406773917646121742)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1423525874909934506274738563671862576161)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.004098338646046865122459664947239111298524)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3203286637326511000882086573060433529094e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2641536751640138646146395939004587594407e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7777876663062235617693516558976641009819e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7061443477097101636871806229515157914789e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3463537849537988455590834887691613484813e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7719578215795234036320348283011129450595e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7398586479708476329563577384044188912075e-16)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 12.2252227365970611572265625; } +}; + +// +// Lanczos Coefficients for N=24 G=20.3209821879863739013671875 +// Max experimental error (with arbitrary precision arithmetic) 1.0541e-38 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos24m113 : public boost::math::integral_constant +{ + // + // Use for long-double precision, when evaluated as an long-double: + // + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2029889364934367661624137213253.22102954656825019111612712252027267955023987678816620961507)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2338599599286656537526273232565.2727349714338768161421882478417543004440597874814359063158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1288527989493833400335117708406.3953711906175960449186720680201425446299360322830739180195)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 451779745834728745064649902914.550539158066332484594436145043388809847364393288132164411521)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 113141284461097964029239556815.291212318665536114012605167994061291631013303788706545334708)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 21533689802794625866812941616.7509064680880468667055339259146063256555368135236149614592432)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3235510315314840089932120340.71494940111731241353655381919722177496659303550321056514776757)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 393537392344185475704891959.081297108513472083749083165179784098220158201055270548272414314)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 39418265082950435024868801.5005452240816902251477336582325944930252142622315101857742955673)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3290158764187118871697791.05850632319194734270969161036889516414516566453884272345518372696)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 230677110449632078321772.618245845856640677845629174549731890660612368500786684333975350954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 13652233645509183190158.5916189185218250859402806777406323001463296297553612462737044693697)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 683661466754325350495.216655026531202476397782296585200982429378069417193575896602446904762)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 28967871782219334117.0122379171041074970463982134039409352925258212207710168851968215545064)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1036104088560167006.2022834098572346459442601718514554488352117620272232373622553429728555)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 31128490785613152.8380102669349814751268126141105475287632676569913936040772990253369753962)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 779327504127342.536207878988196814811198475410572992436243686674896894543126229424358472541)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 16067543181294.643350688789124777020407337133926174150582333950666044399234540521336771876)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 268161795520.300916569439413185778557212729611517883948634711190170998896514639936969855484)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3533216359.10528191668842486732408440112703691790824611391987708562111396961696753452085068)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 35378979.5479656110614685178752543826919239614088343789329169535932709470588426584501652577)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253034.881362204346444503097491737872930637147096453940375713745904094735506180552724766444)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1151.61895453463992438325318456328526085882924197763140514450975619271382783957699017875304)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2.50662827463100050241576528481104515966515623051532908941425544355490413900497467936202516)) + }; + BOOST_MATH_STATIC const T denom[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3035162425359883494754.02878223286972654682199012688209026810841953293372712802258398358538)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3496756894406430103600.16057175075063458536101374170860226963245118484234495645518505519827)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1926652656689320888654.01954015145958293168365236755537645929361841917596501251362171653478)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 675517066488272766316.083023742440619929434602223726894748181327187670231286180156444871912)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 169172853104918752780.086262749564831660238912144573032141700464995906149421555926000038492)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 32197935167225605785.6444116302160245528783954573163541751756353183343357329404208062043808)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4837849542714083249.37587447454818124327561966323276633775195138872820542242539845253171632)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 588431038090493242.308438203986649553459461798968819276505178004064031201740043314534404158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 58939585141634058.6206417889192563007809470547755357240808035714047014324843817783741669733)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4919561837722192.82991866530802080996138070630296720420704876654726991998309206256077395868)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 344916580244240.407442753122831512004021081677987651622305356145640394384006997569631719101)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 20413302960687.8250598845969238472629322716685686993835561234733641729957841485003560103066)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1022234822943.78400752460970689311934727763870970686747383486600540378889311406851534545789)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43313787191.9821354846952908076307094286897439975815501673706144217246093900159173598852503)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1549219505.59667418528481770869280437577581951167003505825834192510436144666564648361001914)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 46544421.1998761919380541579358096705925369145324466147390364674998568485110045455014967149)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1165278.06807504975090675074910052763026564833951579556132777702952882101173607903881127542)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 24024.759267256769471083727721827405338569868270177779485912486668586611981795179894572115)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 400.965008113421955824358063769761286758463521789765880962939528760888853281920872064838918)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 5.28299015654478269617039029170846385138134929147421558771949982217659507918482272439717603)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0528999024412510102409256676599360516359062802002483877724963720047531347449011629466149805)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.000378346710654740685454266569593414561162134092347356968516522170279688139165340746957511115)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.172194142179211139195966608011235161516824700287310869949928393345257114743230967204370963e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.374799931707148855771381263542708435935402853962736029347951399323367765509988401336565436e-8)) + }; + BOOST_MATH_STATIC const T denom[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[23] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7.4734083002469026177867421609938203388868806387315406134072298925733950040583068760685908)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -50.4225805042247530267317342133388132970816607563062253708655085754357843064134941138154171)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 152.288200621747008570784082624444625293884063492396162110698238568311211546361189979357019)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -271.894959539150384169327513139846971255640842175739337449692360299099322742181325023644769)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 319.240102980202312307047586791116902719088581839891008532114107693294261542869734803906793)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -259.493144143048088289689500935518073716201741349569864988870534417890269467336454358361499)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 149.747518319689708813209645403067832020714660918583227716408482877303972685262557460145835)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -61.9261301009341333289187201425188698128684426428003249782448828881580630606817104372760037)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 18.3077524177286961563937379403377462608113523887554047531153187277072451294845795496072365)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -3.82011322251948043097070160584761236869363471824695092089556195047949392738162970152230254)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.549382685505691522516705902336780999493262538301283190963770663549981309645795228539620711)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.0524814679715180697633723771076668718265358076235229045603747927518423453658004287459638024)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.00315392664003333528534120626687784812050217700942910879712808180705014754163256855643360698)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000110098373127648510519799564665442121339511198561008748083409549601095293123407080388658329)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.19809382866681658224945717689377373458866950897791116315219376038432014207446832310901893e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.152278977408600291408265615203504153130482270424202400677280558181047344681214058227949755e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.364344768076106268872239259083188037615571711218395765792787047015406264051536972018235217e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.148897510480440424971521542520683536298361220674662555578951242811522959610991621951203526e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.261199241161582662426512749820666625442516059622425213340053324061794752786482115387573582e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.780072664167099103420998436901014795601783313858454665485256897090476089641613851903791529e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.303465867587106629530056603454807425512962762653755513440561256044986695349304176849392735e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.615420597971283870342083342286977366161772327800327789325710571275345878439656918541092056e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.499641233843540749369110053005439398774706583601830828776209650445427083113181961630763702e-26)), + }; + // LCOV_EXCL_STOP + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[23] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 61.4165001061101455341808888883960361969557848005400286332291451422461117307237198559485365)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -414.372973678657049667308134761613915623353625332248315105320470271523320700386200587519147)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1251.50505818554680171298972755376376836161706773644771875668053742215217922228357204561873)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -2234.43389421602399514176336175766511311493214354568097811220122848998413358085613880612158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2623.51647746991904821899989145639147785427273427135380151752779100215839537090464785708684)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -2132.51572435428751962745870184529534443305617818870214348386131243463614597272260797772423)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1230.62572059218405766499842067263311220019173335523810725664442147670956427061920234820189)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -508.90919151163744999377586956023909888833335885805154492270846381061182696305011395981929)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 150.453184562246579758706538566480316921938628645961177699894388251635886834047343195475395)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -31.3937061525822497422230490071156186113405446381476081565548185848237169870395131828731397)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4.51482916590287954234936829724231512565732528859217337795452389161322923867318809206313688)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.431292919341108177524462194102701868233551186625103849565527515201492276412231365776131952)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0259189820815586225636729971503340447445001375909094681698918294680345547092233915092128323)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000904788882557558697594884691337532557729219389814315972435534723829065673966567231504429712)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.162793589759218213439218473348810982422449144393340433592232065020562974405674317564164312e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.125142926178202562426432039899709511761368233479483128438847484617555752948755923647214487e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.299418680048132583204152682950097239197934281178261879500770485862852229898797687301941982e-9)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.122364035267809278675627784883078206654408225276233049012165202996967011873995261617995421e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.21465364366598631597052073538883430194257709353929022544344097235100199405814005393447785e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.641064035802907518396608051803921688237330857546406669209280666066685733941549058513986818e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.249388374622173329690271566855185869111237201309011956145463506483151054813346819490278951e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.505752900177513489906064295001851463338022055787536494321532352380960774349054239257683149e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.410605371184590959139968810080063542546949719163227555918846829816144878123034347778284006e-25)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g(){ return 20.3209821879863739013671875; } +}; + +// +// Lanczos Coefficients for N=27 G=2.472513680905104038743047567550092935562134e+01 +// Max experimental error (with MP precision arithmetic) 0.000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 23 2021 +// Type precision was 134 bits or 42 max_digits10 +// +struct lanczos27MP : public boost::math::integral_constant +{ + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.532923291341302819860952064783714673718970e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.715272050979243637524956158081893927075092e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.399396313336459710065708403038293278484916e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.615805213483907585030394968151583590083805e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.094287593119694642121339924355455488336630e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.985179143643083871895846729884916046817583e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.864723387203319421361199873281888626383507e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.374651939493419385833371654981557918551584e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.304504350810987437240912594601486056121725e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.724892917231894382998818728699010291796660e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.909901039551708500588401626148435467434009e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.145381204249362220411918333792713760478856e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.902980366355225260615014098246446681081078e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.620997933261144559370948440813656891792187e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.003441440382636640319535096309665505136930e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.309721390821762354780404195884829522953769e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.381514076593540726655991152770953882150136e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.275266040978137565809877941293859174071955e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.690398430937632687996992361090819887063422e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.142411407304237744553849404860811146407986e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.174971623395676312463521417132401487856454e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.384092119107453943335286646923309490786229e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.296932429990667045419860753608558102709582e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.299378037650538629629318998114044963408825e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.792561328661952922209314899668849919321249e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.580741273679785112052701460119954412080073e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.506628274631000502415765284811045253005320e+00)) + }; + BOOST_MATH_STATIC const T denom[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 0.000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.551121004333098598400000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.919012881170120359936000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.004801715483511615488000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.023395306017446756725760000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.087414531983767267719680000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.577035564590760682636262400000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.374646821796792697868000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.144457803247115877036800000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.001369304512841374110000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.969281004511108202428800000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.188201437529851278250000000000000000000000e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.284218746244111474800000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.805445587427335451250000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.514594692699448186500000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.557372853474553750000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.349615694227860500000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.297275331854287500000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.956673043671350000000000000000000000000000e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.256393782500000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.968295763000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.724710487500000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.336854950000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.858750000000000000000000000000000000000000e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.005000000000000000000000000000000000000000e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.250000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.630539114451826442425094380936505531231478e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.963898228350662244301785145431331232866294e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.558292778812387748738731408569861630189290e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.438339470758124934572462000795083198080916e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.000511235267926346573212315280041509763731e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.629185970715063928416526096935558921044815e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.237116237146422484431753186953979152997281e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.169337167415775727114018906990954798102547e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.041097534463262894898495303906833076469281e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.981486521549315574859643064948741979243976e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.491567035847004398885838650781864506656075e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.093917524216073202169716871304960622121045e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.079147622499629876874169792116583887362096e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.791551915666662583520458128259897770660473e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.834431723470453391466841656396291574724498e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.050635015489291434258728317621551605496937e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.715072384266421431637543951156767586591045e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.159505514655385281007353699906486901798470e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.574706336771416438731056639147393961539411e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.488547033239016552342729952719496931402330e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.148012961586177396403312787979484589898276e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.530314564772178162122057449947469958774484e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.370974425637913452858480025228307253546963e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.700056764080375263450528442694493496437080e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.761474446005270789145652778771406388702068e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.889816806780013044430000551700375309307825e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.582468135039046226997146555551548992616343e-11)) + }; + BOOST_MATH_STATIC const T denom[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 0.000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.551121004333098598400000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.919012881170120359936000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.004801715483511615488000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.023395306017446756725760000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.087414531983767267719680000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.577035564590760682636262400000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.374646821796792697868000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.144457803247115877036800000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.001369304512841374110000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.969281004511108202428800000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.188201437529851278250000000000000000000000e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.284218746244111474800000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.805445587427335451250000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.514594692699448186500000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.557372853474553750000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.349615694227860500000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.297275331854287500000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.956673043671350000000000000000000000000000e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.256393782500000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.968295763000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.724710487500000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.336854950000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.858750000000000000000000000000000000000000e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.005000000000000000000000000000000000000000e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.250000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[34] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.264579889722939745225908247624593169040293e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -3.470545597111704235784909052092266897169254e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.398164226943527197542310295220360303173237e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.166490739555248669771075340695671987349622e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.028101937812836112448434230485371426845812e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.003050880354706854567842055875605768028585e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.355206767355338215012383892758889890708805e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.173166763225116428638036856999036700963277e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.055748115088123667349396984075505516234940e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.127784364612243323022358484127515048080935e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.013011055366411613813518259345336997226641e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.271137289000937686705998821090835222190159e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.195172534910278451113805217678979457290834e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.421890451863814077221239932785029648679973e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.066311611137421591999312557597869716741027e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.797948012646761974584234409950319937184538e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -5.274002995605577985657965320478056380380290e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.270091452696164640108774677242731307730848e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.933040546739252731034872986511694993372995e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.405071936614348906224568346156522897751303e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.105092450748689398417350156762592106638543e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.573335807137266819877752062372030042747590e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.690602407074901259448169161354115161602278e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.445091932555604281164557526008785529455861e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.932804556880430674197633802977544778784320e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.320001406610629373227596309759263536640140e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -7.699733918513786660891771237627803608806010e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.776870859236169815307382842451635095251495e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.526154769745297076196084765279504608995696e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.939458578626915680695594094484224178207306e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.229538969055131478930409285699348366508295e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.207569067702627873429089508800955397620386e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.542428477414786133402832964643707382175743e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.409458057545117569935733339065832415295665e-25)) + }; + // LCOV_EXCL_STOP + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[34] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.391991857844535020743473289228849738381662e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.433141291692735004291785549611375831426138e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.887812040849956173864447000497922705559488e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -8.178070869177285054991117755136346786974125e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.207850198088647199855281811058606257270817e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.208638257131458956367681504789416772705762e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.651195950543217389263490876246883903526458e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.327903648523876358512872196882929451369963e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.401672908678997114468388150043974540095678e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -7.906706968342945744899907670199667000072243e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.916704391410548803397953511596928808893685e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.592256249729202493268939584019491192080080e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.240081857804364904696255913500139170039349e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -9.968635402954290441376528527568797927543768e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.475731807209447934074840206826861054997914e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.961594409606987475034042150632670295904917e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -3.697515016601028609216707527257479621172555e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.591523031442252914289458638424672100510104e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.860638409502590149748648713304503849363893e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.850723614235842081434077716825371111986246e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.475844999417373489569601576817086030522522e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.804122560714365990744061859839148408328067e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.886336206511766947905039498619940334834436e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.714212931833249115161397417081604581762608e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.355056847554880232469037060291577918972607e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.254308400931922182743462783124793743058980e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -5.398154269396277345367516583851274647578103e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.647900793652290520419156346839352858087685e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.069961504286664892352397126472100106281531e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.462971538614891132079878533424998572755101e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -8.620091428399885297009840750915836982112365e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.547689636281132331592940788973245529484744e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.782453950387991004107321678322483537333246e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.881473972208065873607436095608077625677024e-25)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g() { return 2.472513680905104038743047567550092935562134e+01; } +}; + +BOOST_MATH_GPU_ENABLED inline double lanczos_g_near_1_and_2(const lanczos27MP&) +{ + return 17.03623256087303; +} + +// +// Lanczos Coefficients for N=35 G=2.96640371531248092651367187500000000000000000000000000e+01 +// Max experimental error (with 50 digit precision arithmetic) 67eps +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019 +// Type precision was 168 bits or 53 max_digits10 +// +struct lanczos35MP : public boost::math::integral_constant +{ + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.17215050716253100021302249837728942659410271586236104e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.51055117651708470336913962553466820524801246971658127e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40813458996718289733677017073036013655624930344397267e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.10569518324826607478187974291222641098997506635019681e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34502197565331471178368569687788687058240547971732391e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.74311603169690571192608960963509140372217014888512918e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.50656021978234091874071935392175934984492682009447097e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.12703102551730381018400796362603958419580969330315139e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.02844698442195350077632196816248435420923619452768200e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.90106767379334717236568166816961185224083190775430842e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.86371531667026447746284883480888667804130713757839681e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.34808948517797782155274346690360992144536507118093783e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.83232124439938458545786668616393415008373341980153072e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.62895707563068512468013948922815298700909218398406635e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.30384063116420066671650072267242339695473078925159324e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.76258309689585811716178198120267186946262194080905971e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51837231299916455171135124843484994848995300472356341e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.46324357690180919340289798257560253430931750807924001e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.75333853376321853646128997503611223620394342435525484e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01719517877315910652307531002686423847077617217874485e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.27861878894319497853745513558138184450369083409359360e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.89640024726662067702004632718605032785787967237099607e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.81537701811791870172286588846619085013138846074815251e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.03090758312551459302562064161308518889144037164899961e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.60538569869661647274451913615710409703905629234367906e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.18176163448730621246454091850022844174919234685832508e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.56586635256765282348264053213197702964352373258511008e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.58289895656990946427745668670352144404744258615044371e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.19373478903102411154024309088124853938046967389531861e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.54192605870424877025476980158698548681325282029269310e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.73027427579217615249706012469272147499107562412573337e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.82675918536460865549992482360500962016208597062710654e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.21869956201943834772161655315196962519434419814106818e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50897418653428667959996348205296461689142907811767371e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50662827463100050241576528481104525300698674060984055e+00)) + }; + BOOST_MATH_STATIC const T denom[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.84421398435712762388902267099927585742388886580864424e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28731583799033736725852757551292030085556435695468295e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.84381150359300352571680869181416248982215282642834936e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.68539753215772969226355064737523321566208288321687448e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.76117184320624276162478300964159399462275652881271996e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.59183627116994441494601110756468114877940946273012852e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.90089018057779871758440184258134151304912092733579104e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.02273473587728940068021671629793244969348874651645551e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.20304883823127369598764418881022021049206245678741573e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.03625836242722113759123056762610636251641913153595812e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.67794913334462808923359541498599600753842936204419932e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.69338859264140114791649895977363900871692586779302150e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.70864158121145435408364940074910197916145829346031858e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.13295647753179115743895667847873122731507276407230715e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.08730493440263847356723847541024859440843056640671533e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.92672649809905793239714364398097142490510744815940192e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.98815678372776973689475889094271298156568135487559824e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.15357141696015228406471054927723105303656292491717836e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29582156512528703674984172534752222415664014582498353e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.56951562180494343732211791410530161839249714612303326e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.67422350715677024140556410421772283993277946880053914e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.79254663081905790190270601146772274854974105071798035e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.61465496276608608941993297108655885737613121720232292e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34987044168298086318822469739196823360923972361455073e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.10209211537761991333937729340544738747931371426736883e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.85679879496413826670691454915567101976631415248412906e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.35974553231926272707704478737590721340254406209650188e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.38204802486455055334129565820015244464343854444712513e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.87247644413155087645140975008088533286977710080244249e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.01899805954981363917258740277358024893572331522514601e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.14314215799519834172753514406176454576793263619287700e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01075867159821346256470334018168931185179114379271616e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.59576526838074751422330690168945437827562833198707558e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28525092722679899458094768960179796663588010298597603e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28217919006153582429216342066702743329957749672852350e-13)) + }; + BOOST_MATH_STATIC const T denom[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[42] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.2258008829795701933757823508857131818190413131511363e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.1680809698202901664719598422224259984110345848176138e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.0937956909159916126016144892534179459545368045658870e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.2570860117223597345299309707009980433696777143916823e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.7808407045434705509914139521956838552432057817709310e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.5355182201018147597112724614545263772722036922648575e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.8474340895549068665467127190441982794533803160633534e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.9687073432491586288948383529096081854867384409828362e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.4457539281218595159502905008069838638140685905208109e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.0724321926101376768201888687693227423632630755627070e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.1941554220476109189863208161993450668341832413951177e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.0469416499468520752326008902894754184436051369514739e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.0254471406496505041361077191383344271915106887055424e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.9743975328123868311047848806382369109187457702980947e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.6326975883294075748535457727960259872733702003969396e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8276395425975110081829250599527615065306178329307764e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.4994926214942760944619799278085799215984014361562132e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.1685212562684580327244208091708941173130794374261284e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.0566129445336641178978472923139566421562362783155822e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.6744193557172228303189080097715371728193237070211608e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.3116377246238995291497495503598572469502355628188604e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.7791795131683583370183641939988202673347172514688534e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.6372242277604226411817535739257869758194674562641039e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.7502495488892655715569603094708394381657045801526069e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.0501577132014302973783965458067331883116843242885033e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.0246214059191840597181314245134333087378581123342727e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4016071303078853730266134475467378117726380022343630e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.6214830666337247122639245651193515459936309025504988e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.6312853482448038567407561706085851388360060108080568e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.4458785355627609495060506977643541320437284829970271e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.1331287575394227733315016732552406681866623847709417e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -7.8351635033967037250982310034619565150687081453609992e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.7520885958378593874310858129100278585054737696926701e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.5058409122183022757924336573867978222207111500077203e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.1353898614924597482474648262273645405650282912119167e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.3531153377666279783383214654257629384565834244973196e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.3839135182642184911017974189326632232475070566724497e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.5479558181723745255902653783884759401621303982915322e-29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.0441825447107352322817077249008075090725287665933142e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.0157887327297754418593987114368959771100770274203800e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.4607280988529299025458955706898751267120992042268667e-32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.2702032336418528894772149178970767164510337389404370e-33)) + }; + // LCOV_EXCL_STOP + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[42] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.3782193657165970743894979068466124765194827248379940e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.5325256602067816772285455933211570612342576586214891e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.8780522570799869937961476290263461833002660531646012e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8184384596766268378888212415693303553880671796724735e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.1851863962133477520750252664910607723762372771833722e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.9651417912803026185477059393373316779106801664686922e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.4509968222802070571038728168526976259879110509473673e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.7658529366356277958293590921029620586497540226150778e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.6785479743985639684438881535624244315638292743993560e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.8588900406390499925005060563245955316983471925301184e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.7619921996662567540276653040387614527561121386327888e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.4238684621351227134322239416053684476498738936970880e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.4045887339956612618258661862314001628281850888893694e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.5648780296066214471224136948413423004282323597057130e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4644654223878248996887367583334112564695286627087816e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.4332418933955508302078477926243914098802666261366678e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.0358676398914795323109452992079597262040795201720992e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.9450781456519433542572418782578042705818718277820822e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.7416614067965791526251519843473783727166050306987362e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.9866912469474631311384623900742191091588854047124831e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.7643298058164570865040068204832109970445542816595386e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.4928145473701388663847838847907869194628008362147191e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.6442105079571407791997926495585104881317603986245265e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.4668655090053572169091092679046557243825245275372519e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.4267531441890485644063141608998212380717408586417687e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -9.1904503977518246823477462773596622658428222241396033e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.2571863845333234910026102012663485977044671519503762e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.4544064381831932921238058900083969277495893492892409e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4631986986621358205011740516995928067691739105999606e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.2968960911316058263225162731552440661464077730310616e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.0163718599154085420173689991270137222141149005433561e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -7.0278330240079354003556694314544898753730575016426382e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.2624362787531585897289168590458242934350512724487489e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.2476405895248242769628910185593849817270999749433590e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.0183999810930941402072961555627198647985838184285745e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.9045729824028673594421184017022743317479187113896743e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.2413159115073860802650598534057774896614268826143102e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.1823766097367740928881247634568036933183255409575449e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.3183542619623422719031481991659628332908631907371078e-29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -9.1112247985618590949970839428497941653776549519221927e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.4859004327675283792859615082199609974336399587796249e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8302040910318742925508017945893539585506545571212821e-32)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g() { return 2.96640371531248092651367187500000000000000000000000000e+01; } +}; + +BOOST_MATH_GPU_ENABLED inline double lanczos_g_near_1_and_2(const lanczos35MP&) +{ + return 22.36563469469547; +} +// +// Lanczos Coefficients for N=48 G=2.880805098265409469604492187500000000000000000000000000000000000e+01 +// Max experimental error (with 60-digit precision arithmetic) 51eps +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019 +// Type precision was 201 bits or 63 max_digits10 +// +struct lanczos48MP : public boost::math::integral_constant +{ + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.761757987425932419978923296640371540367427757167447418730589877e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.723233313564421930629677035555276136256253817229396631458438691e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.460052620548943146316510839385235752729444155384745952604400014e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.118620599704657143233902039524163888476114389296433891234019212e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.103553323924588863191816202847384353588419783622786374048756587e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.051624469576894078907076790635986076815810433950937821174281248e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.865434054315747674202246332480484800778071304068935338977820344e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.291785980379681713553231795767203835753576510251486784293089714e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.073927196464385740270105346713079967925505577692095446860826790e+67)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.884317172328855613403642857232246924724496526520223674336243586e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.515983058669346491005379681336434957516572863544374020968683717e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.791988252541273516986153564408477102509671668999707480365384945e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.645764905652320236264233988360776875326874810201273735655153182e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.144135487589921315512939394666974184673239886993573956770438389e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.444700846549614719681016920231266383188819427952261902403138865e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.721099093953481665535866508692670759355705777392277743203856663e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.100969797434901880312682514502493221610943693861105392844971160e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.418121506159806547634040503980950792234471035467217702752406105e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.417864259432558812733518752689742288284271989351444645566759428e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.665995533734965936996397899459612023184583125575089834552055942e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.444766925649844009950058690449625999301860892596426461258095232e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.053637791492838551734963920042182131006240650838206322215619662e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.150696853422753584935226676401667305978026730065639035499393518e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.985976091763077924792684854305586783380530313659602423780141188e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.269589095786672590317833654141210781129738119237951536741077115e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.718300118825405526804849893058410300716988331091767076237827497e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.001037055130874457401651655102738871459032839441218104652569066e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.475842513986568687160423191409256650108932454810648362428602348e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.620452049086499203878684285356863241396518483154492676811559133e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.169661026157169583693125067814111812572434991018171004040405784e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.227918466522161929152413190031319328201533237960827483146218740e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.876388843752351291646654793076860108915313255758699513365393870e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.145947758366681136606104191450792163942386660344907590963820717e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.853323303407534484800459250019301328433169196161471441696806506e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.154628006575221227908667538321556179086649067527404327882584768e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.357526820024103486396860374714568600536209103260198100884104997e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.431529899588725297356982438015035066854198997921929156832870645e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.345565129287503320724079046959642760096964859126850291147857935e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.118851309483567225684739040233675455708538654675741148330404763e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.153371780240325463304870847387326315142505274277395976930776452e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.146212685927632120682088036018035709941745020823689824280902727e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.771109638413640784841091904266004758198074452790973613270876444e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.247775743837944205683004431867637625466576857881195465700397478e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.570311375510395966207715903995528566489264305503840005145629111e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.307932649387240491969419239876926639445902586258953887216911993e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.743144608535924824275750439447323876880302369055576390115394778e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.749690888961891063146468955091435916957208840312184463551812828e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.506628274631000502415765284811045253006986740609938316629929233e+00)) + }; + BOOST_MATH_STATIC const T denom[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.775732062655417998910881298714821053061055705608286949609421120e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.688437299644448784121592662352787426980194425446481703306505899e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.990941408817264621124181941423397180231807676408175000011574647e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.611362716446299768312931282360230566955098878347512701289885826e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.401071382066693821667231534775770086983519477562699643517826070e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.404885497858970433702192998314287586471872015950314081905843790e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.115877029354588030985670444733795075439494699793733843615128537e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.981190790128533233774351539949086864384527026303253658346042487e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.391693345003088328615594164751621620795026048184784616056424156e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.889256530644592752851605934648543064680013184446459552930302708e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.083600502252557317792851907104175947655615832167024966482957198e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.168663303100387254423547467716347840589509950430146037235024663e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.123598327107617380847613820395680616677588511868146055764672247e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.689997752127767317102012222013845618089045780981297513260591263e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.534390868711924145397558028431517797916157184545344400315049888e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.304302698603539256283286371502868034443493795813215278491516590e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.393109140624987047793401361048831961769792029208766436336102130e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.978018543190809154654104033779556195143800802618966016721119650e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.053360999285885098804414279382371819392475408561904784568215676e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.134477518753880004346650767299407142912151189519394755303948278e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.294423222517027804991661400849986263936601088969957809227734095e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.411090410120803602405769061472811786006792830932395177026805674e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.546364324011365762789375386661337991434000702963811196005801731e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.228448949533845774618310075362255075191314754073111861819975658e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.912781600174900095022672513908490962899309128877584272045832513e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.145953154225327686809754524860534768156895534588187817885425867e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.085123669861365984774838320924008647858451270384142925874188908e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.630367231261397170650842427640465271470437848007390468680241668e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.732182596346604787991836614669276692020582495778773122326853797e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.604810530255586389021528105443008249789929772232910820974558737e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.866283281281868197964883431828004811500103664332499479032936741e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.194674953754173153419535571352963617418336620849047024493757781e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.894136566262225941799684575793203365634052117390221232065529506e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.728530091896234109430773225830735206267902257956559214561779937e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.558479853180206010560597094150305393424259777860361999786422123e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.183799294403182487629551851184805610521945574359855930862189385e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.411871423439005125979602342436157376541872925894678545707600871e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.146934230284030660663814250662713645615827253848318877256260252e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.448218665084135299794121636822853382005896647323977605040284573e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.512810104228409918190743070957013357446861162954554120244345275e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.586025460907685522041021408846741988415862331430490056017676558e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.540359114012197595748944623835295064565126012703153392373623351e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.845554430040583564794301575257907183920519062724643766057340299e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.408536849955106342184570268692357634552350288861587703063273018e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.030953654039823541442226125506893371879437951634029024402619056e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.454172918244607114802676127860508419821673596398248024962237789e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155627562127299657410444702080985966726894475302009989071093439e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.725246714864934496649491688787278190129598018071339049048385845e-13)) + }; + BOOST_MATH_STATIC const T denom[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[47] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059629332377126683204423480567078764834299559082175332563440691e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.045539783916612448318159279915745234781500064405838259582295756e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.784116147862702971548198855631720823614071322755242269800139953e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.347627123899697763041970836639890836066182746484603984701614322e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.616287350264343765684251764154979472791739226517501453422663702e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.713882062539651653939339395399443747287004395732955159091898814e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.991169606573224259776909844091992693404451938778998047720606365e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.317302161605094814956529918647229867233820698992970037871348037e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.160243421312714521088457044577429625205805822189897013706603525e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.109943233027050100899811890306430189301581767622560123811853152e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.510589694767723034579229465791750718722450232983242500655372350e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.447631000703120050516586541372187152390222336990410786008441418e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.650513815713423478665128697883383003943391843803280033790640056e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.169833252147741984016531016457108860830636610643268300442548571e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.082891222574188256195988224106955541928146669677565424595939508e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.236107424816170540654753273736991964308279435358993150196240041e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.042295614972976540486053879488442847688158698802215145729595300e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -6.301008161384761854991230670333450694872613042265540662425668275e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.626174700692043436308812511757112824553679923076031241653340508e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.165638597797307942127436742547456896168876912136407736672893749e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.193760947891421842393017150194414897043594152709554867681454093e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.102566205604210639065160857917396944102487766555058309172771685e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.915816623470797626925445072607835810426224865943397673652473644e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.588275837841705058968991523347781566219989845111381889185487327e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.200550301285945062259329336559146630395284987411539369061121774e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.164333226683698411437894680594408940426530663957731548446585176e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.066415481671710192926882432742434212829003971627792457166443068e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.794259516500627365643093960688415401054083199354112116216326548e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.109766027021453750770079684473469373477285891593627979028234104e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.857040454431507009464118652247309465880198950544005451066913133e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.257636833252205356462338019252188768182918234805529456629813332e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.657386968948568677903872677704817552898314429680193647771915640e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.807368757318279512579151153998249666772948741065806312921477647e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.661046240741398691824399424582067048482718145278248186045239803e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.310274358393495831279259654715581878034928245769119610060724565e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.979289812994200254512860775692570111131240734486735844065571645e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -5.374132043246630393307108400571746261019561481928368054130159659e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.807680467889122570534300256450516518962725443297886143108832476e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.273791157694681089776609329544693948790210894828257493359951461e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.971177216154470328027539744763226999793762414262864963697237346e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.645869582759689501568146144102914403686604774258048281344406053e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.533836765077295478897031652308024155740827573708543095934776509e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.011071482407693628614243045457397049948479637840391111641112292e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.753334959707221495336088007359122169612976692723773645699626150e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.217604773736938924265403811396189809599754278055061061653740309e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.819104328189909539214493755590516594857915205552841395610714917e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.261124772729210946163851510369531392121538686694430629664292782e-42)) + }; + // LCOV_EXCL_STOP + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[47] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.201442621036266842137537764128372139686555918574926377003612763e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.185467427150643969519910927764836582205108528009141221591420898e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.424388386017623557963301151646679462091516489317860889362683594e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.527983998220780910263892115033927387104053611029099941633323011e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.966432728352315714505545454293409301356907573727621630702827634e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.210921746972897898551337991192707389898034825880579655985363009e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.525319492963037163576188790739239848749059077112768508582824310e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.761266399512640929192286468240357629226481512485264527650043412e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.449355108314973517543246836489412427594992113516547680523282212e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.258490177973741431378782429416242097479994678322390199981700552e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.114255088752286384038861754183366335220682008583459292808501983e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.641371685961506906939690430062582517060728808639566257675679493e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.139072742579462987548668350779672609568514018384674745960251434e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.129392978890804438983060711164783076784089453197491087525720250e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.227817717944841986447189375517242505918979312023367060292099051e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.401539292067249253713639886818857395065226008969910929456090178e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.181789081601278618540976740818676551399023595924451938057596056e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.144290488450459735914078985115746320918090890348935029860425141e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.977643331768050273059868974450773270172308183228656321879824795e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.124636941696344229278652214634921673116603924841964381194849043e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.353525462444406600575359080915245707387262742058104197063680358e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.250125861423094782405286690199652039727315544398975014264972834e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.573714720964717327652547152474097356959063887913062262865877352e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -9.737669879005051560419153179757554889911318336987864449783329044e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.762722217636305077074994367900679148917691897585712642440813437e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.587825185218585020252537180920386716805319681061835516115435092e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.209136980512837161314713015292452549173388035330975386269996826e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.034390508507134900778125110328032318737425888723900242108805840e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.659788018772143666295222723749466460348336784193790467337277007e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.908571128342935499766722474863105091718059244706787068658556651e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.425950044120254934054607924023969978647876123112048584684333719e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.879199908120536747953526966437055347446296944118172532473563579e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.049254197314637745167349860869170443784687973315125511356920644e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.883348910945891785870183207161008885784794173754432580579430117e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.485632203001929498321635338807138918181560966989477820879657556e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.018101439657813295290872898460623215815148336073781084176896879e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -6.093367832078140478972419022586567008505333455627897676553352131e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.183440545955440848970303491445824299419388286256245840846211512e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.444266348988579122529259208173467560400718346248315966198898381e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.636484383471871096369253024129613184534143941833907586683970329e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.866141116496477515961611479835778926021343627571438400431425496e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.140613382384541819628458619521408963917801187880958447868987984e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.146386132171160390143187663792496413753249459594650450672610453e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.987988898740147227778865012441676866493607979490727350027458052e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.514393298082843730831623322496784440966181704206301582735570257e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.062560373914843383483799612278119836498689222815662595453851079e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.232902310328177520527925464546117674377821202617522000849431630e-41)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g() { return 2.880805098265409469604492187500000000000000000000000000000000000e+01; } +}; +// +// Lanczos Coefficients for N=49 G=3.531905273437499914734871708787977695465087890625000000000000000000000000e+01 +// Max experimental error (with MP precision arithmetic) 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 23 2021 +// Type precision was 234 bits or 72 max_digits10 +// +struct lanczos49MP : public boost::math::integral_constant +{ + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.019754080776483553135944314398390557182640085494778723336498544843678485e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.676059842235360762770131859925648183945167646928679564649946220888559950e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.735650057396761011129552305882284776566019938011364428733911563803428382e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.344111322348095681337661934126816558843997557802467558098296633193647235e+74)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.279680216265226689865713732197298481387164441051031689408254603978998739e+74)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.534520884978570988754896701605114795240254179745381857143817149573644190e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.094111428842887690996413081740290562974159836498138544655694952917058279e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.810579629726532069935485995735078752851873354363515145898406449827612179e+72)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.558918434547693216059693184449337082460551934950816980580247364223027781e+71)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.135873934032978624782044873078145389831812962597897650459872577452106819e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.371686637133152315568960647279607142944608875215381633194517073295482279e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.210709791290211789451664416279176396010610028867877916229859938579263979e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.728493971517374186383948573740973812742868532549695728659376828743835354e+67)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.082196640005602972025690170863702787506422900608580581233509996818990072e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.434296904963427729210616126543061543796855074189151534322145897294331943e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.956561957668034323532429269801091280845027370525277092791205986418388937e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.088465031117387833989029481250197681372395074774197408003458965955199114e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.638006253255673292005995366039132327048285444095672469721651872147026836e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.251091350064240218784436940525650498454117574503185703454335896105827459e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.438965470269742797671507642697325276853822736866823134892262314489634493e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.171096428020164782492194583597894107448038723781192404665010946856416728e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.967964763783296071512049792468354332039332869323402055488486515880211228e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.691239511306362286583973595898917873397629545053239582674237238671075149e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.371351678345135454487045322888974392983710298168736348320865063481886470e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.399139456864000364822305296187724318277750756512114883045860699513780982e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.335644907596902422235465624341780552277299385700659659374735347476790554e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.541494306852766687136536628805359613169443442681232300932385167150904206e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.454056970723993494338669836718832149990196703371093557999871225274488103e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.122804036582476347394286398036300142213667443126058369432667730381406969e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.350437044906396962588019269622122085882249454809361766675217669398941902e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.350870345849974415762276588597695308720927596639430565914494820338490132e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.751385019528115548010259296564491721747559138159547937603014471132985302e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.476113159838159765344429146854859477076267913220368138623944281045558949e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.294398437121931983845715884547145127710330599817550100565429763115048575e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.839781945206891229035081139535266037057033378415390353746447012903101485e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.711123560991297649877080280435694393772679378388200862936651880878974513e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.629549637595714724789129505098155944312207076674498749184233965222505036e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.574490956477982663124058935512682291631619753616365947349506147258465402e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.813448512582564107136706674347542806763477703915847701777955330517207527e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.794883897023788035285405896000621807947409236640451176090748912226153397e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.960479107645842137800504870276268649357196518321705636965540139043447991e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.584873693858658935208259218348427715203386574579073396812006362138544628e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.245936834930690813978996898166861135901321349975150652784783993349872251e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.773017141345068472510554017030953209437181800565207451480397068178339458e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.641092177320087625773994531564401851985558319657745034892144486195046163e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.105900602857710093040451403979744395599050533242553243284994146810134883e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.764831079995208797424885873124263386851285031310243195313947355076198006e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.390800780998954208500039666019609185743083611214630479125238184115750385e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.506628274631000502415765284811045253006986740609938316629923576327386304e+00)) + }; + BOOST_MATH_STATIC const T denom[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.586232415111681806429643551536119799691976323891200000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.147760594457772724544789095126583405046340554378444800000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.336873167741057974874912069439520834275222024827699200000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.939317717948202275053279980882650292343063152909352960000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.587321266207338310075066414082486631849657629849681920000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.708759679197182632355739853743909528366304368999677296640000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.853793140116069180377738686747691213170064352110549401600000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.712847307796887697739638943011607706661342285570961571840000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.289323070446191229806483814370209648903283093834096836608000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.773184626371587855448424329320482554352785932897781894348800000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.435061276344423987072041299926950982073631843385358712832000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.038454928643566553335326814205831024316152779380233211904000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.839990097014298964461251746728788062040820983609914982400000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.354892309375504992458915625473361082395092049509521612800000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.297725282262744672148100400166565576520346155229059072000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.209049614463758144562437732220821438434464881014066944000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.403659584108905732081564809222007746403637980496076800000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.460430771262504410833767704612689276896332359898060800000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.366143204159002782577065768878538489390347732147072000000000000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.152069768627836143111498892510529224478160293107040000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.778134072359739526905845579458057851415301312320000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.054274336803456047167091188388392791058897181680000000000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.785217864372490349864295597961987080566291959200000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.147675745636024418606666386969855430516329329000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.106702410770888109717062552947599620817425600000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.181697115208175590688403931524236804258068000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.204691425427143998305817115095088274690720000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.522623270425567317240421434031487657474000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.991703958167186325234691030612357960000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.527992642977421966550442489563632412000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.749637581210127837980751990835613680000000000000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.178189516884684460466301376197071000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.691582574877344639525149014665600000000000000000000000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.588845541974326926673272048872000000000000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.832472360434176596931313852800000000000000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.162585907585797437278546956000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.759447826405610148821312000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.354174640292022182957920000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.764512833139771127128000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.823199175622735427100000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.478468141272164800000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.842713641648132000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.137488170420800000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.672014134600000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.194862400000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.183320000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.128000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.256115936295239128792053510340342045264892843178101822334871337037830072e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.226382973449509462464247401218271019985727521806127065773488938845990367e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.954125855720840120393676022050001333138789037332565663424594891457273557e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.365654586155298475098646391183374531128854691159534781627889669107191405e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.044730374864121201936514442517987939299764008179567577221682561782183421e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.536356651078758500509516730725625323443004425012359430385110182685573948e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.014086778674585662580239648780048641118590040590185584314710995851825637e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.297512615100351568281310997196097430272736169985311846063847409602541101e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.172699484909110833455814713100736399837181820940085502574724938707290372e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.437106278000765568297205273500695563702563420274384149002742312586130286e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.545174371038470657228461270859888251519093095798232203286784662979129719e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.471402006255895070535216946049289412987253853074246902793428565040300946e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.250412452299054568666234182931337401773386777590706330586351790579683785e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.542277292811232416618979097150690892713986488440887554977845301225180167e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.573086578098175124839634461979173468237189761083032074786971884241523043e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.104607420271440962257749252277010146224322860594339170999893725175800398e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.331938462909285706991247107187321645123045527742414883815000495606636547e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.208943799307442534797422457740696336724404643783689597868534121046756796e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.733493346199244389057953770564978235470425412393741328222813802783023596e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.492565577437473684677047557246888601845840521959370888739670894941330993e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.949686666262532681847746981577965659951530620900061798663932175932503947e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.651553737747111429808666993553840522239787479567412806226997545642698201e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.233339502372167653077823100186702309252932859938068579827741608727620372e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.836417632015534931979173072268670137192644539820843175043472436022533106e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.099476078371695988128239701316213720767789442435824569996795481661867708e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.903495249944998411669955533495843613032560579446280190215596256375769138e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.064350138053898858268455142115215057417819864153422362951139202939062254e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.582922994233975143266417356893351025577967930478759984258796518122317112e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.264234026390622585348908134631186844315412961960282698027228844566912117e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.188774153889105680535092985608022230760508397240005354866271201170463092e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.077355341399798609786211120408446935756994848842131485074396331912972263e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.719182300108746375704686202821491852452619639378413670885143111968297622e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.509589596583338412898049035294868361167322854043341291672085090640104583e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.342872197271389972201661238004898097226547537612646678471852083509061055e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.051089551701679946626603411942133093477647785693757342688765248578133558e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.450407423742747934005020832364099630124534867513398798024857849571995697e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.413023778896356322547226273989314105826233010702360664846872922408122652e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.929512168994516762673517469057078217752079550440541815733308359698355209e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.122462776963280343259527700358220850883119067227711325233658329309622143e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.197396290684303702682694949348422316362810937601334045965871833844532390e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.356726450420886407112529306259506900505875228060535982041959265851381932e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.263148912218322814862431970673685825699419657740452507847522864799628960e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.320663245567314255422944457710191091603773917350053498982455870821336578e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.270816501767199044429825237923512258332267743288560304635568302760089360e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.960034133400021433681975737071902053498506976351095156717280432287769760e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.650907660437171004901238983264357806498757360812524606971708594836581635e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.725344352001816640635025885398718044955247687225228912342703408863775468e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.012213341659767638341287600182102653785253052492980766472349845276996656e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.148735984247176123115370642724455566337349193609892794757225210307646070e-15)) + }; + BOOST_MATH_STATIC const T denom[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.586232415111681806429643551536119799691976323891200000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.147760594457772724544789095126583405046340554378444800000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.336873167741057974874912069439520834275222024827699200000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.939317717948202275053279980882650292343063152909352960000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.587321266207338310075066414082486631849657629849681920000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.708759679197182632355739853743909528366304368999677296640000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.853793140116069180377738686747691213170064352110549401600000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.712847307796887697739638943011607706661342285570961571840000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.289323070446191229806483814370209648903283093834096836608000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.773184626371587855448424329320482554352785932897781894348800000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.435061276344423987072041299926950982073631843385358712832000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.038454928643566553335326814205831024316152779380233211904000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.839990097014298964461251746728788062040820983609914982400000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.354892309375504992458915625473361082395092049509521612800000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.297725282262744672148100400166565576520346155229059072000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.209049614463758144562437732220821438434464881014066944000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.403659584108905732081564809222007746403637980496076800000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.460430771262504410833767704612689276896332359898060800000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.366143204159002782577065768878538489390347732147072000000000000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.152069768627836143111498892510529224478160293107040000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.778134072359739526905845579458057851415301312320000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.054274336803456047167091188388392791058897181680000000000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.785217864372490349864295597961987080566291959200000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.147675745636024418606666386969855430516329329000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.106702410770888109717062552947599620817425600000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.181697115208175590688403931524236804258068000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.204691425427143998305817115095088274690720000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.522623270425567317240421434031487657474000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.991703958167186325234691030612357960000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.527992642977421966550442489563632412000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.749637581210127837980751990835613680000000000000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.178189516884684460466301376197071000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.691582574877344639525149014665600000000000000000000000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.588845541974326926673272048872000000000000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.832472360434176596931313852800000000000000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.162585907585797437278546956000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.759447826405610148821312000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.354174640292022182957920000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.764512833139771127128000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.823199175622735427100000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.478468141272164800000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.842713641648132000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.137488170420800000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.672014134600000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.194862400000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.183320000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.128000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.233965513689195496302526816415068018137532804347903252026160914018410959e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.432567696701419045483804034990696504881298696037704685583731202573594084e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.800990151010204780591569831451389602736047219596430673280355834870101274e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.648373417629954217779547889047207255669324591553480603234009701221311635e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.284437059737535030909183878223579768026497336818714964176813046702885009e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.107670081863262975759677889098250504331506870772724719160419469778560968e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.504360049237893454280746661699303420195288960483588101185311510511921407e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.611963690317610801367925234041815344408602188860817148261094946859641055e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.384196825969374886217890731633708081987015968697189525652444057097652970e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -9.622790278065968351142661698209916105231451436587332112667311309898112907e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.449580263451402816852387882691399098166718792531955596134468390704873784e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.521891259305373384442177581056279631601936059906718384076120380236152660e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.540905879286304237452585078525021002948388724011947750659051968465604420e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.945234350579576646146368625320015500721771847656877764914364796999018932e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.387416831492605275144126841246803690906548552137287238128485938487779304e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.495798927786732788454640929952042349030889163403974404914516146280530443e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.422943482445615791699986810123527175351383953692494761445061153868299970e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.102903565532198274392276413606953369815588940855811878456066484772851432e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.094535028891646496546262084074169534843273855151767819779938179094208188e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.358095366769232988323350838247191988585424776577310286935330610243011743e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.340530976890392038064297300042596231921772020705486053763028541479656280e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.516126555541810552632615941497264105370152230590961486150754875983890898e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.581070770182358530034488215134552244420314579258249233845063889274308385e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.004041803560396287949218893554883846494476801309699018606217164405518118e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.544940513373792201443764129828570298376651506143103507977578771056330357e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.379886756316120706725450388823927894039691498002769785120646242635823255e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.045944766231461555774689284231476775257484866624431880423176393512207387e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.148008349481903710728852060629194581596537318553456161574664356163226596e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.275939213508899016428747078031525836021120921513924955762486505940940452e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.002074313199153828387282409848698339315167131865367803807278126600553143e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.312111841788085794021549817149806212210409562054999023338937587332395908e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.626943187621427535665396572257733498961554813667830477603994486170242725e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.301342661659868689654008011518619781951990528882947953585638647826710208e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.943206436729179344584590804980950978078020765463364229230497237642990035e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.427985516258891942239250982488681113868086410604389604401061682071089711e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.507315406936486999900039292673781706696418133992677762607195734544800586e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.128602212783277628616662270027724563712726585388232543952969868791288808e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.491772665541813784561971549986243397968726526748411110109050933398474269e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.703534948980953284999107504304646577995487754638088095508324603995172100e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.254734374358011114570777363031532176229997594050978074992481078060588238e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.744400882431682663010546719169103111178937911186079762496396144974231758e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.962681142344559707919656870822506290159603512929253279249408502104315114e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.676028721091677637759913537058723470799950761402802553076562435074866681e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.784145301171889911387402141919770031244273301985414474074193734901497838e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.609382025715763421062067113377305459236198785081684246167946524325632358e-44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -8.390549764136377795654766730143252213193890014751189315315457960953487009e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.892571860428412953244204670046307154753124542150699703190076405369134986e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.750996769906711001487027901108989269217518777400665423098451353536180397e-47)) + }; + // LCOV_EXCL_STOP + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.614127734928823683399031924928203896697519780457812139739363243361356121e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.873915620620241270111954934939697069495813017577862172724257417200307532e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.020433263568799913803105156119729477192007677199414299858195073560627451e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.464288862550385816890047588667703388387049707546055857832236105882063068e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.220557255453323997837181773609238378313171107809994660932186398177260086e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.448922988893760252035044756495535237100474172953062930583429032976738764e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.967825884804576295373543809345485166700533400342174877153161242305801190e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.108580240999530194943835615053920860235079936071561387017856553284307741e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.810642568703399030220299393722324927217417866857948859237865608524037352e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.258739608434628125323282855631713548863857229929349389847042534864564944e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.128496339139347963949841917163532287235353252857530075762245657435637432e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.298839862995292241245807816785011319551976707839297599695370993581498944e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.248028459892634227909925496833936295152351078572924268478121601580013392e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.852607223132643180520259993802350485519940462836224552121831884016060957e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.663344935420648740647632834149137036410170363282848810726789852512040974e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.956627238308290890004850312580119602770863155061517303602115059073018915e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.169408084580850119987259593698335014334975914638255180200227109093248923e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.058851441448441752395908342271882717629330686791993331066549580482119207e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.047904711622988136321913253467026391205138759157051345098701122533901641e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.084581449711468658856874852797634685668605539676219540421511092086784257e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.753524069615947925605286028020036313127948537531901833841745089038345419e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.215544327537876774584851905154058374732203881621234998864896154317725107e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.068169776809028066872463505146223239383722607505095101927453621607143258e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.929532177536816530254915957100118239727512976366989010196601003141928983e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.637071893688824301043677755554700799944720607401583032240419889530137613e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.113086368090515818656083953394041201305628629939937324183681568207995992e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.052475329075586591944149534403412432330839345810529801140374324740860043e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.501688739492061913271178171928421774535209059448213231063121542726735922e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.901359655394917555561825304708227606591126162154019191593957327845941711e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -6.543121984804052902464306048576584437634232699686221158393201347605610557e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.640594686585611716813857202286477090235259523435190405734068397561049518e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.360501538535076761830231649645320930651740695652757112015168140991871811e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.702262550718545671102818966852852449667460777654069395734978498316238097e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.541872823365472358451692936741339351955915607098512711275660224596475692e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.176003476857354088823169817786505980377842772003301806663816129924483628e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.279773456918425628141724849602711155924011970103858226014129388572719403e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.784385649492108496180681575852127700091310578360977342260193352159187181e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.951360558254817806983487356566692526413661637802019026539779594905551108e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.138493498985334706374097781200574458692873800531006014767134080212447095e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.565540270144127561133019747139820473778629043608866511009741796439135919e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.281818911412862056602174736820614290615384940807745468773991962352596562e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.799674220733213250330301520376602557698625350979839820580611411813901622e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.192382536820850868749995412323169490150589703968805623276375892630104761e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.949971304595638285364920838869349221534754917093372730956379282259345856e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.645611826340683772044616248727903964535937439036743879074020086333544390e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.097552479007470044347986004697357054639788223386746160457893283010512693e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.016047273189589762707582112298788030798897468010511171850691914431226857e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.598528593988298984798384438686079221879557020145063999565131046963034260e-46)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g() { return 3.531905273437499914734871708787977695465087890625000000000000000000000000e+01; } +}; + +BOOST_MATH_GPU_ENABLED inline double lanczos_g_near_1_and_2(const lanczos49MP&) +{ + return 33.54638671875000; +} + +// +// Lanczos Coefficients for N=52 G=4.9921416015624998863131622783839702606201171875000000000000000000000000000000000000e+01 +// Max experimental error (with MP precision arithmetic) 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 22 2021 +// Type precision was 267 bits or 82 max_digits10 +// +struct lanczos52MP : public boost::math::integral_constant +{ + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2155666558597192337239536765115831322604714024167432764126799013946738944179064162e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.4127424062560995063147129656553600039438028633959646865531341376543275935920940510e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2432219642804430367752303997394644425738553439619047355470691880100895245432999409e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0716287209474721369403884015994122665163651602768597920624758793936677215462844844e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6014675657079399574912415792629561012344641595734333223485162579517263855066064448e+85)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.9469676695440316675866392095745726625355531618465991865275205877617243118858829897e+84)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.6725271559955312030697432949232367888201769834554225137624859446813736913045818789e+83)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.9780497929717466762906957902715326245615108291247102827737801883575021795143342955e+82)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1101996681004003890634693624249367763382356608502270377869975360325542360496573703e+82)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0730494939748425861290791265310097852481749101609248058586423168275758843014930972e+81)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.1172053614337336389459663390209768009612090987295451850767107564157925998672033369e+79)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.8745706482859815560001340912167784132864948819270481387088631069414787418480398968e+78)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.6357176185157048005266104227745750047123126912102898052446617690907900639513363491e+77)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8133959284164525780065088214012765730887094925955713435258703832914376223639644932e+76)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5448240429477602353083070839059087571962149587434416045281607922549720081768160509e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.7087163798498299832185901789792446192843546181020939291287863440328666852365937976e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5087881343681529988104227139117041222747015656224230641710513581568311157611360164e+72)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4613990031561986058105893353533330535471171288800176856715938119122276074192401252e+71)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.5842870550209699690118875938391296069620575640884684638841925128818533345720622707e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9620974233284411294099207169175001352700074635064713292874723705223947089062735699e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3508670578887212089913735806070046196943428333276779526487779234259460474649929457e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8965656059697746722951241391165378222796048954133067890004635351203115571283351365e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.2318932193708961851167812069245962898666936025147808964284039760031905048392189838e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3345087899695578368548637479429057252399026780996532026306572668368481753083446035e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1496377806602727082710361157715063723084394483433707624016834119253720339362659524e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.8813988021021593903128761372635593523664342047294885462297735355749747492567917846e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3920956168650489448209669451137968296707297452484593173253158710325555644182737609e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6075799130233642952967048487438119546115615639287311948474085370143960495152991553e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5215062065032735365892761801093050964342794846560150713881139044884954246649618411e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.2544625196666558309461059934941389307783421507071758131936839820683873609174384275e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0762146929190267795931737389984769617036500590695127135611707890269647516827819385e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4748530311527356370488285932357594780386892716488623785717991900210848418789146683e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8647515097879595082625933421641550420004206477055484917914396725134286781971556627e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1719649433541326415406560692060639805792580579388667358862336598215919709516402950e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3261545166351967601378626266818200343311913249759151579277193749871910741821474852e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2856597199911108057679518458817252978491416960383076400280909448497251424577297828e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0550442252418806202988575468283015522717243147245311227478147425985867569431393246e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6853992677311201643273807677942992750803865734634293875367989072577697582186788546e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2561436609157539906689091056055983931948431067099841829117491622768568140084478954e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.4705206401662673954957473131998048608819946981033942322942114785407455940229233196e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.1407133281903210341367420024686210845937006762879607281383052013961468193494392782e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.7901285852211406723998154843259068960125192963338996339928284868353890653815257694e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3438998631585891046402379167404007265944767353624748363650936091693896699924614422e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.6902706401090767936392657986442523138728548699749092883267263725876049498265301615e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0929659841192947874271802260842934838560431084502779238527946412041140734245143884e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5862712170406726646812829026907981494912831615106789457689818325123973212320279526e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7379005522986464990683100411983090503131358664627225315444053238030719367736285441e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.7401492854176051649551304067922101744785432102294852270917872876250420006402939364e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3052097444388598287826452442622724171650622602495079541553039504582845036611195233e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.8093796662195533917872631136981728293723308532958487302137409818490410036072819019e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3192906485096381210566149918556620595525679738152760526187454875638091923687554946e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5066282746310005024157652848110452530069867406099383166299235763422936546004304390e+00)) + }; + BOOST_MATH_STATIC const T denom[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0414093201713378043612608166064768844377641568960512000000000000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3683925049359750564345782687270252191318781054337155072000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8312047394413543873001574618939688475496532684433218600960000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6266290361540649084000356943724186480051615706407501824000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2578261522689833134479268958172001145701798207577980403712000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2001844261052005486660334218376501837226733355004196185702400000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1681037008119350981332433342566749327534832358109654944841728000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0293361153311185534392570196926631029364162024577328008396800000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7968291458361430782020246122299560311802074147902210076049408000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4212998306869600977887871207212578754682594793002122395254784000000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4006322967557247180769968530346138316658911433773347563153653760000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1334912462852682149761710693821775975226278702191992823808000000000000000000000000e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1263921790865468343839418571823409266633338824655665334886400000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0548002159482240692664043366538929906734975613031337827840000000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6095781466700764043324234378972985924892034584990590768742400000000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1887214284827766716471402753528692603931747042835394432000000000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6644926572075096083148238618984385847884240529010940198400000000000000000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9154102380883742873084802432628398856163736124576909120000000000000000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8768151045628896730547232493410634338494669305466040192000000000000000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5674503027583263140245049650089911892130421780961760000000000000000000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0774565729992714117801952876016228015049549176491224000000000000000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5271995659293168127377699172748774995796493494870600000000000000000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0217297271367563021376459886512004721472442416486880000000000000000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2295402510227377004563262212164474005108576587500000000000000000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4652078765044198452095090589463630638929867781650000000000000000000000000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7599751702378955591170076678443001141850220448750000000000000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.1661954970720573655661780303655361431161958585000000000000000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4624589782073664468902246801624082962588775000000000000000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3415303241063823936930939721131813816093940000000000000000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7484118887814252101652801793318408875609500000000000000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5345701242523770267594030980609724717749800000000000000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5242293875075726230709587746676742825000000000000000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2153799706792737162996155167868591485000000000000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9704836232659058554494106146940431250000000000000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5926306456751344865378122278650335000000000000000000000000000000000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3255133142885196993084362383550000000000000000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4074634262098477202456261501600000000000000000000000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9362537824702021303895557050000000000000000000000000000000000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7695574975175958167624223800000000000000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5430949131153796097540000000000000000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.7427444047045863749135000000000000000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.9163115009072256171250000000000000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9274383168492884295000000000000000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.0731790610548750000000000000000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9491312919646000000000000000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1366198225750000000000000000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.3570498490000000000000000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1862250000000000000000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9135000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2750000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_expG_scaled(const T& z) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T num[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2968364952374867351881152115042817894191583875220489481700563388077315440993668645e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3379758994539627857606593702434364057385206718035611620158459666404856221820703129e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.7667661507089657936560642518188013126674666141084536651063996312630940638352438169e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2358817974531517479015567958773172164495426366469934483861648449503257164430597676e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4277884337482721045863559292777143585727342521289738221346249419373476553706960477e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0321517843552558179026592998573667333331808062275687745076218349815677074985963362e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6008215787076020416349896191435806440785263359504290408274535992043818825469757467e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0818534880683055883178218002277669005830432150690130666222387190067193078388546735e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3163575041638782544481444410280012073460223217514438140658322833554580013590099428e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2388461455413602821779255933063678852868399289922539164611151211712717693487661387e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9022440433706121764851738708000810548525373575286185895490944900856672029848122464e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4343332795539887118781806263726922877784774015269102474184340994778721415926159254e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.6721153873219058826376914786734034750310419590675042405183247501763477751707551977e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.8699628167986487178009534272364155924157279822557444996249799757685987843467799627e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2231722520846745745100754786781488061001048923809737738337722261187091800649653747e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6083722187098822924476598339806607838145759265459316214837904824198871273160389130e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.3208522386531907691637761481331075921814846045082743370064300808114976199945037122e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0491114749931089548713463433723654679587396917777106103842119656518486449033314603e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1651242201716492163343440840407055970036142959703118121095709130441296636187948680e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.0937853081905503955154539906393844955264076759979726863680373891843152853217317289e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3250660210211249438634406634827812076838178133500698949898645633350310552370070845e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9570575453729198045577937136948643736522682229986841993417806493265120889607818521e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0915995985127530070498760979124015775616748288243587047367665303776535820627821806e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.7843635148151485646319955417265990806303645948936943738048724343049029864512194310e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5715089981189796608580098957107087883056675964697423692398096552244865201126563742e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4357579282713452366310121777478478833619311278663562587227576970753556113485917320e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9045145853415845950075255530781663873014618840017618405203106705648527948595759022e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4405414384364870662900944749199576151689786973539596080446881216688775114111401244e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.4338208995125086931437020109275839003754703899452696411395381222142064582727164193e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5135951828248789401437398422210292739440102976394266807495518051141687446206426902e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2454501218684993019799803589484969919745689383924985827556442495293105857928357346e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0771824063818140076215034706980442595962662610399835096143334152833816531221628660e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.8906795572088352821870480514365587413988764084322141604846302060067104077934035979e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5316598805398286987903918997966274192433403859480290402541541527289805994033568970e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8533661333839969582529636915290426021792269810841946250308753325085094758818317464e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7688764431225908123092120518561018783609436337842987641148647520393460757258932651e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.2877126063932361367573287637428749753108811218139980724742491890986894871059180965e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5164730755154849065370365582371664006783859248354506763822538105452920154803662025e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6208599037402680475080806960664748732421517587082652352333314249266933718172853538e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7673175927530323929887314159232706831613273850912577130092484125942772196619237882e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0725755228231653548395606930605822556041123469753556193146323302002970112193491322e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.8214170582643892131251904381692606071847290625764371754232909841174413907293095377e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8039573621910762166001861467061356387294777080327106241940313632291985560896860294e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1872369877837204032074079418146123055615124618000942960799358353269625124323889098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.3668338250989578832466315465536077672534713261875481920848252453271529995224516632e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3741815275584317532245789502116967720634823787379160467839166784058598703361284195e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6260135014231198723283200126807995474827979567257597700738272144468899515236872878e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.8035718374820798318368374097127140964803349360705519156103446564446533105562174708e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3155399273220963343988533731471377905809634204429087235409329216539588313353641052e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6293749415061585604836546051163481302110136557722031417335367202114639560092787049e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3184778139696006596104645792244972612333458493576785210966728195969324996631733257e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.2299125832253333486600023635817464870204660970908989075481425992405717273229096642e-22)) + }; + BOOST_MATH_STATIC const T denom[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0414093201713378043612608166064768844377641568960512000000000000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3683925049359750564345782687270252191318781054337155072000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8312047394413543873001574618939688475496532684433218600960000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6266290361540649084000356943724186480051615706407501824000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2578261522689833134479268958172001145701798207577980403712000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2001844261052005486660334218376501837226733355004196185702400000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1681037008119350981332433342566749327534832358109654944841728000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0293361153311185534392570196926631029364162024577328008396800000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7968291458361430782020246122299560311802074147902210076049408000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4212998306869600977887871207212578754682594793002122395254784000000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4006322967557247180769968530346138316658911433773347563153653760000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1334912462852682149761710693821775975226278702191992823808000000000000000000000000e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1263921790865468343839418571823409266633338824655665334886400000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0548002159482240692664043366538929906734975613031337827840000000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6095781466700764043324234378972985924892034584990590768742400000000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1887214284827766716471402753528692603931747042835394432000000000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6644926572075096083148238618984385847884240529010940198400000000000000000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9154102380883742873084802432628398856163736124576909120000000000000000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8768151045628896730547232493410634338494669305466040192000000000000000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5674503027583263140245049650089911892130421780961760000000000000000000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0774565729992714117801952876016228015049549176491224000000000000000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5271995659293168127377699172748774995796493494870600000000000000000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0217297271367563021376459886512004721472442416486880000000000000000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2295402510227377004563262212164474005108576587500000000000000000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4652078765044198452095090589463630638929867781650000000000000000000000000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7599751702378955591170076678443001141850220448750000000000000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.1661954970720573655661780303655361431161958585000000000000000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4624589782073664468902246801624082962588775000000000000000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3415303241063823936930939721131813816093940000000000000000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7484118887814252101652801793318408875609500000000000000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5345701242523770267594030980609724717749800000000000000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5242293875075726230709587746676742825000000000000000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2153799706792737162996155167868591485000000000000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9704836232659058554494106146940431250000000000000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5926306456751344865378122278650335000000000000000000000000000000000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3255133142885196993084362383550000000000000000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4074634262098477202456261501600000000000000000000000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9362537824702021303895557050000000000000000000000000000000000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7695574975175958167624223800000000000000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5430949131153796097540000000000000000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.7427444047045863749135000000000000000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.9163115009072256171250000000000000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9274383168492884295000000000000000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.0731790610548750000000000000000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9491312919646000000000000000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1366198225750000000000000000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.3570498490000000000000000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1862250000000000000000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9135000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2750000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + // LCOV_EXCL_STOP + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_1(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[56] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4249481633301349696310814410227012806541100102720500928500445853537331413655453290e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9263209672927829270913652941762375058727326960303110137656951784697992824730035351e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2326134462101140657073655882621393643823409472993225649429843685598155061860815843e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.9662801801612054404095225935108977904002486830482176026791636595192650184999106786e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4138906470545941456294493142170199869989528110729651897652377168498087934667952997e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0258375230969759913527502498295624381557778356817817750999982139142785355759733840e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0558030423043855628646211274492485894483342086566824594162146024985516781169314244e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.7626679132766782666656123523498939281680490327213627146988312255304416262392894908e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.3671346711777066286093979449135095463576878628561846047759456811238250487006378990e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.6153175690992245402186127652781399642963298842199508872954793356226534605339323333e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.9373755602608411416894250529851681229919578866115774473369305562033628341735461195e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0800169087178819510009898255169517991710412699732186488007608833012065028092686003e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6113163429881357240014185384821233436360839107514932109343845514870210427965645190e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -7.0800055208994526950912019754052939899262033086446277779400918426435279835354194130e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6124888869258097801249338962341633267998552553797818622228028001697157538310910762e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.0821345203062947277822243784585588745042841720677807798397954250617939305106506107e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0897234684613304316686535121178451999373954297009955842614973223259353042645941321e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.4950083481830885847356672064097545823284701899839135264776743195466249025042048810e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9937323326320843218449977911798288651196634496462091472078054583251005505547883394e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.1659790383945267871585567047493689107693027444469426401770619301894048344984407423e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3811750187329199929662456874823737031712476205965338135458988288637511665389967467e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.3126057597099554726738230571307233576246752870932752732642137542414937991213738675e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.8603278118738070120786476302797971799214428999935477462676132231556636610008100990e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -5.7497497499750147559650543128496209797619661773802614023013669364107360500260024694e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5455669051693660429433444114100199274899990967149528799831986363426701813268631682e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.3264707731119706730021053355613906861401420453549875829176477978488700910763350933e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9452716333766656109625805591981088427443890665155986807469770654997947109460588842e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.1107270143427404085533822649150071785436589803547989849458232547054059840123879700e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2247407103283988605835624937345007318815870047594787786390767998944461846883100894e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.0188429331847134597398824340892444962476368435762668313929678602451262836436731615e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.9431143198672109701045920614322844783143358661530851155605617982604226639477903946e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.1511473493622067561750500375000264321547190996454590396416983138367840485620637483e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.6282967029324804059233959451615215356643254329321661581764544172041721688288262211e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.5217584051959451141711566663295724419583710296958056943098481375601920843969902641e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7686779496951341450129898316334506462294006086177935245787611395642697303462481134e-32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.8183279898437068462121010262051285364082674967144808177521395570040237794774928143e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.2301356317533360807190133199588525842189842444453020346114472115201441728418314131e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0538087755476779873724252308339637373681982420524344896439951953765025296864700289e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.7368861518094102628071448870890238982875711317443189777819779346097156832497387210e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2127031296187719256650789211253726767816659542004125362087789737915250037588745613e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.2845218026163010098046208410081722573197086178079121337275774350592686815176989662e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9013371187879239559027439498823204927228357549709009148789220121477613502450061401e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.2089862298013055403993867290116144511841012233395353799752061257869549127164945780e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4527554216741432380141011585082087141319941270266854468232919279949735902352803053e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.2837166837027744593760237442711271028335526295415770894642075176684832265233618094e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.1059350216220761035803511769514044782618497241929104348673618588819476720900045601e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7687314351211090978609979306272584841117647148823431923713385159635722296908466519e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5969462796000208210556070606779102539560199436191964981433237450523523642860510077e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.1139078862715122066066654151520960142401928001906787354175105139384536625985592872e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7479750622279993094858160487261517850737208803407757126835554161719741165140561935e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.3023257271883644155548861805986381464362072120660374852325331311980696768011868477e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3944877765920457854470382189260552086188360983214813092431218719428924850775816044e-50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.4340311277195491754628728769381617236158442845382974748650525927232846582643581377e-51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6046447704173152191387256911138439680611975514728905319266554977285611063458373730e-52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.4634008445755689570224291035627638546740260971523702032261365019321949141711275488e-53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.2246731300220072906782081133065950352668949898418513030190006777980796985877588993e-55)) + }; + // LCOV_EXCL_STOP + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + BOOST_MATH_GPU_ENABLED static T lanczos_sum_near_2(const T& dz) + { + // LCOV_EXCL_START + BOOST_MATH_STATIC const T d[56] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1359871474796665853092357455924330354587340093067807143261699873815704783987359772e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.8875414095359657817766255009397774415784763914903057809977502598124862632510767554e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8476787764422274017528261804071971508619123082396685980448133660376964287516316704e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -7.4444186171772165373465718949072340109367841198406244729719893501352272283072463708e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1194120093410237139270201027497804988299179344758829377397770385486861046469631203e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.5357088952571626888790834841289410266972526362527135768453266364708511931775492144e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5786127498932741985489606333645851990301122033327283854824446437684628190530769575e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.0137191034145345260388746496030657014468720426439135322862142167063250610782207818e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1043282398857092560432546685968118908647431787644471096079379813564778477126420342e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -9.9163139177426012658354764048015319057833754923450432555380434933570665536720208880e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.4010907978229491816684804764341724977655263945662331641124141340242633003517508734e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.6169234084041844689042685434707229435012900685910183054712320472809843835362299874e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4153517213588660353769404140539796364318846647922938442928982516763682295297524025e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.0612877847699383856310204418767999963941175773527544927951233517414654065993562292e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9161022337583429443319078749411063125143924304273472659235111671109967684138896371e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2115062080034682817602956663792443265985654149672855657063890194977099012713284199e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1324805949350810193947943179103430601921304099416931772402636138580376468344900971e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.7379854977281995958474241831424455939028898406040636148869222006236410315246590813e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1982547830365481876880107367272973441376153376561639433022240961322166151300388030e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7477942737376629095840094280792553329439356352076603742418189295402785845496828618e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0703715155075453775002558378654461695986020593253642834916629665157095201951753511e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9675866846243159020907742164534290169104130230063615572789631974066350817947062221e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4780561158714357685758956261017689353220221023341472401836356861114284203430539079e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.6188339219787319686113112867608363101891398970645607178011869309209804235190901119e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.8157866597647120851117681906042345217930339391652255480834165995078338419417330285e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2481320382678181695580703583602390565135442535050898393382403247198998298046344360e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9159483230174733349570293758760922152980844047473628166544981799492351078480622954e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.6629576379996951454117430064764364032095890196838102664116218770332578145496215211e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8338633562069325240602901391334379837235954960205324388722028354858275502279946625e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0262311774099493927119217222064229499121659914970978765047236920420564019570051218e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0407678912374899180410563256969325940215095079830235805022567411720384237429934979e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7255616775185743686583950617043659309702235282144322436444914063380593981448767314e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1434762424301802086970046614089097993428600914262940192954247147222512140342020251e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.2811050104947718753668138286684667456060595320836882460657390484001848305710926658e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.6472071585409775242391978767682093973522869636260937895265262698161653967448170294e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.7256607055318261608651300407042778032797661723154154620044497458638616772687293939e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2336914691939376212057695014798607076719945066572302277992040650923577371403732374e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0786447260639215447891518190226750925343851277049431943886851989702400712288529676e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.1025728477854679597292503557220243198932574654689944030312971203381791545284070615e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8158191084622128024881877808372136805034582816867095109911304441480739442791111504e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.9234747877490011456140079812669308237793558885580849786063897631770733025035207671e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.3490836759659078559291835803157452697088321139262167213210146255834532556301891370e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.3112546247213856964589957649093570444521154190936715486464158458810486032666803106e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1776700296770363161098741319363506481285657595677761712371712460328658791045355723e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2417232307174566390298057341943116719841715593695502126267674406446096534743228763e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1547673524314003744185487198857922344498908431160001720400958944740800214791613435e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.6513158232596442320093540701345954468693696224501434722041096230050093398371645003e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.8887754856348531434071033903412118519453856283236928328635658056271487149248163047e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.1687328649763305634603605974128554276109745864508580830005398092245895954643537734e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.6161736776863672083691176367303804395378775987877354282547095064819083181262752062e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9521769890951289875720183789100014523337064918766622763963203875214061068994800866e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5893201221052508883479696840784788679013550155716308694609078334579681197829045250e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -5.1475882011819285876938214420399142925361432312238692258191602240316479716676925358e-50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4033368363711826759446617519812384260206693934532562051784267615057052651438166096e-51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.6926203201715401183464726950807528731521709827951454941037337126228208878967951308e-52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2328726440751392123787631395330686880390176572387043105330275032212649717981066795e-53)), + }; + // LCOV_EXCL_STOP + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + BOOST_MATH_GPU_ENABLED static double g() { return 4.9921416015624998863131622783839702606201171875000000000000000000000000000000000000e+01; } +}; + +BOOST_MATH_GPU_ENABLED inline double lanczos_g_near_1_and_2(const lanczos52MP&) +{ + return 38.73733398437500; +} + + +// +// placeholder for no lanczos info available: +// +struct undefined_lanczos : public boost::math::integral_constant::max)() - 1> { }; + +template +struct lanczos +{ + BOOST_MATH_STATIC constexpr auto target_precision = policies::precision::type::value <= 0 ? (boost::math::numeric_limits::max)()-2 : + policies::precision::type::value; + + using type = typename boost::math::conditional<(target_precision <= lanczos6m24::value), lanczos6m24, + typename boost::math::conditional<(target_precision <= lanczos13m53::value), lanczos13m53, + typename boost::math::conditional<(target_precision <= lanczos11::value), lanczos11, + typename boost::math::conditional<(target_precision <= lanczos17m64::value), lanczos17m64, + typename boost::math::conditional<(target_precision <= lanczos24m113::value), lanczos24m113, + typename boost::math::conditional<(target_precision <= lanczos27MP::value), lanczos27MP, + typename boost::math::conditional<(target_precision <= lanczos35MP::value), lanczos35MP, + typename boost::math::conditional<(target_precision <= lanczos48MP::value), lanczos48MP, + typename boost::math::conditional<(target_precision <= lanczos49MP::value), lanczos49MP, + typename boost::math::conditional<(target_precision <= lanczos52MP::value), lanczos52MP, undefined_lanczos>::type + >::type>::type>::type>::type>::type>::type>::type>::type + >::type; +}; + +} // namespace lanczos +} // namespace math +} // namespace boost + +#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) +#if ((defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64)) && !defined(_MANAGED) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) +#include +#endif +#endif + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS diff --git a/third-party/boost-math/include/boost/math/special_functions/legendre.hpp b/third-party/boost-math/include/boost/math/special_functions/legendre.hpp new file mode 100644 index 0000000000000..992953e231156 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/legendre.hpp @@ -0,0 +1,380 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SPECIAL_LEGENDRE_HPP +#define BOOST_MATH_SPECIAL_LEGENDRE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for legendre P and Q polynomials: +template +inline typename tools::promote_args::type + legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * l + 1) * result_type(x) * result_type(Pl) - l * result_type(Plm1)) / (l + 1); +} + +namespace detail{ + +// Implement Legendre P and Q polynomials via recurrence: +template +T legendre_imp(unsigned l, T x, const Policy& pol, bool second = false) +{ + static const char* function = "boost::math::legrendre_p<%1%>(unsigned, %1%)"; + // Error handling: + if((x < -1) || (x > 1)) + return policies::raise_domain_error(function, "The Legendre Polynomial is defined for -1 <= x <= 1, but got x = %1%.", x, pol); + + T p0, p1; + if(second) + { + // A solution of the second kind (Q): + p0 = (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2; + p1 = x * p0 - 1; + } + else + { + // A solution of the first kind (P): + p0 = 1; + p1 = x; + } + if(l == 0) + return p0; + + unsigned n = 1; + + while(n < l) + { + std::swap(p0, p1); + p1 = static_cast(boost::math::legendre_next(n, x, p0, p1)); + ++n; + } + return p1; +} + +template +T legendre_p_prime_imp(unsigned l, T x, const Policy& pol, T* Pn +#ifdef BOOST_NO_CXX11_NULLPTR + = 0 +#else + = nullptr +#endif +) +{ + static const char* function = "boost::math::legrendre_p_prime<%1%>(unsigned, %1%)"; + // Error handling: + if ((x < -1) || (x > 1)) + return policies::raise_domain_error(function, "The Legendre Polynomial is defined for -1 <= x <= 1, but got x = %1%.", x, pol); + + if (l == 0) + { + BOOST_MATH_ASSERT(Pn == nullptr); // There are no zeros of P_0 so we shoud never call this with l = 0 and Pn non-null. + return 0; + } + T p0 = 1; + T p1 = x; + T p_prime; + bool odd = ((l & 1) == 1); + // If the order is odd, we sum all the even polynomials: + if (odd) + { + p_prime = p0; + } + else // Otherwise we sum the odd polynomials * (2n+1) + { + p_prime = 3*p1; + } + + unsigned n = 1; + while(n < l - 1) + { + std::swap(p0, p1); + p1 = static_cast(boost::math::legendre_next(n, x, p0, p1)); + ++n; + if (odd) + { + p_prime += (2*n+1)*p1; + odd = false; + } + else + { + odd = true; + } + } + // This allows us to evaluate the derivative and the function for the same cost. + if (Pn) + { + std::swap(p0, p1); + *Pn = static_cast(boost::math::legendre_next(n, x, p0, p1)); + } + return p_prime; +} + +template +struct legendre_p_zero_func +{ + int n; + const Policy& pol; + + legendre_p_zero_func(int n_, const Policy& p) : n(n_), pol(p) {} + + std::pair operator()(T x) const + { + T Pn; + T Pn_prime = detail::legendre_p_prime_imp(n, x, pol, &Pn); + return std::pair(Pn, Pn_prime); + } +}; + +template +std::vector legendre_p_zeros_imp(int n, const Policy& pol) +{ + using std::cos; + using std::sin; + using std::ceil; + using std::sqrt; + using boost::math::constants::pi; + using boost::math::constants::half; + using boost::math::tools::newton_raphson_iterate; + + BOOST_MATH_ASSERT(n >= 0); + std::vector zeros; + if (n == 0) + { + // There are no zeros of P_0(x) = 1. + return zeros; + } + int k; + if (n & 1) + { + zeros.resize((n-1)/2 + 1, std::numeric_limits::quiet_NaN()); + zeros[0] = 0; + k = 1; + } + else + { + zeros.resize(n/2, std::numeric_limits::quiet_NaN()); + k = 0; + } + T half_n = ceil(n*half()); + + while (k < (int)zeros.size()) + { + // Bracket the root: Szego: + // Gabriel Szego, Inequalities for the Zeros of Legendre Polynomials and Related Functions, Transactions of the American Mathematical Society, Vol. 39, No. 1 (1936) + T theta_nk = ((half_n - half()*half() - static_cast(k))*pi())/(static_cast(n)+half()); + T lower_bound = cos( (half_n - static_cast(k))*pi()/static_cast(n + 1)); + T cos_nk = cos(theta_nk); + T upper_bound = cos_nk; + // First guess follows from: + // F. G. Tricomi, Sugli zeri dei polinomi sferici ed ultrasferici, Ann. Mat. Pura Appl., 31 (1950), pp. 93-97; + T inv_n_sq = 1/static_cast(n*n); + T sin_nk = sin(theta_nk); + T x_nk_guess = (1 - inv_n_sq/static_cast(8) + inv_n_sq /static_cast(8*n) - (inv_n_sq*inv_n_sq/384)*(39 - 28 / (sin_nk*sin_nk) ) )*cos_nk; + + std::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + legendre_p_zero_func f(n, pol); + + const T x_nk = newton_raphson_iterate(f, x_nk_guess, + lower_bound, upper_bound, + policies::digits(), + number_of_iterations); + if (number_of_iterations >= policies::get_max_root_iterations()) + { + policies::raise_evaluation_error("legendre_p_zeros<%1%>", "Unable to locate solution in a reasonable time:" // LCOV_EXCL_LINE + " either there is no answer or the answer is infinite. Current best guess is %1%", x_nk, Policy()); // LCOV_EXCL_LINE + } + + BOOST_MATH_ASSERT(lower_bound < x_nk); + BOOST_MATH_ASSERT(upper_bound > x_nk); + zeros[k] = x_nk; + ++k; + } + return zeros; +} // LCOV_EXCL_LINE + +} // namespace detail + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p(int l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + static const char* function = "boost::math::legendre_p<%1%>(unsigned, %1%)"; + if(l < 0) + return policies::checked_narrowing_cast(detail::legendre_imp(-l-1, static_cast(x), pol, false), function); + return policies::checked_narrowing_cast(detail::legendre_imp(l, static_cast(x), pol, false), function); +} + + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p_prime(int l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + static const char* function = "boost::math::legendre_p_prime<%1%>(unsigned, %1%)"; + if(l < 0) + return policies::checked_narrowing_cast(detail::legendre_p_prime_imp(-l-1, static_cast(x), pol), function); + return policies::checked_narrowing_cast(detail::legendre_p_prime_imp(l, static_cast(x), pol), function); +} + +template +inline typename tools::promote_args::type + legendre_p(int l, T x) +{ + return boost::math::legendre_p(l, x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + legendre_p_prime(int l, T x) +{ + return boost::math::legendre_p_prime(l, x, policies::policy<>()); +} + +template +inline std::vector legendre_p_zeros(int l, const Policy& pol) +{ + if(l < 0) + return detail::legendre_p_zeros_imp(-l-1, pol); + + return detail::legendre_p_zeros_imp(l, pol); +} + + +template +inline std::vector legendre_p_zeros(int l) +{ + return boost::math::legendre_p_zeros(l, policies::policy<>()); +} + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_q(unsigned l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::legendre_imp(l, static_cast(x), pol, true), "boost::math::legendre_q<%1%>(unsigned, %1%)"); +} + +template +inline typename tools::promote_args::type + legendre_q(unsigned l, T x) +{ + return boost::math::legendre_q(l, x, policies::policy<>()); +} + +// Recurrence for associated polynomials: +template +inline typename tools::promote_args::type + legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * l + 1) * result_type(x) * result_type(Pl) - (l + m) * result_type(Plm1)) / (l + 1 - m); +} + +namespace detail{ +// Legendre P associated polynomial: +template +T legendre_p_imp(int l, int m, T x, T sin_theta_power, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Error handling: + if((x < -1) || (x > 1)) + return policies::raise_domain_error("boost::math::legendre_p<%1%>(int, int, %1%)", "The associated Legendre Polynomial is defined for -1 <= x <= 1, but got x = %1%.", x, pol); + // Handle negative arguments first: + if(l < 0) + return legendre_p_imp(-l-1, m, x, sin_theta_power, pol); + if ((l == 0) && (m == -1)) + { + return sqrt((1 - x) / (1 + x)); + } + if ((l == 1) && (m == 0)) + { + return x; + } + if (-m == l) + { + return pow((1 - x * x) / 4, T(l) / 2) / boost::math::tgamma(l + 1, pol); + } + if(m < 0) + { + int sign = (m&1) ? -1 : 1; + return sign * boost::math::tgamma_ratio(static_cast(l+m+1), static_cast(l+1-m), pol) * legendre_p_imp(l, -m, x, sin_theta_power, pol); + } + // Special cases: + if(m > l) + return 0; + if(m == 0) + return boost::math::legendre_p(l, x, pol); + + T p0 = boost::math::double_factorial(2 * m - 1, pol) * sin_theta_power; + + if(m&1) + p0 *= -1; + if(m == l) + return p0; + + T p1 = x * (2 * m + 1) * p0; + + int n = m + 1; + + while(n < l) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, m, x, p0, p1); + ++n; + } + return p1; +} + +template +inline T legendre_p_imp(int l, int m, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // TODO: we really could use that mythical "pow1p" function here: + return legendre_p_imp(l, m, x, static_cast(pow(1 - x*x, T(abs(m))/2)), pol); +} + +} + +template +inline typename tools::promote_args::type + legendre_p(int l, int m, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::legendre_p_imp(l, m, static_cast(x), pol), "boost::math::legendre_p<%1%>(int, int, %1%)"); +} + +template +inline typename tools::promote_args::type + legendre_p(int l, int m, T x) +{ + return boost::math::legendre_p(l, m, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_LEGENDRE_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/legendre_stieltjes.hpp b/third-party/boost-math/include/boost/math/special_functions/legendre_stieltjes.hpp new file mode 100644 index 0000000000000..44eafea2d5b9e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/legendre_stieltjes.hpp @@ -0,0 +1,234 @@ +// Copyright Nick Thompson 2017. +// 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) + +#ifndef BOOST_MATH_SPECIAL_LEGENDRE_STIELTJES_HPP +#define BOOST_MATH_SPECIAL_LEGENDRE_STIELTJES_HPP + +/* + * Constructs the Legendre-Stieltjes polynomial of degree m. + * The Legendre-Stieltjes polynomials are used to create extensions for Gaussian quadratures, + * commonly called "Gauss-Konrod" quadratures. + * + * References: + * Patterson, TNL. "The optimum addition of points to quadrature formulae." Mathematics of Computation 22.104 (1968): 847-856. + */ + +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +template +class legendre_stieltjes +{ +public: + legendre_stieltjes(size_t m) + { + if (m == 0) + { + throw std::domain_error("The Legendre-Stieltjes polynomial is defined for order m > 0.\n"); + } + m_m = static_cast(m); + std::ptrdiff_t n = m - 1; + std::ptrdiff_t q; + std::ptrdiff_t r; + if ((n & 1) == 1) + { + q = 1; + r = (n-1)/2 + 2; + } + else + { + q = 0; + r = n/2 + 1; + } + m_a.resize(r + 1); + // We'll keep the ones-based indexing at the cost of storing a superfluous element + // so that we can follow Patterson's notation exactly. + m_a[r] = static_cast(1); + // Make sure using the zero index is a bug: + m_a[0] = std::numeric_limits::quiet_NaN(); + + for (std::ptrdiff_t k = 1; k < r; ++k) + { + Real ratio = 1; + m_a[r - k] = 0; + for (std::ptrdiff_t i = r + 1 - k; i <= r; ++i) + { + // See Patterson, equation 12 + std::ptrdiff_t num = (n - q + 2*(i + k - 1))*(n + q + 2*(k - i + 1))*(n-1-q+2*(i-k))*(2*(k+i-1) -1 -q -n); + std::ptrdiff_t den = (n - q + 2*(i - k))*(2*(k + i - 1) - q - n)*(n + 1 + q + 2*(k - i))*(n - 1 - q + 2*(i + k)); + ratio *= static_cast(num)/static_cast(den); + m_a[r - k] -= ratio*m_a[i]; + } + } + } + + + Real norm_sq() const + { + Real t = 0; + bool odd = ((m_m & 1) == 1); + for (size_t i = 1; i < m_a.size(); ++i) + { + if(odd) + { + t += 2*m_a[i]*m_a[i]/static_cast(4*i-1); + } + else + { + t += 2*m_a[i]*m_a[i]/static_cast(4*i-3); + } + } + return t; + } + + + Real operator()(Real x) const + { + // Trivial implementation: + // Em += m_a[i]*legendre_p(2*i - 1, x); m odd + // Em += m_a[i]*legendre_p(2*i - 2, x); m even + size_t r = m_a.size() - 1; + Real p0 = 1; + Real p1 = x; + + Real Em; + bool odd = ((m_m & 1) == 1); + if (odd) + { + Em = m_a[1]*p1; + } + else + { + Em = m_a[1]*p0; + } + + unsigned n = 1; + for (size_t i = 2; i <= r; ++i) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + if (!odd) + { + Em += m_a[i]*p1; + } + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + if(odd) + { + Em += m_a[i]*p1; + } + } + return Em; + } + + + Real prime(Real x) const + { + Real Em_prime = 0; + + for (size_t i = 1; i < m_a.size(); ++i) + { + if(m_m & 1) + { + Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast(2*i - 1), x, policies::policy<>()); + } + else + { + Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast(2*i - 2), x, policies::policy<>()); + } + } + return Em_prime; + } + + std::vector zeros() const + { + using boost::math::constants::half; + + std::vector stieltjes_zeros; + std::vector legendre_zeros = legendre_p_zeros(m_m - 1); + size_t k; + if (m_m & 1) + { + stieltjes_zeros.resize(legendre_zeros.size() + 1, std::numeric_limits::quiet_NaN()); + stieltjes_zeros[0] = 0; + k = 1; + } + else + { + stieltjes_zeros.resize(legendre_zeros.size(), std::numeric_limits::quiet_NaN()); + k = 0; + } + + while (k < stieltjes_zeros.size()) + { + Real lower_bound; + Real upper_bound; + if (m_m & 1) + { + lower_bound = legendre_zeros[k - 1]; + if (k == legendre_zeros.size()) + { + upper_bound = 1; + } + else + { + upper_bound = legendre_zeros[k]; + } + } + else + { + lower_bound = legendre_zeros[k]; + if (k == legendre_zeros.size() - 1) + { + upper_bound = 1; + } + else + { + upper_bound = legendre_zeros[k+1]; + } + } + + // The root bracketing is not very tight; to keep weird stuff from happening + // in the Newton's method, let's tighten up the tolerance using a few bisections. + boost::math::tools::eps_tolerance tol(6); + auto g = [&](Real t) { return this->operator()(t); }; + auto p = boost::math::tools::bisect(g, lower_bound, upper_bound, tol); + + Real x_nk_guess = p.first + (p.second - p.first)*half(); + std::uintmax_t number_of_iterations = 500; + + auto f = [&] (Real x) { Real Pn = this->operator()(x); + Real Pn_prime = this->prime(x); + return std::pair(Pn, Pn_prime); }; + + const Real x_nk = boost::math::tools::newton_raphson_iterate(f, x_nk_guess, + p.first, p.second, + tools::digits(), + number_of_iterations); + + BOOST_MATH_ASSERT(p.first < x_nk); + BOOST_MATH_ASSERT(x_nk < p.second); + stieltjes_zeros[k] = x_nk; + ++k; + } + return stieltjes_zeros; + } + +private: + // Coefficients of Legendre expansion + std::vector m_a; + int m_m; +}; + +}} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/log1p.hpp b/third-party/boost-math/include/boost/math/special_functions/log1p.hpp new file mode 100644 index 0000000000000..3851fb3a4bdf1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/log1p.hpp @@ -0,0 +1,417 @@ +// (C) Copyright John Maddock 2005-2006. +// 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) + +#ifndef BOOST_MATH_LOG1P_INCLUDED +#define BOOST_MATH_LOG1P_INCLUDED + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#if defined __has_include +# if ((__cplusplus > 202002L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 202002L))) +# if __has_include () +# include +# endif +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +namespace detail +{ + // Functor log1p_series returns the next term in the Taylor series + // pow(-1, k-1)*pow(x, k) / k + // each time that operator() is invoked. + // + template + struct log1p_series + { + typedef T result_type; + + BOOST_MATH_GPU_ENABLED log1p_series(T x) + : k(0), m_mult(-x), m_prod(-1){} + + BOOST_MATH_GPU_ENABLED T operator()() + { + m_prod *= m_mult; + return m_prod / ++k; + } + + BOOST_MATH_GPU_ENABLED int count()const + { + return k; + } + + private: + int k; + const T m_mult; + T m_prod; + log1p_series(const log1p_series&) = delete; + log1p_series& operator=(const log1p_series&) = delete; + }; + +// Algorithm log1p is part of C99, but is not yet provided by many compilers. +// +// This version uses a Taylor series expansion for 0.5 > x > epsilon, which may +// require up to std::numeric_limits::digits+1 terms to be calculated. +// It would be much more efficient to use the equivalence: +// log(1+x) == (log(1+x) * x) / ((1-x) - 1) +// Unfortunately many optimizing compilers make such a mess of this, that +// it performs no better than log(1+x): which is to say not very well at all. +// +template +BOOST_MATH_GPU_ENABLED T log1p_imp(T const & x, const Policy& pol, const boost::math::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::log1p<%1%>(%1%)"; + + if((x < -1) || (boost::math::isnan)(x)) + return policies::raise_domain_error(function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + + result_type a = abs(result_type(x)); + if(a > result_type(0.5f)) + return log(1 + result_type(x)); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + detail::log1p_series s(x); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + result_type result = tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return result; +} + +template +BOOST_MATH_GPU_ENABLED T log1p_imp(T const& x, const Policy& pol, const boost::math::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error(function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 1.846e-017 + // Expected Error Term: 1.843e-017 + // Maximum Relative Change in Control Points: 8.138e-004 + // Max Error found at double precision = 3.250766e-016 + BOOST_MATH_STATIC const T P[] = { + static_cast(0.15141069795941984e-16L), + static_cast(0.35495104378055055e-15L), + static_cast(0.33333333333332835L), + static_cast(0.99249063543365859L), + static_cast(1.1143969784156509L), + static_cast(0.58052937949269651L), + static_cast(0.13703234928513215L), + static_cast(0.011294864812099712L) + }; + BOOST_MATH_STATIC const T Q[] = { + static_cast(1L), + static_cast(3.7274719063011499L), + static_cast(5.5387948649720334L), + static_cast(4.159201143419005L), + static_cast(1.6423855110312755L), + static_cast(0.31706251443180914L), + static_cast(0.022665554431410243L), + static_cast(-0.29252538135177773e-5L) + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED T log1p_imp(T const& x, const Policy& pol, const boost::math::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error(function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 8.089e-20 + // Expected Error Term: 8.088e-20 + // Maximum Relative Change in Control Points: 9.648e-05 + // Max Error found at long double precision = 2.242324e-19 + BOOST_MATH_STATIC const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.807533446680736736712e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.490881544804798926426e-18), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.333333333333333373941), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.17141290782087994162), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.62790522814926264694), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.13156411870766876113), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.408087379932853785336), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0706537026422828914622), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00441709903782239229447) + }; + BOOST_MATH_STATIC const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.26423872346263928361), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.48189472704477708962), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94757016732904280913), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.6493508622280767304), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.06884863623790638317), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.158292216998514145947), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00885295524069924328658), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.560026216133415663808e-6) + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED T log1p_imp(T const& x, const Policy& pol, const boost::math::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error( + function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 6.910e-08 + // Expected Error Term: 6.910e-08 + // Maximum Relative Change in Control Points: 2.509e-04 + // Max Error found at double precision = 6.910422e-08 + // Max Error found at float precision = 8.357242e-08 + BOOST_MATH_STATIC const T P[] = { + -0.671192866803148236519e-7L, + 0.119670999140731844725e-6L, + 0.333339469182083148598L, + 0.237827183019664122066L + }; + BOOST_MATH_STATIC const T Q[] = { + 1L, + 1.46348272586988539733L, + 0.497859871350117338894L, + -0.00471666268910169651936L + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type log1p(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef boost::math::integral_constant tag_type; + + return policies::checked_narrowing_cast( + detail::log1p_imp(static_cast(x), forwarding_policy(), tag_type()), "boost::math::log1p<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline float log1p(float x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error("log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error("log1p<%1%>(%1%)", nullptr, pol); + #ifndef BOOST_MATH_HAS_NVRTC + return std::log1p(x); + #else + return ::log1pf(x); + #endif +} +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template +BOOST_MATH_GPU_ENABLED inline long double log1p(long double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error("log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error("log1p<%1%>(%1%)", nullptr, pol); + return std::log1p(x); +} +#endif +template +BOOST_MATH_GPU_ENABLED inline double log1p(double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error("log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error("log1p<%1%>(%1%)", nullptr, pol); + #ifndef BOOST_MATH_HAS_NVRTC + return std::log1p(x); + #else + return ::log1p(x); + #endif +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type log1p(T x) +{ + return boost::math::log1p(x, policies::policy<>()); +} +// +// Compute log(1+x)-x: +// +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + log1pmx(T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::log1pmx<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error(function, "log1pmx(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + + result_type a = abs(result_type(x)); + if(a > result_type(0.95f)) + return log(1 + result_type(x)) - result_type(x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return -x * x / 2; + boost::math::detail::log1p_series s(x); + s(); + boost::math::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type log1pmx(T x) +{ + return log1pmx(x, policies::policy<>()); +} + +// +// Specific width floating point types: +// +#ifdef __STDCPP_FLOAT32_T__ +template +BOOST_MATH_GPU_ENABLED inline std::float32_t log1p(std::float32_t x, const Policy& pol) +{ + return boost::math::log1p(static_cast(x), pol); +} +#endif +#ifdef __STDCPP_FLOAT64_T__ +template +BOOST_MATH_GPU_ENABLED inline std::float64_t log1p(std::float64_t x, const Policy& pol) +{ + return boost::math::log1p(static_cast(x), pol); +} +#endif +#ifdef __STDCPP_FLOAT128_T__ +template +BOOST_MATH_GPU_ENABLED inline std::float128_t log1p(std::float128_t x, const Policy& pol) +{ + if constexpr (std::numeric_limits::digits == std::numeric_limits::digits) + { + return boost::math::log1p(static_cast(x), pol); + } + else + { + return boost::math::detail::log1p_imp(x, pol, boost::math::integral_constant()); + } +} +#endif +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_LOG1P_INCLUDED + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/logaddexp.hpp b/third-party/boost-math/include/boost/math/special_functions/logaddexp.hpp new file mode 100644 index 0000000000000..8949496f6ec14 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/logaddexp.hpp @@ -0,0 +1,41 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#include +#include +#include +#include + +namespace boost { namespace math { + +// Calculates log(exp(x1) + exp(x2)) +template +Real logaddexp(Real x1, Real x2) noexcept +{ + using std::log1p; + using std::exp; + using std::abs; + + // Validate inputs first + if (!(boost::math::isfinite)(x1)) + { + return x1; + } + else if (!(boost::math::isfinite)(x2)) + { + return x2; + } + + const Real temp = x1 - x2; + + if (temp > 0) + { + return x1 + log1p(exp(-temp)); + } + + return x2 + log1p(exp(temp)); +} + +}} // Namespace boost::math diff --git a/third-party/boost-math/include/boost/math/special_functions/logsumexp.hpp b/third-party/boost-math/include/boost/math/special_functions/logsumexp.hpp new file mode 100644 index 0000000000000..8aa1d4bffd83a --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/logsumexp.hpp @@ -0,0 +1,60 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + +// https://nhigham.com/2021/01/05/what-is-the-log-sum-exp-function/ +// See equation (#) +template ::value_type> +Real logsumexp(ForwardIterator first, ForwardIterator last) +{ + using std::exp; + using std::log1p; + + const auto elem = std::max_element(first, last); + const Real max_val = *elem; + + Real arg = 0; + while (first != last) + { + if (first != elem) + { + arg += exp(*first - max_val); + } + + ++first; + } + + return max_val + log1p(arg); +} + +template +inline Real logsumexp(const Container& c) +{ + return logsumexp(std::begin(c), std::end(c)); +} + +template ::type, + typename std::enable_if::value, bool>::type = true> +inline Real logsumexp(Args&& ...args) +{ + std::initializer_list list {std::forward(args)...}; + + if(list.size() == 2) + { + return logaddexp(*list.begin(), *std::next(list.begin())); + } + return logsumexp(list.begin(), list.end()); +} + +}} // Namespace boost::math diff --git a/third-party/boost-math/include/boost/math/special_functions/math_fwd.hpp b/third-party/boost-math/include/boost/math/special_functions/math_fwd.hpp new file mode 100644 index 0000000000000..54f51c531a13e --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/math_fwd.hpp @@ -0,0 +1,1901 @@ +// math_fwd.hpp + +// TODO revise completely for new distribution classes. + +// Copyright Paul A. Bristow 2006. +// Copyright John Maddock 2006. +// Copyright Matt Borland 2024 + +// 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) + +// Omnibus list of forward declarations of math special functions. + +// IT = Integer type. +// RT = Real type (built-in floating-point types, float, double, long double) & User Defined Types +// AT = Integer or Real type + +#ifndef BOOST_MATH_SPECIAL_MATH_FWD_HPP +#define BOOST_MATH_SPECIAL_MATH_FWD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include // for argument promotion. +#include +#include +#include + +#ifdef BOOST_MATH_HAS_NVRTC + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type +beta(RT1 a, RT2 b, A arg); + +namespace detail{ + + template + struct ellint_3_result + { + using type = typename boost::math::conditional< + policies::is_policy::value, + tools::promote_args_t, + tools::promote_args_t + >::type; + }; + + template + struct expint_result + { + using type = typename boost::math::conditional< + policies::is_policy::value, + tools::promote_args_t, + typename tools::promote_args::type + >::type; + }; + + typedef boost::math::integral_constant bessel_no_int_tag; // No integer optimisation possible. + typedef boost::math::integral_constant bessel_maybe_int_tag; // Maybe integer optimisation. + typedef boost::math::integral_constant bessel_int_tag; // Definite integer optimisation. + + template + struct bessel_traits + { + using result_type = typename boost::math::conditional< + boost::math::is_integral::value, + typename tools::promote_args::type, + tools::promote_args_t + >::type; + + typedef typename policies::precision::type precision_type; + + using optimisation_tag = typename boost::math::conditional< + (precision_type::value <= 0 || precision_type::value > 64), + bessel_no_int_tag, + typename boost::math::conditional< + boost::math::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + + using optimisation_tag128 = typename boost::math::conditional< + (precision_type::value <= 0 || precision_type::value > 113), + bessel_no_int_tag, + typename boost::math::conditional< + boost::math::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + }; + +} // namespace detail + +} // namespace math +} // namespace boost + +#else + +#include +#include +#include +#include +#include +#include + +#define BOOST_NO_MACRO_EXPAND /**/ + +namespace boost +{ + namespace math + { // Math functions (in roughly alphabetic order). + + // Beta functions. + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + beta(RT1 a, RT2 b); // Beta function (2 arguments). + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + beta(RT1 a, RT2 b, A x); // Beta function (3 arguments). + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + beta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Beta function (3 arguments). + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + betac(RT1 a, RT2 b, RT3 x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + betac(RT1 a, RT2 b, RT3 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta(RT1 a, RT2 b, RT3 x); // Incomplete beta function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac(RT1 a, RT2 b, RT3 x); // Incomplete beta complement function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta complement function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inv(T1 a, T2 b, T3 p, T4* py); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inv(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inv(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inva(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_inva(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_invb(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_invb(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inv(T1 a, T2 b, T3 q, T4* py); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inv(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inva(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_inva(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_invb(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibetac_invb(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_derivative(RT1 a, RT2 b, RT3 x); // derivative of incomplete beta + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy& pol); // derivative of incomplete beta + + // Binomial: + template + BOOST_MATH_GPU_ENABLED T binomial_coefficient(unsigned n, unsigned k, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED T binomial_coefficient(unsigned n, unsigned k); + + // erf & erfc error functions. + template // Error function. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erf(RT z); + template // Error function. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erf(RT z, const Policy&); + + template // Error function complement. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erfc(RT z); + template // Error function complement. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erfc(RT z, const Policy&); + + template // Error function inverse. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erf_inv(RT z); + template // Error function inverse. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erf_inv(RT z, const Policy& pol); + + template // Error function complement inverse. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erfc_inv(RT z); + template // Error function complement inverse. + BOOST_MATH_GPU_ENABLED tools::promote_args_t erfc_inv(RT z, const Policy& pol); + + // Polynomials: + template + tools::promote_args_t + legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1); + + template + tools::promote_args_t + legendre_p(int l, T x); + template + tools::promote_args_t + legendre_p_prime(int l, T x); + + + template + inline std::vector legendre_p_zeros(int l, const Policy& pol); + + template + inline std::vector legendre_p_zeros(int l); + + template + typename std::enable_if::value, tools::promote_args_t>::type + legendre_p(int l, T x, const Policy& pol); + template + inline typename std::enable_if::value, tools::promote_args_t>::type + legendre_p_prime(int l, T x, const Policy& pol); + + template + tools::promote_args_t + legendre_q(unsigned l, T x); + + template + typename std::enable_if::value, tools::promote_args_t>::type + legendre_q(unsigned l, T x, const Policy& pol); + + template + tools::promote_args_t + legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1); + + template + tools::promote_args_t + legendre_p(int l, int m, T x); + + template + tools::promote_args_t + legendre_p(int l, int m, T x, const Policy& pol); + + template + tools::promote_args_t + laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1); + + template + tools::promote_args_t + laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1); + + template + tools::promote_args_t + laguerre(unsigned n, T x); + + template + tools::promote_args_t + laguerre(unsigned n, unsigned m, T x, const Policy& pol); + + template + struct laguerre_result + { + using type = typename std::conditional< + policies::is_policy::value, + typename tools::promote_args::type, + typename tools::promote_args::type + >::type; + }; + + template + typename laguerre_result::type + laguerre(unsigned n, T1 m, T2 x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + hermite(unsigned n, T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + hermite(unsigned n, T x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1); + + template + tools::promote_args_t chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1); + + template + tools::promote_args_t + chebyshev_t(unsigned n, Real const & x, const Policy&); + template + tools::promote_args_t chebyshev_t(unsigned n, Real const & x); + + template + tools::promote_args_t + chebyshev_u(unsigned n, Real const & x, const Policy&); + template + tools::promote_args_t chebyshev_u(unsigned n, Real const & x); + + template + tools::promote_args_t + chebyshev_t_prime(unsigned n, Real const & x, const Policy&); + template + tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x); + + template + Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const T2& x); + + template + std::complex> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi); + + template + std::complex> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + template + tools::promote_args_t + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi); + + template + tools::promote_args_t + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + template + tools::promote_args_t + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi); + + template + tools::promote_args_t + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + // Elliptic integrals: + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rf(T1 x, T2 y, T3 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rf(T1 x, T2 y, T3 z, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rd(T1 x, T2 y, T3 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rd(T1 x, T2 y, T3 z, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rc(T1 x, T2 y); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rc(T1 x, T2 y, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rj(T1 x, T2 y, T3 z, T4 p); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rg(T1 x, T2 y, T3 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + ellint_rg(T1 x, T2 y, T3 z, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_2(T k); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_2(T1 k, T2 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_2(T1 k, T2 phi, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_1(T k); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_1(T1 k, T2 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_1(T1 k, T2 phi, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_d(T k); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_d(T1 k, T2 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_d(T1 k, T2 phi, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t jacobi_zeta(T1 k, T2 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t jacobi_zeta(T1 k, T2 phi, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t heuman_lambda(T1 k, T2 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t heuman_lambda(T1 k, T2 phi, const Policy& pol); + + namespace detail{ + + template + struct ellint_3_result + { + using type = typename boost::math::conditional< + policies::is_policy::value, + tools::promote_args_t, + tools::promote_args_t + >::type; + }; + + } // namespace detail + + + template + BOOST_MATH_GPU_ENABLED typename detail::ellint_3_result::type ellint_3(T1 k, T2 v, T3 phi); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_3(T1 k, T2 v, T3 phi, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t ellint_3(T1 k, T2 v); + + // Factorial functions. + // Note: not for integral types, at present. + template + struct max_factorial; + template + BOOST_MATH_GPU_ENABLED RT factorial(unsigned int); + template + BOOST_MATH_GPU_ENABLED RT factorial(unsigned int, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED RT unchecked_factorial(unsigned int BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(RT)); + template + BOOST_MATH_GPU_ENABLED RT double_factorial(unsigned i); + template + BOOST_MATH_GPU_ENABLED RT double_factorial(unsigned i, const Policy& pol); + + template + tools::promote_args_t falling_factorial(RT x, unsigned n); + + template + tools::promote_args_t falling_factorial(RT x, unsigned n, const Policy& pol); + + template + tools::promote_args_t rising_factorial(RT x, int n); + + template + tools::promote_args_t rising_factorial(RT x, int n, const Policy& pol); + + // Gamma functions. + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma1pm1(RT z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma1pm1(RT z, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT1 a, RT2 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma(RT1 a, RT2 z, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t lgamma(RT z, int* sign); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t lgamma(RT z, int* sign, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t lgamma(RT x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t lgamma(RT x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_lower(RT1 a, RT2 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_lower(RT1 a, RT2 z, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q(RT1 a, RT2 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q(RT1 a, RT2 z, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p(RT1 a, RT2 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p(RT1 a, RT2 z, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_ratio(T1 a, T2 b); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t tgamma_ratio(T1 a, T2 b, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_derivative(T1 a, T2 x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_derivative(T1 a, T2 x, const Policy&); + + // gamma inverse. + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_inv(T1 a, T2 p); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_inva(T1 a, T2 p, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_inva(T1 a, T2 p); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_p_inv(T1 a, T2 p, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q_inv(T1 a, T2 q); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q_inv(T1 a, T2 q, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q_inva(T1 a, T2 q); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t gamma_q_inva(T1 a, T2 q, const Policy&); + + // digamma: + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t digamma(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t digamma(T x, const Policy&); + + // trigamma: + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t trigamma(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t trigamma(T x, const Policy&); + + // polygamma: + template + tools::promote_args_t polygamma(int n, T x); + + template + tools::promote_args_t polygamma(int n, T x, const Policy&); + + // Hypotenuse function sqrt(x ^ 2 + y ^ 2). + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + hypot(T1 x, T2 y); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + hypot(T1 x, T2 y, const Policy&); + + // cbrt - cube root. + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t cbrt(RT z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t cbrt(RT z, const Policy&); + + // log1p is log(x + 1) + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t log1p(T); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t log1p(T, const Policy&); + + // log1pmx is log(x + 1) - x + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t log1pmx(T); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t log1pmx(T, const Policy&); + + // Exp (x) minus 1 functions. + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t expm1(T); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t expm1(T, const Policy&); + + // Power - 1 + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + powm1(const T1 a, const T2 z); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t + powm1(const T1 a, const T2 z, const Policy&); + + // sqrt(1+x) - 1 + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sqrt1pm1(const T& val); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sqrt1pm1(const T& val, const Policy&); + + // sinus cardinals: + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sinc_pi(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sinc_pi(T x, const Policy&); + + template + tools::promote_args_t sinhc_pi(T x); + + template + tools::promote_args_t sinhc_pi(T x, const Policy&); + + // inverse hyperbolics: + template + tools::promote_args_t asinh(T x); + + template + tools::promote_args_t asinh(T x, const Policy&); + + template + tools::promote_args_t acosh(T x); + + template + tools::promote_args_t acosh(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t atanh(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t atanh(T x, const Policy&); + + namespace detail{ + + typedef boost::math::integral_constant bessel_no_int_tag; // No integer optimisation possible. + typedef boost::math::integral_constant bessel_maybe_int_tag; // Maybe integer optimisation. + typedef boost::math::integral_constant bessel_int_tag; // Definite integer optimisation. + + template + struct bessel_traits + { + using result_type = typename boost::math::conditional< + boost::math::is_integral::value, + typename tools::promote_args::type, + tools::promote_args_t + >::type; + + typedef typename policies::precision::type precision_type; + + using optimisation_tag = typename boost::math::conditional< + (precision_type::value <= 0 || precision_type::value > 64), + bessel_no_int_tag, + typename boost::math::conditional< + boost::math::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + + using optimisation_tag128 = typename boost::math::conditional< + (precision_type::value <= 0 || precision_type::value > 113), + bessel_no_int_tag, + typename boost::math::conditional< + boost::math::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + }; + } // detail + + // Bessel functions: + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_j(T1 v, T2 x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_j_prime(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type sph_bessel(unsigned v, T x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type sph_bessel(unsigned v, T x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type sph_bessel_prime(unsigned v, T x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_i(T1 v, T2 x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_i(T1 v, T2 x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_i_prime(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_k(T1 v, T2 x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_k(T1 v, T2 x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_k_prime(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_neumann(T1 v, T2 x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_neumann(T1 v, T2 x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_neumann_prime(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type sph_neumann(unsigned v, T x, const Policy& pol); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type sph_neumann_prime(unsigned v, T x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type sph_neumann(unsigned v, T x); + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type sph_neumann_prime(unsigned v, T x); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_bessel_j_zero(T v, int m); + + template + BOOST_MATH_GPU_ENABLED OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + + template + BOOST_MATH_GPU_ENABLED OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits::result_type cyl_neumann_zero(T v, int m, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED typename detail::bessel_traits >::result_type cyl_neumann_zero(T v, int m); + + template + BOOST_MATH_GPU_ENABLED OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + + template + BOOST_MATH_GPU_ENABLED OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex >::result_type> cyl_hankel_1(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex::result_type> cyl_hankel_1(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex::result_type> cyl_hankel_2(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex >::result_type> cyl_hankel_2(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex::result_type> sph_hankel_1(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex >::result_type> sph_hankel_1(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex::result_type> sph_hankel_2(T1 v, T2 x, const Policy& pol); + + template + BOOST_MATH_GPU_ENABLED boost::math::complex >::result_type> sph_hankel_2(T1 v, T2 x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_ai(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_ai(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_bi(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_bi(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_ai_prime(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_ai_prime(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_bi_prime(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t airy_bi_prime(T x); + + template + BOOST_MATH_GPU_ENABLED T airy_ai_zero(int m); + template + BOOST_MATH_GPU_ENABLED T airy_ai_zero(int m, const Policy&); + + template + BOOST_MATH_GPU_ENABLED OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + template + BOOST_MATH_GPU_ENABLED OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + BOOST_MATH_GPU_ENABLED T airy_bi_zero(int m); + template + BOOST_MATH_GPU_ENABLED T airy_bi_zero(int m, const Policy&); + + template + BOOST_MATH_GPU_ENABLED OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + template + BOOST_MATH_GPU_ENABLED OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sin_pi(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t sin_pi(T x); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t cos_pi(T x, const Policy&); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t cos_pi(T x); + + template + BOOST_MATH_GPU_ENABLED int fpclassify BOOST_NO_MACRO_EXPAND(T t); + + template + BOOST_MATH_GPU_ENABLED bool isfinite BOOST_NO_MACRO_EXPAND(T z); + + template + BOOST_MATH_GPU_ENABLED bool isinf BOOST_NO_MACRO_EXPAND(T t); + + template + BOOST_MATH_GPU_ENABLED bool isnan BOOST_NO_MACRO_EXPAND(T t); + + template + BOOST_MATH_GPU_ENABLED bool isnormal BOOST_NO_MACRO_EXPAND(T t); + + template + BOOST_MATH_GPU_ENABLED int signbit BOOST_NO_MACRO_EXPAND(T x); + + template + BOOST_MATH_GPU_ENABLED int sign BOOST_NO_MACRO_EXPAND(const T& z); + + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args_permissive::type + copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y); + + template + BOOST_MATH_GPU_ENABLED typename tools::promote_args_permissive::type + changesign BOOST_NO_MACRO_EXPAND(const T& z); + + // Exponential integrals: + namespace detail{ + + template + struct expint_result + { + typedef typename boost::math::conditional< + policies::is_policy::value, + tools::promote_args_t, + typename tools::promote_args::type + >::type type; + }; + + } // namespace detail + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t expint(unsigned n, T z, const Policy&); + + template + BOOST_MATH_GPU_ENABLED typename detail::expint_result::type expint(T const z, U const u); + + template + BOOST_MATH_GPU_ENABLED tools::promote_args_t expint(T z); + + // Zeta: + template + tools::promote_args_t zeta(T s, const Policy&); + + // Owen's T function: + template + tools::promote_args_t owens_t(T1 h, T2 a, const Policy& pol); + + template + tools::promote_args_t owens_t(T1 h, T2 a); + + // Jacobi Functions: + template + tools::promote_args_t jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&); + + template + tools::promote_args_t jacobi_elliptic(T k, U theta, V* pcn = 0, V* pdn = 0); + + template + tools::promote_args_t jacobi_sn(U k, T theta, const Policy& pol); + + template + tools::promote_args_t jacobi_sn(U k, T theta); + + template + tools::promote_args_t jacobi_cn(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_cn(T k, U theta); + + template + tools::promote_args_t jacobi_dn(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_dn(T k, U theta); + + template + tools::promote_args_t jacobi_cd(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_cd(T k, U theta); + + template + tools::promote_args_t jacobi_dc(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_dc(T k, U theta); + + template + tools::promote_args_t jacobi_ns(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_ns(T k, U theta); + + template + tools::promote_args_t jacobi_sd(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_sd(T k, U theta); + + template + tools::promote_args_t jacobi_ds(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_ds(T k, U theta); + + template + tools::promote_args_t jacobi_nc(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_nc(T k, U theta); + + template + tools::promote_args_t jacobi_nd(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_nd(T k, U theta); + + template + tools::promote_args_t jacobi_sc(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_sc(T k, U theta); + + template + tools::promote_args_t jacobi_cs(T k, U theta, const Policy& pol); + + template + tools::promote_args_t jacobi_cs(T k, U theta); + + // Jacobi Theta Functions: + template + tools::promote_args_t jacobi_theta1(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta1(T z, U q); + + template + tools::promote_args_t jacobi_theta2(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta2(T z, U q); + + template + tools::promote_args_t jacobi_theta3(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta3(T z, U q); + + template + tools::promote_args_t jacobi_theta4(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta4(T z, U q); + + template + tools::promote_args_t jacobi_theta1tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta1tau(T z, U tau); + + template + tools::promote_args_t jacobi_theta2tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta2tau(T z, U tau); + + template + tools::promote_args_t jacobi_theta3tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta3tau(T z, U tau); + + template + tools::promote_args_t jacobi_theta4tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta4tau(T z, U tau); + + template + tools::promote_args_t jacobi_theta3m1(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta3m1(T z, U q); + + template + tools::promote_args_t jacobi_theta4m1(T z, U q, const Policy& pol); + + template + tools::promote_args_t jacobi_theta4m1(T z, U q); + + template + tools::promote_args_t jacobi_theta3m1tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta3m1tau(T z, U tau); + + template + tools::promote_args_t jacobi_theta4m1tau(T z, U tau, const Policy& pol); + + template + tools::promote_args_t jacobi_theta4m1tau(T z, U tau); + + + template + tools::promote_args_t zeta(T s); + + // pow: + template + BOOST_MATH_GPU_ENABLED BOOST_MATH_CXX14_CONSTEXPR tools::promote_args_t pow(T base, const Policy& policy); + + template + BOOST_MATH_GPU_ENABLED BOOST_MATH_CXX14_CONSTEXPR tools::promote_args_t pow(T base); + + // next: + template + tools::promote_args_t nextafter(const T&, const U&, const Policy&); + template + tools::promote_args_t nextafter(const T&, const U&); + template + tools::promote_args_t float_next(const T&, const Policy&); + template + tools::promote_args_t float_next(const T&); + template + tools::promote_args_t float_prior(const T&, const Policy&); + template + tools::promote_args_t float_prior(const T&); + template + tools::promote_args_t float_distance(const T&, const U&, const Policy&); + template + tools::promote_args_t float_distance(const T&, const U&); + template + tools::promote_args_t float_advance(T val, int distance, const Policy& pol); + template + tools::promote_args_t float_advance(const T& val, int distance); + + template + tools::promote_args_t ulp(const T& val, const Policy& pol); + template + tools::promote_args_t ulp(const T& val); + + template + tools::promote_args_t relative_difference(const T&, const U&); + template + tools::promote_args_t epsilon_difference(const T&, const U&); + + template + BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n); + template + T bernoulli_b2n(const int i, const Policy &pol); + template + T bernoulli_b2n(const int i); + template + OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol); + template + OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it); + template + T tangent_t2n(const int i, const Policy &pol); + template + T tangent_t2n(const int i); + template + OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol); + template + OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it); + + // Lambert W: + template + boost::math::tools::promote_args_t lambert_w0(T z, const Policy& pol); + template + boost::math::tools::promote_args_t lambert_w0(T z); + template + boost::math::tools::promote_args_t lambert_wm1(T z, const Policy& pol); + template + boost::math::tools::promote_args_t lambert_wm1(T z); + template + boost::math::tools::promote_args_t lambert_w0_prime(T z, const Policy& pol); + template + boost::math::tools::promote_args_t lambert_w0_prime(T z); + template + boost::math::tools::promote_args_t lambert_wm1_prime(T z, const Policy& pol); + template + boost::math::tools::promote_args_t lambert_wm1_prime(T z); + + // Hypergeometrics: + template tools::promote_args_t hypergeometric_1F0(T1 a, T2 z); + template tools::promote_args_t hypergeometric_1F0(T1 a, T2 z, const Policy&); + + template tools::promote_args_t hypergeometric_0F1(T1 b, T2 z); + template tools::promote_args_t hypergeometric_0F1(T1 b, T2 z, const Policy&); + + template tools::promote_args_t hypergeometric_2F0(T1 a1, T2 a2, T3 z); + template tools::promote_args_t hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy&); + + template tools::promote_args_t hypergeometric_1F1(T1 a, T2 b, T3 z); + template tools::promote_args_t hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy&); + + + } // namespace math +} // namespace boost + +#define BOOST_MATH_DETAIL_LL_FUNC(Policy)\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline long long lltrunc(const T& v){ using boost::math::lltrunc; return lltrunc(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline long long llround(const T& v){ using boost::math::llround; return llround(v, Policy()); }\ + +# define BOOST_MATH_DETAIL_11_FUNC(Policy)\ + template \ + inline boost::math::tools::promote_args_t hypergeometric_1F1(const T& a, const U& b, const V& z)\ + { return boost::math::hypergeometric_1F1(a, b, z, Policy()); }\ + +#define BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)\ + \ + BOOST_MATH_DETAIL_LL_FUNC(Policy)\ + BOOST_MATH_DETAIL_11_FUNC(Policy)\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + beta(RT1 a, RT2 b) { return ::boost::math::beta(a, b, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + beta(RT1 a, RT2 b, A x){ return ::boost::math::beta(a, b, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + betac(RT1 a, RT2 b, RT3 x) { return ::boost::math::betac(a, b, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta(a, b, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibetac(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibetac(a, b, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta_inv(T1 a, T2 b, T3 p, T4* py){ return ::boost::math::ibeta_inv(a, b, p, py, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta_inv(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inv(a, b, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibetac_inv(T1 a, T2 b, T3 q, T4* py){ return ::boost::math::ibetac_inv(a, b, q, py, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta_inva(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inva(a, b, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibetac_inva(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_inva(a, b, q, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta_invb(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_invb(a, b, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibetac_invb(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_invb(a, b, q, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibetac_inv(RT1 a, RT2 b, RT3 q){ return ::boost::math::ibetac_inv(a, b, q, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ibeta_derivative(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta_derivative(a, b, x, Policy()); }\ +\ + template BOOST_MATH_GPU_ENABLED T binomial_coefficient(unsigned n, unsigned k){ return ::boost::math::binomial_coefficient(n, k, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t erf(RT z) { return ::boost::math::erf(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t erfc(RT z){ return ::boost::math::erfc(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t erf_inv(RT z) { return ::boost::math::erf_inv(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t erfc_inv(RT z){ return ::boost::math::erfc_inv(z, Policy()); }\ +\ + using boost::math::legendre_next;\ +\ + template \ + inline boost::math::tools::promote_args_t \ + legendre_p(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + legendre_p_prime(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + legendre_q(unsigned l, T x){ return ::boost::math::legendre_q(l, x, Policy()); }\ +\ + using ::boost::math::legendre_next;\ +\ + template \ + inline boost::math::tools::promote_args_t \ + legendre_p(int l, int m, T x){ return ::boost::math::legendre_p(l, m, x, Policy()); }\ +\ + using ::boost::math::laguerre_next;\ +\ + template \ + inline boost::math::tools::promote_args_t \ + laguerre(unsigned n, T x){ return ::boost::math::laguerre(n, x, Policy()); }\ +\ + template \ + inline typename boost::math::laguerre_result::type \ + laguerre(unsigned n, T1 m, T2 x) { return ::boost::math::laguerre(n, m, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + hermite(unsigned n, T x){ return ::boost::math::hermite(n, x, Policy()); }\ +\ + using boost::math::hermite_next;\ +\ + using boost::math::chebyshev_next;\ +\ + template\ + Real chebyshev_t(unsigned n, Real const & x){ return ::boost::math::chebyshev_t(n, x, Policy()); }\ +\ + template\ + Real chebyshev_u(unsigned n, Real const & x){ return ::boost::math::chebyshev_u(n, x, Policy()); }\ +\ + template\ + Real chebyshev_t_prime(unsigned n, Real const & x){ return ::boost::math::chebyshev_t_prime(n, x, Policy()); }\ +\ + using ::boost::math::chebyshev_clenshaw_recurrence;\ +\ + template \ + inline std::complex> \ + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic(n, m, theta, phi, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi){ return ::boost::math::spherical_harmonic_r(n, m, theta, phi, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic_i(n, m, theta, phi, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ellint_rf(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rf(x, y, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ellint_rd(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rd(x, y, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ellint_rc(T1 x, T2 y){ return ::boost::math::ellint_rc(x, y, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ellint_rj(T1 x, T2 y, T3 z, T4 p){ return boost::math::ellint_rj(x, y, z, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t \ + ellint_rg(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rg(x, y, z, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_2(T k){ return boost::math::ellint_2(k, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_2(T1 k, T2 phi){ return boost::math::ellint_2(k, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_d(T k){ return boost::math::ellint_d(k, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_d(T1 k, T2 phi){ return boost::math::ellint_d(k, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t jacobi_zeta(T1 k, T2 phi){ return boost::math::jacobi_zeta(k, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t heuman_lambda(T1 k, T2 phi){ return boost::math::heuman_lambda(k, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_1(T k){ return boost::math::ellint_1(k, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_1(T1 k, T2 phi){ return boost::math::ellint_1(k, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_3(T1 k, T2 v, T3 phi){ return boost::math::ellint_3(k, v, phi, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t ellint_3(T1 k, T2 v){ return boost::math::ellint_3(k, v, Policy()); }\ +\ + using boost::math::max_factorial;\ + template \ + BOOST_MATH_GPU_ENABLED inline RT factorial(unsigned int i) { return boost::math::factorial(i, Policy()); }\ + using boost::math::unchecked_factorial;\ + template \ + BOOST_MATH_GPU_ENABLED inline RT double_factorial(unsigned i){ return boost::math::double_factorial(i, Policy()); }\ + template \ + inline boost::math::tools::promote_args_t falling_factorial(RT x, unsigned n){ return boost::math::falling_factorial(x, n, Policy()); }\ + template \ + inline boost::math::tools::promote_args_t rising_factorial(RT x, unsigned n){ return boost::math::rising_factorial(x, n, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma(RT z){ return boost::math::tgamma(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma1pm1(RT z){ return boost::math::tgamma1pm1(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma(RT1 a, RT2 z){ return boost::math::tgamma(a, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t lgamma(RT z, int* sign){ return boost::math::lgamma(z, sign, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t lgamma(RT x){ return boost::math::lgamma(x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma_lower(RT1 a, RT2 z){ return boost::math::tgamma_lower(a, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_q(RT1 a, RT2 z){ return boost::math::gamma_q(a, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_p(RT1 a, RT2 z){ return boost::math::gamma_p(a, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma_delta_ratio(T1 z, T2 delta){ return boost::math::tgamma_delta_ratio(z, delta, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t tgamma_ratio(T1 a, T2 b) { return boost::math::tgamma_ratio(a, b, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_p_derivative(T1 a, T2 x){ return boost::math::gamma_p_derivative(a, x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_p_inv(T1 a, T2 p){ return boost::math::gamma_p_inv(a, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_p_inva(T1 a, T2 p){ return boost::math::gamma_p_inva(a, p, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_q_inv(T1 a, T2 q){ return boost::math::gamma_q_inv(a, q, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t gamma_q_inva(T1 a, T2 q){ return boost::math::gamma_q_inva(a, q, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t digamma(T x){ return boost::math::digamma(x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t trigamma(T x){ return boost::math::trigamma(x, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t polygamma(int n, T x){ return boost::math::polygamma(n, x, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t \ + BOOST_MATH_GPU_ENABLED hypot(T1 x, T2 y){ return boost::math::hypot(x, y, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t cbrt(RT z){ return boost::math::cbrt(z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t log1p(T x){ return boost::math::log1p(x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t log1pmx(T x){ return boost::math::log1pmx(x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t expm1(T x){ return boost::math::expm1(x, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t \ + BOOST_MATH_GPU_ENABLED powm1(const T1 a, const T2 z){ return boost::math::powm1(a, z, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t sqrt1pm1(const T& val){ return boost::math::sqrt1pm1(val, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t sinc_pi(T x){ return boost::math::sinc_pi(x, Policy()); }\ +\ + template \ + inline boost::math::tools::promote_args_t sinhc_pi(T x){ return boost::math::sinhc_pi(x, Policy()); }\ +\ + template\ + inline boost::math::tools::promote_args_t asinh(const T x){ return boost::math::asinh(x, Policy()); }\ +\ + template\ + inline boost::math::tools::promote_args_t acosh(const T x){ return boost::math::acosh(x, Policy()); }\ +\ + template\ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t atanh(const T x){ return boost::math::atanh(x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x)\ + { return boost::math::cyl_bessel_j(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x)\ + { return boost::math::cyl_bessel_j_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type sph_bessel(unsigned v, T x)\ + { return boost::math::sph_bessel(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x)\ + { return boost::math::sph_bessel_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_i(T1 v, T2 x) { return boost::math::cyl_bessel_i(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_i_prime(T1 v, T2 x) { return boost::math::cyl_bessel_i_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_k(T1 v, T2 x) { return boost::math::cyl_bessel_k(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_k_prime(T1 v, T2 x) { return boost::math::cyl_bessel_k_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_neumann(T1 v, T2 x){ return boost::math::cyl_neumann(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_neumann_prime(T1 v, T2 x){ return boost::math::cyl_neumann_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + sph_neumann(unsigned v, T x){ return boost::math::sph_neumann(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + sph_neumann_prime(unsigned v, T x){ return boost::math::sph_neumann_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m)\ + { return boost::math::cyl_bessel_j_zero(v, m, Policy()); }\ +\ +template \ + inline void cyl_bessel_j_zero(T v,\ + int start_index,\ + unsigned number_of_zeros,\ + OutputIterator out_it)\ + { boost::math::cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_neumann_zero(T v, int m)\ + { return boost::math::cyl_neumann_zero(v, m, Policy()); }\ +\ +template \ + inline void cyl_neumann_zero(T v,\ + int start_index,\ + unsigned number_of_zeros,\ + OutputIterator out_it)\ + { boost::math::cyl_neumann_zero(v, start_index, number_of_zeros, out_it, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t sin_pi(T x){ return boost::math::sin_pi(x, Policy()); }\ +\ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t cos_pi(T x){ return boost::math::cos_pi(x, Policy()); }\ +\ + using boost::math::fpclassify;\ + using boost::math::isfinite;\ + using boost::math::isinf;\ + using boost::math::isnan;\ + using boost::math::isnormal;\ + using boost::math::signbit;\ + using boost::math::sign;\ + using boost::math::copysign;\ + using boost::math::changesign;\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline typename boost::math::tools::promote_args_t expint(T const& z, U const& u)\ + { return boost::math::expint(z, u, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t expint(T z){ return boost::math::expint(z, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t zeta(T s){ return boost::math::zeta(s, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T round(const T& v){ using boost::math::round; return round(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline int iround(const T& v){ using boost::math::iround; return iround(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline long lround(const T& v){ using boost::math::lround; return lround(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T trunc(const T& v){ using boost::math::trunc; return trunc(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline int itrunc(const T& v){ using boost::math::itrunc; return itrunc(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline long ltrunc(const T& v){ using boost::math::ltrunc; return ltrunc(v, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T modf(const T& v, T* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T modf(const T& v, int* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t pow(T v){ return boost::math::pow(v, Policy()); }\ + \ + template T nextafter(const T& a, const T& b){ return static_cast(boost::math::nextafter(a, b, Policy())); }\ + template T float_next(const T& a){ return static_cast(boost::math::float_next(a, Policy())); }\ + template T float_prior(const T& a){ return static_cast(boost::math::float_prior(a, Policy())); }\ + template T float_distance(const T& a, const T& b){ return static_cast(boost::math::float_distance(a, b, Policy())); }\ + template T ulp(const T& a){ return static_cast(boost::math::ulp(a, Policy())); }\ + \ + template \ + inline boost::math::tools::promote_args_t owens_t(RT1 a, RT2 z){ return boost::math::owens_t(a, z, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> cyl_hankel_1(T1 v, T2 x)\ + { return boost::math::cyl_hankel_1(v, x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> cyl_hankel_2(T1 v, T2 x)\ + { return boost::math::cyl_hankel_2(v, x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> sph_hankel_1(T1 v, T2 x)\ + { return boost::math::sph_hankel_1(v, x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::complex::result_type> sph_hankel_2(T1 v, T2 x)\ + { return boost::math::sph_hankel_2(v, x, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_elliptic(T k, T theta, T* pcn, T* pdn)\ + { return static_cast>(boost::math::jacobi_elliptic(k, theta, pcn, pdn, Policy())); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_sn(U k, T theta)\ + { return boost::math::jacobi_sn(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_cn(T k, U theta)\ + { return boost::math::jacobi_cn(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_dn(T k, U theta)\ + { return boost::math::jacobi_dn(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_cd(T k, U theta)\ + { return boost::math::jacobi_cd(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_dc(T k, U theta)\ + { return boost::math::jacobi_dc(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_ns(T k, U theta)\ + { return boost::math::jacobi_ns(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_sd(T k, U theta)\ + { return boost::math::jacobi_sd(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_ds(T k, U theta)\ + { return boost::math::jacobi_ds(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_nc(T k, U theta)\ + { return boost::math::jacobi_nc(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_nd(T k, U theta)\ + { return boost::math::jacobi_nd(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_sc(T k, U theta)\ + { return boost::math::jacobi_sc(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_cs(T k, U theta)\ + { return boost::math::jacobi_cs(k, theta, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta1(T z, U q)\ + { return boost::math::jacobi_theta1(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta2(T z, U q)\ + { return boost::math::jacobi_theta2(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta3(T z, U q)\ + { return boost::math::jacobi_theta3(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta4(T z, U q)\ + { return boost::math::jacobi_theta4(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta1tau(T z, U q)\ + { return boost::math::jacobi_theta1tau(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta2tau(T z, U q)\ + { return boost::math::jacobi_theta2tau(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta3tau(T z, U q)\ + { return boost::math::jacobi_theta3tau(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta4tau(T z, U q)\ + { return boost::math::jacobi_theta4tau(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta3m1(T z, U q)\ + { return boost::math::jacobi_theta3m1(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta4m1(T z, U q)\ + { return boost::math::jacobi_theta4m1(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta3m1tau(T z, U q)\ + { return boost::math::jacobi_theta3m1tau(z, q, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t jacobi_theta4m1tau(T z, U q)\ + { return boost::math::jacobi_theta4m1tau(z, q, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t airy_ai(T x)\ + { return boost::math::airy_ai(x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t airy_bi(T x)\ + { return boost::math::airy_bi(x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t airy_ai_prime(T x)\ + { return boost::math::airy_ai_prime(x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline boost::math::tools::promote_args_t airy_bi_prime(T x)\ + { return boost::math::airy_bi_prime(x, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T airy_ai_zero(int m)\ + { return boost::math::airy_ai_zero(m, Policy()); }\ + template \ + BOOST_MATH_GPU_ENABLED OutputIterator airy_ai_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\ + { return boost::math::airy_ai_zero(start_index, number_of_zeros, out_it, Policy()); }\ + \ + template \ + BOOST_MATH_GPU_ENABLED inline T airy_bi_zero(int m)\ + { return boost::math::airy_bi_zero(m, Policy()); }\ + template \ + BOOST_MATH_GPU_ENABLED OutputIterator airy_bi_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\ + { return boost::math::airy_bi_zero(start_index, number_of_zeros, out_it, Policy()); }\ + \ + template \ + T bernoulli_b2n(const int i)\ + { return boost::math::bernoulli_b2n(i, Policy()); }\ + template \ + OutputIterator bernoulli_b2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\ + { return boost::math::bernoulli_b2n(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\ + \ + template \ + T tangent_t2n(const int i)\ + { return boost::math::tangent_t2n(i, Policy()); }\ + template \ + OutputIterator tangent_t2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\ + { return boost::math::tangent_t2n(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\ + \ + template inline boost::math::tools::promote_args_t lambert_w0(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_wm1(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_w0_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline boost::math::tools::promote_args_t lambert_wm1_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t hypergeometric_1F0(const T& a, const U& z)\ + { return boost::math::hypergeometric_1F0(a, z, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t hypergeometric_0F1(const T& a, const U& z)\ + { return boost::math::hypergeometric_0F1(a, z, Policy()); }\ + \ + template \ + inline boost::math::tools::promote_args_t hypergeometric_2F0(const T& a1, const U& a2, const V& z)\ + { return boost::math::hypergeometric_2F0(a1, a2, z, Policy()); }\ + \ + + + + +#endif // BOOST_MATH_HAS_NVRTC + +#endif // BOOST_MATH_SPECIAL_MATH_FWD_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/modf.hpp b/third-party/boost-math/include/boost/math/special_functions/modf.hpp new file mode 100644 index 0000000000000..6e372ec9a3c24 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/modf.hpp @@ -0,0 +1,74 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_MODF_HPP +#define BOOST_MATH_MODF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +namespace boost{ namespace math{ + +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, T* ipart, const Policy& pol) +{ + *ipart = trunc(v, pol); + return v - *ipart; +} +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, T* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, int* ipart, const Policy& pol) +{ + *ipart = itrunc(v, pol); + return v - *ipart; +} +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, int* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long* ipart, const Policy& pol) +{ + *ipart = ltrunc(v, pol); + return v - *ipart; +} +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - *ipart; +} +template +BOOST_MATH_GPU_ENABLED inline T modf(const T& v, long long* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_MODF_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/next.hpp b/third-party/boost-math/include/boost/math/special_functions/next.hpp new file mode 100644 index 0000000000000..74c34f06ad8ca --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/next.hpp @@ -0,0 +1,886 @@ +// (C) Copyright John Maddock 2008. +// 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) + +#ifndef BOOST_MATH_SPECIAL_NEXT_HPP +#define BOOST_MATH_SPECIAL_NEXT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +// TODO(mborland): Need to remove recurrsion from these algos +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include +#include + + +#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) +#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) +#include "xmmintrin.h" +#define BOOST_MATH_CHECK_SSE2 +#endif +#endif + +namespace boost{ namespace math{ + + namespace concepts { + + class real_concept; + class std_real_concept; + + } + +namespace detail{ + +template +struct has_hidden_guard_digits; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +#ifdef BOOST_HAS_FLOAT128 +template <> +struct has_hidden_guard_digits<__float128> : public std::false_type {}; +#endif +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; + +template +struct has_hidden_guard_digits_10 : public std::false_type {}; +template +struct has_hidden_guard_digits_10 : public std::integral_constant::digits10 != std::numeric_limits::max_digits10)> {}; + +template +struct has_hidden_guard_digits + : public has_hidden_guard_digits_10::is_specialized + && (std::numeric_limits::radix == 10) > +{}; + +template +inline const T& normalize_value(const T& val, const std::false_type&) { return val; } +template +inline T normalize_value(const T& val, const std::true_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + std::intmax_t shift = (std::intmax_t)std::numeric_limits::digits - (std::intmax_t)ilogb(val) - 1; + T result = scalbn(val, shift); + result = round(result); + return scalbn(result, -shift); +} + +template +inline T get_smallest_value(std::true_type const&) { + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + // + // numeric_limits lies about denorms being present - particularly + // when this can be turned on or off at runtime, as is the case + // when using the SSE2 registers in DAZ or FTZ mode. + // + static const T m = std::numeric_limits::denorm_min(); +#ifdef BOOST_MATH_CHECK_SSE2 + return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value() : m; +#else + return ((tools::min_value() / 2) == 0) ? tools::min_value() : m; +#endif +} + +template +inline T get_smallest_value(std::false_type const&) +{ + return tools::min_value(); +} + +template +inline T get_smallest_value() +{ + return get_smallest_value(std::integral_constant::is_specialized>()); +} + +template +inline bool has_denorm_now() { + return get_smallest_value() < tools::min_value(); +} + +// +// Returns the smallest value that won't generate denorms when +// we calculate the value of the least-significant-bit: +// +template +T get_min_shift_value(); + +template +inline T calc_min_shifted(const std::true_type&) +{ + BOOST_MATH_STD_USING + return ldexp(tools::min_value(), tools::digits() + 1); +} +template +inline T calc_min_shifted(const std::false_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + return scalbn(tools::min_value(), std::numeric_limits::digits + 1); +} + + +template +inline T get_min_shift_value() +{ + static const T val = calc_min_shifted(std::integral_constant::is_specialized || std::numeric_limits::radix == 2>()); + return val; +} + +template ::value> +struct exponent_type +{ + typedef int type; +}; + +template +struct exponent_type +{ + typedef typename T::backend_type::exponent_type type; +}; + +template +T float_next_imp(const T& val, const std::true_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_next<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if (fpclass == (int)FP_INFINITE) + { + if (val < 0) + return -tools::max_value(); + return val; // +INF + } + else if (fpclass == (int)FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return ldexp(float_next(T(ldexp(val, 2 * tools::digits())), pol), -2 * tools::digits()); + } + + if(-0.5f == frexp(val, &expon)) + --expon; // reduce exponent when val is a power of two, and negative. + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return val + diff; +} // float_next_imp +// +// Special version for some base other than 2: +// +template +T float_next_imp(const T& val, const std::false_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_next<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if (fpclass == (int)FP_INFINITE) + { + if (val < 0) + return -tools::max_value(); + return val; // +INF + } + else if (fpclass == (int)FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return scalbn(float_next(T(scalbn(val, 2 * std::numeric_limits::digits)), pol), -2 * std::numeric_limits::digits); + } + + expon = 1 + ilogb(val); + if(-1 == scalbn(val, -expon) * std::numeric_limits::radix) + --expon; // reduce exponent when val is a power of base, and negative. + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return val + diff; +} // float_next_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_next(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_next_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +#if 0 //def BOOST_MSVC +// +// We used to use ::_nextafter here, but doing so fails when using +// the SSE2 registers if the FTZ or DAZ flags are set, so use our own +// - albeit slower - code instead as at least that gives the correct answer. +// +template +inline double float_next(const double& val, const Policy& pol) +{ + static const char* function = "float_next<%1%>(%1%)"; + + if(!(boost::math::isfinite)(val) && (val > 0)) + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + return ::_nextafter(val, tools::max_value()); +} +#endif + +template +inline typename tools::promote_args::type float_next(const T& val) +{ + return float_next(val, policies::policy<>()); +} + +namespace detail{ + +template +T float_prior_imp(const T& val, const std::true_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_prior<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if (fpclass == (int)FP_INFINITE) + { + if (val > 0) + return tools::max_value(); + return val; // -INF + } + else if (fpclass == (int)FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return -detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return ldexp(float_prior(T(ldexp(val, 2 * tools::digits())), pol), -2 * tools::digits()); + } + + T remain = frexp(val, &expon); + if(remain == 0.5f) + --expon; // when val is a power of two we must reduce the exponent + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return val - diff; +} // float_prior_imp +// +// Special version for bases other than 2: +// +template +T float_prior_imp(const T& val, const std::false_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_prior<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if (fpclass == (int)FP_INFINITE) + { + if (val > 0) + return tools::max_value(); + return val; // -INF + } + else if (fpclass == (int)FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return -detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return scalbn(float_prior(T(scalbn(val, 2 * std::numeric_limits::digits)), pol), -2 * std::numeric_limits::digits); + } + + expon = 1 + ilogb(val); + T remain = scalbn(val, -expon); + if(remain * std::numeric_limits::radix == 1) + --expon; // when val is a power of two we must reduce the exponent + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return val - diff; +} // float_prior_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_prior(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_prior_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +#if 0 //def BOOST_MSVC +// +// We used to use ::_nextafter here, but doing so fails when using +// the SSE2 registers if the FTZ or DAZ flags are set, so use our own +// - albeit slower - code instead as at least that gives the correct answer. +// +template +inline double float_prior(const double& val, const Policy& pol) +{ + static const char* function = "float_prior<%1%>(%1%)"; + + if(!(boost::math::isfinite)(val) && (val < 0)) + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + return ::_nextafter(val, -tools::max_value()); +} +#endif + +template +inline typename tools::promote_args::type float_prior(const T& val) +{ + return float_prior(val, policies::policy<>()); +} + +template +inline typename tools::promote_args::type nextafter(const T& val, const U& direction, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return val < direction ? boost::math::float_next(val, pol) : val == direction ? val : boost::math::float_prior(val, pol); +} + +template +inline typename tools::promote_args::type nextafter(const T& val, const U& direction) +{ + return nextafter(val, direction, policies::policy<>()); +} + +namespace detail{ + +template +T float_distance_imp(const T& a, const T& b, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_distance<%1%>(%1%, %1%)"; + if(!(boost::math::isfinite)(a)) + return policies::raise_domain_error(function, "Argument a must be finite, but got %1%", a, pol); + if(!(boost::math::isfinite)(b)) + return policies::raise_domain_error(function, "Argument b must be finite, but got %1%", b, pol); + // + // Special cases: + // + if(a > b) + return -float_distance(b, a, pol); + if(a == b) + return T(0); + if(a == 0) + return 1 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)); + if(b == 0) + return 1 + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + if(boost::math::sign(a) != boost::math::sign(b)) + return 2 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)) + + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + // + // By the time we get here, both a and b must have the same sign, we want + // b > a and both positive for the following logic: + // + if(a < 0) + return float_distance(static_cast(-b), static_cast(-a), pol); + + BOOST_MATH_ASSERT(a >= 0); + BOOST_MATH_ASSERT(b >= a); + + int expon; + // + // Note that if a is a denorm then the usual formula fails + // because we actually have fewer than tools::digits() + // significant bits in the representation: + // + (void)frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value() : a, &expon); + T upper = ldexp(T(1), expon); + T result = T(0); + // + // If b is greater than upper, then we *must* split the calculation + // as the size of the ULP changes with each order of magnitude change: + // + if(b > upper) + { + int expon2; + (void)frexp(b, &expon2); + T upper2 = ldexp(T(0.5), expon2); + result = float_distance(upper2, b); + result += (expon2 - expon - 1) * ldexp(T(1), tools::digits() - 1); + } + // + // Use compensated double-double addition to avoid rounding + // errors in the subtraction: + // + expon = tools::digits() - expon; + T mb, x, y, z; + if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value())) + { + // + // Special case - either one end of the range is a denormal, or else the difference is. + // The regular code will fail if we're using the SSE2 registers on Intel and either + // the FTZ or DAZ flags are set. + // + T a2 = ldexp(a, tools::digits()); + T b2 = ldexp(b, tools::digits()); + mb = -(std::min)(T(ldexp(upper, tools::digits())), b2); + x = a2 + mb; + z = x - a2; + y = (a2 - (x - z)) + (mb - z); + + expon -= tools::digits(); + } + else + { + mb = -(std::min)(upper, b); + x = a + mb; + z = x - a; + y = (a - (x - z)) + (mb - z); + } + if(x < 0) + { + x = -x; + y = -y; + } + result += ldexp(x, expon) + ldexp(y, expon); + // + // Result must be an integer: + // + BOOST_MATH_ASSERT(result == floor(result)); + return result; +} // float_distance_imp +// +// Special versions for bases other than 2: +// +template +T float_distance_imp(const T& a, const T& b, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_distance<%1%>(%1%, %1%)"; + if(!(boost::math::isfinite)(a)) + return policies::raise_domain_error(function, "Argument a must be finite, but got %1%", a, pol); + if(!(boost::math::isfinite)(b)) + return policies::raise_domain_error(function, "Argument b must be finite, but got %1%", b, pol); + // + // Special cases: + // + if(a > b) + return -float_distance(b, a, pol); + if(a == b) + return T(0); + if(a == 0) + return 1 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)); + if(b == 0) + return 1 + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + if(boost::math::sign(a) != boost::math::sign(b)) + return 2 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)) + + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + // + // By the time we get here, both a and b must have the same sign, we want + // b > a and both positive for the following logic: + // + if(a < 0) + return float_distance(static_cast(-b), static_cast(-a), pol); + + BOOST_MATH_ASSERT(a >= 0); + BOOST_MATH_ASSERT(b >= a); + + std::intmax_t expon; + // + // Note that if a is a denorm then the usual formula fails + // because we actually have fewer than tools::digits() + // significant bits in the representation: + // + expon = 1 + ilogb(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value() : a); + T upper = scalbn(T(1), expon); + T result = T(0); + // + // If b is greater than upper, then we *must* split the calculation + // as the size of the ULP changes with each order of magnitude change: + // + if(b > upper) + { + std::intmax_t expon2 = 1 + ilogb(b); + T upper2 = scalbn(T(1), expon2 - 1); + result = float_distance(upper2, b); + result += (expon2 - expon - 1) * scalbn(T(1), std::numeric_limits::digits - 1); + } + // + // Use compensated double-double addition to avoid rounding + // errors in the subtraction: + // + expon = std::numeric_limits::digits - expon; + T mb, x, y, z; + if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value())) + { + // + // Special case - either one end of the range is a denormal, or else the difference is. + // The regular code will fail if we're using the SSE2 registers on Intel and either + // the FTZ or DAZ flags are set. + // + T a2 = scalbn(a, std::numeric_limits::digits); + T b2 = scalbn(b, std::numeric_limits::digits); + mb = -(std::min)(T(scalbn(upper, std::numeric_limits::digits)), b2); + x = a2 + mb; + z = x - a2; + y = (a2 - (x - z)) + (mb - z); + + expon -= std::numeric_limits::digits; + } + else + { + mb = -(std::min)(upper, b); + x = a + mb; + z = x - a; + y = (a - (x - z)) + (mb - z); + } + if(x < 0) + { + x = -x; + y = -y; + } + result += scalbn(x, expon) + scalbn(y, expon); + // + // Result must be an integer: + // + BOOST_MATH_ASSERT(result == floor(result)); + return result; +} // float_distance_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_distance(const T& a, const U& b, const Policy& pol) +{ + // + // We allow ONE of a and b to be an integer type, otherwise both must be the SAME type. + // + static_assert( + (std::is_same::value + || (std::is_integral::value && !std::is_integral::value) + || (!std::is_integral::value && std::is_integral::value) + || (std::numeric_limits::is_specialized && std::numeric_limits::is_specialized + && (std::numeric_limits::digits == std::numeric_limits::digits) + && (std::numeric_limits::radix == std::numeric_limits::radix) + && !std::numeric_limits::is_integer && !std::numeric_limits::is_integer)), + "Float distance between two different floating point types is undefined."); + + BOOST_MATH_IF_CONSTEXPR (!std::is_same::value) + { + BOOST_MATH_IF_CONSTEXPR(std::is_integral::value) + { + return float_distance(static_cast(a), b, pol); + } + else + { + return float_distance(a, static_cast(b), pol); + } + } + else + { + typedef typename tools::promote_args::type result_type; + return detail::float_distance_imp(detail::normalize_value(static_cast(a), typename detail::has_hidden_guard_digits::type()), detail::normalize_value(static_cast(b), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); + } +} + +template +typename tools::promote_args::type float_distance(const T& a, const U& b) +{ + return boost::math::float_distance(a, b, policies::policy<>()); +} + +namespace detail{ + +template +T float_advance_imp(T val, int distance, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_advance<%1%>(%1%, int)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + return policies::raise_domain_error(function, "Argument val must be finite, but got %1%", val, pol); + + if(val < 0) + return -float_advance(-val, -distance, pol); + if(distance == 0) + return val; + if(distance == 1) + return float_next(val, pol); + if(distance == -1) + return float_prior(val, pol); + + if(fabs(val) < detail::get_min_shift_value()) + { + // + // Special case: if the value of the least significant bit is a denorm, + // implement in terms of float_next/float_prior. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + if(distance > 0) + { + do{ val = float_next(val, pol); } while(--distance); + } + else + { + do{ val = float_prior(val, pol); } while(++distance); + } + return val; + } + + int expon; + (void)frexp(val, &expon); + T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon); + // We can not have denorms here, since we have taken care of them above: + BOOST_MATH_ASSERT(val > tools::min_value()); + T limit_distance = float_distance(val, limit); + while(fabs(limit_distance) < abs(distance)) + { + distance -= itrunc(limit_distance); + val = limit; + if(distance < 0) + { + limit /= 2; + expon--; + } + else + { + limit *= 2; + expon++; + } + limit_distance = float_distance(val, limit); + if(distance && (limit_distance == 0)) + { + return policies::raise_evaluation_error(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); // LCOV_EXCL_LINE This *should* be unreachable. + } + } + if((0.5f == frexp(val, &expon)) && (distance < 0)) + --expon; + T diff = 0; + if(val != 0) + diff = distance * ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = distance * detail::get_smallest_value(); // LCOV_EXCL_LINE This *should* be unreachable given that denorms are handled above already. + return val += diff; +} // float_advance_imp +// +// Special version for bases other than 2: +// +template +T float_advance_imp(T val, int distance, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_advance<%1%>(%1%, int)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + return policies::raise_domain_error(function, "Argument val must be finite, but got %1%", val, pol); + + if(val < 0) + return -float_advance(-val, -distance, pol); + if(distance == 0) + return val; + if(distance == 1) + return float_next(val, pol); + if(distance == -1) + return float_prior(val, pol); + + if(fabs(val) < detail::get_min_shift_value()) + { + // + // Special case: if the value of the least significant bit is a denorm, + // implement in terms of float_next/float_prior. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + if(distance > 0) + { + do{ val = float_next(val, pol); } while(--distance); + } + else + { + do{ val = float_prior(val, pol); } while(++distance); + } + return val; + } + + std::intmax_t expon = 1 + ilogb(val); + T limit = scalbn(T(1), distance < 0 ? expon - 1 : expon); + BOOST_MATH_ASSERT(val > tools::min_value()); // denorms already handled. + T limit_distance = float_distance(val, limit); + while(fabs(limit_distance) < abs(distance)) + { + distance -= itrunc(limit_distance); + val = limit; + if(distance < 0) + { + limit /= std::numeric_limits::radix; + expon--; + } + else + { + limit *= std::numeric_limits::radix; // LCOV_EXCL_LINE Probably unreachable for the decimal types we have? + expon++; // LCOV_EXCL_LINE + } + limit_distance = float_distance(val, limit); + if(distance && (limit_distance == 0)) + { + return policies::raise_evaluation_error(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); // LCOV_EXCL_LINE should never get here! + } + } + /*expon = 1 + ilogb(val); + if((1 == scalbn(val, 1 + expon)) && (distance < 0)) + --expon;*/ + T diff = 0; + if(val != 0) + diff = distance * scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = distance * detail::get_smallest_value(); // LCOV_EXCL_LINE This *should* be unreachable given that denorms are handled above. + return val += diff; +} // float_advance_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_advance(T val, int distance, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_advance_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), distance, std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +template +inline typename tools::promote_args::type float_advance(const T& val, int distance) +{ + return boost::math::float_advance(val, distance, policies::policy<>()); +} + +}} // boost math namespaces + +#endif + +#endif // BOOST_MATH_SPECIAL_NEXT_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/nonfinite_num_facets.hpp b/third-party/boost-math/include/boost/math/special_functions/nonfinite_num_facets.hpp new file mode 100644 index 0000000000000..5e08c10d3fd8d --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/nonfinite_num_facets.hpp @@ -0,0 +1,588 @@ +#ifndef BOOST_MATH_NONFINITE_NUM_FACETS_HPP +#define BOOST_MATH_NONFINITE_NUM_FACETS_HPP + +// Copyright 2006 Johan Rade +// Copyright 2012 K R Walker +// Copyright 2011, 2012 Paul A. Bristow + +// 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) + +/* +\file + +\brief non_finite_num facets for C99 standard output of infinity and NaN. + +\details See fuller documentation at Boost.Math Facets + for Floating-Point Infinities and NaNs. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) // conditional expression is constant. +# pragma warning(disable : 4706) // assignment within conditional expression. +#endif + +namespace boost { + namespace math { + + // flags (enums can be ORed together) ----------------------------------- + + const int legacy = 0x1; //!< get facet will recognize most string representations of infinity and NaN. + const int signed_zero = 0x2; //!< put facet will distinguish between positive and negative zero. + const int trap_infinity = 0x4; /*!< put facet will throw an exception of type std::ios_base::failure + when an attempt is made to format positive or negative infinity. + get will set the fail bit of the stream when an attempt is made + to parse a string that represents positive or negative sign infinity. + */ + const int trap_nan = 0x8; /*!< put facet will throw an exception of type std::ios_base::failure + when an attempt is made to format positive or negative NaN. + get will set the fail bit of the stream when an attempt is made + to parse a string that represents positive or negative sign infinity. + */ + + // class nonfinite_num_put ----------------------------------------------------- + + template< + class CharType, + class OutputIterator = std::ostreambuf_iterator + > + class nonfinite_num_put : public std::num_put + { + public: + explicit nonfinite_num_put(int flags = 0) : flags_(flags) {} + + protected: + virtual OutputIterator do_put( + OutputIterator it, std::ios_base& iosb, CharType fill, double val) const + { + put_and_reset_width(it, iosb, fill, val); + return it; + } + + virtual OutputIterator do_put( + OutputIterator it, std::ios_base& iosb, CharType fill, long double val) const + { + put_and_reset_width(it, iosb, fill, val); + return it; + } + + private: + template void put_and_reset_width( + OutputIterator& it, std::ios_base& iosb, + CharType fill, ValType val) const + { + put_impl(it, iosb, fill, val); + iosb.width(0); + } + + template void put_impl( + OutputIterator& it, std::ios_base& iosb, + CharType fill, ValType val) const + { + static const CharType prefix_plus[2] = { '+', '\0' }; + static const CharType prefix_minus[2] = { '-', '\0' }; + static const CharType body_inf[4] = { 'i', 'n', 'f', '\0' }; + static const CharType body_nan[4] = { 'n', 'a', 'n', '\0' }; + static const CharType* null_string = 0; + + switch((boost::math::fpclassify)(val)) + { + + case FP_INFINITE: + if(flags_ & trap_infinity) + { + BOOST_MATH_THROW_EXCEPTION(std::ios_base::failure("Infinity")); + } + else if((boost::math::signbit)(val)) + { // negative infinity. + put_num_and_fill(it, iosb, prefix_minus, body_inf, fill, val); + } + else if(iosb.flags() & std::ios_base::showpos) + { // Explicit "+inf" wanted. + put_num_and_fill(it, iosb, prefix_plus, body_inf, fill, val); + } + else + { // just "inf" wanted. + put_num_and_fill(it, iosb, null_string, body_inf, fill, val); + } + break; + + case FP_NAN: + if(flags_ & trap_nan) + { + BOOST_MATH_THROW_EXCEPTION(std::ios_base::failure("NaN")); + } + else if((boost::math::signbit)(val)) + { // negative so "-nan". + put_num_and_fill(it, iosb, prefix_minus, body_nan, fill, val); + } + else if(iosb.flags() & std::ios_base::showpos) + { // explicit "+nan" wanted. + put_num_and_fill(it, iosb, prefix_plus, body_nan, fill, val); + } + else + { // Just "nan". + put_num_and_fill(it, iosb, null_string, body_nan, fill, val); + } + break; + + case FP_ZERO: + if((flags_ & signed_zero) && ((boost::math::signbit)(val))) + { // Flag set to distinguish between positive and negative zero. + // But string "0" should have stuff after decimal point if setprecision and/or exp format. + + std::basic_ostringstream zeros; // Needs to be CharType version. + + // Copy flags, fill, width and precision. + zeros.flags(iosb.flags()); + zeros.unsetf(std::ios::showpos); // Ignore showpos because must be negative. + zeros.precision(iosb.precision()); + //zeros.width is set by put_num_and_fill + zeros.fill(static_cast(fill)); + zeros << ValType(0); + put_num_and_fill(it, iosb, prefix_minus, zeros.str().c_str(), fill, val); + } + else + { // Output the platform default for positive and negative zero. + put_num_and_fill(it, iosb, null_string, null_string, fill, val); + } + break; + + default: // Normal non-zero finite value. + it = std::num_put::do_put(it, iosb, fill, val); + break; + } + } + + template + void put_num_and_fill( + OutputIterator& it, std::ios_base& iosb, const CharType* prefix, + const CharType* body, CharType fill, ValType val) const + { + int prefix_length = prefix ? (int)std::char_traits::length(prefix) : 0; + int body_length = body ? (int)std::char_traits::length(body) : 0; + int width = prefix_length + body_length; + std::ios_base::fmtflags adjust = iosb.flags() & std::ios_base::adjustfield; + const std::ctype& ct + = std::use_facet >(iosb.getloc()); + + if(body || prefix) + { // adjust == std::ios_base::right, so leading fill needed. + if(adjust != std::ios_base::internal && adjust != std::ios_base::left) + put_fill(it, iosb, fill, width); + } + + if(prefix) + { // Adjust width for prefix. + while(*prefix) + *it = *(prefix++); + iosb.width( iosb.width() - prefix_length ); + width -= prefix_length; + } + + if(body) + { // + if(adjust == std::ios_base::internal) + { // Put fill between sign and digits. + put_fill(it, iosb, fill, width); + } + if(iosb.flags() & std::ios_base::uppercase) + { + while(*body) + *it = ct.toupper(*(body++)); + } + else + { + while(*body) + *it = *(body++); + } + + if(adjust == std::ios_base::left) + put_fill(it, iosb, fill, width); + } + else + { + it = std::num_put::do_put(it, iosb, fill, val); + } + } + + void put_fill( + OutputIterator& it, std::ios_base& iosb, CharType fill, int width) const + { // Insert fill chars. + for(std::streamsize i = iosb.width() - static_cast(width); i > 0; --i) + *it = fill; + } + + const int flags_; + }; + + + // class nonfinite_num_get ------------------------------------------------------ + + template< + class CharType, + class InputIterator = std::istreambuf_iterator + > + class nonfinite_num_get : public std::num_get + { + + public: + explicit nonfinite_num_get(int flags = 0) : flags_(flags) + {} + + protected: // float, double and long double versions of do_get. + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, float& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, double& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, long double& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + //.............................................................................. + + private: + template static ValType positive_nan() + { + // On some platforms quiet_NaN() may be negative. + return (boost::math::copysign)( + std::numeric_limits::quiet_NaN(), static_cast(1) + ); + // static_cast(1) added Paul A. Bristow 5 Apr 11 + } + + template void get_and_check_eof + ( + InputIterator& it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, ValType& val + ) const + { + get_signed(it, end, iosb, state, val); + if(it == end) + state |= std::ios_base::eofbit; + } + + template void get_signed + ( + InputIterator& it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, ValType& val + ) const + { + const std::ctype& ct + = std::use_facet >(iosb.getloc()); + + char c = peek_char(it, end, ct); + + bool negative = (c == '-'); + + if(negative || c == '+') + { + ++it; + c = peek_char(it, end, ct); + if(c == '-' || c == '+') + { // Without this check, "++5" etc would be accepted. + state |= std::ios_base::failbit; + return; + } + } + + get_unsigned(it, end, iosb, ct, state, val); + + if(negative) + { + val = (boost::math::changesign)(val); + } + } // void get_signed + + template void get_unsigned + ( //! Get an unsigned floating-point value into val, + //! but checking for letters indicating non-finites. + InputIterator& it, InputIterator end, std::ios_base& iosb, + const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + switch(peek_char(it, end, ct)) + { + case 'i': + get_i(it, end, ct, state, val); + break; + + case 'n': + get_n(it, end, ct, state, val); + break; + + case 'q': + case 's': + get_q(it, end, ct, state, val); + break; + + default: // Got a normal floating-point value into val. + it = std::num_get::do_get( + it, end, iosb, state, val); + if((flags_ & legacy) && val == static_cast(1) + && peek_char(it, end, ct) == '#') + get_one_hash(it, end, ct, state, val); + break; + } + } // get_unsigned + + //.......................................................................... + + template void get_i + ( // Get the rest of all strings starting with 'i', expect "inf", "infinity". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_infinity + || (flags_ & trap_infinity)) + { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "nf")) + { + state |= std::ios_base::failbit; + return; + } + + if(peek_char(it, end, ct) != 'i') + { + val = std::numeric_limits::infinity(); // "inf" + return; + } + + ++it; + if(!match_string(it, end, ct, "nity")) + { // Expected "infinity" + state |= std::ios_base::failbit; + return; + } + + val = std::numeric_limits::infinity(); // "infinity" + } // void get_i + + template void get_n + ( // Get expected strings after 'n', "nan", "nanq", "nans", "nan(...)" + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_quiet_NaN + || (flags_ & trap_nan)) { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "an")) + { + state |= std::ios_base::failbit; + return; + } + + switch(peek_char(it, end, ct)) { + case 'q': + case 's': + if(flags_ & legacy) + ++it; + break; // "nanq", "nans" + + case '(': // Optional payload field in (...) follows. + { + ++it; + char c; + while((c = peek_char(it, end, ct)) + && c != ')' && c != ' ' && c != '\n' && c != '\t') + ++it; + if(c != ')') + { // Optional payload field terminator missing! + state |= std::ios_base::failbit; + return; + } + ++it; + break; // "nan(...)" + } + + default: + break; // "nan" + } + + val = positive_nan(); + } // void get_n + + template void get_q + ( // Get expected rest of string starting with 'q': "qnan". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_quiet_NaN + || (flags_ & trap_nan) || !(flags_ & legacy)) + { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "nan")) + { + state |= std::ios_base::failbit; + return; + } + + val = positive_nan(); // "QNAN" + } // void get_q + + template void get_one_hash + ( // Get expected string after having read "1.#": "1.#IND", "1.#QNAN", "1.#SNAN". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + + ++it; + switch(peek_char(it, end, ct)) + { + case 'i': // from IND (indeterminate), considered same a QNAN. + get_one_hash_i(it, end, ct, state, val); // "1.#IND" + return; + + case 'q': // from QNAN + case 's': // from SNAN - treated the same as QNAN. + if(std::numeric_limits::has_quiet_NaN + && !(flags_ & trap_nan)) + { + ++it; + if(match_string(it, end, ct, "nan")) + { // "1.#QNAN", "1.#SNAN" + // ++it; // removed as caused assert() cannot increment iterator). +// (match_string consumes string, so not needed?). +// https://svn.boost.org/trac/boost/ticket/5467 +// Change in nonfinite_num_facet.hpp Paul A. Bristow 11 Apr 11 makes legacy_test.cpp work OK. + val = positive_nan(); // "1.#QNAN" + return; + } + } + break; // LCOV_EXCL_LINE simple fallthrough not registered as covered. + + default: + break; // LCOV_EXCL_LINE simple fallthrough not registered as covered. + } + + state |= std::ios_base::failbit; + } // void get_one_hash + + template void get_one_hash_i + ( // Get expected strings after 'i', "1.#INF", 1.#IND". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + ++it; + + if(peek_char(it, end, ct) == 'n') + { + ++it; + switch(peek_char(it, end, ct)) + { + case 'f': // "1.#INF" + if(std::numeric_limits::has_infinity + && !(flags_ & trap_infinity)) + { + ++it; + val = std::numeric_limits::infinity(); + return; + } + break; // LCOV_EXCL_LINE simple fallthrough not registered as covered. + + case 'd': // 1.#IND" + if(std::numeric_limits::has_quiet_NaN + && !(flags_ & trap_nan)) + { + ++it; + val = positive_nan(); + return; + } + break; // LCOV_EXCL_LINE simple fallthrough not registered as covered. + + default: // LCOV_EXCL_LINE simple fallthrough not registered as covered. + break; // LCOV_EXCL_LINE simple fallthrough not registered as covered. + } + } + + state |= std::ios_base::failbit; + } // void get_one_hash_i + + //.......................................................................... + + char peek_char + ( //! \return next char in the input buffer, ensuring lowercase (but do not 'consume' char). + InputIterator& it, InputIterator end, + const std::ctype& ct + ) const + { + if(it == end) return 0; + return ct.narrow(ct.tolower(*it), 0); // Always tolower to ensure case insensitive. + } + + bool match_string + ( //! Match remaining chars to expected string (case insensitive), + //! consuming chars that match OK. + //! \return true if matched expected string, else false. + InputIterator& it, InputIterator end, + const std::ctype& ct, + const char* s + ) const + { + while(it != end && *s && *s == ct.narrow(ct.tolower(*it), 0)) + { + ++s; + ++it; // + } + return !*s; + } // bool match_string + + const int flags_; + }; // + + //------------------------------------------------------------------------------ + + } // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_NONFINITE_NUM_FACETS_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/owens_t.hpp b/third-party/boost-math/include/boost/math/special_functions/owens_t.hpp new file mode 100644 index 0000000000000..4fa5c6aa7e611 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/owens_t.hpp @@ -0,0 +1,1067 @@ +// Copyright Benjamin Sobotta 2012 + +// 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) + +#ifndef BOOST_OWENS_T_HPP +#define BOOST_OWENS_T_HPP + +// Reference: +// Mike Patefield, David Tandy +// FAST AND ACCURATE CALCULATION OF OWEN'S T-FUNCTION +// Journal of Statistical Software, 5 (5), 1-25 + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost +{ + namespace math + { + namespace detail + { + // owens_t_znorm1(x) = P(-oo + inline RealType owens_t_znorm1(const RealType x, const Policy& pol) + { + using namespace boost::math::constants; + return boost::math::erf(x*one_div_root_two(), pol)*half(); + } // RealType owens_t_znorm1(const RealType x) + + // owens_t_znorm2(x) = P(x<=Z + inline RealType owens_t_znorm2(const RealType x, const Policy& pol) + { + using namespace boost::math::constants; + return boost::math::erfc(x*one_div_root_two(), pol)*half(); + } // RealType owens_t_znorm2(const RealType x) + + // Auxiliary function, it computes an array key that is used to determine + // the specific computation method for Owen's T and the order thereof + // used in owens_t_dispatch. + template + inline unsigned short owens_t_compute_code(const RealType h, const RealType a) + { + // LCOV_EXCL_START + static const RealType hrange[] = + { 0.02f, 0.06f, 0.09f, 0.125f, 0.26f, 0.4f, 0.6f, 1.6f, 1.7f, 2.33f, 2.4f, 3.36f, 3.4f, 4.8f }; + + static const RealType arange[] = { 0.025f, 0.09f, 0.15f, 0.36f, 0.5f, 0.9f, 0.99999f }; + /* + original select array from paper: + 1, 1, 2,13,13,13,13,13,13,13,13,16,16,16, 9 + 1, 2, 2, 3, 3, 5, 5,14,14,15,15,16,16,16, 9 + 2, 2, 3, 3, 3, 5, 5,15,15,15,15,16,16,16,10 + 2, 2, 3, 5, 5, 5, 5, 7, 7,16,16,16,16,16,10 + 2, 3, 3, 5, 5, 6, 6, 8, 8,17,17,17,12,12,11 + 2, 3, 5, 5, 5, 6, 6, 8, 8,17,17,17,12,12,12 + 2, 3, 4, 4, 6, 6, 8, 8,17,17,17,17,17,12,12 + 2, 3, 4, 4, 6, 6,18,18,18,18,17,17,17,12,12 + */ + // subtract one because the array is written in FORTRAN in mind - in C arrays start @ zero + static const unsigned short select[] = + { + 0, 0 , 1 , 12 ,12 , 12 , 12 , 12 , 12 , 12 , 12 , 15 , 15 , 15 , 8, + 0 , 1 , 1 , 2 , 2 , 4 , 4 , 13 , 13 , 14 , 14 , 15 , 15 , 15 , 8, + 1 , 1 , 2 , 2 , 2 , 4 , 4 , 14 , 14 , 14 , 14 , 15 , 15 , 15 , 9, + 1 , 1 , 2 , 4 , 4 , 4 , 4 , 6 , 6 , 15 , 15 , 15 , 15 , 15 , 9, + 1 , 2 , 2 , 4 , 4 , 5 , 5 , 7 , 7 , 16 ,16 , 16 , 11 , 11 , 10, + 1 , 2 , 4 , 4 , 4 , 5 , 5 , 7 , 7 , 16 , 16 , 16 , 11 , 11 , 11, + 1 , 2 , 3 , 3 , 5 , 5 , 7 , 7 , 16 , 16 , 16 , 16 , 16 , 11 , 11, + 1 , 2 , 3 , 3 , 5 , 5 , 17 , 17 , 17 , 17 , 16 , 16 , 16 , 11 , 11 + }; + // LCOV_EXCL_STOP + + unsigned short ihint = 14, iaint = 7; + for(unsigned short i = 0; i != 14; i++) + { + if( h <= hrange[i] ) + { + ihint = i; + break; + } + } // for(unsigned short i = 0; i != 14; i++) + + for(unsigned short i = 0; i != 7; i++) + { + if( a <= arange[i] ) + { + iaint = i; + break; + } + } // for(unsigned short i = 0; i != 7; i++) + + // interpret select array as 8x15 matrix + BOOST_MATH_ASSERT(iaint * 15 + ihint < (int)(sizeof(select) / sizeof(select[0]))); + return select[iaint*15 + ihint]; + + } // unsigned short owens_t_compute_code(const RealType h, const RealType a) + + template + inline unsigned short owens_t_get_order_imp(const unsigned short icode, RealType, const std::integral_constant&) + { + // LCOV_EXCL_START + static const unsigned short ord[] = {2, 3, 4, 5, 7, 10, 12, 18, 10, 20, 30, 0, 4, 7, 8, 20, 0, 0}; // 18 entries + // LCOV_EXCL_STOP + + BOOST_MATH_ASSERT(icode<18); + + return ord[icode]; + } // unsigned short owens_t_get_order(const unsigned short icode, RealType, std::integral_constant const&) + + template + inline unsigned short owens_t_get_order_imp(const unsigned short icode, RealType, const std::integral_constant&) + { + // method ================>>> {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5, 6} + // LCOV_EXCL_START + static const unsigned short ord[] = {3, 4, 5, 6, 8, 11, 13, 19, 10, 20, 30, 0, 7, 10, 11, 23, 0, 0}; // 18 entries + // LCOV_EXCL_STOP + + BOOST_MATH_ASSERT(icode<18); + + return ord[icode]; + } // unsigned short owens_t_get_order(const unsigned short icode, RealType, std::integral_constant const&) + + template + inline unsigned short owens_t_get_order(const unsigned short icode, RealType r, const Policy&) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_get_order_imp(icode, r, tag_type()); + } + + // compute the value of Owen's T function with method T1 from the reference paper + template + inline RealType owens_t_T1(const RealType h, const RealType a, const unsigned short m, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType hs = -h*h*half(); + const RealType dhs = exp( hs ); + const RealType as = a*a; + + unsigned short j=1; + RealType jj = 1; + RealType aj = a * one_div_two_pi(); + RealType dj = boost::math::expm1( hs, pol); + RealType gj = hs*dhs; + + RealType val = atan( a ) * one_div_two_pi(); + + while( true ) + { + val += dj*aj/jj; + + if( m <= j ) + break; + + j++; + jj += static_cast(2); + aj *= as; + dj = gj - dj; + gj *= hs / static_cast(j); + } // while( true ) + + return val; + } // RealType owens_t_T1(const RealType h, const RealType a, const unsigned short m) + + // compute the value of Owen's T function with method T2 from the reference paper + template + inline RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah, const Policy& pol, const std::false_type&) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType z = owens_t_znorm1(ah, pol)/h; + + while( true ) + { + val += z; + if( maxii <= ii ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( maxii <= ii ) + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + + return val; + } // RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah) + + // compute the value of Owen's T function with method T3 from the reference paper + template + inline RealType owens_t_T3_imp(const RealType h, const RealType a, const RealType ah, const std::integral_constant&, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short m = 20; + + // LCOV_EXCL_START + static const RealType c2[] = + { + static_cast(0.99999999999999987510), + static_cast(-0.99999999999988796462), static_cast(0.99999999998290743652), + static_cast(-0.99999999896282500134), static_cast(0.99999996660459362918), + static_cast(-0.99999933986272476760), static_cast(0.99999125611136965852), + static_cast(-0.99991777624463387686), static_cast(0.99942835555870132569), + static_cast(-0.99697311720723000295), static_cast(0.98751448037275303682), + static_cast(-0.95915857980572882813), static_cast(0.89246305511006708555), + static_cast(-0.76893425990463999675), static_cast(0.58893528468484693250), + static_cast(-0.38380345160440256652), static_cast(0.20317601701045299653), + static_cast(-0.82813631607004984866E-01), static_cast(0.24167984735759576523E-01), + static_cast(-0.44676566663971825242E-02), static_cast(0.39141169402373836468E-03) + }; + // LCOV_EXCL_STOP + + const RealType as = a*a; + const RealType hs = h*h; + const RealType y = static_cast(1)/hs; + + RealType ii = 1; + unsigned short i = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType zi = owens_t_znorm1(ah, pol)/h; + RealType val = 0; + + while( true ) + { + BOOST_MATH_ASSERT(i < 21); + val += zi*c2[i]; + if( m <= i ) // if( m < i+1 ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( m < i ) + zi = y * (ii*zi - vi); + vi *= as; + ii += 2; + i++; + } // while( true ) + + return val; + } // RealType owens_t_T3(const RealType h, const RealType a, const RealType ah) + + // compute the value of Owen's T function with method T3 from the reference paper + template + inline RealType owens_t_T3_imp(const RealType h, const RealType a, const RealType ah, const std::integral_constant&, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short m = 30; + + // LCOV_EXCL_START + static const RealType c2[] = + { + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999999999999999729978162447266851932041876728736094298092917625009873), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.99999999999999999999467056379678391810626533251885323416799874878563998732905968), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999999999824849349313270659391127814689133077036298754586814091034842536), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999999999997703859616213643405880166422891953033591551179153879839440241685), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999998394883415238173334565554173013941245103172035286759201504179038147), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999999993063616095509371081203145247992197457263066869044528823599399470977), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999999999797336340409464429599229870590160411238245275855903767652432017766116267), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.999999999574958412069046680119051639753412378037565521359444170241346845522403274), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999999933226234193375324943920160947158239076786103108097456617750134812033362048), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999188923242461073033481053037468263536806742737922476636768006622772762168467), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999992195143483674402853783549420883055129680082932629160081128947764415749728967), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.999993935137206712830997921913316971472227199741857386575097250553105958772041501), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99996135597690552745362392866517133091672395614263398912807169603795088421057688716), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.99979556366513946026406788969630293820987757758641211293079784585126692672425362469), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.999092789629617100153486251423850590051366661947344315423226082520411961968929483), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.996593837411918202119308620432614600338157335862888580671450938858935084316004769854), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.98910017138386127038463510314625339359073956513420458166238478926511821146316469589567), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.970078558040693314521331982203762771512160168582494513347846407314584943870399016019), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.92911438683263187495758525500033707204091967947532160289872782771388170647150321633673), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.8542058695956156057286980736842905011429254735181323743367879525470479126968822863), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.73796526033030091233118357742803709382964420335559408722681794195743240930748630755), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.58523469882837394570128599003785154144164680587615878645171632791404210655891158), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.415997776145676306165661663581868460503874205343014196580122174949645271353372263), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.2588210875241943574388730510317252236407805082485246378222935376279663808416534365), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.1375535825163892648504646951500265585055789019410617565727090346559210218472356689), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.0607952766325955730493900985022020434830339794955745989150270485056436844239206648), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.0216337683299871528059836483840390514275488679530797294557060229266785853764115), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.00593405693455186729876995814181203900550014220428843483927218267309209471516256), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.0011743414818332946510474576182739210553333860106811865963485870668929503649964142), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -1.489155613350368934073453260689881330166342484405529981510694514036264969925132e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 9.072354320794357587710929507988814669454281514268844884841547607134260303118208e-6) + }; + // LCOV_EXCL_STOP + + const RealType as = a*a; + const RealType hs = h*h; + const RealType y = 1 / hs; + + RealType ii = 1; + unsigned short i = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType zi = owens_t_znorm1(ah, pol)/h; + RealType val = 0; + + while( true ) + { + BOOST_MATH_ASSERT(i < 31); + val += zi*c2[i]; + if( m <= i ) // if( m < i+1 ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( m < i ) + zi = y * (ii*zi - vi); + vi *= as; + ii += 2; + i++; + } // while( true ) + + return val; + } // RealType owens_t_T3(const RealType h, const RealType a, const RealType ah) + + template + inline RealType owens_t_T3(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_T3_imp(h, a, ah, tag_type(), pol); + } + + // compute the value of Owen's T function with method T4 from the reference paper + template + inline RealType owens_t_T4(const RealType h, const RealType a, const unsigned short m) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + + unsigned short ii = 1; + RealType ai = a * exp( -hs*(static_cast(1)-as)*half() ) * one_div_two_pi(); + RealType yi = 1; + RealType val = 0; + + while( true ) + { + val += ai*yi; + if( maxii <= ii ) + break; + ii += 2; + yi = (static_cast(1)-hs*yi) / static_cast(ii); + ai *= as; + } // while( true ) + + return val; + } // RealType owens_t_T4(const RealType h, const RealType a, const unsigned short m) + + // compute the value of Owen's T function with method T5 from the reference paper + template + inline RealType owens_t_T5_imp(const RealType h, const RealType a, const std::integral_constant&) + { + BOOST_MATH_STD_USING + /* + NOTICE: + - The pts[] array contains the squares (!) of the abscissas, i.e. the roots of the Legendre + polynomial P_n(x), instead of the plain roots as required in Gauss-Legendre + quadrature, because T5(h,a,m) contains only x^2 terms. + - The wts[] array contains the weights for Gauss-Legendre quadrature scaled with a factor + of 1/(2*pi) according to T5(h,a,m). + */ + + const unsigned short m = 13; + // LCOV_EXCL_START + static const RealType pts[] = { + static_cast(0.35082039676451715489E-02), + static_cast(0.31279042338030753740E-01), static_cast(0.85266826283219451090E-01), + static_cast(0.16245071730812277011), static_cast(0.25851196049125434828), + static_cast(0.36807553840697533536), static_cast(0.48501092905604697475), + static_cast(0.60277514152618576821), static_cast(0.71477884217753226516), + static_cast(0.81475510988760098605), static_cast(0.89711029755948965867), + static_cast(0.95723808085944261843), static_cast(0.99178832974629703586) }; + static const RealType wts[] = { + static_cast(0.18831438115323502887E-01), + static_cast(0.18567086243977649478E-01), static_cast(0.18042093461223385584E-01), + static_cast(0.17263829606398753364E-01), static_cast(0.16243219975989856730E-01), + static_cast(0.14994592034116704829E-01), static_cast(0.13535474469662088392E-01), + static_cast(0.11886351605820165233E-01), static_cast(0.10070377242777431897E-01), + static_cast(0.81130545742299586629E-02), static_cast(0.60419009528470238773E-02), + static_cast(0.38862217010742057883E-02), static_cast(0.16793031084546090448E-02) }; + + const RealType as = a*a; + const RealType hs = -h*h*boost::math::constants::half(); + // LCOV_EXCL_STOP + + RealType val = 0; + for(unsigned short i = 0; i < m; ++i) + { + BOOST_MATH_ASSERT(i < 13); + const RealType r = static_cast(1) + as*pts[i]; + val += wts[i] * exp( hs*r ) / r; + } // for(unsigned short i = 0; i < m; ++i) + + return val*a; + } // RealType owens_t_T5(const RealType h, const RealType a) + + // compute the value of Owen's T function with method T5 from the reference paper + template + inline RealType owens_t_T5_imp(const RealType h, const RealType a, const std::integral_constant&) + { + BOOST_MATH_STD_USING + /* + NOTICE: + - The pts[] array contains the squares (!) of the abscissas, i.e. the roots of the Legendre + polynomial P_n(x), instead of the plain roots as required in Gauss-Legendre + quadrature, because T5(h,a,m) contains only x^2 terms. + - The wts[] array contains the weights for Gauss-Legendre quadrature scaled with a factor + of 1/(2*pi) according to T5(h,a,m). + */ + + const unsigned short m = 19; + // LCOV_EXCL_START + static const RealType pts[] = { + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0016634282895983227941), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.014904509242697054183), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.04103478879005817919), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.079359853513391511008), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.1288612130237615133), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.18822336642448518856), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.25586876186122962384), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.32999972011807857222), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.40864620815774761438), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.48971819306044782365), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.57106118513245543894), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.6505134942981533829), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.72596367859928091618), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.79540665919549865924), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.85699701386308739244), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.90909804422384697594), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.95032536436570154409), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.97958418733152273717), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.99610366384229088321) + }; + static const RealType wts[] = { + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012975111395684900835), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012888764187499150078), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012716644398857307844), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012459897461364705691), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012120231988292330388), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.011699908404856841158), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.011201723906897224448), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.010628993848522759853), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0099855296835573320047), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0092756136096132857933), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0085039700881139589055), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0076757344408814561254), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0067964187616556459109), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.005871875456524750363), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0049082589542498110071), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0039119870792519721409), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0028897090921170700834), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0018483371329504443947), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.00079623320100438873578) + }; + // LCOV_EXCL_STOP + + const RealType as = a*a; + const RealType hs = -h*h*boost::math::constants::half(); + + RealType val = 0; + for(unsigned short i = 0; i < m; ++i) + { + BOOST_MATH_ASSERT(i < 19); + const RealType r = 1 + as*pts[i]; + val += wts[i] * exp( hs*r ) / r; + } // for(unsigned short i = 0; i < m; ++i) + + return val*a; + } // RealType owens_t_T5(const RealType h, const RealType a) + + template + inline RealType owens_t_T5(const RealType h, const RealType a, const Policy&) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_T5_imp(h, a, tag_type()); + } + + + // compute the value of Owen's T function with method T6 from the reference paper + template + inline RealType owens_t_T6(const RealType h, const RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType normh = owens_t_znorm2(h, pol); + const RealType y = static_cast(1) - a; + const RealType r = atan2(y, static_cast(1 + a) ); + + RealType val = normh * ( static_cast(1) - normh ) * half(); + + if( r != 0 ) + val -= r * exp( -y*h*h*half()/r ) * one_div_two_pi(); + + return val; + } // RealType owens_t_T6(const RealType h, const RealType a, const unsigned short m) + + template + std::pair owens_t_T1_accelerated(T h, T a, const Policy& pol) + { + // + // This is the same series as T1, but: + // * The Taylor series for atan has been combined with that for T1, + // reducing but not eliminating cancellation error. + // * The resulting alternating series is then accelerated using method 1 + // from H. Cohen, F. Rodriguez Villegas, D. Zagier, + // "Convergence acceleration of alternating series", Bonn, (1991). + // + BOOST_MATH_STD_USING + static const char* function = "boost::math::owens_t<%1%>(%1%, %1%)"; + T half_h_h = h * h / 2; + T a_pow = a; + T aa = a * a; + T exp_term = exp(-h * h / 2); + T one_minus_dj_sum = exp_term; + T sum = a_pow * exp_term; + T dj_pow = exp_term; + T term = sum; + T abs_err; + int j = 1; + + // + // Normally with this form of series acceleration we can calculate + // up front how many terms will be required - based on the assumption + // that each term decreases in size by a factor of 3. However, + // that assumption does not apply here, as the underlying T1 series can + // go quite strongly divergent in the early terms, before strongly + // converging later. Various "guesstimates" have been tried to take account + // of this, but they don't always work.... so instead set "n" to the + // largest value that won't cause overflow later, and abort iteration + // when the last accelerated term was small enough... + // + int n; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + n = itrunc(T(tools::log_max_value() / 6)); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(...) + { + n = (std::numeric_limits::max)(); + } +#endif + n = (std::min)(n, 1500); + T d = pow(3 + sqrt(T(8)), T(n)); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + c = b - c; + sum *= c; + b = -n * n * b * 2; + abs_err = ldexp(fabs(sum), -tools::digits()); + + while(j < n) + { + a_pow *= aa; + dj_pow *= half_h_h / j; + one_minus_dj_sum += dj_pow; + term = one_minus_dj_sum * a_pow / (2 * j + 1); + c = b - c; + sum += c * term; + abs_err += ldexp((std::max)(T(fabs(sum)), T(fabs(c*term))), -tools::digits()); + b = (j + n) * (j - n) * b / ((j + T(0.5)) * (j + 1)); + ++j; + // + // Include an escape route to prevent calculating too many terms: + // + if((j > 10) && (fabs(sum * tools::epsilon()) > fabs(c * term))) + break; + } + abs_err += fabs(c * term); + if(sum < 0) // sum must always be positive, if it's negative something really bad has happened: + policies::raise_evaluation_error(function, 0, T(0), pol); + return std::pair((sum / d) / boost::math::constants::two_pi(), abs_err / sum); + } + + template + inline RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah, const Policy& pol, const std::true_type&) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) / root_two_pi(); + RealType z = owens_t_znorm1(ah, pol)/h; + RealType last_z = fabs(z); + RealType lim = policies::get_epsilon(); + + while( true ) + { + val += z; + // + // This series stops converging after a while, so put a limit + // on how far we go before returning our best guess: + // + if((fabs(lim * val) > fabs(z)) || ((ii > maxii) && (fabs(z) > last_z)) || (z == 0)) + { + val *= exp( -hs*half() ) / root_two_pi(); + break; + } // if( maxii <= ii ) + last_z = fabs(z); + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + + return val; + } // RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah) + + template + inline std::pair owens_t_T2_accelerated(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + // + // This is the same series as T2, but with acceleration applied. + // Note that we have to be *very* careful to check that nothing bad + // has happened during evaluation - this series will go divergent + // and/or fail to alternate at a drop of a hat! :-( + // + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) / root_two_pi(); + RealType z = boost::math::detail::owens_t_znorm1(ah, pol)/h; + RealType last_z = fabs(z); + + // + // Normally with this form of series acceleration we can calculate + // up front how many terms will be required - based on the assumption + // that each term decreases in size by a factor of 3. However, + // that assumption does not apply here, as the underlying T1 series can + // go quite strongly divergent in the early terms, before strongly + // converging later. Various "guesstimates" have been tried to take account + // of this, but they don't always work.... so instead set "n" to the + // largest value that won't cause overflow later, and abort iteration + // when the last accelerated term was small enough... + // + int n; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + n = itrunc(RealType(tools::log_max_value() / 6)); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(...) + { + n = (std::numeric_limits::max)(); + } +#endif + n = (std::min)(n, 1500); + RealType d = pow(3 + sqrt(RealType(8)), RealType(n)); + d = (d + 1 / d) / 2; + RealType b = -1; + RealType c = -d; + int s = 1; + + for(int k = 0; k < n; ++k) + { + // + // Check for both convergence and whether the series has gone bad: + // + if( + (fabs(z) > last_z) // Series has gone divergent, abort + || (fabs(val) * tools::epsilon() > fabs(c * s * z)) // Convergence! + || (z * s < 0) // Series has stopped alternating - all bets are off - abort. + ) + { + break; + } + c = b - c; + val += c * s * z; + b = (k + n) * (k - n) * b / ((k + RealType(0.5)) * (k + 1)); + last_z = fabs(z); + s = -s; + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + RealType err = fabs(c * z) / val; + return std::pair(val * exp( -hs*half() ) / (d * root_two_pi()), err); + } // RealType owens_t_T2_accelerated(const RealType h, const RealType a, const RealType ah, const Policy&) + + template + inline RealType T4_mp(const RealType h, const RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + + const RealType hs = h*h; + const RealType as = -a*a; + + unsigned short ii = 1; + RealType ai = constants::one_div_two_pi() * a * exp( -0.5*hs*(1.0-as) ); + RealType yi = 1.0; + RealType val = 0.0; + + RealType lim = boost::math::policies::get_epsilon(); + + while( true ) + { + RealType term = ai*yi; + val += term; + if((yi != 0) && (fabs(val * lim) > fabs(term))) + break; + ii += 2; + yi = (1.0-hs*yi) / static_cast(ii); + ai *= as; + if(ii > (std::min)(1500, (int)policies::get_max_series_iterations())) + policies::raise_evaluation_error("boost::math::owens_t<%1%>", 0, val, pol); + } // while( true ) + + return val; + } // arg_type owens_t_T4(const arg_type h, const arg_type a, const unsigned short m) + + + // This routine dispatches the call to one of six subroutines, depending on the values + // of h and a. + // preconditions: h >= 0, 0<=a<=1, ah=a*h + // + // Note there are different versions for different precisions.... + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, std::integral_constant const&) + { + // Simple main case for 64-bit precision or less, this is as per the Patefield-Tandy paper: + BOOST_MATH_STD_USING + // + // Handle some special cases first, these are from + // page 1077 of Owen's original paper: + // + if(h == 0) + { + return atan(a) * constants::one_div_two_pi(); + } + if(a == 0) + { + return 0; + } + if(a == 1) + { + return owens_t_znorm2(RealType(-h), pol) * owens_t_znorm2(h, pol) / 2; + } + // Rationale: when a>1 we call this routine with 1/a: + BOOST_MATH_ASSERT(a <= 1); + RealType val = 0; // avoid compiler warnings, 0 will be overwritten in any case + const unsigned short icode = owens_t_compute_code(h, a); + const unsigned short m = owens_t_get_order(icode, val /* just a dummy for the type */, pol); + static const unsigned short meth[] = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5, 6}; // 18 entries + BOOST_MATH_ASSERT(icode < sizeof(meth) / sizeof(meth[0])); + + // determine the appropriate method, T1 ... T6 + switch( meth[icode] ) + { + case 1: // T1 + val = owens_t_T1(h,a,m,pol); + break; + case 2: // T2 + typedef typename policies::precision::type precision_type; + typedef std::integral_constant 64)> tag_type; + val = owens_t_T2(h, a, m, ah, pol, tag_type()); + break; + case 3: // T3 + val = owens_t_T3(h,a,ah, pol); + break; + case 4: // T4 + val = owens_t_T4(h,a,m); + break; + case 5: // T5 + val = owens_t_T5(h,a, pol); + break; + case 6: // T6 + val = owens_t_T6(h,a, pol); + break; + } + return val; + } + + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, const std::integral_constant&) + { + // Arbitrary precision version: + BOOST_MATH_STD_USING + // + // Handle some special cases first, these are from + // page 1077 of Owen's original paper: + // + if(h == 0) + { + return atan(a) * constants::one_div_two_pi(); + } + if(a == 0) + { + return 0; + } + if(a == 1) + { + return owens_t_znorm2(RealType(-h), pol) * owens_t_znorm2(h, pol) / 2; + } + if(a >= tools::max_value()) + { + return owens_t_znorm2(RealType(fabs(h)), pol); + } + // Attempt arbitrary precision code, this will throw if it goes wrong: + typedef typename boost::math::policies::normalise >::type forwarding_policy; + std::pair p1(0, tools::max_value()), p2(0, tools::max_value()); + RealType target_precision = policies::get_epsilon() * 1000; + bool have_t1(false), have_t2(false); + if(ah < 3) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + have_t1 = true; + p1 = owens_t_T1_accelerated(h, a, forwarding_policy()); + if(p1.second < target_precision) + return p1.first; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T1 may fail and throw, that's OK +#endif + } + if(ah > 1) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + have_t2 = true; + p2 = owens_t_T2_accelerated(h, a, ah, forwarding_policy()); + if(p2.second < target_precision) + return p2.first; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T2 may fail and throw, that's OK +#endif + } + // + // If we haven't tried T1 yet, do it now - sometimes it succeeds and the number of iterations + // is fairly low compared to T4. + // + if(!have_t1) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + have_t1 = true; + p1 = owens_t_T1_accelerated(h, a, forwarding_policy()); + if(p1.second < target_precision) + return p1.first; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T1 may fail and throw, that's OK +#endif + } + // + // If we haven't tried T2 yet, do it now - sometimes it succeeds and the number of iterations + // is fairly low compared to T4. + // + if(!have_t2) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + have_t2 = true; + p2 = owens_t_T2_accelerated(h, a, ah, forwarding_policy()); + if(p2.second < target_precision) + return p2.first; +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T2 may fail and throw, that's OK +#endif + } + // + // OK, nothing left to do but try the most expensive option which is T4, + // this is often slow to converge, but when it does converge it tends to + // be accurate: +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + return T4_mp(h, a, pol); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T4 may fail and throw, that's OK +#endif + // + // Now look back at the results from T1 and T2 and see if either gave better + // results than we could get from the 64-bit precision versions. + // + if((std::min)(p1.second, p2.second) < RealType(1e-20)) + { + return p1.second < p2.second ? p1.first : p2.first; + } + // + // We give up - no arbitrary precision versions succeeded! + // + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + } // RealType owens_t_dispatch(RealType h, RealType a, RealType ah) + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, const std::integral_constant&) + { + // We don't know what the precision is until runtime: + if(tools::digits() <= 64) + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + } + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + // Figure out the precision and forward to the correct version: + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_dispatch(h, a, ah, pol, tag_type()); + } + // compute Owen's T function, T(h,a), for arbitrary values of h and a + template + inline RealType owens_t(RealType h, RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + // exploit that T(-h,a) == T(h,a) + h = fabs(h); + + // Use equation (2) in the paper to remap the arguments + // such that h>=0 and 0<=a<=1 for the call of the actual + // computation routine. + + const RealType fabs_a = fabs(a); + const RealType fabs_ah = fabs_a*h; + + RealType val = static_cast(0.0f); // avoid compiler warnings, 0.0 will be overwritten in any case + + if(fabs_a <= 1) + { + val = owens_t_dispatch(h, fabs_a, fabs_ah, pol); + } // if(fabs_a <= 1.0) + else + { + if( h <= RealType(0.67) ) + { + const RealType normh = owens_t_znorm1(h, pol); + const RealType normah = owens_t_znorm1(fabs_ah, pol); + val = static_cast(1)/static_cast(4) - normh*normah - + owens_t_dispatch(fabs_ah, static_cast(1 / fabs_a), h, pol); + } // if( h <= 0.67 ) + else + { + const RealType normh = detail::owens_t_znorm2(h, pol); + const RealType normah = detail::owens_t_znorm2(fabs_ah, pol); + val = constants::half()*(normh+normah) - normh*normah - + owens_t_dispatch(fabs_ah, static_cast(1 / fabs_a), h, pol); + } // else [if( h <= 0.67 )] + } // else [if(fabs_a <= 1)] + + // exploit that T(h,-a) == -T(h,a) + if(a < 0) + { + return -val; + } // if(a < 0) + + return val; + } // RealType owens_t(RealType h, RealType a) + + } // namespace detail + + template + inline typename tools::promote_args::type owens_t(T1 h, T2 a, const Policy& pol) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + + return policies::checked_narrowing_cast(detail::owens_t(static_cast(h), static_cast(a), pol), "boost::math::owens_t<%1%>(%1%,%1%)"); + } + + template + inline typename tools::promote_args::type owens_t(T1 h, T2 a) + { + return owens_t(h, a, policies::policy<>()); + } + + + } // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif +// EOF diff --git a/third-party/boost-math/include/boost/math/special_functions/polygamma.hpp b/third-party/boost-math/include/boost/math/special_functions/polygamma.hpp new file mode 100644 index 0000000000000..6b7815d5e07fd --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/polygamma.hpp @@ -0,0 +1,83 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2013 Paul Bristow +// 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) + +#ifndef _BOOST_POLYGAMMA_2013_07_30_HPP_ + #define _BOOST_POLYGAMMA_2013_07_30_HPP_ + +#include +#include +#include + +namespace boost { namespace math { + + + template + inline typename tools::promote_args::type polygamma(const int n, T x, const Policy& pol) + { + // + // Filter off special cases right at the start: + // + if(n == 0) + return boost::math::digamma(x, pol); + if(n == 1) + return boost::math::trigamma(x, pol); + // + // We've found some standard library functions to misbehave if any FPU exception flags + // are set prior to their call, this code will clear those flags, then reset them + // on exit: + // + BOOST_FPU_EXCEPTION_GUARD + // + // The type of the result - the common type of T and U after + // any integer types have been promoted to double: + // + typedef typename tools::promote_args::type result_type; + // + // The type used for the calculation. This may be a wider type than + // the result in order to ensure full precision: + // + typedef typename policies::evaluation::type value_type; + // + // The type of the policy to forward to the actual implementation. + // We disable promotion of float and double as that's [possibly] + // happened already in the line above. Also reset to the default + // any policies we don't use (reduces code bloat if we're called + // multiple times with differing policies we don't actually use). + // Also normalise the type, again to reduce code bloat in case we're + // called multiple times with functionally identical policies that happen + // to be different types. + // + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + // + // Whew. Now we can make the actual call to the implementation. + // Arguments are explicitly cast to the evaluation type, and the result + // passed through checked_narrowing_cast which handles things like overflow + // according to the policy passed: + // + return policies::checked_narrowing_cast( + detail::polygamma_imp(n, static_cast(x), forwarding_policy()), + "boost::math::polygamma<%1%>(int, %1%)"); + } + + template + inline typename tools::promote_args::type polygamma(const int n, T x) + { + return boost::math::polygamma(n, x, policies::policy<>()); + } + +} } // namespace boost::math + +#endif // _BOOST_BERNOULLI_2013_05_30_HPP_ + diff --git a/third-party/boost-math/include/boost/math/special_functions/pow.hpp b/third-party/boost-math/include/boost/math/special_functions/pow.hpp new file mode 100644 index 0000000000000..7a1bb14eba539 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/pow.hpp @@ -0,0 +1,144 @@ +// Boost pow.hpp header file +// Computes a power with exponent known at compile-time + +// (C) Copyright Bruno Lalande 2008. +// (C) Copyright Matt Borland 2024. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_MATH_POW_HPP +#define BOOST_MATH_POW_HPP + +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +namespace boost { +namespace math { + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code, only triggered in release mode and /W4 +#endif + +namespace detail { + + +template +struct positive_power +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base) + { + T power = positive_power::result(base); + return power * power; + } +}; + +template +struct positive_power +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base) + { + T power = positive_power::result(base); + return base * power * power; + } +}; + +template <> +struct positive_power<1, 1> +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base){ return base; } +}; + + +template +struct power_if_positive +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy&) + { return positive_power::result(base); } +}; + +template +struct power_if_positive +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy) + { + if (base == 0) + { + return policies::raise_overflow_error( + "boost::math::pow(%1%)", + "Attempted to compute a negative power of 0", + policy + ); + } + + return T(1) / positive_power<-N>::result(base); + } +}; + +template <> +struct power_if_positive<0, true> +{ + template + BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy) + { + if (base == 0) + { + return policies::raise_indeterminate_result_error( + "boost::math::pow(%1%)", + "The result of pow<0>(%1%) is undetermined", + base, + T(1), + policy + ); + } + + return T(1); + } +}; + + +template +struct select_power_if_positive +{ + using type = power_if_positive= 0)>; +}; + + +} // namespace detail + + +template +BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args::type pow(T base, const Policy& policy) +{ + using result_type = typename tools::promote_args::type; + return detail::select_power_if_positive::type::result(static_cast(base), policy); +} + +template +BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args::type pow(T base) +{ return pow(base, policies::policy<>()); } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +} // namespace math +} // namespace boost + + +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/powm1.hpp b/third-party/boost-math/include/boost/math/special_functions/powm1.hpp new file mode 100644 index 0000000000000..80d02dc2996b4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/powm1.hpp @@ -0,0 +1,101 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_POWM1 +#define BOOST_MATH_POWM1 + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline T powm1_imp(const T x, const T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::powm1<%1%>(%1%, %1%)"; + + if ((fabs(y * (x - 1)) < T(0.5)) || (fabs(y) < T(0.2))) + { + // We don't have any good/quick approximation for log(x) * y + // so just try it and see: + T l = y * log(x); + if (l < T(0.5)) + return boost::math::expm1(l, pol); + if (l > boost::math::tools::log_max_value()) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + // fall through.... + } + + T result = pow(x, y) - 1; + if((boost::math::isinf)(result)) + return result < 0 ? -boost::math::policies::raise_overflow_error(function, nullptr, pol) : boost::math::policies::raise_overflow_error(function, nullptr, pol); + if((boost::math::isnan)(result)) + return boost::math::policies::raise_domain_error(function, "Result of pow is complex or undefined", x, pol); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline T powm1_imp_dispatch(const T x, const T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if ((boost::math::signbit)(x)) // Need to error check -0 here as well + { + constexpr auto function = "boost::math::powm1<%1%>(%1%, %1%)"; + + // y had better be an integer: + if (boost::math::trunc(y) != y) + return boost::math::policies::raise_domain_error(function, "For non-integral exponent, expected base > 0 but got %1%", x, pol); + if (boost::math::trunc(y / 2) == y / 2) + return powm1_imp(T(-x), T(y), pol); + } + + return powm1_imp(T(x), T(y), pol); +} + +} // detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + powm1(const T1 a, const T2 z) +{ + typedef typename tools::promote_args::type result_type; + return detail::powm1_imp_dispatch(static_cast(a), static_cast(z), policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + powm1(const T1 a, const T2 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::powm1_imp_dispatch(static_cast(a), static_cast(z), pol); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_POWM1 + + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/prime.hpp b/third-party/boost-math/include/boost/math/special_functions/prime.hpp new file mode 100644 index 0000000000000..35d9c1a470fa5 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/prime.hpp @@ -0,0 +1,2433 @@ +// Copyright 2008 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) + +#ifndef BOOST_MATH_SF_PRIME_HPP +#define BOOST_MATH_SF_PRIME_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ + + // + // See https://github.com/boostorg/math/issues/923 for the reasons behind using struct's here: + // + template + struct prime_data_imp + { + // + // This is basically three big tables which together + // occupy 19946 bytes, we use the smallest type which + // will handle each value, and store the final set of + // values in a uint16_t with the values offset by 0xffff. + // That gives us the first 10000 primes with the largest + // being 104729: + // +#ifndef BOOST_MATH_HAVE_CONSTEXPR_TABLES + static const unsigned b1 = 53; + static const unsigned b2 = 6541; + static const unsigned b3 = 10000; + static const std::array a1; + static const std::array a2; + static const std::array a3; +#else + static constexpr unsigned b1 = 53; + static constexpr unsigned b2 = 6541; + static constexpr unsigned b3 = 10000; + static constexpr std::array a1 = { { + 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, + 37u, 41u, 43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, + 79u, 83u, 89u, 97u, 101u, 103u, 107u, 109u, 113u, + 127u, 131u, 137u, 139u, 149u, 151u, 157u, 163u, + 167u, 173u, 179u, 181u, 191u, 193u, 197u, 199u, + 211u, 223u, 227u, 229u, 233u, 239u, 241u, 251u + }}; + static constexpr std::array a2 = {{ + 257u, 263u, 269u, 271u, 277u, 281u, 283u, 293u, + 307u, 311u, 313u, 317u, 331u, 337u, 347u, 349u, 353u, + 359u, 367u, 373u, 379u, 383u, 389u, 397u, 401u, 409u, + 419u, 421u, 431u, 433u, 439u, 443u, 449u, 457u, 461u, + 463u, 467u, 479u, 487u, 491u, 499u, 503u, 509u, 521u, + 523u, 541u, 547u, 557u, 563u, 569u, 571u, 577u, 587u, + 593u, 599u, 601u, 607u, 613u, 617u, 619u, 631u, 641u, + 643u, 647u, 653u, 659u, 661u, 673u, 677u, 683u, 691u, + 701u, 709u, 719u, 727u, 733u, 739u, 743u, 751u, 757u, + 761u, 769u, 773u, 787u, 797u, 809u, 811u, 821u, 823u, + 827u, 829u, 839u, 853u, 857u, 859u, 863u, 877u, 881u, + 883u, 887u, 907u, 911u, 919u, 929u, 937u, 941u, 947u, + 953u, 967u, 971u, 977u, 983u, 991u, 997u, 1009u, 1013u, + 1019u, 1021u, 1031u, 1033u, 1039u, 1049u, 1051u, 1061u, 1063u, + 1069u, 1087u, 1091u, 1093u, 1097u, 1103u, 1109u, 1117u, 1123u, + 1129u, 1151u, 1153u, 1163u, 1171u, 1181u, 1187u, 1193u, 1201u, + 1213u, 1217u, 1223u, 1229u, 1231u, 1237u, 1249u, 1259u, 1277u, + 1279u, 1283u, 1289u, 1291u, 1297u, 1301u, 1303u, 1307u, 1319u, + 1321u, 1327u, 1361u, 1367u, 1373u, 1381u, 1399u, 1409u, 1423u, + 1427u, 1429u, 1433u, 1439u, 1447u, 1451u, 1453u, 1459u, 1471u, + 1481u, 1483u, 1487u, 1489u, 1493u, 1499u, 1511u, 1523u, 1531u, + 1543u, 1549u, 1553u, 1559u, 1567u, 1571u, 1579u, 1583u, 1597u, + 1601u, 1607u, 1609u, 1613u, 1619u, 1621u, 1627u, 1637u, 1657u, + 1663u, 1667u, 1669u, 1693u, 1697u, 1699u, 1709u, 1721u, 1723u, + 1733u, 1741u, 1747u, 1753u, 1759u, 1777u, 1783u, 1787u, 1789u, + 1801u, 1811u, 1823u, 1831u, 1847u, 1861u, 1867u, 1871u, 1873u, + 1877u, 1879u, 1889u, 1901u, 1907u, 1913u, 1931u, 1933u, 1949u, + 1951u, 1973u, 1979u, 1987u, 1993u, 1997u, 1999u, 2003u, 2011u, + 2017u, 2027u, 2029u, 2039u, 2053u, 2063u, 2069u, 2081u, 2083u, + 2087u, 2089u, 2099u, 2111u, 2113u, 2129u, 2131u, 2137u, 2141u, + 2143u, 2153u, 2161u, 2179u, 2203u, 2207u, 2213u, 2221u, 2237u, + 2239u, 2243u, 2251u, 2267u, 2269u, 2273u, 2281u, 2287u, 2293u, + 2297u, 2309u, 2311u, 2333u, 2339u, 2341u, 2347u, 2351u, 2357u, + 2371u, 2377u, 2381u, 2383u, 2389u, 2393u, 2399u, 2411u, 2417u, + 2423u, 2437u, 2441u, 2447u, 2459u, 2467u, 2473u, 2477u, 2503u, + 2521u, 2531u, 2539u, 2543u, 2549u, 2551u, 2557u, 2579u, 2591u, + 2593u, 2609u, 2617u, 2621u, 2633u, 2647u, 2657u, 2659u, 2663u, + 2671u, 2677u, 2683u, 2687u, 2689u, 2693u, 2699u, 2707u, 2711u, + 2713u, 2719u, 2729u, 2731u, 2741u, 2749u, 2753u, 2767u, 2777u, + 2789u, 2791u, 2797u, 2801u, 2803u, 2819u, 2833u, 2837u, 2843u, + 2851u, 2857u, 2861u, 2879u, 2887u, 2897u, 2903u, 2909u, 2917u, + 2927u, 2939u, 2953u, 2957u, 2963u, 2969u, 2971u, 2999u, 3001u, + 3011u, 3019u, 3023u, 3037u, 3041u, 3049u, 3061u, 3067u, 3079u, + 3083u, 3089u, 3109u, 3119u, 3121u, 3137u, 3163u, 3167u, 3169u, + 3181u, 3187u, 3191u, 3203u, 3209u, 3217u, 3221u, 3229u, 3251u, + 3253u, 3257u, 3259u, 3271u, 3299u, 3301u, 3307u, 3313u, 3319u, + 3323u, 3329u, 3331u, 3343u, 3347u, 3359u, 3361u, 3371u, 3373u, + 3389u, 3391u, 3407u, 3413u, 3433u, 3449u, 3457u, 3461u, 3463u, + 3467u, 3469u, 3491u, 3499u, 3511u, 3517u, 3527u, 3529u, 3533u, + 3539u, 3541u, 3547u, 3557u, 3559u, 3571u, 3581u, 3583u, 3593u, + 3607u, 3613u, 3617u, 3623u, 3631u, 3637u, 3643u, 3659u, 3671u, + 3673u, 3677u, 3691u, 3697u, 3701u, 3709u, 3719u, 3727u, 3733u, + 3739u, 3761u, 3767u, 3769u, 3779u, 3793u, 3797u, 3803u, 3821u, + 3823u, 3833u, 3847u, 3851u, 3853u, 3863u, 3877u, 3881u, 3889u, + 3907u, 3911u, 3917u, 3919u, 3923u, 3929u, 3931u, 3943u, 3947u, + 3967u, 3989u, 4001u, 4003u, 4007u, 4013u, 4019u, 4021u, 4027u, + 4049u, 4051u, 4057u, 4073u, 4079u, 4091u, 4093u, 4099u, 4111u, + 4127u, 4129u, 4133u, 4139u, 4153u, 4157u, 4159u, 4177u, 4201u, + 4211u, 4217u, 4219u, 4229u, 4231u, 4241u, 4243u, 4253u, 4259u, + 4261u, 4271u, 4273u, 4283u, 4289u, 4297u, 4327u, 4337u, 4339u, + 4349u, 4357u, 4363u, 4373u, 4391u, 4397u, 4409u, 4421u, 4423u, + 4441u, 4447u, 4451u, 4457u, 4463u, 4481u, 4483u, 4493u, 4507u, + 4513u, 4517u, 4519u, 4523u, 4547u, 4549u, 4561u, 4567u, 4583u, + 4591u, 4597u, 4603u, 4621u, 4637u, 4639u, 4643u, 4649u, 4651u, + 4657u, 4663u, 4673u, 4679u, 4691u, 4703u, 4721u, 4723u, 4729u, + 4733u, 4751u, 4759u, 4783u, 4787u, 4789u, 4793u, 4799u, 4801u, + 4813u, 4817u, 4831u, 4861u, 4871u, 4877u, 4889u, 4903u, 4909u, + 4919u, 4931u, 4933u, 4937u, 4943u, 4951u, 4957u, 4967u, 4969u, + 4973u, 4987u, 4993u, 4999u, 5003u, 5009u, 5011u, 5021u, 5023u, + 5039u, 5051u, 5059u, 5077u, 5081u, 5087u, 5099u, 5101u, 5107u, + 5113u, 5119u, 5147u, 5153u, 5167u, 5171u, 5179u, 5189u, 5197u, + 5209u, 5227u, 5231u, 5233u, 5237u, 5261u, 5273u, 5279u, 5281u, + 5297u, 5303u, 5309u, 5323u, 5333u, 5347u, 5351u, 5381u, 5387u, + 5393u, 5399u, 5407u, 5413u, 5417u, 5419u, 5431u, 5437u, 5441u, + 5443u, 5449u, 5471u, 5477u, 5479u, 5483u, 5501u, 5503u, 5507u, + 5519u, 5521u, 5527u, 5531u, 5557u, 5563u, 5569u, 5573u, 5581u, + 5591u, 5623u, 5639u, 5641u, 5647u, 5651u, 5653u, 5657u, 5659u, + 5669u, 5683u, 5689u, 5693u, 5701u, 5711u, 5717u, 5737u, 5741u, + 5743u, 5749u, 5779u, 5783u, 5791u, 5801u, 5807u, 5813u, 5821u, + 5827u, 5839u, 5843u, 5849u, 5851u, 5857u, 5861u, 5867u, 5869u, + 5879u, 5881u, 5897u, 5903u, 5923u, 5927u, 5939u, 5953u, 5981u, + 5987u, 6007u, 6011u, 6029u, 6037u, 6043u, 6047u, 6053u, 6067u, + 6073u, 6079u, 6089u, 6091u, 6101u, 6113u, 6121u, 6131u, 6133u, + 6143u, 6151u, 6163u, 6173u, 6197u, 6199u, 6203u, 6211u, 6217u, + 6221u, 6229u, 6247u, 6257u, 6263u, 6269u, 6271u, 6277u, 6287u, + 6299u, 6301u, 6311u, 6317u, 6323u, 6329u, 6337u, 6343u, 6353u, + 6359u, 6361u, 6367u, 6373u, 6379u, 6389u, 6397u, 6421u, 6427u, + 6449u, 6451u, 6469u, 6473u, 6481u, 6491u, 6521u, 6529u, 6547u, + 6551u, 6553u, 6563u, 6569u, 6571u, 6577u, 6581u, 6599u, 6607u, + 6619u, 6637u, 6653u, 6659u, 6661u, 6673u, 6679u, 6689u, 6691u, + 6701u, 6703u, 6709u, 6719u, 6733u, 6737u, 6761u, 6763u, 6779u, + 6781u, 6791u, 6793u, 6803u, 6823u, 6827u, 6829u, 6833u, 6841u, + 6857u, 6863u, 6869u, 6871u, 6883u, 6899u, 6907u, 6911u, 6917u, + 6947u, 6949u, 6959u, 6961u, 6967u, 6971u, 6977u, 6983u, 6991u, + 6997u, 7001u, 7013u, 7019u, 7027u, 7039u, 7043u, 7057u, 7069u, + 7079u, 7103u, 7109u, 7121u, 7127u, 7129u, 7151u, 7159u, 7177u, + 7187u, 7193u, 7207u, 7211u, 7213u, 7219u, 7229u, 7237u, 7243u, + 7247u, 7253u, 7283u, 7297u, 7307u, 7309u, 7321u, 7331u, 7333u, + 7349u, 7351u, 7369u, 7393u, 7411u, 7417u, 7433u, 7451u, 7457u, + 7459u, 7477u, 7481u, 7487u, 7489u, 7499u, 7507u, 7517u, 7523u, + 7529u, 7537u, 7541u, 7547u, 7549u, 7559u, 7561u, 7573u, 7577u, + 7583u, 7589u, 7591u, 7603u, 7607u, 7621u, 7639u, 7643u, 7649u, + 7669u, 7673u, 7681u, 7687u, 7691u, 7699u, 7703u, 7717u, 7723u, + 7727u, 7741u, 7753u, 7757u, 7759u, 7789u, 7793u, 7817u, 7823u, + 7829u, 7841u, 7853u, 7867u, 7873u, 7877u, 7879u, 7883u, 7901u, + 7907u, 7919u, 7927u, 7933u, 7937u, 7949u, 7951u, 7963u, 7993u, + 8009u, 8011u, 8017u, 8039u, 8053u, 8059u, 8069u, 8081u, 8087u, + 8089u, 8093u, 8101u, 8111u, 8117u, 8123u, 8147u, 8161u, 8167u, + 8171u, 8179u, 8191u, 8209u, 8219u, 8221u, 8231u, 8233u, 8237u, + 8243u, 8263u, 8269u, 8273u, 8287u, 8291u, 8293u, 8297u, 8311u, + 8317u, 8329u, 8353u, 8363u, 8369u, 8377u, 8387u, 8389u, 8419u, + 8423u, 8429u, 8431u, 8443u, 8447u, 8461u, 8467u, 8501u, 8513u, + 8521u, 8527u, 8537u, 8539u, 8543u, 8563u, 8573u, 8581u, 8597u, + 8599u, 8609u, 8623u, 8627u, 8629u, 8641u, 8647u, 8663u, 8669u, + 8677u, 8681u, 8689u, 8693u, 8699u, 8707u, 8713u, 8719u, 8731u, + 8737u, 8741u, 8747u, 8753u, 8761u, 8779u, 8783u, 8803u, 8807u, + 8819u, 8821u, 8831u, 8837u, 8839u, 8849u, 8861u, 8863u, 8867u, + 8887u, 8893u, 8923u, 8929u, 8933u, 8941u, 8951u, 8963u, 8969u, + 8971u, 8999u, 9001u, 9007u, 9011u, 9013u, 9029u, 9041u, 9043u, + 9049u, 9059u, 9067u, 9091u, 9103u, 9109u, 9127u, 9133u, 9137u, + 9151u, 9157u, 9161u, 9173u, 9181u, 9187u, 9199u, 9203u, 9209u, + 9221u, 9227u, 9239u, 9241u, 9257u, 9277u, 9281u, 9283u, 9293u, + 9311u, 9319u, 9323u, 9337u, 9341u, 9343u, 9349u, 9371u, 9377u, + 9391u, 9397u, 9403u, 9413u, 9419u, 9421u, 9431u, 9433u, 9437u, + 9439u, 9461u, 9463u, 9467u, 9473u, 9479u, 9491u, 9497u, 9511u, + 9521u, 9533u, 9539u, 9547u, 9551u, 9587u, 9601u, 9613u, 9619u, + 9623u, 9629u, 9631u, 9643u, 9649u, 9661u, 9677u, 9679u, 9689u, + 9697u, 9719u, 9721u, 9733u, 9739u, 9743u, 9749u, 9767u, 9769u, + 9781u, 9787u, 9791u, 9803u, 9811u, 9817u, 9829u, 9833u, 9839u, + 9851u, 9857u, 9859u, 9871u, 9883u, 9887u, 9901u, 9907u, 9923u, + 9929u, 9931u, 9941u, 9949u, 9967u, 9973u, 10007u, 10009u, 10037u, + 10039u, 10061u, 10067u, 10069u, 10079u, 10091u, 10093u, 10099u, 10103u, + 10111u, 10133u, 10139u, 10141u, 10151u, 10159u, 10163u, 10169u, 10177u, + 10181u, 10193u, 10211u, 10223u, 10243u, 10247u, 10253u, 10259u, 10267u, + 10271u, 10273u, 10289u, 10301u, 10303u, 10313u, 10321u, 10331u, 10333u, + 10337u, 10343u, 10357u, 10369u, 10391u, 10399u, 10427u, 10429u, 10433u, + 10453u, 10457u, 10459u, 10463u, 10477u, 10487u, 10499u, 10501u, 10513u, + 10529u, 10531u, 10559u, 10567u, 10589u, 10597u, 10601u, 10607u, 10613u, + 10627u, 10631u, 10639u, 10651u, 10657u, 10663u, 10667u, 10687u, 10691u, + 10709u, 10711u, 10723u, 10729u, 10733u, 10739u, 10753u, 10771u, 10781u, + 10789u, 10799u, 10831u, 10837u, 10847u, 10853u, 10859u, 10861u, 10867u, + 10883u, 10889u, 10891u, 10903u, 10909u, 10937u, 10939u, 10949u, 10957u, + 10973u, 10979u, 10987u, 10993u, 11003u, 11027u, 11047u, 11057u, 11059u, + 11069u, 11071u, 11083u, 11087u, 11093u, 11113u, 11117u, 11119u, 11131u, + 11149u, 11159u, 11161u, 11171u, 11173u, 11177u, 11197u, 11213u, 11239u, + 11243u, 11251u, 11257u, 11261u, 11273u, 11279u, 11287u, 11299u, 11311u, + 11317u, 11321u, 11329u, 11351u, 11353u, 11369u, 11383u, 11393u, 11399u, + 11411u, 11423u, 11437u, 11443u, 11447u, 11467u, 11471u, 11483u, 11489u, + 11491u, 11497u, 11503u, 11519u, 11527u, 11549u, 11551u, 11579u, 11587u, + 11593u, 11597u, 11617u, 11621u, 11633u, 11657u, 11677u, 11681u, 11689u, + 11699u, 11701u, 11717u, 11719u, 11731u, 11743u, 11777u, 11779u, 11783u, + 11789u, 11801u, 11807u, 11813u, 11821u, 11827u, 11831u, 11833u, 11839u, + 11863u, 11867u, 11887u, 11897u, 11903u, 11909u, 11923u, 11927u, 11933u, + 11939u, 11941u, 11953u, 11959u, 11969u, 11971u, 11981u, 11987u, 12007u, + 12011u, 12037u, 12041u, 12043u, 12049u, 12071u, 12073u, 12097u, 12101u, + 12107u, 12109u, 12113u, 12119u, 12143u, 12149u, 12157u, 12161u, 12163u, + 12197u, 12203u, 12211u, 12227u, 12239u, 12241u, 12251u, 12253u, 12263u, + 12269u, 12277u, 12281u, 12289u, 12301u, 12323u, 12329u, 12343u, 12347u, + 12373u, 12377u, 12379u, 12391u, 12401u, 12409u, 12413u, 12421u, 12433u, + 12437u, 12451u, 12457u, 12473u, 12479u, 12487u, 12491u, 12497u, 12503u, + 12511u, 12517u, 12527u, 12539u, 12541u, 12547u, 12553u, 12569u, 12577u, + 12583u, 12589u, 12601u, 12611u, 12613u, 12619u, 12637u, 12641u, 12647u, + 12653u, 12659u, 12671u, 12689u, 12697u, 12703u, 12713u, 12721u, 12739u, + 12743u, 12757u, 12763u, 12781u, 12791u, 12799u, 12809u, 12821u, 12823u, + 12829u, 12841u, 12853u, 12889u, 12893u, 12899u, 12907u, 12911u, 12917u, + 12919u, 12923u, 12941u, 12953u, 12959u, 12967u, 12973u, 12979u, 12983u, + 13001u, 13003u, 13007u, 13009u, 13033u, 13037u, 13043u, 13049u, 13063u, + 13093u, 13099u, 13103u, 13109u, 13121u, 13127u, 13147u, 13151u, 13159u, + 13163u, 13171u, 13177u, 13183u, 13187u, 13217u, 13219u, 13229u, 13241u, + 13249u, 13259u, 13267u, 13291u, 13297u, 13309u, 13313u, 13327u, 13331u, + 13337u, 13339u, 13367u, 13381u, 13397u, 13399u, 13411u, 13417u, 13421u, + 13441u, 13451u, 13457u, 13463u, 13469u, 13477u, 13487u, 13499u, 13513u, + 13523u, 13537u, 13553u, 13567u, 13577u, 13591u, 13597u, 13613u, 13619u, + 13627u, 13633u, 13649u, 13669u, 13679u, 13681u, 13687u, 13691u, 13693u, + 13697u, 13709u, 13711u, 13721u, 13723u, 13729u, 13751u, 13757u, 13759u, + 13763u, 13781u, 13789u, 13799u, 13807u, 13829u, 13831u, 13841u, 13859u, + 13873u, 13877u, 13879u, 13883u, 13901u, 13903u, 13907u, 13913u, 13921u, + 13931u, 13933u, 13963u, 13967u, 13997u, 13999u, 14009u, 14011u, 14029u, + 14033u, 14051u, 14057u, 14071u, 14081u, 14083u, 14087u, 14107u, 14143u, + 14149u, 14153u, 14159u, 14173u, 14177u, 14197u, 14207u, 14221u, 14243u, + 14249u, 14251u, 14281u, 14293u, 14303u, 14321u, 14323u, 14327u, 14341u, + 14347u, 14369u, 14387u, 14389u, 14401u, 14407u, 14411u, 14419u, 14423u, + 14431u, 14437u, 14447u, 14449u, 14461u, 14479u, 14489u, 14503u, 14519u, + 14533u, 14537u, 14543u, 14549u, 14551u, 14557u, 14561u, 14563u, 14591u, + 14593u, 14621u, 14627u, 14629u, 14633u, 14639u, 14653u, 14657u, 14669u, + 14683u, 14699u, 14713u, 14717u, 14723u, 14731u, 14737u, 14741u, 14747u, + 14753u, 14759u, 14767u, 14771u, 14779u, 14783u, 14797u, 14813u, 14821u, + 14827u, 14831u, 14843u, 14851u, 14867u, 14869u, 14879u, 14887u, 14891u, + 14897u, 14923u, 14929u, 14939u, 14947u, 14951u, 14957u, 14969u, 14983u, + 15013u, 15017u, 15031u, 15053u, 15061u, 15073u, 15077u, 15083u, 15091u, + 15101u, 15107u, 15121u, 15131u, 15137u, 15139u, 15149u, 15161u, 15173u, + 15187u, 15193u, 15199u, 15217u, 15227u, 15233u, 15241u, 15259u, 15263u, + 15269u, 15271u, 15277u, 15287u, 15289u, 15299u, 15307u, 15313u, 15319u, + 15329u, 15331u, 15349u, 15359u, 15361u, 15373u, 15377u, 15383u, 15391u, + 15401u, 15413u, 15427u, 15439u, 15443u, 15451u, 15461u, 15467u, 15473u, + 15493u, 15497u, 15511u, 15527u, 15541u, 15551u, 15559u, 15569u, 15581u, + 15583u, 15601u, 15607u, 15619u, 15629u, 15641u, 15643u, 15647u, 15649u, + 15661u, 15667u, 15671u, 15679u, 15683u, 15727u, 15731u, 15733u, 15737u, + 15739u, 15749u, 15761u, 15767u, 15773u, 15787u, 15791u, 15797u, 15803u, + 15809u, 15817u, 15823u, 15859u, 15877u, 15881u, 15887u, 15889u, 15901u, + 15907u, 15913u, 15919u, 15923u, 15937u, 15959u, 15971u, 15973u, 15991u, + 16001u, 16007u, 16033u, 16057u, 16061u, 16063u, 16067u, 16069u, 16073u, + 16087u, 16091u, 16097u, 16103u, 16111u, 16127u, 16139u, 16141u, 16183u, + 16187u, 16189u, 16193u, 16217u, 16223u, 16229u, 16231u, 16249u, 16253u, + 16267u, 16273u, 16301u, 16319u, 16333u, 16339u, 16349u, 16361u, 16363u, + 16369u, 16381u, 16411u, 16417u, 16421u, 16427u, 16433u, 16447u, 16451u, + 16453u, 16477u, 16481u, 16487u, 16493u, 16519u, 16529u, 16547u, 16553u, + 16561u, 16567u, 16573u, 16603u, 16607u, 16619u, 16631u, 16633u, 16649u, + 16651u, 16657u, 16661u, 16673u, 16691u, 16693u, 16699u, 16703u, 16729u, + 16741u, 16747u, 16759u, 16763u, 16787u, 16811u, 16823u, 16829u, 16831u, + 16843u, 16871u, 16879u, 16883u, 16889u, 16901u, 16903u, 16921u, 16927u, + 16931u, 16937u, 16943u, 16963u, 16979u, 16981u, 16987u, 16993u, 17011u, + 17021u, 17027u, 17029u, 17033u, 17041u, 17047u, 17053u, 17077u, 17093u, + 17099u, 17107u, 17117u, 17123u, 17137u, 17159u, 17167u, 17183u, 17189u, + 17191u, 17203u, 17207u, 17209u, 17231u, 17239u, 17257u, 17291u, 17293u, + 17299u, 17317u, 17321u, 17327u, 17333u, 17341u, 17351u, 17359u, 17377u, + 17383u, 17387u, 17389u, 17393u, 17401u, 17417u, 17419u, 17431u, 17443u, + 17449u, 17467u, 17471u, 17477u, 17483u, 17489u, 17491u, 17497u, 17509u, + 17519u, 17539u, 17551u, 17569u, 17573u, 17579u, 17581u, 17597u, 17599u, + 17609u, 17623u, 17627u, 17657u, 17659u, 17669u, 17681u, 17683u, 17707u, + 17713u, 17729u, 17737u, 17747u, 17749u, 17761u, 17783u, 17789u, 17791u, + 17807u, 17827u, 17837u, 17839u, 17851u, 17863u, 17881u, 17891u, 17903u, + 17909u, 17911u, 17921u, 17923u, 17929u, 17939u, 17957u, 17959u, 17971u, + 17977u, 17981u, 17987u, 17989u, 18013u, 18041u, 18043u, 18047u, 18049u, + 18059u, 18061u, 18077u, 18089u, 18097u, 18119u, 18121u, 18127u, 18131u, + 18133u, 18143u, 18149u, 18169u, 18181u, 18191u, 18199u, 18211u, 18217u, + 18223u, 18229u, 18233u, 18251u, 18253u, 18257u, 18269u, 18287u, 18289u, + 18301u, 18307u, 18311u, 18313u, 18329u, 18341u, 18353u, 18367u, 18371u, + 18379u, 18397u, 18401u, 18413u, 18427u, 18433u, 18439u, 18443u, 18451u, + 18457u, 18461u, 18481u, 18493u, 18503u, 18517u, 18521u, 18523u, 18539u, + 18541u, 18553u, 18583u, 18587u, 18593u, 18617u, 18637u, 18661u, 18671u, + 18679u, 18691u, 18701u, 18713u, 18719u, 18731u, 18743u, 18749u, 18757u, + 18773u, 18787u, 18793u, 18797u, 18803u, 18839u, 18859u, 18869u, 18899u, + 18911u, 18913u, 18917u, 18919u, 18947u, 18959u, 18973u, 18979u, 19001u, + 19009u, 19013u, 19031u, 19037u, 19051u, 19069u, 19073u, 19079u, 19081u, + 19087u, 19121u, 19139u, 19141u, 19157u, 19163u, 19181u, 19183u, 19207u, + 19211u, 19213u, 19219u, 19231u, 19237u, 19249u, 19259u, 19267u, 19273u, + 19289u, 19301u, 19309u, 19319u, 19333u, 19373u, 19379u, 19381u, 19387u, + 19391u, 19403u, 19417u, 19421u, 19423u, 19427u, 19429u, 19433u, 19441u, + 19447u, 19457u, 19463u, 19469u, 19471u, 19477u, 19483u, 19489u, 19501u, + 19507u, 19531u, 19541u, 19543u, 19553u, 19559u, 19571u, 19577u, 19583u, + 19597u, 19603u, 19609u, 19661u, 19681u, 19687u, 19697u, 19699u, 19709u, + 19717u, 19727u, 19739u, 19751u, 19753u, 19759u, 19763u, 19777u, 19793u, + 19801u, 19813u, 19819u, 19841u, 19843u, 19853u, 19861u, 19867u, 19889u, + 19891u, 19913u, 19919u, 19927u, 19937u, 19949u, 19961u, 19963u, 19973u, + 19979u, 19991u, 19993u, 19997u, 20011u, 20021u, 20023u, 20029u, 20047u, + 20051u, 20063u, 20071u, 20089u, 20101u, 20107u, 20113u, 20117u, 20123u, + 20129u, 20143u, 20147u, 20149u, 20161u, 20173u, 20177u, 20183u, 20201u, + 20219u, 20231u, 20233u, 20249u, 20261u, 20269u, 20287u, 20297u, 20323u, + 20327u, 20333u, 20341u, 20347u, 20353u, 20357u, 20359u, 20369u, 20389u, + 20393u, 20399u, 20407u, 20411u, 20431u, 20441u, 20443u, 20477u, 20479u, + 20483u, 20507u, 20509u, 20521u, 20533u, 20543u, 20549u, 20551u, 20563u, + 20593u, 20599u, 20611u, 20627u, 20639u, 20641u, 20663u, 20681u, 20693u, + 20707u, 20717u, 20719u, 20731u, 20743u, 20747u, 20749u, 20753u, 20759u, + 20771u, 20773u, 20789u, 20807u, 20809u, 20849u, 20857u, 20873u, 20879u, + 20887u, 20897u, 20899u, 20903u, 20921u, 20929u, 20939u, 20947u, 20959u, + 20963u, 20981u, 20983u, 21001u, 21011u, 21013u, 21017u, 21019u, 21023u, + 21031u, 21059u, 21061u, 21067u, 21089u, 21101u, 21107u, 21121u, 21139u, + 21143u, 21149u, 21157u, 21163u, 21169u, 21179u, 21187u, 21191u, 21193u, + 21211u, 21221u, 21227u, 21247u, 21269u, 21277u, 21283u, 21313u, 21317u, + 21319u, 21323u, 21341u, 21347u, 21377u, 21379u, 21383u, 21391u, 21397u, + 21401u, 21407u, 21419u, 21433u, 21467u, 21481u, 21487u, 21491u, 21493u, + 21499u, 21503u, 21517u, 21521u, 21523u, 21529u, 21557u, 21559u, 21563u, + 21569u, 21577u, 21587u, 21589u, 21599u, 21601u, 21611u, 21613u, 21617u, + 21647u, 21649u, 21661u, 21673u, 21683u, 21701u, 21713u, 21727u, 21737u, + 21739u, 21751u, 21757u, 21767u, 21773u, 21787u, 21799u, 21803u, 21817u, + 21821u, 21839u, 21841u, 21851u, 21859u, 21863u, 21871u, 21881u, 21893u, + 21911u, 21929u, 21937u, 21943u, 21961u, 21977u, 21991u, 21997u, 22003u, + 22013u, 22027u, 22031u, 22037u, 22039u, 22051u, 22063u, 22067u, 22073u, + 22079u, 22091u, 22093u, 22109u, 22111u, 22123u, 22129u, 22133u, 22147u, + 22153u, 22157u, 22159u, 22171u, 22189u, 22193u, 22229u, 22247u, 22259u, + 22271u, 22273u, 22277u, 22279u, 22283u, 22291u, 22303u, 22307u, 22343u, + 22349u, 22367u, 22369u, 22381u, 22391u, 22397u, 22409u, 22433u, 22441u, + 22447u, 22453u, 22469u, 22481u, 22483u, 22501u, 22511u, 22531u, 22541u, + 22543u, 22549u, 22567u, 22571u, 22573u, 22613u, 22619u, 22621u, 22637u, + 22639u, 22643u, 22651u, 22669u, 22679u, 22691u, 22697u, 22699u, 22709u, + 22717u, 22721u, 22727u, 22739u, 22741u, 22751u, 22769u, 22777u, 22783u, + 22787u, 22807u, 22811u, 22817u, 22853u, 22859u, 22861u, 22871u, 22877u, + 22901u, 22907u, 22921u, 22937u, 22943u, 22961u, 22963u, 22973u, 22993u, + 23003u, 23011u, 23017u, 23021u, 23027u, 23029u, 23039u, 23041u, 23053u, + 23057u, 23059u, 23063u, 23071u, 23081u, 23087u, 23099u, 23117u, 23131u, + 23143u, 23159u, 23167u, 23173u, 23189u, 23197u, 23201u, 23203u, 23209u, + 23227u, 23251u, 23269u, 23279u, 23291u, 23293u, 23297u, 23311u, 23321u, + 23327u, 23333u, 23339u, 23357u, 23369u, 23371u, 23399u, 23417u, 23431u, + 23447u, 23459u, 23473u, 23497u, 23509u, 23531u, 23537u, 23539u, 23549u, + 23557u, 23561u, 23563u, 23567u, 23581u, 23593u, 23599u, 23603u, 23609u, + 23623u, 23627u, 23629u, 23633u, 23663u, 23669u, 23671u, 23677u, 23687u, + 23689u, 23719u, 23741u, 23743u, 23747u, 23753u, 23761u, 23767u, 23773u, + 23789u, 23801u, 23813u, 23819u, 23827u, 23831u, 23833u, 23857u, 23869u, + 23873u, 23879u, 23887u, 23893u, 23899u, 23909u, 23911u, 23917u, 23929u, + 23957u, 23971u, 23977u, 23981u, 23993u, 24001u, 24007u, 24019u, 24023u, + 24029u, 24043u, 24049u, 24061u, 24071u, 24077u, 24083u, 24091u, 24097u, + 24103u, 24107u, 24109u, 24113u, 24121u, 24133u, 24137u, 24151u, 24169u, + 24179u, 24181u, 24197u, 24203u, 24223u, 24229u, 24239u, 24247u, 24251u, + 24281u, 24317u, 24329u, 24337u, 24359u, 24371u, 24373u, 24379u, 24391u, + 24407u, 24413u, 24419u, 24421u, 24439u, 24443u, 24469u, 24473u, 24481u, + 24499u, 24509u, 24517u, 24527u, 24533u, 24547u, 24551u, 24571u, 24593u, + 24611u, 24623u, 24631u, 24659u, 24671u, 24677u, 24683u, 24691u, 24697u, + 24709u, 24733u, 24749u, 24763u, 24767u, 24781u, 24793u, 24799u, 24809u, + 24821u, 24841u, 24847u, 24851u, 24859u, 24877u, 24889u, 24907u, 24917u, + 24919u, 24923u, 24943u, 24953u, 24967u, 24971u, 24977u, 24979u, 24989u, + 25013u, 25031u, 25033u, 25037u, 25057u, 25073u, 25087u, 25097u, 25111u, + 25117u, 25121u, 25127u, 25147u, 25153u, 25163u, 25169u, 25171u, 25183u, + 25189u, 25219u, 25229u, 25237u, 25243u, 25247u, 25253u, 25261u, 25301u, + 25303u, 25307u, 25309u, 25321u, 25339u, 25343u, 25349u, 25357u, 25367u, + 25373u, 25391u, 25409u, 25411u, 25423u, 25439u, 25447u, 25453u, 25457u, + 25463u, 25469u, 25471u, 25523u, 25537u, 25541u, 25561u, 25577u, 25579u, + 25583u, 25589u, 25601u, 25603u, 25609u, 25621u, 25633u, 25639u, 25643u, + 25657u, 25667u, 25673u, 25679u, 25693u, 25703u, 25717u, 25733u, 25741u, + 25747u, 25759u, 25763u, 25771u, 25793u, 25799u, 25801u, 25819u, 25841u, + 25847u, 25849u, 25867u, 25873u, 25889u, 25903u, 25913u, 25919u, 25931u, + 25933u, 25939u, 25943u, 25951u, 25969u, 25981u, 25997u, 25999u, 26003u, + 26017u, 26021u, 26029u, 26041u, 26053u, 26083u, 26099u, 26107u, 26111u, + 26113u, 26119u, 26141u, 26153u, 26161u, 26171u, 26177u, 26183u, 26189u, + 26203u, 26209u, 26227u, 26237u, 26249u, 26251u, 26261u, 26263u, 26267u, + 26293u, 26297u, 26309u, 26317u, 26321u, 26339u, 26347u, 26357u, 26371u, + 26387u, 26393u, 26399u, 26407u, 26417u, 26423u, 26431u, 26437u, 26449u, + 26459u, 26479u, 26489u, 26497u, 26501u, 26513u, 26539u, 26557u, 26561u, + 26573u, 26591u, 26597u, 26627u, 26633u, 26641u, 26647u, 26669u, 26681u, + 26683u, 26687u, 26693u, 26699u, 26701u, 26711u, 26713u, 26717u, 26723u, + 26729u, 26731u, 26737u, 26759u, 26777u, 26783u, 26801u, 26813u, 26821u, + 26833u, 26839u, 26849u, 26861u, 26863u, 26879u, 26881u, 26891u, 26893u, + 26903u, 26921u, 26927u, 26947u, 26951u, 26953u, 26959u, 26981u, 26987u, + 26993u, 27011u, 27017u, 27031u, 27043u, 27059u, 27061u, 27067u, 27073u, + 27077u, 27091u, 27103u, 27107u, 27109u, 27127u, 27143u, 27179u, 27191u, + 27197u, 27211u, 27239u, 27241u, 27253u, 27259u, 27271u, 27277u, 27281u, + 27283u, 27299u, 27329u, 27337u, 27361u, 27367u, 27397u, 27407u, 27409u, + 27427u, 27431u, 27437u, 27449u, 27457u, 27479u, 27481u, 27487u, 27509u, + 27527u, 27529u, 27539u, 27541u, 27551u, 27581u, 27583u, 27611u, 27617u, + 27631u, 27647u, 27653u, 27673u, 27689u, 27691u, 27697u, 27701u, 27733u, + 27737u, 27739u, 27743u, 27749u, 27751u, 27763u, 27767u, 27773u, 27779u, + 27791u, 27793u, 27799u, 27803u, 27809u, 27817u, 27823u, 27827u, 27847u, + 27851u, 27883u, 27893u, 27901u, 27917u, 27919u, 27941u, 27943u, 27947u, + 27953u, 27961u, 27967u, 27983u, 27997u, 28001u, 28019u, 28027u, 28031u, + 28051u, 28057u, 28069u, 28081u, 28087u, 28097u, 28099u, 28109u, 28111u, + 28123u, 28151u, 28163u, 28181u, 28183u, 28201u, 28211u, 28219u, 28229u, + 28277u, 28279u, 28283u, 28289u, 28297u, 28307u, 28309u, 28319u, 28349u, + 28351u, 28387u, 28393u, 28403u, 28409u, 28411u, 28429u, 28433u, 28439u, + 28447u, 28463u, 28477u, 28493u, 28499u, 28513u, 28517u, 28537u, 28541u, + 28547u, 28549u, 28559u, 28571u, 28573u, 28579u, 28591u, 28597u, 28603u, + 28607u, 28619u, 28621u, 28627u, 28631u, 28643u, 28649u, 28657u, 28661u, + 28663u, 28669u, 28687u, 28697u, 28703u, 28711u, 28723u, 28729u, 28751u, + 28753u, 28759u, 28771u, 28789u, 28793u, 28807u, 28813u, 28817u, 28837u, + 28843u, 28859u, 28867u, 28871u, 28879u, 28901u, 28909u, 28921u, 28927u, + 28933u, 28949u, 28961u, 28979u, 29009u, 29017u, 29021u, 29023u, 29027u, + 29033u, 29059u, 29063u, 29077u, 29101u, 29123u, 29129u, 29131u, 29137u, + 29147u, 29153u, 29167u, 29173u, 29179u, 29191u, 29201u, 29207u, 29209u, + 29221u, 29231u, 29243u, 29251u, 29269u, 29287u, 29297u, 29303u, 29311u, + 29327u, 29333u, 29339u, 29347u, 29363u, 29383u, 29387u, 29389u, 29399u, + 29401u, 29411u, 29423u, 29429u, 29437u, 29443u, 29453u, 29473u, 29483u, + 29501u, 29527u, 29531u, 29537u, 29567u, 29569u, 29573u, 29581u, 29587u, + 29599u, 29611u, 29629u, 29633u, 29641u, 29663u, 29669u, 29671u, 29683u, + 29717u, 29723u, 29741u, 29753u, 29759u, 29761u, 29789u, 29803u, 29819u, + 29833u, 29837u, 29851u, 29863u, 29867u, 29873u, 29879u, 29881u, 29917u, + 29921u, 29927u, 29947u, 29959u, 29983u, 29989u, 30011u, 30013u, 30029u, + 30047u, 30059u, 30071u, 30089u, 30091u, 30097u, 30103u, 30109u, 30113u, + 30119u, 30133u, 30137u, 30139u, 30161u, 30169u, 30181u, 30187u, 30197u, + 30203u, 30211u, 30223u, 30241u, 30253u, 30259u, 30269u, 30271u, 30293u, + 30307u, 30313u, 30319u, 30323u, 30341u, 30347u, 30367u, 30389u, 30391u, + 30403u, 30427u, 30431u, 30449u, 30467u, 30469u, 30491u, 30493u, 30497u, + 30509u, 30517u, 30529u, 30539u, 30553u, 30557u, 30559u, 30577u, 30593u, + 30631u, 30637u, 30643u, 30649u, 30661u, 30671u, 30677u, 30689u, 30697u, + 30703u, 30707u, 30713u, 30727u, 30757u, 30763u, 30773u, 30781u, 30803u, + 30809u, 30817u, 30829u, 30839u, 30841u, 30851u, 30853u, 30859u, 30869u, + 30871u, 30881u, 30893u, 30911u, 30931u, 30937u, 30941u, 30949u, 30971u, + 30977u, 30983u, 31013u, 31019u, 31033u, 31039u, 31051u, 31063u, 31069u, + 31079u, 31081u, 31091u, 31121u, 31123u, 31139u, 31147u, 31151u, 31153u, + 31159u, 31177u, 31181u, 31183u, 31189u, 31193u, 31219u, 31223u, 31231u, + 31237u, 31247u, 31249u, 31253u, 31259u, 31267u, 31271u, 31277u, 31307u, + 31319u, 31321u, 31327u, 31333u, 31337u, 31357u, 31379u, 31387u, 31391u, + 31393u, 31397u, 31469u, 31477u, 31481u, 31489u, 31511u, 31513u, 31517u, + 31531u, 31541u, 31543u, 31547u, 31567u, 31573u, 31583u, 31601u, 31607u, + 31627u, 31643u, 31649u, 31657u, 31663u, 31667u, 31687u, 31699u, 31721u, + 31723u, 31727u, 31729u, 31741u, 31751u, 31769u, 31771u, 31793u, 31799u, + 31817u, 31847u, 31849u, 31859u, 31873u, 31883u, 31891u, 31907u, 31957u, + 31963u, 31973u, 31981u, 31991u, 32003u, 32009u, 32027u, 32029u, 32051u, + 32057u, 32059u, 32063u, 32069u, 32077u, 32083u, 32089u, 32099u, 32117u, + 32119u, 32141u, 32143u, 32159u, 32173u, 32183u, 32189u, 32191u, 32203u, + 32213u, 32233u, 32237u, 32251u, 32257u, 32261u, 32297u, 32299u, 32303u, + 32309u, 32321u, 32323u, 32327u, 32341u, 32353u, 32359u, 32363u, 32369u, + 32371u, 32377u, 32381u, 32401u, 32411u, 32413u, 32423u, 32429u, 32441u, + 32443u, 32467u, 32479u, 32491u, 32497u, 32503u, 32507u, 32531u, 32533u, + 32537u, 32561u, 32563u, 32569u, 32573u, 32579u, 32587u, 32603u, 32609u, + 32611u, 32621u, 32633u, 32647u, 32653u, 32687u, 32693u, 32707u, 32713u, + 32717u, 32719u, 32749u, 32771u, 32779u, 32783u, 32789u, 32797u, 32801u, + 32803u, 32831u, 32833u, 32839u, 32843u, 32869u, 32887u, 32909u, 32911u, + 32917u, 32933u, 32939u, 32941u, 32957u, 32969u, 32971u, 32983u, 32987u, + 32993u, 32999u, 33013u, 33023u, 33029u, 33037u, 33049u, 33053u, 33071u, + 33073u, 33083u, 33091u, 33107u, 33113u, 33119u, 33149u, 33151u, 33161u, + 33179u, 33181u, 33191u, 33199u, 33203u, 33211u, 33223u, 33247u, 33287u, + 33289u, 33301u, 33311u, 33317u, 33329u, 33331u, 33343u, 33347u, 33349u, + 33353u, 33359u, 33377u, 33391u, 33403u, 33409u, 33413u, 33427u, 33457u, + 33461u, 33469u, 33479u, 33487u, 33493u, 33503u, 33521u, 33529u, 33533u, + 33547u, 33563u, 33569u, 33577u, 33581u, 33587u, 33589u, 33599u, 33601u, + 33613u, 33617u, 33619u, 33623u, 33629u, 33637u, 33641u, 33647u, 33679u, + 33703u, 33713u, 33721u, 33739u, 33749u, 33751u, 33757u, 33767u, 33769u, + 33773u, 33791u, 33797u, 33809u, 33811u, 33827u, 33829u, 33851u, 33857u, + 33863u, 33871u, 33889u, 33893u, 33911u, 33923u, 33931u, 33937u, 33941u, + 33961u, 33967u, 33997u, 34019u, 34031u, 34033u, 34039u, 34057u, 34061u, + 34123u, 34127u, 34129u, 34141u, 34147u, 34157u, 34159u, 34171u, 34183u, + 34211u, 34213u, 34217u, 34231u, 34253u, 34259u, 34261u, 34267u, 34273u, + 34283u, 34297u, 34301u, 34303u, 34313u, 34319u, 34327u, 34337u, 34351u, + 34361u, 34367u, 34369u, 34381u, 34403u, 34421u, 34429u, 34439u, 34457u, + 34469u, 34471u, 34483u, 34487u, 34499u, 34501u, 34511u, 34513u, 34519u, + 34537u, 34543u, 34549u, 34583u, 34589u, 34591u, 34603u, 34607u, 34613u, + 34631u, 34649u, 34651u, 34667u, 34673u, 34679u, 34687u, 34693u, 34703u, + 34721u, 34729u, 34739u, 34747u, 34757u, 34759u, 34763u, 34781u, 34807u, + 34819u, 34841u, 34843u, 34847u, 34849u, 34871u, 34877u, 34883u, 34897u, + 34913u, 34919u, 34939u, 34949u, 34961u, 34963u, 34981u, 35023u, 35027u, + 35051u, 35053u, 35059u, 35069u, 35081u, 35083u, 35089u, 35099u, 35107u, + 35111u, 35117u, 35129u, 35141u, 35149u, 35153u, 35159u, 35171u, 35201u, + 35221u, 35227u, 35251u, 35257u, 35267u, 35279u, 35281u, 35291u, 35311u, + 35317u, 35323u, 35327u, 35339u, 35353u, 35363u, 35381u, 35393u, 35401u, + 35407u, 35419u, 35423u, 35437u, 35447u, 35449u, 35461u, 35491u, 35507u, + 35509u, 35521u, 35527u, 35531u, 35533u, 35537u, 35543u, 35569u, 35573u, + 35591u, 35593u, 35597u, 35603u, 35617u, 35671u, 35677u, 35729u, 35731u, + 35747u, 35753u, 35759u, 35771u, 35797u, 35801u, 35803u, 35809u, 35831u, + 35837u, 35839u, 35851u, 35863u, 35869u, 35879u, 35897u, 35899u, 35911u, + 35923u, 35933u, 35951u, 35963u, 35969u, 35977u, 35983u, 35993u, 35999u, + 36007u, 36011u, 36013u, 36017u, 36037u, 36061u, 36067u, 36073u, 36083u, + 36097u, 36107u, 36109u, 36131u, 36137u, 36151u, 36161u, 36187u, 36191u, + 36209u, 36217u, 36229u, 36241u, 36251u, 36263u, 36269u, 36277u, 36293u, + 36299u, 36307u, 36313u, 36319u, 36341u, 36343u, 36353u, 36373u, 36383u, + 36389u, 36433u, 36451u, 36457u, 36467u, 36469u, 36473u, 36479u, 36493u, + 36497u, 36523u, 36527u, 36529u, 36541u, 36551u, 36559u, 36563u, 36571u, + 36583u, 36587u, 36599u, 36607u, 36629u, 36637u, 36643u, 36653u, 36671u, + 36677u, 36683u, 36691u, 36697u, 36709u, 36713u, 36721u, 36739u, 36749u, + 36761u, 36767u, 36779u, 36781u, 36787u, 36791u, 36793u, 36809u, 36821u, + 36833u, 36847u, 36857u, 36871u, 36877u, 36887u, 36899u, 36901u, 36913u, + 36919u, 36923u, 36929u, 36931u, 36943u, 36947u, 36973u, 36979u, 36997u, + 37003u, 37013u, 37019u, 37021u, 37039u, 37049u, 37057u, 37061u, 37087u, + 37097u, 37117u, 37123u, 37139u, 37159u, 37171u, 37181u, 37189u, 37199u, + 37201u, 37217u, 37223u, 37243u, 37253u, 37273u, 37277u, 37307u, 37309u, + 37313u, 37321u, 37337u, 37339u, 37357u, 37361u, 37363u, 37369u, 37379u, + 37397u, 37409u, 37423u, 37441u, 37447u, 37463u, 37483u, 37489u, 37493u, + 37501u, 37507u, 37511u, 37517u, 37529u, 37537u, 37547u, 37549u, 37561u, + 37567u, 37571u, 37573u, 37579u, 37589u, 37591u, 37607u, 37619u, 37633u, + 37643u, 37649u, 37657u, 37663u, 37691u, 37693u, 37699u, 37717u, 37747u, + 37781u, 37783u, 37799u, 37811u, 37813u, 37831u, 37847u, 37853u, 37861u, + 37871u, 37879u, 37889u, 37897u, 37907u, 37951u, 37957u, 37963u, 37967u, + 37987u, 37991u, 37993u, 37997u, 38011u, 38039u, 38047u, 38053u, 38069u, + 38083u, 38113u, 38119u, 38149u, 38153u, 38167u, 38177u, 38183u, 38189u, + 38197u, 38201u, 38219u, 38231u, 38237u, 38239u, 38261u, 38273u, 38281u, + 38287u, 38299u, 38303u, 38317u, 38321u, 38327u, 38329u, 38333u, 38351u, + 38371u, 38377u, 38393u, 38431u, 38447u, 38449u, 38453u, 38459u, 38461u, + 38501u, 38543u, 38557u, 38561u, 38567u, 38569u, 38593u, 38603u, 38609u, + 38611u, 38629u, 38639u, 38651u, 38653u, 38669u, 38671u, 38677u, 38693u, + 38699u, 38707u, 38711u, 38713u, 38723u, 38729u, 38737u, 38747u, 38749u, + 38767u, 38783u, 38791u, 38803u, 38821u, 38833u, 38839u, 38851u, 38861u, + 38867u, 38873u, 38891u, 38903u, 38917u, 38921u, 38923u, 38933u, 38953u, + 38959u, 38971u, 38977u, 38993u, 39019u, 39023u, 39041u, 39043u, 39047u, + 39079u, 39089u, 39097u, 39103u, 39107u, 39113u, 39119u, 39133u, 39139u, + 39157u, 39161u, 39163u, 39181u, 39191u, 39199u, 39209u, 39217u, 39227u, + 39229u, 39233u, 39239u, 39241u, 39251u, 39293u, 39301u, 39313u, 39317u, + 39323u, 39341u, 39343u, 39359u, 39367u, 39371u, 39373u, 39383u, 39397u, + 39409u, 39419u, 39439u, 39443u, 39451u, 39461u, 39499u, 39503u, 39509u, + 39511u, 39521u, 39541u, 39551u, 39563u, 39569u, 39581u, 39607u, 39619u, + 39623u, 39631u, 39659u, 39667u, 39671u, 39679u, 39703u, 39709u, 39719u, + 39727u, 39733u, 39749u, 39761u, 39769u, 39779u, 39791u, 39799u, 39821u, + 39827u, 39829u, 39839u, 39841u, 39847u, 39857u, 39863u, 39869u, 39877u, + 39883u, 39887u, 39901u, 39929u, 39937u, 39953u, 39971u, 39979u, 39983u, + 39989u, 40009u, 40013u, 40031u, 40037u, 40039u, 40063u, 40087u, 40093u, + 40099u, 40111u, 40123u, 40127u, 40129u, 40151u, 40153u, 40163u, 40169u, + 40177u, 40189u, 40193u, 40213u, 40231u, 40237u, 40241u, 40253u, 40277u, + 40283u, 40289u, 40343u, 40351u, 40357u, 40361u, 40387u, 40423u, 40427u, + 40429u, 40433u, 40459u, 40471u, 40483u, 40487u, 40493u, 40499u, 40507u, + 40519u, 40529u, 40531u, 40543u, 40559u, 40577u, 40583u, 40591u, 40597u, + 40609u, 40627u, 40637u, 40639u, 40693u, 40697u, 40699u, 40709u, 40739u, + 40751u, 40759u, 40763u, 40771u, 40787u, 40801u, 40813u, 40819u, 40823u, + 40829u, 40841u, 40847u, 40849u, 40853u, 40867u, 40879u, 40883u, 40897u, + 40903u, 40927u, 40933u, 40939u, 40949u, 40961u, 40973u, 40993u, 41011u, + 41017u, 41023u, 41039u, 41047u, 41051u, 41057u, 41077u, 41081u, 41113u, + 41117u, 41131u, 41141u, 41143u, 41149u, 41161u, 41177u, 41179u, 41183u, + 41189u, 41201u, 41203u, 41213u, 41221u, 41227u, 41231u, 41233u, 41243u, + 41257u, 41263u, 41269u, 41281u, 41299u, 41333u, 41341u, 41351u, 41357u, + 41381u, 41387u, 41389u, 41399u, 41411u, 41413u, 41443u, 41453u, 41467u, + 41479u, 41491u, 41507u, 41513u, 41519u, 41521u, 41539u, 41543u, 41549u, + 41579u, 41593u, 41597u, 41603u, 41609u, 41611u, 41617u, 41621u, 41627u, + 41641u, 41647u, 41651u, 41659u, 41669u, 41681u, 41687u, 41719u, 41729u, + 41737u, 41759u, 41761u, 41771u, 41777u, 41801u, 41809u, 41813u, 41843u, + 41849u, 41851u, 41863u, 41879u, 41887u, 41893u, 41897u, 41903u, 41911u, + 41927u, 41941u, 41947u, 41953u, 41957u, 41959u, 41969u, 41981u, 41983u, + 41999u, 42013u, 42017u, 42019u, 42023u, 42043u, 42061u, 42071u, 42073u, + 42083u, 42089u, 42101u, 42131u, 42139u, 42157u, 42169u, 42179u, 42181u, + 42187u, 42193u, 42197u, 42209u, 42221u, 42223u, 42227u, 42239u, 42257u, + 42281u, 42283u, 42293u, 42299u, 42307u, 42323u, 42331u, 42337u, 42349u, + 42359u, 42373u, 42379u, 42391u, 42397u, 42403u, 42407u, 42409u, 42433u, + 42437u, 42443u, 42451u, 42457u, 42461u, 42463u, 42467u, 42473u, 42487u, + 42491u, 42499u, 42509u, 42533u, 42557u, 42569u, 42571u, 42577u, 42589u, + 42611u, 42641u, 42643u, 42649u, 42667u, 42677u, 42683u, 42689u, 42697u, + 42701u, 42703u, 42709u, 42719u, 42727u, 42737u, 42743u, 42751u, 42767u, + 42773u, 42787u, 42793u, 42797u, 42821u, 42829u, 42839u, 42841u, 42853u, + 42859u, 42863u, 42899u, 42901u, 42923u, 42929u, 42937u, 42943u, 42953u, + 42961u, 42967u, 42979u, 42989u, 43003u, 43013u, 43019u, 43037u, 43049u, + 43051u, 43063u, 43067u, 43093u, 43103u, 43117u, 43133u, 43151u, 43159u, + 43177u, 43189u, 43201u, 43207u, 43223u, 43237u, 43261u, 43271u, 43283u, + 43291u, 43313u, 43319u, 43321u, 43331u, 43391u, 43397u, 43399u, 43403u, + 43411u, 43427u, 43441u, 43451u, 43457u, 43481u, 43487u, 43499u, 43517u, + 43541u, 43543u, 43573u, 43577u, 43579u, 43591u, 43597u, 43607u, 43609u, + 43613u, 43627u, 43633u, 43649u, 43651u, 43661u, 43669u, 43691u, 43711u, + 43717u, 43721u, 43753u, 43759u, 43777u, 43781u, 43783u, 43787u, 43789u, + 43793u, 43801u, 43853u, 43867u, 43889u, 43891u, 43913u, 43933u, 43943u, + 43951u, 43961u, 43963u, 43969u, 43973u, 43987u, 43991u, 43997u, 44017u, + 44021u, 44027u, 44029u, 44041u, 44053u, 44059u, 44071u, 44087u, 44089u, + 44101u, 44111u, 44119u, 44123u, 44129u, 44131u, 44159u, 44171u, 44179u, + 44189u, 44201u, 44203u, 44207u, 44221u, 44249u, 44257u, 44263u, 44267u, + 44269u, 44273u, 44279u, 44281u, 44293u, 44351u, 44357u, 44371u, 44381u, + 44383u, 44389u, 44417u, 44449u, 44453u, 44483u, 44491u, 44497u, 44501u, + 44507u, 44519u, 44531u, 44533u, 44537u, 44543u, 44549u, 44563u, 44579u, + 44587u, 44617u, 44621u, 44623u, 44633u, 44641u, 44647u, 44651u, 44657u, + 44683u, 44687u, 44699u, 44701u, 44711u, 44729u, 44741u, 44753u, 44771u, + 44773u, 44777u, 44789u, 44797u, 44809u, 44819u, 44839u, 44843u, 44851u, + 44867u, 44879u, 44887u, 44893u, 44909u, 44917u, 44927u, 44939u, 44953u, + 44959u, 44963u, 44971u, 44983u, 44987u, 45007u, 45013u, 45053u, 45061u, + 45077u, 45083u, 45119u, 45121u, 45127u, 45131u, 45137u, 45139u, 45161u, + 45179u, 45181u, 45191u, 45197u, 45233u, 45247u, 45259u, 45263u, 45281u, + 45289u, 45293u, 45307u, 45317u, 45319u, 45329u, 45337u, 45341u, 45343u, + 45361u, 45377u, 45389u, 45403u, 45413u, 45427u, 45433u, 45439u, 45481u, + 45491u, 45497u, 45503u, 45523u, 45533u, 45541u, 45553u, 45557u, 45569u, + 45587u, 45589u, 45599u, 45613u, 45631u, 45641u, 45659u, 45667u, 45673u, + 45677u, 45691u, 45697u, 45707u, 45737u, 45751u, 45757u, 45763u, 45767u, + 45779u, 45817u, 45821u, 45823u, 45827u, 45833u, 45841u, 45853u, 45863u, + 45869u, 45887u, 45893u, 45943u, 45949u, 45953u, 45959u, 45971u, 45979u, + 45989u, 46021u, 46027u, 46049u, 46051u, 46061u, 46073u, 46091u, 46093u, + 46099u, 46103u, 46133u, 46141u, 46147u, 46153u, 46171u, 46181u, 46183u, + 46187u, 46199u, 46219u, 46229u, 46237u, 46261u, 46271u, 46273u, 46279u, + 46301u, 46307u, 46309u, 46327u, 46337u, 46349u, 46351u, 46381u, 46399u, + 46411u, 46439u, 46441u, 46447u, 46451u, 46457u, 46471u, 46477u, 46489u, + 46499u, 46507u, 46511u, 46523u, 46549u, 46559u, 46567u, 46573u, 46589u, + 46591u, 46601u, 46619u, 46633u, 46639u, 46643u, 46649u, 46663u, 46679u, + 46681u, 46687u, 46691u, 46703u, 46723u, 46727u, 46747u, 46751u, 46757u, + 46769u, 46771u, 46807u, 46811u, 46817u, 46819u, 46829u, 46831u, 46853u, + 46861u, 46867u, 46877u, 46889u, 46901u, 46919u, 46933u, 46957u, 46993u, + 46997u, 47017u, 47041u, 47051u, 47057u, 47059u, 47087u, 47093u, 47111u, + 47119u, 47123u, 47129u, 47137u, 47143u, 47147u, 47149u, 47161u, 47189u, + 47207u, 47221u, 47237u, 47251u, 47269u, 47279u, 47287u, 47293u, 47297u, + 47303u, 47309u, 47317u, 47339u, 47351u, 47353u, 47363u, 47381u, 47387u, + 47389u, 47407u, 47417u, 47419u, 47431u, 47441u, 47459u, 47491u, 47497u, + 47501u, 47507u, 47513u, 47521u, 47527u, 47533u, 47543u, 47563u, 47569u, + 47581u, 47591u, 47599u, 47609u, 47623u, 47629u, 47639u, 47653u, 47657u, + 47659u, 47681u, 47699u, 47701u, 47711u, 47713u, 47717u, 47737u, 47741u, + 47743u, 47777u, 47779u, 47791u, 47797u, 47807u, 47809u, 47819u, 47837u, + 47843u, 47857u, 47869u, 47881u, 47903u, 47911u, 47917u, 47933u, 47939u, + 47947u, 47951u, 47963u, 47969u, 47977u, 47981u, 48017u, 48023u, 48029u, + 48049u, 48073u, 48079u, 48091u, 48109u, 48119u, 48121u, 48131u, 48157u, + 48163u, 48179u, 48187u, 48193u, 48197u, 48221u, 48239u, 48247u, 48259u, + 48271u, 48281u, 48299u, 48311u, 48313u, 48337u, 48341u, 48353u, 48371u, + 48383u, 48397u, 48407u, 48409u, 48413u, 48437u, 48449u, 48463u, 48473u, + 48479u, 48481u, 48487u, 48491u, 48497u, 48523u, 48527u, 48533u, 48539u, + 48541u, 48563u, 48571u, 48589u, 48593u, 48611u, 48619u, 48623u, 48647u, + 48649u, 48661u, 48673u, 48677u, 48679u, 48731u, 48733u, 48751u, 48757u, + 48761u, 48767u, 48779u, 48781u, 48787u, 48799u, 48809u, 48817u, 48821u, + 48823u, 48847u, 48857u, 48859u, 48869u, 48871u, 48883u, 48889u, 48907u, + 48947u, 48953u, 48973u, 48989u, 48991u, 49003u, 49009u, 49019u, 49031u, + 49033u, 49037u, 49043u, 49057u, 49069u, 49081u, 49103u, 49109u, 49117u, + 49121u, 49123u, 49139u, 49157u, 49169u, 49171u, 49177u, 49193u, 49199u, + 49201u, 49207u, 49211u, 49223u, 49253u, 49261u, 49277u, 49279u, 49297u, + 49307u, 49331u, 49333u, 49339u, 49363u, 49367u, 49369u, 49391u, 49393u, + 49409u, 49411u, 49417u, 49429u, 49433u, 49451u, 49459u, 49463u, 49477u, + 49481u, 49499u, 49523u, 49529u, 49531u, 49537u, 49547u, 49549u, 49559u, + 49597u, 49603u, 49613u, 49627u, 49633u, 49639u, 49663u, 49667u, 49669u, + 49681u, 49697u, 49711u, 49727u, 49739u, 49741u, 49747u, 49757u, 49783u, + 49787u, 49789u, 49801u, 49807u, 49811u, 49823u, 49831u, 49843u, 49853u, + 49871u, 49877u, 49891u, 49919u, 49921u, 49927u, 49937u, 49939u, 49943u, + 49957u, 49991u, 49993u, 49999u, 50021u, 50023u, 50033u, 50047u, 50051u, + 50053u, 50069u, 50077u, 50087u, 50093u, 50101u, 50111u, 50119u, 50123u, + 50129u, 50131u, 50147u, 50153u, 50159u, 50177u, 50207u, 50221u, 50227u, + 50231u, 50261u, 50263u, 50273u, 50287u, 50291u, 50311u, 50321u, 50329u, + 50333u, 50341u, 50359u, 50363u, 50377u, 50383u, 50387u, 50411u, 50417u, + 50423u, 50441u, 50459u, 50461u, 50497u, 50503u, 50513u, 50527u, 50539u, + 50543u, 50549u, 50551u, 50581u, 50587u, 50591u, 50593u, 50599u, 50627u, + 50647u, 50651u, 50671u, 50683u, 50707u, 50723u, 50741u, 50753u, 50767u, + 50773u, 50777u, 50789u, 50821u, 50833u, 50839u, 50849u, 50857u, 50867u, + 50873u, 50891u, 50893u, 50909u, 50923u, 50929u, 50951u, 50957u, 50969u, + 50971u, 50989u, 50993u, 51001u, 51031u, 51043u, 51047u, 51059u, 51061u, + 51071u, 51109u, 51131u, 51133u, 51137u, 51151u, 51157u, 51169u, 51193u, + 51197u, 51199u, 51203u, 51217u, 51229u, 51239u, 51241u, 51257u, 51263u, + 51283u, 51287u, 51307u, 51329u, 51341u, 51343u, 51347u, 51349u, 51361u, + 51383u, 51407u, 51413u, 51419u, 51421u, 51427u, 51431u, 51437u, 51439u, + 51449u, 51461u, 51473u, 51479u, 51481u, 51487u, 51503u, 51511u, 51517u, + 51521u, 51539u, 51551u, 51563u, 51577u, 51581u, 51593u, 51599u, 51607u, + 51613u, 51631u, 51637u, 51647u, 51659u, 51673u, 51679u, 51683u, 51691u, + 51713u, 51719u, 51721u, 51749u, 51767u, 51769u, 51787u, 51797u, 51803u, + 51817u, 51827u, 51829u, 51839u, 51853u, 51859u, 51869u, 51871u, 51893u, + 51899u, 51907u, 51913u, 51929u, 51941u, 51949u, 51971u, 51973u, 51977u, + 51991u, 52009u, 52021u, 52027u, 52051u, 52057u, 52067u, 52069u, 52081u, + 52103u, 52121u, 52127u, 52147u, 52153u, 52163u, 52177u, 52181u, 52183u, + 52189u, 52201u, 52223u, 52237u, 52249u, 52253u, 52259u, 52267u, 52289u, + 52291u, 52301u, 52313u, 52321u, 52361u, 52363u, 52369u, 52379u, 52387u, + 52391u, 52433u, 52453u, 52457u, 52489u, 52501u, 52511u, 52517u, 52529u, + 52541u, 52543u, 52553u, 52561u, 52567u, 52571u, 52579u, 52583u, 52609u, + 52627u, 52631u, 52639u, 52667u, 52673u, 52691u, 52697u, 52709u, 52711u, + 52721u, 52727u, 52733u, 52747u, 52757u, 52769u, 52783u, 52807u, 52813u, + 52817u, 52837u, 52859u, 52861u, 52879u, 52883u, 52889u, 52901u, 52903u, + 52919u, 52937u, 52951u, 52957u, 52963u, 52967u, 52973u, 52981u, 52999u, + 53003u, 53017u, 53047u, 53051u, 53069u, 53077u, 53087u, 53089u, 53093u, + 53101u, 53113u, 53117u, 53129u, 53147u, 53149u, 53161u, 53171u, 53173u, + 53189u, 53197u, 53201u, 53231u, 53233u, 53239u, 53267u, 53269u, 53279u, + 53281u, 53299u, 53309u, 53323u, 53327u, 53353u, 53359u, 53377u, 53381u, + 53401u, 53407u, 53411u, 53419u, 53437u, 53441u, 53453u, 53479u, 53503u, + 53507u, 53527u, 53549u, 53551u, 53569u, 53591u, 53593u, 53597u, 53609u, + 53611u, 53617u, 53623u, 53629u, 53633u, 53639u, 53653u, 53657u, 53681u, + 53693u, 53699u, 53717u, 53719u, 53731u, 53759u, 53773u, 53777u, 53783u, + 53791u, 53813u, 53819u, 53831u, 53849u, 53857u, 53861u, 53881u, 53887u, + 53891u, 53897u, 53899u, 53917u, 53923u, 53927u, 53939u, 53951u, 53959u, + 53987u, 53993u, 54001u, 54011u, 54013u, 54037u, 54049u, 54059u, 54083u, + 54091u, 54101u, 54121u, 54133u, 54139u, 54151u, 54163u, 54167u, 54181u, + 54193u, 54217u, 54251u, 54269u, 54277u, 54287u, 54293u, 54311u, 54319u, + 54323u, 54331u, 54347u, 54361u, 54367u, 54371u, 54377u, 54401u, 54403u, + 54409u, 54413u, 54419u, 54421u, 54437u, 54443u, 54449u, 54469u, 54493u, + 54497u, 54499u, 54503u, 54517u, 54521u, 54539u, 54541u, 54547u, 54559u, + 54563u, 54577u, 54581u, 54583u, 54601u, 54617u, 54623u, 54629u, 54631u, + 54647u, 54667u, 54673u, 54679u, 54709u, 54713u, 54721u, 54727u, 54751u, + 54767u, 54773u, 54779u, 54787u, 54799u, 54829u, 54833u, 54851u, 54869u, + 54877u, 54881u, 54907u, 54917u, 54919u, 54941u, 54949u, 54959u, 54973u, + 54979u, 54983u, 55001u, 55009u, 55021u, 55049u, 55051u, 55057u, 55061u, + 55073u, 55079u, 55103u, 55109u, 55117u, 55127u, 55147u, 55163u, 55171u, + 55201u, 55207u, 55213u, 55217u, 55219u, 55229u, 55243u, 55249u, 55259u, + 55291u, 55313u, 55331u, 55333u, 55337u, 55339u, 55343u, 55351u, 55373u, + 55381u, 55399u, 55411u, 55439u, 55441u, 55457u, 55469u, 55487u, 55501u, + 55511u, 55529u, 55541u, 55547u, 55579u, 55589u, 55603u, 55609u, 55619u, + 55621u, 55631u, 55633u, 55639u, 55661u, 55663u, 55667u, 55673u, 55681u, + 55691u, 55697u, 55711u, 55717u, 55721u, 55733u, 55763u, 55787u, 55793u, + 55799u, 55807u, 55813u, 55817u, 55819u, 55823u, 55829u, 55837u, 55843u, + 55849u, 55871u, 55889u, 55897u, 55901u, 55903u, 55921u, 55927u, 55931u, + 55933u, 55949u, 55967u, 55987u, 55997u, 56003u, 56009u, 56039u, 56041u, + 56053u, 56081u, 56087u, 56093u, 56099u, 56101u, 56113u, 56123u, 56131u, + 56149u, 56167u, 56171u, 56179u, 56197u, 56207u, 56209u, 56237u, 56239u, + 56249u, 56263u, 56267u, 56269u, 56299u, 56311u, 56333u, 56359u, 56369u, + 56377u, 56383u, 56393u, 56401u, 56417u, 56431u, 56437u, 56443u, 56453u, + 56467u, 56473u, 56477u, 56479u, 56489u, 56501u, 56503u, 56509u, 56519u, + 56527u, 56531u, 56533u, 56543u, 56569u, 56591u, 56597u, 56599u, 56611u, + 56629u, 56633u, 56659u, 56663u, 56671u, 56681u, 56687u, 56701u, 56711u, + 56713u, 56731u, 56737u, 56747u, 56767u, 56773u, 56779u, 56783u, 56807u, + 56809u, 56813u, 56821u, 56827u, 56843u, 56857u, 56873u, 56891u, 56893u, + 56897u, 56909u, 56911u, 56921u, 56923u, 56929u, 56941u, 56951u, 56957u, + 56963u, 56983u, 56989u, 56993u, 56999u, 57037u, 57041u, 57047u, 57059u, + 57073u, 57077u, 57089u, 57097u, 57107u, 57119u, 57131u, 57139u, 57143u, + 57149u, 57163u, 57173u, 57179u, 57191u, 57193u, 57203u, 57221u, 57223u, + 57241u, 57251u, 57259u, 57269u, 57271u, 57283u, 57287u, 57301u, 57329u, + 57331u, 57347u, 57349u, 57367u, 57373u, 57383u, 57389u, 57397u, 57413u, + 57427u, 57457u, 57467u, 57487u, 57493u, 57503u, 57527u, 57529u, 57557u, + 57559u, 57571u, 57587u, 57593u, 57601u, 57637u, 57641u, 57649u, 57653u, + 57667u, 57679u, 57689u, 57697u, 57709u, 57713u, 57719u, 57727u, 57731u, + 57737u, 57751u, 57773u, 57781u, 57787u, 57791u, 57793u, 57803u, 57809u, + 57829u, 57839u, 57847u, 57853u, 57859u, 57881u, 57899u, 57901u, 57917u, + 57923u, 57943u, 57947u, 57973u, 57977u, 57991u, 58013u, 58027u, 58031u, + 58043u, 58049u, 58057u, 58061u, 58067u, 58073u, 58099u, 58109u, 58111u, + 58129u, 58147u, 58151u, 58153u, 58169u, 58171u, 58189u, 58193u, 58199u, + 58207u, 58211u, 58217u, 58229u, 58231u, 58237u, 58243u, 58271u, 58309u, + 58313u, 58321u, 58337u, 58363u, 58367u, 58369u, 58379u, 58391u, 58393u, + 58403u, 58411u, 58417u, 58427u, 58439u, 58441u, 58451u, 58453u, 58477u, + 58481u, 58511u, 58537u, 58543u, 58549u, 58567u, 58573u, 58579u, 58601u, + 58603u, 58613u, 58631u, 58657u, 58661u, 58679u, 58687u, 58693u, 58699u, + 58711u, 58727u, 58733u, 58741u, 58757u, 58763u, 58771u, 58787u, 58789u, + 58831u, 58889u, 58897u, 58901u, 58907u, 58909u, 58913u, 58921u, 58937u, + 58943u, 58963u, 58967u, 58979u, 58991u, 58997u, 59009u, 59011u, 59021u, + 59023u, 59029u, 59051u, 59053u, 59063u, 59069u, 59077u, 59083u, 59093u, + 59107u, 59113u, 59119u, 59123u, 59141u, 59149u, 59159u, 59167u, 59183u, + 59197u, 59207u, 59209u, 59219u, 59221u, 59233u, 59239u, 59243u, 59263u, + 59273u, 59281u, 59333u, 59341u, 59351u, 59357u, 59359u, 59369u, 59377u, + 59387u, 59393u, 59399u, 59407u, 59417u, 59419u, 59441u, 59443u, 59447u, + 59453u, 59467u, 59471u, 59473u, 59497u, 59509u, 59513u, 59539u, 59557u, + 59561u, 59567u, 59581u, 59611u, 59617u, 59621u, 59627u, 59629u, 59651u, + 59659u, 59663u, 59669u, 59671u, 59693u, 59699u, 59707u, 59723u, 59729u, + 59743u, 59747u, 59753u, 59771u, 59779u, 59791u, 59797u, 59809u, 59833u, + 59863u, 59879u, 59887u, 59921u, 59929u, 59951u, 59957u, 59971u, 59981u, + 59999u, 60013u, 60017u, 60029u, 60037u, 60041u, 60077u, 60083u, 60089u, + 60091u, 60101u, 60103u, 60107u, 60127u, 60133u, 60139u, 60149u, 60161u, + 60167u, 60169u, 60209u, 60217u, 60223u, 60251u, 60257u, 60259u, 60271u, + 60289u, 60293u, 60317u, 60331u, 60337u, 60343u, 60353u, 60373u, 60383u, + 60397u, 60413u, 60427u, 60443u, 60449u, 60457u, 60493u, 60497u, 60509u, + 60521u, 60527u, 60539u, 60589u, 60601u, 60607u, 60611u, 60617u, 60623u, + 60631u, 60637u, 60647u, 60649u, 60659u, 60661u, 60679u, 60689u, 60703u, + 60719u, 60727u, 60733u, 60737u, 60757u, 60761u, 60763u, 60773u, 60779u, + 60793u, 60811u, 60821u, 60859u, 60869u, 60887u, 60889u, 60899u, 60901u, + 60913u, 60917u, 60919u, 60923u, 60937u, 60943u, 60953u, 60961u, 61001u, + 61007u, 61027u, 61031u, 61043u, 61051u, 61057u, 61091u, 61099u, 61121u, + 61129u, 61141u, 61151u, 61153u, 61169u, 61211u, 61223u, 61231u, 61253u, + 61261u, 61283u, 61291u, 61297u, 61331u, 61333u, 61339u, 61343u, 61357u, + 61363u, 61379u, 61381u, 61403u, 61409u, 61417u, 61441u, 61463u, 61469u, + 61471u, 61483u, 61487u, 61493u, 61507u, 61511u, 61519u, 61543u, 61547u, + 61553u, 61559u, 61561u, 61583u, 61603u, 61609u, 61613u, 61627u, 61631u, + 61637u, 61643u, 61651u, 61657u, 61667u, 61673u, 61681u, 61687u, 61703u, + 61717u, 61723u, 61729u, 61751u, 61757u, 61781u, 61813u, 61819u, 61837u, + 61843u, 61861u, 61871u, 61879u, 61909u, 61927u, 61933u, 61949u, 61961u, + 61967u, 61979u, 61981u, 61987u, 61991u, 62003u, 62011u, 62017u, 62039u, + 62047u, 62053u, 62057u, 62071u, 62081u, 62099u, 62119u, 62129u, 62131u, + 62137u, 62141u, 62143u, 62171u, 62189u, 62191u, 62201u, 62207u, 62213u, + 62219u, 62233u, 62273u, 62297u, 62299u, 62303u, 62311u, 62323u, 62327u, + 62347u, 62351u, 62383u, 62401u, 62417u, 62423u, 62459u, 62467u, 62473u, + 62477u, 62483u, 62497u, 62501u, 62507u, 62533u, 62539u, 62549u, 62563u, + 62581u, 62591u, 62597u, 62603u, 62617u, 62627u, 62633u, 62639u, 62653u, + 62659u, 62683u, 62687u, 62701u, 62723u, 62731u, 62743u, 62753u, 62761u, + 62773u, 62791u, 62801u, 62819u, 62827u, 62851u, 62861u, 62869u, 62873u, + 62897u, 62903u, 62921u, 62927u, 62929u, 62939u, 62969u, 62971u, 62981u, + 62983u, 62987u, 62989u, 63029u, 63031u, 63059u, 63067u, 63073u, 63079u, + 63097u, 63103u, 63113u, 63127u, 63131u, 63149u, 63179u, 63197u, 63199u, + 63211u, 63241u, 63247u, 63277u, 63281u, 63299u, 63311u, 63313u, 63317u, + 63331u, 63337u, 63347u, 63353u, 63361u, 63367u, 63377u, 63389u, 63391u, + 63397u, 63409u, 63419u, 63421u, 63439u, 63443u, 63463u, 63467u, 63473u, + 63487u, 63493u, 63499u, 63521u, 63527u, 63533u, 63541u, 63559u, 63577u, + 63587u, 63589u, 63599u, 63601u, 63607u, 63611u, 63617u, 63629u, 63647u, + 63649u, 63659u, 63667u, 63671u, 63689u, 63691u, 63697u, 63703u, 63709u, + 63719u, 63727u, 63737u, 63743u, 63761u, 63773u, 63781u, 63793u, 63799u, + 63803u, 63809u, 63823u, 63839u, 63841u, 63853u, 63857u, 63863u, 63901u, + 63907u, 63913u, 63929u, 63949u, 63977u, 63997u, 64007u, 64013u, 64019u, + 64033u, 64037u, 64063u, 64067u, 64081u, 64091u, 64109u, 64123u, 64151u, + 64153u, 64157u, 64171u, 64187u, 64189u, 64217u, 64223u, 64231u, 64237u, + 64271u, 64279u, 64283u, 64301u, 64303u, 64319u, 64327u, 64333u, 64373u, + 64381u, 64399u, 64403u, 64433u, 64439u, 64451u, 64453u, 64483u, 64489u, + 64499u, 64513u, 64553u, 64567u, 64577u, 64579u, 64591u, 64601u, 64609u, + 64613u, 64621u, 64627u, 64633u, 64661u, 64663u, 64667u, 64679u, 64693u, + 64709u, 64717u, 64747u, 64763u, 64781u, 64783u, 64793u, 64811u, 64817u, + 64849u, 64853u, 64871u, 64877u, 64879u, 64891u, 64901u, 64919u, 64921u, + 64927u, 64937u, 64951u, 64969u, 64997u, 65003u, 65011u, 65027u, 65029u, + 65033u, 65053u, 65063u, 65071u, 65089u, 65099u, 65101u, 65111u, 65119u, + 65123u, 65129u, 65141u, 65147u, 65167u, 65171u, 65173u, 65179u, 65183u, + 65203u, 65213u, 65239u, 65257u, 65267u, 65269u, 65287u, 65293u, 65309u, + 65323u, 65327u, 65353u, 65357u, 65371u, 65381u, 65393u, 65407u, 65413u, + 65419u, 65423u, 65437u, 65447u, 65449u, 65479u, 65497u, 65519u, 65521u + }}; + static constexpr std::array a3 = {{ + 2u, 4u, 8u, 16u, 22u, 28u, 44u, + 46u, 52u, 64u, 74u, 82u, 94u, 98u, 112u, + 116u, 122u, 142u, 152u, 164u, 166u, 172u, 178u, + 182u, 184u, 194u, 196u, 226u, 242u, 254u, 274u, + 292u, 296u, 302u, 304u, 308u, 316u, 332u, 346u, + 364u, 386u, 392u, 394u, 416u, 422u, 428u, 446u, + 448u, 458u, 494u, 502u, 506u, 512u, 532u, 536u, + 548u, 554u, 568u, 572u, 574u, 602u, 626u, 634u, + 638u, 644u, 656u, 686u, 704u, 736u, 758u, 766u, + 802u, 808u, 812u, 824u, 826u, 838u, 842u, 848u, + 868u, 878u, 896u, 914u, 922u, 928u, 932u, 956u, + 964u, 974u, 988u, 994u, 998u, 1006u, 1018u, 1034u, + 1036u, 1052u, 1058u, 1066u, 1082u, 1094u, 1108u, 1118u, + 1148u, 1162u, 1166u, 1178u, 1186u, 1198u, 1204u, 1214u, + 1216u, 1228u, 1256u, 1262u, 1274u, 1286u, 1306u, 1316u, + 1318u, 1328u, 1342u, 1348u, 1354u, 1384u, 1388u, 1396u, + 1408u, 1412u, 1414u, 1424u, 1438u, 1442u, 1468u, 1486u, + 1498u, 1508u, 1514u, 1522u, 1526u, 1538u, 1544u, 1568u, + 1586u, 1594u, 1604u, 1606u, 1618u, 1622u, 1634u, 1646u, + 1652u, 1654u, 1676u, 1678u, 1682u, 1684u, 1696u, 1712u, + 1726u, 1736u, 1738u, 1754u, 1772u, 1804u, 1808u, 1814u, + 1834u, 1856u, 1864u, 1874u, 1876u, 1886u, 1892u, 1894u, + 1898u, 1912u, 1918u, 1942u, 1946u, 1954u, 1958u, 1964u, + 1976u, 1988u, 1996u, 2002u, 2012u, 2024u, 2032u, 2042u, + 2044u, 2054u, 2066u, 2072u, 2084u, 2096u, 2116u, 2144u, + 2164u, 2174u, 2188u, 2198u, 2206u, 2216u, 2222u, 2224u, + 2228u, 2242u, 2248u, 2254u, 2266u, 2272u, 2284u, 2294u, + 2308u, 2318u, 2332u, 2348u, 2356u, 2366u, 2392u, 2396u, + 2398u, 2404u, 2408u, 2422u, 2426u, 2432u, 2444u, 2452u, + 2458u, 2488u, 2506u, 2518u, 2524u, 2536u, 2552u, 2564u, + 2576u, 2578u, 2606u, 2612u, 2626u, 2636u, 2672u, 2674u, + 2678u, 2684u, 2692u, 2704u, 2726u, 2744u, 2746u, 2776u, + 2794u, 2816u, 2836u, 2854u, 2864u, 2902u, 2908u, 2912u, + 2914u, 2938u, 2942u, 2948u, 2954u, 2956u, 2966u, 2972u, + 2986u, 2996u, 3004u, 3008u, 3032u, 3046u, 3062u, 3076u, + 3098u, 3104u, 3124u, 3134u, 3148u, 3152u, 3164u, 3176u, + 3178u, 3194u, 3202u, 3208u, 3214u, 3232u, 3236u, 3242u, + 3256u, 3278u, 3284u, 3286u, 3328u, 3344u, 3346u, 3356u, + 3362u, 3364u, 3368u, 3374u, 3382u, 3392u, 3412u, 3428u, + 3458u, 3466u, 3476u, 3484u, 3494u, 3496u, 3526u, 3532u, + 3538u, 3574u, 3584u, 3592u, 3608u, 3614u, 3616u, 3628u, + 3656u, 3658u, 3662u, 3668u, 3686u, 3698u, 3704u, 3712u, + 3722u, 3724u, 3728u, 3778u, 3782u, 3802u, 3806u, 3836u, + 3844u, 3848u, 3854u, 3866u, 3868u, 3892u, 3896u, 3904u, + 3922u, 3928u, 3932u, 3938u, 3946u, 3956u, 3958u, 3962u, + 3964u, 4004u, 4022u, 4058u, 4088u, 4118u, 4126u, 4142u, + 4156u, 4162u, 4174u, 4202u, 4204u, 4226u, 4228u, 4232u, + 4244u, 4274u, 4286u, 4292u, 4294u, 4298u, 4312u, 4322u, + 4324u, 4342u, 4364u, 4376u, 4394u, 4396u, 4406u, 4424u, + 4456u, 4462u, 4466u, 4468u, 4474u, 4484u, 4504u, 4516u, + 4526u, 4532u, 4544u, 4564u, 4576u, 4582u, 4586u, 4588u, + 4604u, 4606u, 4622u, 4628u, 4642u, 4646u, 4648u, 4664u, + 4666u, 4672u, 4688u, 4694u, 4702u, 4706u, 4714u, 4736u, + 4754u, 4762u, 4774u, 4778u, 4786u, 4792u, 4816u, 4838u, + 4844u, 4846u, 4858u, 4888u, 4894u, 4904u, 4916u, 4922u, + 4924u, 4946u, 4952u, 4954u, 4966u, 4972u, 4994u, 5002u, + 5014u, 5036u, 5038u, 5048u, 5054u, 5072u, 5084u, 5086u, + 5092u, 5104u, 5122u, 5128u, 5132u, 5152u, 5174u, 5182u, + 5194u, 5218u, 5234u, 5248u, 5258u, 5288u, 5306u, 5308u, + 5314u, 5318u, 5332u, 5342u, 5344u, 5356u, 5366u, 5378u, + 5384u, 5386u, 5402u, 5414u, 5416u, 5422u, 5434u, 5444u, + 5446u, 5456u, 5462u, 5464u, 5476u, 5488u, 5504u, 5524u, + 5534u, 5546u, 5554u, 5584u, 5594u, 5608u, 5612u, 5618u, + 5626u, 5632u, 5636u, 5656u, 5674u, 5698u, 5702u, 5714u, + 5722u, 5726u, 5728u, 5752u, 5758u, 5782u, 5792u, 5794u, + 5798u, 5804u, 5806u, 5812u, 5818u, 5824u, 5828u, 5852u, + 5854u, 5864u, 5876u, 5878u, 5884u, 5894u, 5902u, 5908u, + 5918u, 5936u, 5938u, 5944u, 5948u, 5968u, 5992u, 6002u, + 6014u, 6016u, 6028u, 6034u, 6058u, 6062u, 6098u, 6112u, + 6128u, 6136u, 6158u, 6164u, 6172u, 6176u, 6178u, 6184u, + 6206u, 6226u, 6242u, 6254u, 6272u, 6274u, 6286u, 6302u, + 6308u, 6314u, 6326u, 6332u, 6344u, 6346u, 6352u, 6364u, + 6374u, 6382u, 6398u, 6406u, 6412u, 6428u, 6436u, 6448u, + 6452u, 6458u, 6464u, 6484u, 6496u, 6508u, 6512u, 6518u, + 6538u, 6542u, 6554u, 6556u, 6566u, 6568u, 6574u, 6604u, + 6626u, 6632u, 6634u, 6638u, 6676u, 6686u, 6688u, 6692u, + 6694u, 6716u, 6718u, 6734u, 6736u, 6742u, 6752u, 6772u, + 6778u, 6802u, 6806u, 6818u, 6832u, 6844u, 6848u, 6886u, + 6896u, 6926u, 6932u, 6934u, 6946u, 6958u, 6962u, 6968u, + 6998u, 7012u, 7016u, 7024u, 7042u, 7078u, 7082u, 7088u, + 7108u, 7112u, 7114u, 7126u, 7136u, 7138u, 7144u, 7154u, + 7166u, 7172u, 7184u, 7192u, 7198u, 7204u, 7228u, 7232u, + 7262u, 7282u, 7288u, 7324u, 7334u, 7336u, 7348u, 7354u, + 7358u, 7366u, 7372u, 7376u, 7388u, 7396u, 7402u, 7414u, + 7418u, 7424u, 7438u, 7442u, 7462u, 7474u, 7478u, 7484u, + 7502u, 7504u, 7508u, 7526u, 7528u, 7544u, 7556u, 7586u, + 7592u, 7598u, 7606u, 7646u, 7654u, 7702u, 7708u, 7724u, + 7742u, 7756u, 7768u, 7774u, 7792u, 7796u, 7816u, 7826u, + 7828u, 7834u, 7844u, 7852u, 7882u, 7886u, 7898u, 7918u, + 7924u, 7936u, 7942u, 7948u, 7982u, 7988u, 7994u, 8012u, + 8018u, 8026u, 8036u, 8048u, 8054u, 8062u, 8072u, 8074u, + 8078u, 8102u, 8108u, 8116u, 8138u, 8144u, 8146u, 8158u, + 8164u, 8174u, 8186u, 8192u, 8216u, 8222u, 8236u, 8248u, + 8284u, 8288u, 8312u, 8314u, 8324u, 8332u, 8342u, 8348u, + 8362u, 8372u, 8404u, 8408u, 8416u, 8426u, 8438u, 8464u, + 8482u, 8486u, 8492u, 8512u, 8516u, 8536u, 8542u, 8558u, + 8564u, 8566u, 8596u, 8608u, 8614u, 8624u, 8626u, 8632u, + 8642u, 8654u, 8662u, 8666u, 8668u, 8674u, 8684u, 8696u, + 8722u, 8744u, 8752u, 8758u, 8762u, 8776u, 8782u, 8788u, + 8818u, 8822u, 8828u, 8842u, 8846u, 8848u, 8876u, 8878u, + 8884u, 8906u, 8914u, 8918u, 8936u, 8954u, 8972u, 8974u, + 8986u, 8992u, 8996u, 9016u, 9026u, 9032u, 9038u, 9052u, + 9062u, 9074u, 9076u, 9088u, 9118u, 9152u, 9164u, 9172u, + 9178u, 9182u, 9184u, 9194u, 9196u, 9212u, 9224u, 9226u, + 9236u, 9244u, 9262u, 9286u, 9292u, 9296u, 9308u, 9322u, + 9326u, 9334u, 9338u, 9352u, 9356u, 9362u, 9368u, 9388u, + 9394u, 9398u, 9406u, 9424u, 9476u, 9478u, 9482u, 9494u, + 9502u, 9506u, 9544u, 9548u, 9574u, 9598u, 9614u, 9626u, + 9632u, 9634u, 9646u, 9658u, 9674u, 9676u, 9682u, 9688u, + 9692u, 9704u, 9718u, 9734u, 9742u, 9754u, 9772u, 9788u, + 9794u, 9802u, 9812u, 9818u, 9832u, 9842u, 9854u, 9856u, + 9866u, 9868u, 9872u, 9896u, 9902u, 9944u, 9968u, 9976u, + 9986u, 9992u, 9998u, 10004u, 10006u, 10018u, 10022u, 10036u, + 10042u, 10048u, 10076u, 10082u, 10084u, 10094u, 10106u, 10118u, + 10124u, 10144u, 10148u, 10154u, 10168u, 10172u, 10174u, 10186u, + 10196u, 10208u, 10232u, 10238u, 10246u, 10252u, 10258u, 10262u, + 10286u, 10298u, 10318u, 10334u, 10348u, 10378u, 10396u, 10402u, + 10406u, 10432u, 10444u, 10448u, 10454u, 10456u, 10462u, 10466u, + 10468u, 10496u, 10504u, 10544u, 10546u, 10556u, 10564u, 10568u, + 10588u, 10594u, 10612u, 10622u, 10624u, 10628u, 10672u, 10678u, + 10696u, 10708u, 10714u, 10718u, 10724u, 10726u, 10748u, 10754u, + 10768u, 10798u, 10808u, 10832u, 10834u, 10844u, 10852u, 10868u, + 10886u, 10888u, 10906u, 10928u, 10936u, 10946u, 10952u, 10958u, + 10972u, 10976u, 10984u, 11002u, 11006u, 11008u, 11026u, 11044u, + 11062u, 11068u, 11072u, 11096u, 11114u, 11116u, 11132u, 11138u, + 11144u, 11162u, 11182u, 11198u, 11218u, 11222u, 11236u, 11242u, + 11246u, 11266u, 11284u, 11294u, 11296u, 11302u, 11312u, 11336u, + 11338u, 11348u, 11372u, 11378u, 11384u, 11408u, 11414u, 11426u, + 11428u, 11456u, 11468u, 11482u, 11488u, 11494u, 11506u, 11512u, + 11534u, 11546u, 11558u, 11566u, 11602u, 11606u, 11618u, 11632u, + 11636u, 11656u, 11666u, 11678u, 11702u, 11704u, 11708u, 11714u, + 11726u, 11728u, 11732u, 11734u, 11744u, 11756u, 11782u, 11788u, + 11804u, 11812u, 11816u, 11824u, 11834u, 11842u, 11848u, 11882u, + 11884u, 11896u, 11912u, 11936u, 11942u, 11944u, 11954u, 11956u, + 11974u, 11978u, 11986u, 11992u, 12008u, 12014u, 12016u, 12022u, + 12028u, 12034u, 12038u, 12052u, 12056u, 12076u, 12082u, 12086u, + 12106u, 12112u, 12124u, 12146u, 12152u, 12154u, 12164u, 12176u, + 12178u, 12184u, 12188u, 12196u, 12208u, 12212u, 12226u, 12238u, + 12248u, 12262u, 12266u, 12278u, 12304u, 12314u, 12328u, 12332u, + 12358u, 12364u, 12394u, 12398u, 12416u, 12434u, 12442u, 12448u, + 12464u, 12472u, 12482u, 12496u, 12506u, 12514u, 12524u, 12544u, + 12566u, 12586u, 12602u, 12604u, 12622u, 12628u, 12632u, 12638u, + 12644u, 12656u, 12658u, 12668u, 12694u, 12698u, 12706u, 12724u, + 12742u, 12748u, 12766u, 12772u, 12776u, 12782u, 12806u, 12812u, + 12832u, 12866u, 12892u, 12902u, 12904u, 12932u, 12944u, 12952u, + 12962u, 12974u, 12976u, 12982u, 13004u, 13006u, 13018u, 13034u, + 13036u, 13042u, 13048u, 13058u, 13072u, 13088u, 13108u, 13114u, + 13118u, 13156u, 13162u, 13172u, 13178u, 13186u, 13202u, 13244u, + 13246u, 13252u, 13256u, 13262u, 13268u, 13274u, 13288u, 13304u, + 13318u, 13322u, 13342u, 13352u, 13354u, 13358u, 13366u, 13384u, + 13394u, 13406u, 13442u, 13444u, 13454u, 13496u, 13504u, 13508u, + 13528u, 13552u, 13568u, 13576u, 13598u, 13604u, 13612u, 13616u, + 13618u, 13624u, 13646u, 13652u, 13658u, 13666u, 13694u, 13696u, + 13706u, 13724u, 13738u, 13744u, 13748u, 13766u, 13774u, 13784u, + 13798u, 13802u, 13814u, 13822u, 13832u, 13844u, 13858u, 13862u, + 13864u, 13876u, 13888u, 13892u, 13898u, 13916u, 13946u, 13958u, + 13996u, 14002u, 14014u, 14024u, 14026u, 14044u, 14054u, 14066u, + 14074u, 14078u, 14086u, 14092u, 14096u, 14098u, 14122u, 14134u, + 14152u, 14156u, 14158u, 14162u, 14164u, 14222u, 14234u, 14242u, + 14266u, 14276u, 14278u, 14282u, 14288u, 14294u, 14306u, 14308u, + 14312u, 14326u, 14332u, 14338u, 14354u, 14366u, 14368u, 14372u, + 14404u, 14408u, 14432u, 14438u, 14444u, 14452u, 14462u, 14464u, + 14486u, 14504u, 14516u, 14536u, 14542u, 14572u, 14576u, 14606u, + 14612u, 14614u, 14618u, 14632u, 14638u, 14642u, 14656u, 14672u, + 14674u, 14686u, 14696u, 14698u, 14704u, 14716u, 14728u, 14738u, + 14744u, 14752u, 14774u, 14782u, 14794u, 14806u, 14812u, 14828u, + 14834u, 14852u, 14872u, 14894u, 14912u, 14914u, 14936u, 14938u, + 14954u, 14956u, 14978u, 14992u, 15002u, 15022u, 15032u, 15064u, + 15068u, 15076u, 15086u, 15092u, 15094u, 15116u, 15122u, 15134u, + 15136u, 15142u, 15146u, 15148u, 15152u, 15166u, 15178u, 15202u, + 15212u, 15214u, 15226u, 15242u, 15244u, 15248u, 15254u, 15268u, + 15274u, 15284u, 15296u, 15298u, 15314u, 15328u, 15362u, 15374u, + 15376u, 15382u, 15388u, 15394u, 15398u, 15418u, 15428u, 15454u, + 15466u, 15478u, 15482u, 15484u, 15488u, 15496u, 15506u, 15508u, + 15512u, 15514u, 15536u, 15542u, 15548u, 15562u, 15566u, 15584u, + 15596u, 15622u, 15628u, 15638u, 15646u, 15662u, 15664u, 15668u, + 15688u, 15698u, 15704u, 15746u, 15748u, 15758u, 15764u, 15772u, + 15796u, 15808u, 15814u, 15818u, 15824u, 15836u, 15838u, 15866u, + 15874u, 15886u, 15904u, 15922u, 15928u, 15974u, 15982u, 15992u, + 15998u, 16012u, 16016u, 16018u, 16024u, 16028u, 16034u, 16076u, + 16084u, 16094u, 16102u, 16112u, 16114u, 16132u, 16136u, 16142u, + 16154u, 16166u, 16168u, 16172u, 16192u, 16202u, 16214u, 16226u, + 16234u, 16238u, 16264u, 16282u, 16304u, 16312u, 16318u, 16334u, + 16348u, 16364u, 16366u, 16384u, 16394u, 16396u, 16402u, 16408u, + 16418u, 16432u, 16436u, 16438u, 16468u, 16472u, 16474u, 16478u, + 16486u, 16496u, 16502u, 16504u, 16516u, 16532u, 16538u, 16594u, + 16604u, 16606u, 16618u, 16628u, 16636u, 16648u, 16654u, 16658u, + 16672u, 16682u, 16684u, 16688u, 16696u, 16702u, 16706u, 16726u, + 16732u, 16744u, 16766u, 16772u, 16804u, 16814u, 16816u, 16826u, + 16838u, 16852u, 16858u, 16886u, 16922u, 16928u, 16934u, 16936u, + 16948u, 16952u, 16958u, 16964u, 16972u, 16994u, 16996u, 17014u, + 17024u, 17026u, 17032u, 17036u, 17056u, 17066u, 17074u, 17078u, + 17084u, 17098u, 17116u, 17122u, 17164u, 17186u, 17188u, 17192u, + 17194u, 17222u, 17224u, 17228u, 17246u, 17252u, 17258u, 17264u, + 17276u, 17278u, 17302u, 17312u, 17348u, 17354u, 17356u, 17368u, + 17378u, 17404u, 17428u, 17446u, 17462u, 17468u, 17474u, 17488u, + 17512u, 17524u, 17528u, 17536u, 17542u, 17554u, 17558u, 17566u, + 17582u, 17602u, 17642u, 17668u, 17672u, 17684u, 17686u, 17692u, + 17696u, 17698u, 17708u, 17722u, 17732u, 17734u, 17738u, 17764u, + 17776u, 17804u, 17806u, 17822u, 17848u, 17854u, 17864u, 17866u, + 17872u, 17882u, 17888u, 17896u, 17902u, 17908u, 17914u, 17924u, + 17936u, 17942u, 17962u, 18002u, 18022u, 18026u, 18028u, 18044u, + 18056u, 18062u, 18074u, 18082u, 18086u, 18104u, 18106u, 18118u, + 18128u, 18154u, 18166u, 18182u, 18184u, 18202u, 18226u, 18238u, + 18242u, 18256u, 18278u, 18298u, 18308u, 18322u, 18334u, 18338u, + 18356u, 18368u, 18376u, 18386u, 18398u, 18404u, 18434u, 18448u, + 18452u, 18476u, 18482u, 18512u, 18518u, 18524u, 18526u, 18532u, + 18554u, 18586u, 18592u, 18596u, 18602u, 18608u, 18628u, 18644u, + 18646u, 18656u, 18664u, 18676u, 18686u, 18688u, 18694u, 18704u, + 18712u, 18728u, 18764u, 18772u, 18778u, 18782u, 18784u, 18812u, + 18814u, 18842u, 18854u, 18856u, 18866u, 18872u, 18886u, 18896u, + 18902u, 18908u, 18914u, 18922u, 18928u, 18932u, 18946u, 18964u, + 18968u, 18974u, 18986u, 18988u, 18998u, 19016u, 19024u, 19054u, + 19094u, 19096u, 19114u, 19118u, 19124u, 19138u, 19156u, 19162u, + 19166u, 19178u, 19184u, 19196u, 19202u, 19216u, 19226u, 19252u, + 19258u, 19274u, 19276u, 19292u, 19322u, 19324u, 19334u, 19336u, + 19378u, 19384u, 19412u, 19426u, 19432u, 19442u, 19444u, 19456u, + 19474u, 19486u, 19492u, 19502u, 19514u, 19526u, 19546u, 19552u, + 19556u, 19558u, 19568u, 19574u, 19586u, 19598u, 19612u, 19624u, + 19658u, 19664u, 19666u, 19678u, 19688u, 19694u, 19702u, 19708u, + 19712u, 19724u, 19762u, 19768u, 19778u, 19796u, 19798u, 19826u, + 19828u, 19834u, 19846u, 19876u, 19892u, 19894u, 19904u, 19912u, + 19916u, 19918u, 19934u, 19952u, 19978u, 19982u, 19988u, 19996u, + 20014u, 20036u, 20042u, 20062u, 20066u, 20072u, 20084u, 20086u, + 20092u, 20104u, 20108u, 20126u, 20132u, 20134u, 20156u, 20168u, + 20176u, 20182u, 20198u, 20216u, 20246u, 20258u, 20282u, 20284u, + 20294u, 20296u, 20302u, 20308u, 20312u, 20318u, 20354u, 20368u, + 20374u, 20396u, 20398u, 20456u, 20464u, 20476u, 20482u, 20492u, + 20494u, 20534u, 20542u, 20548u, 20576u, 20578u, 20582u, 20596u, + 20602u, 20608u, 20626u, 20636u, 20644u, 20648u, 20662u, 20666u, + 20674u, 20704u, 20708u, 20714u, 20722u, 20728u, 20734u, 20752u, + 20756u, 20758u, 20762u, 20776u, 20788u, 20806u, 20816u, 20818u, + 20822u, 20834u, 20836u, 20846u, 20854u, 20864u, 20878u, 20888u, + 20906u, 20918u, 20926u, 20932u, 20942u, 20956u, 20966u, 20974u, + 20996u, 20998u, 21004u, 21026u, 21038u, 21044u, 21052u, 21064u, + 21092u, 21094u, 21142u, 21154u, 21158u, 21176u, 21184u, 21194u, + 21208u, 21218u, 21232u, 21236u, 21248u, 21278u, 21302u, 21308u, + 21316u, 21322u, 21326u, 21334u, 21388u, 21392u, 21394u, 21404u, + 21416u, 21424u, 21434u, 21446u, 21458u, 21476u, 21478u, 21502u, + 21506u, 21514u, 21536u, 21548u, 21568u, 21572u, 21584u, 21586u, + 21598u, 21614u, 21616u, 21644u, 21646u, 21652u, 21676u, 21686u, + 21688u, 21716u, 21718u, 21722u, 21742u, 21746u, 21758u, 21764u, + 21778u, 21782u, 21788u, 21802u, 21824u, 21848u, 21868u, 21872u, + 21886u, 21892u, 21898u, 21908u, 21938u, 21946u, 21956u, 21974u, + 21976u, 21982u, 21988u, 22004u, 22006u, 22012u, 22018u, 22022u, + 22024u, 22048u, 22052u, 22054u, 22078u, 22088u, 22094u, 22096u, + 22106u, 22108u, 22114u, 22136u, 22144u, 22148u, 22156u, 22162u, + 22166u, 22184u, 22186u, 22204u, 22208u, 22216u, 22232u, 22258u, + 22262u, 22268u, 22276u, 22298u, 22318u, 22334u, 22342u, 22346u, + 22352u, 22376u, 22382u, 22396u, 22408u, 22424u, 22426u, 22438u, + 22442u, 22456u, 22466u, 22468u, 22472u, 22484u, 22502u, 22534u, + 22544u, 22558u, 22582u, 22594u, 22634u, 22642u, 22676u, 22688u, + 22702u, 22706u, 22724u, 22726u, 22754u, 22766u, 22786u, 22792u, + 22802u, 22804u, 22844u, 22862u, 22876u, 22888u, 22892u, 22928u, + 22934u, 22936u, 22958u, 22964u, 22978u, 22988u, 23012u, 23054u, + 23056u, 23072u, 23074u, 23108u, 23116u, 23122u, 23126u, 23128u, + 23132u, 23146u, 23186u, 23194u, 23206u, 23212u, 23236u, 23254u, + 23258u, 23264u, 23266u, 23272u, 23276u, 23278u, 23282u, 23284u, + 23308u, 23318u, 23326u, 23332u, 23338u, 23348u, 23362u, 23368u, + 23384u, 23402u, 23416u, 23434u, 23458u, 23462u, 23468u, 23474u, + 23482u, 23486u, 23506u, 23516u, 23522u, 23534u, 23536u, 23548u, + 23552u, 23566u, 23572u, 23578u, 23584u, 23588u, 23602u, 23618u, + 23654u, 23668u, 23674u, 23678u, 23692u, 23696u, 23702u, 23726u, + 23734u, 23738u, 23758u, 23768u, 23782u, 23794u, 23828u, 23836u, + 23846u, 23852u, 23858u, 23864u, 23878u, 23882u, 23896u, 23908u, + 23914u, 23924u, 23942u, 23956u, 23966u, 23978u, 23984u, 23986u, + 23992u, 23998u, 24026u, 24028u, 24032u, 24056u, 24062u, 24064u, + 24068u, 24076u, 24092u, 24098u, 24118u, 24122u, 24124u, 24134u, + 24136u, 24146u, 24154u, 24218u, 24224u, 24232u, 24244u, 24248u, + 24262u, 24274u, 24284u, 24286u, 24298u, 24304u, 24314u, 24332u, + 24356u, 24362u, 24364u, 24374u, 24382u, 24388u, 24404u, 24424u, + 24428u, 24442u, 24448u, 24454u, 24466u, 24472u, 24476u, 24482u, + 24484u, 24488u, 24496u, 24518u, 24524u, 24532u, 24536u, 24538u, + 24554u, 24572u, 24586u, 24592u, 24614u, 24628u, 24638u, 24652u, + 24656u, 24662u, 24664u, 24668u, 24682u, 24692u, 24704u, 24712u, + 24728u, 24736u, 24746u, 24754u, 24778u, 24818u, 24824u, 24836u, + 24838u, 24844u, 24862u, 24866u, 24868u, 24872u, 24902u, 24904u, + 24934u, 24938u, 24946u, 24964u, 24976u, 24988u, 24992u, 24994u, + 24998u, 25012u, 25048u, 25064u, 25082u, 25084u, 25096u, 25106u, + 25112u, 25124u, 25142u, 25144u, 25162u, 25168u, 25174u, 25196u, + 25214u, 25252u, 25258u, 25268u, 25286u, 25288u, 25298u, 25306u, + 25312u, 25328u, 25352u, 25366u, 25372u, 25376u, 25382u, 25396u, + 25412u, 25436u, 25442u, 25454u, 25462u, 25474u, 25484u, 25498u, + 25544u, 25546u, 25562u, 25564u, 25586u, 25592u, 25594u, 25604u, + 25606u, 25616u, 25618u, 25624u, 25628u, 25648u, 25658u, 25664u, + 25694u, 25702u, 25708u, 25714u, 25718u, 25748u, 25756u, 25762u, + 25768u, 25774u, 25796u, 25832u, 25834u, 25838u, 25846u, 25852u, + 25858u, 25862u, 25876u, 25888u, 25898u, 25918u, 25922u, 25924u, + 25928u, 25958u, 25964u, 25978u, 25994u, 26006u, 26036u, 26038u, + 26042u, 26048u, 26056u, 26086u, 26096u, 26104u, 26138u, 26156u, + 26168u, 26176u, 26198u, 26218u, 26222u, 26236u, 26246u, 26266u, + 26272u, 26276u, 26278u, 26288u, 26302u, 26306u, 26332u, 26338u, + 26374u, 26386u, 26404u, 26408u, 26416u, 26422u, 26426u, 26432u, + 26434u, 26462u, 26468u, 26474u, 26498u, 26506u, 26516u, 26542u, + 26548u, 26572u, 26576u, 26584u, 26608u, 26618u, 26638u, 26642u, + 26644u, 26654u, 26668u, 26684u, 26686u, 26692u, 26698u, 26702u, + 26708u, 26716u, 26734u, 26762u, 26776u, 26782u, 26798u, 26812u, + 26818u, 26822u, 26828u, 26834u, 26842u, 26846u, 26848u, 26852u, + 26864u, 26866u, 26878u, 26884u, 26896u, 26924u, 26926u, 26932u, + 26944u, 26954u, 26968u, 26972u, 27016u, 27022u, 27032u, 27034u, + 27046u, 27058u, 27088u, 27092u, 27104u, 27106u, 27112u, 27122u, + 27134u, 27136u, 27146u, 27148u, 27158u, 27164u, 27172u, 27182u, + 27188u, 27202u, 27218u, 27226u, 27232u, 27244u, 27254u, 27256u, + 27266u, 27274u, 27286u, 27296u, 27314u, 27322u, 27326u, 27328u, + 27332u, 27358u, 27364u, 27386u, 27392u, 27406u, 27416u, 27422u, + 27424u, 27452u, 27458u, 27466u, 27512u, 27518u, 27524u, 27542u, + 27548u, 27554u, 27562u, 27568u, 27578u, 27596u, 27598u, 27604u, + 27616u, 27634u, 27644u, 27652u, 27664u, 27694u, 27704u, 27706u, + 27716u, 27718u, 27722u, 27728u, 27746u, 27748u, 27752u, 27772u, + 27784u, 27788u, 27794u, 27802u, 27836u, 27842u, 27848u, 27872u, + 27884u, 27892u, 27928u, 27944u, 27946u, 27952u, 27956u, 27958u, + 27962u, 27968u, 27988u, 27994u, 28018u, 28022u, 28024u, 28028u, + 28046u, 28066u, 28072u, 28094u, 28102u, 28148u, 28166u, 28168u, + 28184u, 28204u, 28226u, 28228u, 28252u, 28274u, 28276u, 28292u, + 28316u, 28336u, 28352u, 28354u, 28358u, 28366u, 28376u, 28378u, + 28388u, 28402u, 28406u, 28414u, 28432u, 28436u, 28444u, 28448u, + 28462u, 28472u, 28474u, 28498u, 28514u, 28522u, 28528u, 28544u, + 28564u, 28574u, 28576u, 28582u, 28586u, 28616u, 28618u, 28634u, + 28666u, 28672u, 28684u, 28694u, 28718u, 28726u, 28738u, 28756u, + 28772u, 28774u, 28786u, 28792u, 28796u, 28808u, 28814u, 28816u, + 28844u, 28862u, 28864u, 28886u, 28892u, 28898u, 28904u, 28906u, + 28912u, 28928u, 28942u, 28948u, 28978u, 28994u, 28996u, 29006u, + 29008u, 29012u, 29024u, 29026u, 29038u, 29048u, 29062u, 29068u, + 29078u, 29086u, 29114u, 29116u, 29152u, 29158u, 29174u, 29188u, + 29192u, 29212u, 29236u, 29242u, 29246u, 29254u, 29258u, 29276u, + 29284u, 29288u, 29302u, 29306u, 29312u, 29314u, 29338u, 29354u, + 29368u, 29372u, 29398u, 29414u, 29416u, 29426u, 29458u, 29464u, + 29468u, 29474u, 29486u, 29492u, 29528u, 29536u, 29548u, 29552u, + 29554u, 29558u, 29566u, 29572u, 29576u, 29596u, 29608u, 29618u, + 29642u, 29654u, 29656u, 29668u, 29678u, 29684u, 29696u, 29698u, + 29704u, 29722u, 29726u, 29732u, 29738u, 29744u, 29752u, 29776u, + 29782u, 29792u, 29804u, 29834u, 29848u, 29858u, 29866u, 29878u, + 29884u, 29894u, 29906u, 29908u, 29926u, 29932u, 29936u, 29944u, + 29948u, 29972u, 29992u, 29996u, 30004u, 30014u, 30026u, 30034u, + 30046u, 30062u, 30068u, 30082u, 30086u, 30094u, 30098u, 30116u, + 30166u, 30172u, 30178u, 30182u, 30188u, 30196u, 30202u, 30212u, + 30238u, 30248u, 30254u, 30256u, 30266u, 30268u, 30278u, 30284u, + 30322u, 30334u, 30338u, 30346u, 30356u, 30376u, 30382u, 30388u, + 30394u, 30412u, 30422u, 30424u, 30436u, 30452u, 30454u, 30466u, + 30478u, 30482u, 30508u, 30518u, 30524u, 30544u, 30562u, 30602u, + 30614u, 30622u, 30632u, 30644u, 30646u, 30664u, 30676u, 30686u, + 30688u, 30698u, 30724u, 30728u, 30734u, 30746u, 30754u, 30758u, + 30788u, 30794u, 30796u, 30802u, 30818u, 30842u, 30866u, 30884u, + 30896u, 30908u, 30916u, 30922u, 30926u, 30934u, 30944u, 30952u, + 30958u, 30962u, 30982u, 30992u, 31018u, 31022u, 31046u, 31052u, + 31054u, 31066u, 31108u, 31126u, 31132u, 31136u, 31162u, 31168u, + 31196u, 31202u, 31204u, 31214u, 31222u, 31228u, 31234u, 31244u, + 31252u, 31262u, 31264u, 31286u, 31288u, 31292u, 31312u, 31316u, + 31322u, 31358u, 31372u, 31376u, 31396u, 31418u, 31424u, 31438u, + 31444u, 31454u, 31462u, 31466u, 31468u, 31472u, 31486u, 31504u, + 31538u, 31546u, 31568u, 31582u, 31592u, 31616u, 31622u, 31624u, + 31634u, 31636u, 31642u, 31652u, 31678u, 31696u, 31706u, 31724u, + 31748u, 31766u, 31768u, 31792u, 31832u, 31834u, 31838u, 31844u, + 31846u, 31852u, 31862u, 31888u, 31894u, 31906u, 31918u, 31924u, + 31928u, 31964u, 31966u, 31976u, 31988u, 32012u, 32014u, 32018u, + 32026u, 32036u, 32042u, 32044u, 32048u, 32072u, 32074u, 32078u, + 32114u, 32116u, 32138u, 32152u, 32176u, 32194u, 32236u, 32242u, + 32252u, 32254u, 32278u, 32294u, 32306u, 32308u, 32312u, 32314u, + 32324u, 32326u, 32336u, 32344u, 32348u, 32384u, 32392u, 32396u, + 32408u, 32426u, 32432u, 32438u, 32452u, 32474u, 32476u, 32482u, + 32506u, 32512u, 32522u, 32546u, 32566u, 32588u, 32594u, 32608u, + 32644u, 32672u, 32678u, 32686u, 32692u, 32716u, 32722u, 32734u, + 32762u, 32764u, 32782u, 32786u, 32788u, 32792u, 32812u, 32834u, + 32842u, 32852u, 32854u, 32872u, 32876u, 32884u, 32894u, 32908u, + 32918u, 32924u, 32932u, 32938u, 32944u, 32956u, 32972u, 32984u, + 32998u, 33008u, 33026u, 33028u, 33038u, 33062u, 33086u, 33092u, + 33104u, 33106u, 33128u, 33134u, 33154u, 33176u, 33178u, 33182u, + 33194u, 33196u, 33202u, 33238u, 33244u, 33266u, 33272u, 33274u, + 33302u, 33314u, 33332u, 33334u, 33338u, 33352u, 33358u, 33362u, + 33364u, 33374u, 33376u, 33392u, 33394u, 33404u, 33412u, 33418u, + 33428u, 33446u, 33458u, 33464u, 33478u, 33482u, 33488u, 33506u, + 33518u, 33544u, 33548u, 33554u, 33568u, 33574u, 33584u, 33596u, + 33598u, 33602u, 33604u, 33614u, 33638u, 33646u, 33656u, 33688u, + 33698u, 33706u, 33716u, 33722u, 33724u, 33742u, 33754u, 33782u, + 33812u, 33814u, 33832u, 33836u, 33842u, 33856u, 33862u, 33866u, + 33874u, 33896u, 33904u, 33934u, 33952u, 33962u, 33988u, 33992u, + 33994u, 34016u, 34024u, 34028u, 34036u, 34042u, 34046u, 34072u, + 34076u, 34088u, 34108u, 34126u, 34132u, 34144u, 34154u, 34172u, + 34174u, 34178u, 34184u, 34186u, 34198u, 34226u, 34232u, 34252u, + 34258u, 34274u, 34282u, 34288u, 34294u, 34298u, 34304u, 34324u, + 34336u, 34342u, 34346u, 34366u, 34372u, 34388u, 34394u, 34426u, + 34436u, 34454u, 34456u, 34468u, 34484u, 34508u, 34514u, 34522u, + 34534u, 34568u, 34574u, 34594u, 34616u, 34618u, 34634u, 34648u, + 34654u, 34658u, 34672u, 34678u, 34702u, 34732u, 34736u, 34744u, + 34756u, 34762u, 34778u, 34798u, 34808u, 34822u, 34826u, 34828u, + 34844u, 34856u, 34858u, 34868u, 34876u, 34882u, 34912u, 34924u, + 34934u, 34948u, 34958u, 34966u, 34976u, 34982u, 34984u, 34988u, + 35002u, 35012u, 35014u, 35024u, 35056u, 35074u, 35078u, 35086u, + 35114u, 35134u, 35138u, 35158u, 35164u, 35168u, 35198u, 35206u, + 35212u, 35234u, 35252u, 35264u, 35266u, 35276u, 35288u, 35294u, + 35312u, 35318u, 35372u, 35378u, 35392u, 35396u, 35402u, 35408u, + 35422u, 35446u, 35452u, 35464u, 35474u, 35486u, 35492u, 35516u, + 35528u, 35546u, 35554u, 35572u, 35576u, 35578u, 35582u, 35584u, + 35606u, 35614u, 35624u, 35626u, 35638u, 35648u, 35662u, 35668u, + 35672u, 35674u, 35686u, 35732u, 35738u, 35744u, 35746u, 35752u, + 35758u, 35788u, 35798u, 35806u, 35812u, 35824u, 35828u, 35842u, + 35848u, 35864u, 35876u, 35884u, 35894u, 35914u, 35932u, 35942u, + 35948u, 35954u, 35966u, 35968u, 35978u, 35992u, 35996u, 35998u, + 36002u, 36026u, 36038u, 36046u, 36064u, 36068u, 36076u, 36092u, + 36106u, 36118u, 36128u, 36146u, 36158u, 36166u, 36184u, 36188u, + 36202u, 36206u, 36212u, 36214u, 36236u, 36254u, 36262u, 36272u, + 36298u, 36302u, 36304u, 36328u, 36334u, 36338u, 36344u, 36356u, + 36382u, 36386u, 36394u, 36404u, 36422u, 36428u, 36442u, 36452u, + 36464u, 36466u, 36478u, 36484u, 36488u, 36496u, 36508u, 36524u, + 36526u, 36536u, 36542u, 36544u, 36566u, 36568u, 36572u, 36586u, + 36604u, 36614u, 36626u, 36646u, 36656u, 36662u, 36664u, 36668u, + 36682u, 36694u, 36698u, 36706u, 36716u, 36718u, 36724u, 36758u, + 36764u, 36766u, 36782u, 36794u, 36802u, 36824u, 36832u, 36862u, + 36872u, 36874u, 36898u, 36902u, 36916u, 36926u, 36946u, 36962u, + 36964u, 36968u, 36988u, 36998u, 37004u, 37012u, 37016u, 37024u, + 37028u, 37052u, 37058u, 37072u, 37076u, 37108u, 37112u, 37118u, + 37132u, 37138u, 37142u, 37144u, 37166u, 37226u, 37228u, 37234u, + 37258u, 37262u, 37276u, 37294u, 37306u, 37324u, 37336u, 37342u, + 37346u, 37376u, 37378u, 37394u, 37396u, 37418u, 37432u, 37448u, + 37466u, 37472u, 37508u, 37514u, 37532u, 37534u, 37544u, 37552u, + 37556u, 37558u, 37564u, 37588u, 37606u, 37636u, 37642u, 37648u, + 37682u, 37696u, 37702u, 37754u, 37756u, 37772u, 37784u, 37798u, + 37814u, 37822u, 37852u, 37856u, 37858u, 37864u, 37874u, 37886u, + 37888u, 37916u, 37922u, 37936u, 37948u, 37976u, 37994u, 38014u, + 38018u, 38026u, 38032u, 38038u, 38042u, 38048u, 38056u, 38078u, + 38084u, 38108u, 38116u, 38122u, 38134u, 38146u, 38152u, 38164u, + 38168u, 38188u, 38234u, 38252u, 38266u, 38276u, 38278u, 38302u, + 38306u, 38308u, 38332u, 38354u, 38368u, 38378u, 38384u, 38416u, + 38428u, 38432u, 38434u, 38444u, 38446u, 38456u, 38458u, 38462u, + 38468u, 38474u, 38486u, 38498u, 38512u, 38518u, 38524u, 38552u, + 38554u, 38572u, 38578u, 38584u, 38588u, 38612u, 38614u, 38626u, + 38638u, 38644u, 38648u, 38672u, 38696u, 38698u, 38704u, 38708u, + 38746u, 38752u, 38762u, 38774u, 38776u, 38788u, 38792u, 38812u, + 38834u, 38846u, 38848u, 38858u, 38864u, 38882u, 38924u, 38936u, + 38938u, 38944u, 38956u, 38978u, 38992u, 39002u, 39008u, 39014u, + 39016u, 39026u, 39044u, 39058u, 39062u, 39088u, 39104u, 39116u, + 39124u, 39142u, 39146u, 39148u, 39158u, 39166u, 39172u, 39176u, + 39182u, 39188u, 39194u + }}; +#endif + }; + +#ifndef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + const unsigned prime_data_imp::b1; + template + const unsigned prime_data_imp::b2; + template + const unsigned prime_data_imp::b3; +#else + template + constexpr unsigned prime_data_imp::b1; + template + constexpr unsigned prime_data_imp::b2; + template + constexpr unsigned prime_data_imp::b3; +#endif + +#ifndef BOOST_MATH_HAVE_CONSTEXPR_TABLES + template + const std::array prime_data_imp::a1 = { { + 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, + 37u, 41u, 43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, + 79u, 83u, 89u, 97u, 101u, 103u, 107u, 109u, 113u, + 127u, 131u, 137u, 139u, 149u, 151u, 157u, 163u, + 167u, 173u, 179u, 181u, 191u, 193u, 197u, 199u, + 211u, 223u, 227u, 229u, 233u, 239u, 241u, 251u + } }; + template + const std::array prime_data_imp::a2 = {{ + 257u, 263u, 269u, 271u, 277u, 281u, 283u, 293u, + 307u, 311u, 313u, 317u, 331u, 337u, 347u, 349u, 353u, + 359u, 367u, 373u, 379u, 383u, 389u, 397u, 401u, 409u, + 419u, 421u, 431u, 433u, 439u, 443u, 449u, 457u, 461u, + 463u, 467u, 479u, 487u, 491u, 499u, 503u, 509u, 521u, + 523u, 541u, 547u, 557u, 563u, 569u, 571u, 577u, 587u, + 593u, 599u, 601u, 607u, 613u, 617u, 619u, 631u, 641u, + 643u, 647u, 653u, 659u, 661u, 673u, 677u, 683u, 691u, + 701u, 709u, 719u, 727u, 733u, 739u, 743u, 751u, 757u, + 761u, 769u, 773u, 787u, 797u, 809u, 811u, 821u, 823u, + 827u, 829u, 839u, 853u, 857u, 859u, 863u, 877u, 881u, + 883u, 887u, 907u, 911u, 919u, 929u, 937u, 941u, 947u, + 953u, 967u, 971u, 977u, 983u, 991u, 997u, 1009u, 1013u, + 1019u, 1021u, 1031u, 1033u, 1039u, 1049u, 1051u, 1061u, 1063u, + 1069u, 1087u, 1091u, 1093u, 1097u, 1103u, 1109u, 1117u, 1123u, + 1129u, 1151u, 1153u, 1163u, 1171u, 1181u, 1187u, 1193u, 1201u, + 1213u, 1217u, 1223u, 1229u, 1231u, 1237u, 1249u, 1259u, 1277u, + 1279u, 1283u, 1289u, 1291u, 1297u, 1301u, 1303u, 1307u, 1319u, + 1321u, 1327u, 1361u, 1367u, 1373u, 1381u, 1399u, 1409u, 1423u, + 1427u, 1429u, 1433u, 1439u, 1447u, 1451u, 1453u, 1459u, 1471u, + 1481u, 1483u, 1487u, 1489u, 1493u, 1499u, 1511u, 1523u, 1531u, + 1543u, 1549u, 1553u, 1559u, 1567u, 1571u, 1579u, 1583u, 1597u, + 1601u, 1607u, 1609u, 1613u, 1619u, 1621u, 1627u, 1637u, 1657u, + 1663u, 1667u, 1669u, 1693u, 1697u, 1699u, 1709u, 1721u, 1723u, + 1733u, 1741u, 1747u, 1753u, 1759u, 1777u, 1783u, 1787u, 1789u, + 1801u, 1811u, 1823u, 1831u, 1847u, 1861u, 1867u, 1871u, 1873u, + 1877u, 1879u, 1889u, 1901u, 1907u, 1913u, 1931u, 1933u, 1949u, + 1951u, 1973u, 1979u, 1987u, 1993u, 1997u, 1999u, 2003u, 2011u, + 2017u, 2027u, 2029u, 2039u, 2053u, 2063u, 2069u, 2081u, 2083u, + 2087u, 2089u, 2099u, 2111u, 2113u, 2129u, 2131u, 2137u, 2141u, + 2143u, 2153u, 2161u, 2179u, 2203u, 2207u, 2213u, 2221u, 2237u, + 2239u, 2243u, 2251u, 2267u, 2269u, 2273u, 2281u, 2287u, 2293u, + 2297u, 2309u, 2311u, 2333u, 2339u, 2341u, 2347u, 2351u, 2357u, + 2371u, 2377u, 2381u, 2383u, 2389u, 2393u, 2399u, 2411u, 2417u, + 2423u, 2437u, 2441u, 2447u, 2459u, 2467u, 2473u, 2477u, 2503u, + 2521u, 2531u, 2539u, 2543u, 2549u, 2551u, 2557u, 2579u, 2591u, + 2593u, 2609u, 2617u, 2621u, 2633u, 2647u, 2657u, 2659u, 2663u, + 2671u, 2677u, 2683u, 2687u, 2689u, 2693u, 2699u, 2707u, 2711u, + 2713u, 2719u, 2729u, 2731u, 2741u, 2749u, 2753u, 2767u, 2777u, + 2789u, 2791u, 2797u, 2801u, 2803u, 2819u, 2833u, 2837u, 2843u, + 2851u, 2857u, 2861u, 2879u, 2887u, 2897u, 2903u, 2909u, 2917u, + 2927u, 2939u, 2953u, 2957u, 2963u, 2969u, 2971u, 2999u, 3001u, + 3011u, 3019u, 3023u, 3037u, 3041u, 3049u, 3061u, 3067u, 3079u, + 3083u, 3089u, 3109u, 3119u, 3121u, 3137u, 3163u, 3167u, 3169u, + 3181u, 3187u, 3191u, 3203u, 3209u, 3217u, 3221u, 3229u, 3251u, + 3253u, 3257u, 3259u, 3271u, 3299u, 3301u, 3307u, 3313u, 3319u, + 3323u, 3329u, 3331u, 3343u, 3347u, 3359u, 3361u, 3371u, 3373u, + 3389u, 3391u, 3407u, 3413u, 3433u, 3449u, 3457u, 3461u, 3463u, + 3467u, 3469u, 3491u, 3499u, 3511u, 3517u, 3527u, 3529u, 3533u, + 3539u, 3541u, 3547u, 3557u, 3559u, 3571u, 3581u, 3583u, 3593u, + 3607u, 3613u, 3617u, 3623u, 3631u, 3637u, 3643u, 3659u, 3671u, + 3673u, 3677u, 3691u, 3697u, 3701u, 3709u, 3719u, 3727u, 3733u, + 3739u, 3761u, 3767u, 3769u, 3779u, 3793u, 3797u, 3803u, 3821u, + 3823u, 3833u, 3847u, 3851u, 3853u, 3863u, 3877u, 3881u, 3889u, + 3907u, 3911u, 3917u, 3919u, 3923u, 3929u, 3931u, 3943u, 3947u, + 3967u, 3989u, 4001u, 4003u, 4007u, 4013u, 4019u, 4021u, 4027u, + 4049u, 4051u, 4057u, 4073u, 4079u, 4091u, 4093u, 4099u, 4111u, + 4127u, 4129u, 4133u, 4139u, 4153u, 4157u, 4159u, 4177u, 4201u, + 4211u, 4217u, 4219u, 4229u, 4231u, 4241u, 4243u, 4253u, 4259u, + 4261u, 4271u, 4273u, 4283u, 4289u, 4297u, 4327u, 4337u, 4339u, + 4349u, 4357u, 4363u, 4373u, 4391u, 4397u, 4409u, 4421u, 4423u, + 4441u, 4447u, 4451u, 4457u, 4463u, 4481u, 4483u, 4493u, 4507u, + 4513u, 4517u, 4519u, 4523u, 4547u, 4549u, 4561u, 4567u, 4583u, + 4591u, 4597u, 4603u, 4621u, 4637u, 4639u, 4643u, 4649u, 4651u, + 4657u, 4663u, 4673u, 4679u, 4691u, 4703u, 4721u, 4723u, 4729u, + 4733u, 4751u, 4759u, 4783u, 4787u, 4789u, 4793u, 4799u, 4801u, + 4813u, 4817u, 4831u, 4861u, 4871u, 4877u, 4889u, 4903u, 4909u, + 4919u, 4931u, 4933u, 4937u, 4943u, 4951u, 4957u, 4967u, 4969u, + 4973u, 4987u, 4993u, 4999u, 5003u, 5009u, 5011u, 5021u, 5023u, + 5039u, 5051u, 5059u, 5077u, 5081u, 5087u, 5099u, 5101u, 5107u, + 5113u, 5119u, 5147u, 5153u, 5167u, 5171u, 5179u, 5189u, 5197u, + 5209u, 5227u, 5231u, 5233u, 5237u, 5261u, 5273u, 5279u, 5281u, + 5297u, 5303u, 5309u, 5323u, 5333u, 5347u, 5351u, 5381u, 5387u, + 5393u, 5399u, 5407u, 5413u, 5417u, 5419u, 5431u, 5437u, 5441u, + 5443u, 5449u, 5471u, 5477u, 5479u, 5483u, 5501u, 5503u, 5507u, + 5519u, 5521u, 5527u, 5531u, 5557u, 5563u, 5569u, 5573u, 5581u, + 5591u, 5623u, 5639u, 5641u, 5647u, 5651u, 5653u, 5657u, 5659u, + 5669u, 5683u, 5689u, 5693u, 5701u, 5711u, 5717u, 5737u, 5741u, + 5743u, 5749u, 5779u, 5783u, 5791u, 5801u, 5807u, 5813u, 5821u, + 5827u, 5839u, 5843u, 5849u, 5851u, 5857u, 5861u, 5867u, 5869u, + 5879u, 5881u, 5897u, 5903u, 5923u, 5927u, 5939u, 5953u, 5981u, + 5987u, 6007u, 6011u, 6029u, 6037u, 6043u, 6047u, 6053u, 6067u, + 6073u, 6079u, 6089u, 6091u, 6101u, 6113u, 6121u, 6131u, 6133u, + 6143u, 6151u, 6163u, 6173u, 6197u, 6199u, 6203u, 6211u, 6217u, + 6221u, 6229u, 6247u, 6257u, 6263u, 6269u, 6271u, 6277u, 6287u, + 6299u, 6301u, 6311u, 6317u, 6323u, 6329u, 6337u, 6343u, 6353u, + 6359u, 6361u, 6367u, 6373u, 6379u, 6389u, 6397u, 6421u, 6427u, + 6449u, 6451u, 6469u, 6473u, 6481u, 6491u, 6521u, 6529u, 6547u, + 6551u, 6553u, 6563u, 6569u, 6571u, 6577u, 6581u, 6599u, 6607u, + 6619u, 6637u, 6653u, 6659u, 6661u, 6673u, 6679u, 6689u, 6691u, + 6701u, 6703u, 6709u, 6719u, 6733u, 6737u, 6761u, 6763u, 6779u, + 6781u, 6791u, 6793u, 6803u, 6823u, 6827u, 6829u, 6833u, 6841u, + 6857u, 6863u, 6869u, 6871u, 6883u, 6899u, 6907u, 6911u, 6917u, + 6947u, 6949u, 6959u, 6961u, 6967u, 6971u, 6977u, 6983u, 6991u, + 6997u, 7001u, 7013u, 7019u, 7027u, 7039u, 7043u, 7057u, 7069u, + 7079u, 7103u, 7109u, 7121u, 7127u, 7129u, 7151u, 7159u, 7177u, + 7187u, 7193u, 7207u, 7211u, 7213u, 7219u, 7229u, 7237u, 7243u, + 7247u, 7253u, 7283u, 7297u, 7307u, 7309u, 7321u, 7331u, 7333u, + 7349u, 7351u, 7369u, 7393u, 7411u, 7417u, 7433u, 7451u, 7457u, + 7459u, 7477u, 7481u, 7487u, 7489u, 7499u, 7507u, 7517u, 7523u, + 7529u, 7537u, 7541u, 7547u, 7549u, 7559u, 7561u, 7573u, 7577u, + 7583u, 7589u, 7591u, 7603u, 7607u, 7621u, 7639u, 7643u, 7649u, + 7669u, 7673u, 7681u, 7687u, 7691u, 7699u, 7703u, 7717u, 7723u, + 7727u, 7741u, 7753u, 7757u, 7759u, 7789u, 7793u, 7817u, 7823u, + 7829u, 7841u, 7853u, 7867u, 7873u, 7877u, 7879u, 7883u, 7901u, + 7907u, 7919u, 7927u, 7933u, 7937u, 7949u, 7951u, 7963u, 7993u, + 8009u, 8011u, 8017u, 8039u, 8053u, 8059u, 8069u, 8081u, 8087u, + 8089u, 8093u, 8101u, 8111u, 8117u, 8123u, 8147u, 8161u, 8167u, + 8171u, 8179u, 8191u, 8209u, 8219u, 8221u, 8231u, 8233u, 8237u, + 8243u, 8263u, 8269u, 8273u, 8287u, 8291u, 8293u, 8297u, 8311u, + 8317u, 8329u, 8353u, 8363u, 8369u, 8377u, 8387u, 8389u, 8419u, + 8423u, 8429u, 8431u, 8443u, 8447u, 8461u, 8467u, 8501u, 8513u, + 8521u, 8527u, 8537u, 8539u, 8543u, 8563u, 8573u, 8581u, 8597u, + 8599u, 8609u, 8623u, 8627u, 8629u, 8641u, 8647u, 8663u, 8669u, + 8677u, 8681u, 8689u, 8693u, 8699u, 8707u, 8713u, 8719u, 8731u, + 8737u, 8741u, 8747u, 8753u, 8761u, 8779u, 8783u, 8803u, 8807u, + 8819u, 8821u, 8831u, 8837u, 8839u, 8849u, 8861u, 8863u, 8867u, + 8887u, 8893u, 8923u, 8929u, 8933u, 8941u, 8951u, 8963u, 8969u, + 8971u, 8999u, 9001u, 9007u, 9011u, 9013u, 9029u, 9041u, 9043u, + 9049u, 9059u, 9067u, 9091u, 9103u, 9109u, 9127u, 9133u, 9137u, + 9151u, 9157u, 9161u, 9173u, 9181u, 9187u, 9199u, 9203u, 9209u, + 9221u, 9227u, 9239u, 9241u, 9257u, 9277u, 9281u, 9283u, 9293u, + 9311u, 9319u, 9323u, 9337u, 9341u, 9343u, 9349u, 9371u, 9377u, + 9391u, 9397u, 9403u, 9413u, 9419u, 9421u, 9431u, 9433u, 9437u, + 9439u, 9461u, 9463u, 9467u, 9473u, 9479u, 9491u, 9497u, 9511u, + 9521u, 9533u, 9539u, 9547u, 9551u, 9587u, 9601u, 9613u, 9619u, + 9623u, 9629u, 9631u, 9643u, 9649u, 9661u, 9677u, 9679u, 9689u, + 9697u, 9719u, 9721u, 9733u, 9739u, 9743u, 9749u, 9767u, 9769u, + 9781u, 9787u, 9791u, 9803u, 9811u, 9817u, 9829u, 9833u, 9839u, + 9851u, 9857u, 9859u, 9871u, 9883u, 9887u, 9901u, 9907u, 9923u, + 9929u, 9931u, 9941u, 9949u, 9967u, 9973u, 10007u, 10009u, 10037u, + 10039u, 10061u, 10067u, 10069u, 10079u, 10091u, 10093u, 10099u, 10103u, + 10111u, 10133u, 10139u, 10141u, 10151u, 10159u, 10163u, 10169u, 10177u, + 10181u, 10193u, 10211u, 10223u, 10243u, 10247u, 10253u, 10259u, 10267u, + 10271u, 10273u, 10289u, 10301u, 10303u, 10313u, 10321u, 10331u, 10333u, + 10337u, 10343u, 10357u, 10369u, 10391u, 10399u, 10427u, 10429u, 10433u, + 10453u, 10457u, 10459u, 10463u, 10477u, 10487u, 10499u, 10501u, 10513u, + 10529u, 10531u, 10559u, 10567u, 10589u, 10597u, 10601u, 10607u, 10613u, + 10627u, 10631u, 10639u, 10651u, 10657u, 10663u, 10667u, 10687u, 10691u, + 10709u, 10711u, 10723u, 10729u, 10733u, 10739u, 10753u, 10771u, 10781u, + 10789u, 10799u, 10831u, 10837u, 10847u, 10853u, 10859u, 10861u, 10867u, + 10883u, 10889u, 10891u, 10903u, 10909u, 10937u, 10939u, 10949u, 10957u, + 10973u, 10979u, 10987u, 10993u, 11003u, 11027u, 11047u, 11057u, 11059u, + 11069u, 11071u, 11083u, 11087u, 11093u, 11113u, 11117u, 11119u, 11131u, + 11149u, 11159u, 11161u, 11171u, 11173u, 11177u, 11197u, 11213u, 11239u, + 11243u, 11251u, 11257u, 11261u, 11273u, 11279u, 11287u, 11299u, 11311u, + 11317u, 11321u, 11329u, 11351u, 11353u, 11369u, 11383u, 11393u, 11399u, + 11411u, 11423u, 11437u, 11443u, 11447u, 11467u, 11471u, 11483u, 11489u, + 11491u, 11497u, 11503u, 11519u, 11527u, 11549u, 11551u, 11579u, 11587u, + 11593u, 11597u, 11617u, 11621u, 11633u, 11657u, 11677u, 11681u, 11689u, + 11699u, 11701u, 11717u, 11719u, 11731u, 11743u, 11777u, 11779u, 11783u, + 11789u, 11801u, 11807u, 11813u, 11821u, 11827u, 11831u, 11833u, 11839u, + 11863u, 11867u, 11887u, 11897u, 11903u, 11909u, 11923u, 11927u, 11933u, + 11939u, 11941u, 11953u, 11959u, 11969u, 11971u, 11981u, 11987u, 12007u, + 12011u, 12037u, 12041u, 12043u, 12049u, 12071u, 12073u, 12097u, 12101u, + 12107u, 12109u, 12113u, 12119u, 12143u, 12149u, 12157u, 12161u, 12163u, + 12197u, 12203u, 12211u, 12227u, 12239u, 12241u, 12251u, 12253u, 12263u, + 12269u, 12277u, 12281u, 12289u, 12301u, 12323u, 12329u, 12343u, 12347u, + 12373u, 12377u, 12379u, 12391u, 12401u, 12409u, 12413u, 12421u, 12433u, + 12437u, 12451u, 12457u, 12473u, 12479u, 12487u, 12491u, 12497u, 12503u, + 12511u, 12517u, 12527u, 12539u, 12541u, 12547u, 12553u, 12569u, 12577u, + 12583u, 12589u, 12601u, 12611u, 12613u, 12619u, 12637u, 12641u, 12647u, + 12653u, 12659u, 12671u, 12689u, 12697u, 12703u, 12713u, 12721u, 12739u, + 12743u, 12757u, 12763u, 12781u, 12791u, 12799u, 12809u, 12821u, 12823u, + 12829u, 12841u, 12853u, 12889u, 12893u, 12899u, 12907u, 12911u, 12917u, + 12919u, 12923u, 12941u, 12953u, 12959u, 12967u, 12973u, 12979u, 12983u, + 13001u, 13003u, 13007u, 13009u, 13033u, 13037u, 13043u, 13049u, 13063u, + 13093u, 13099u, 13103u, 13109u, 13121u, 13127u, 13147u, 13151u, 13159u, + 13163u, 13171u, 13177u, 13183u, 13187u, 13217u, 13219u, 13229u, 13241u, + 13249u, 13259u, 13267u, 13291u, 13297u, 13309u, 13313u, 13327u, 13331u, + 13337u, 13339u, 13367u, 13381u, 13397u, 13399u, 13411u, 13417u, 13421u, + 13441u, 13451u, 13457u, 13463u, 13469u, 13477u, 13487u, 13499u, 13513u, + 13523u, 13537u, 13553u, 13567u, 13577u, 13591u, 13597u, 13613u, 13619u, + 13627u, 13633u, 13649u, 13669u, 13679u, 13681u, 13687u, 13691u, 13693u, + 13697u, 13709u, 13711u, 13721u, 13723u, 13729u, 13751u, 13757u, 13759u, + 13763u, 13781u, 13789u, 13799u, 13807u, 13829u, 13831u, 13841u, 13859u, + 13873u, 13877u, 13879u, 13883u, 13901u, 13903u, 13907u, 13913u, 13921u, + 13931u, 13933u, 13963u, 13967u, 13997u, 13999u, 14009u, 14011u, 14029u, + 14033u, 14051u, 14057u, 14071u, 14081u, 14083u, 14087u, 14107u, 14143u, + 14149u, 14153u, 14159u, 14173u, 14177u, 14197u, 14207u, 14221u, 14243u, + 14249u, 14251u, 14281u, 14293u, 14303u, 14321u, 14323u, 14327u, 14341u, + 14347u, 14369u, 14387u, 14389u, 14401u, 14407u, 14411u, 14419u, 14423u, + 14431u, 14437u, 14447u, 14449u, 14461u, 14479u, 14489u, 14503u, 14519u, + 14533u, 14537u, 14543u, 14549u, 14551u, 14557u, 14561u, 14563u, 14591u, + 14593u, 14621u, 14627u, 14629u, 14633u, 14639u, 14653u, 14657u, 14669u, + 14683u, 14699u, 14713u, 14717u, 14723u, 14731u, 14737u, 14741u, 14747u, + 14753u, 14759u, 14767u, 14771u, 14779u, 14783u, 14797u, 14813u, 14821u, + 14827u, 14831u, 14843u, 14851u, 14867u, 14869u, 14879u, 14887u, 14891u, + 14897u, 14923u, 14929u, 14939u, 14947u, 14951u, 14957u, 14969u, 14983u, + 15013u, 15017u, 15031u, 15053u, 15061u, 15073u, 15077u, 15083u, 15091u, + 15101u, 15107u, 15121u, 15131u, 15137u, 15139u, 15149u, 15161u, 15173u, + 15187u, 15193u, 15199u, 15217u, 15227u, 15233u, 15241u, 15259u, 15263u, + 15269u, 15271u, 15277u, 15287u, 15289u, 15299u, 15307u, 15313u, 15319u, + 15329u, 15331u, 15349u, 15359u, 15361u, 15373u, 15377u, 15383u, 15391u, + 15401u, 15413u, 15427u, 15439u, 15443u, 15451u, 15461u, 15467u, 15473u, + 15493u, 15497u, 15511u, 15527u, 15541u, 15551u, 15559u, 15569u, 15581u, + 15583u, 15601u, 15607u, 15619u, 15629u, 15641u, 15643u, 15647u, 15649u, + 15661u, 15667u, 15671u, 15679u, 15683u, 15727u, 15731u, 15733u, 15737u, + 15739u, 15749u, 15761u, 15767u, 15773u, 15787u, 15791u, 15797u, 15803u, + 15809u, 15817u, 15823u, 15859u, 15877u, 15881u, 15887u, 15889u, 15901u, + 15907u, 15913u, 15919u, 15923u, 15937u, 15959u, 15971u, 15973u, 15991u, + 16001u, 16007u, 16033u, 16057u, 16061u, 16063u, 16067u, 16069u, 16073u, + 16087u, 16091u, 16097u, 16103u, 16111u, 16127u, 16139u, 16141u, 16183u, + 16187u, 16189u, 16193u, 16217u, 16223u, 16229u, 16231u, 16249u, 16253u, + 16267u, 16273u, 16301u, 16319u, 16333u, 16339u, 16349u, 16361u, 16363u, + 16369u, 16381u, 16411u, 16417u, 16421u, 16427u, 16433u, 16447u, 16451u, + 16453u, 16477u, 16481u, 16487u, 16493u, 16519u, 16529u, 16547u, 16553u, + 16561u, 16567u, 16573u, 16603u, 16607u, 16619u, 16631u, 16633u, 16649u, + 16651u, 16657u, 16661u, 16673u, 16691u, 16693u, 16699u, 16703u, 16729u, + 16741u, 16747u, 16759u, 16763u, 16787u, 16811u, 16823u, 16829u, 16831u, + 16843u, 16871u, 16879u, 16883u, 16889u, 16901u, 16903u, 16921u, 16927u, + 16931u, 16937u, 16943u, 16963u, 16979u, 16981u, 16987u, 16993u, 17011u, + 17021u, 17027u, 17029u, 17033u, 17041u, 17047u, 17053u, 17077u, 17093u, + 17099u, 17107u, 17117u, 17123u, 17137u, 17159u, 17167u, 17183u, 17189u, + 17191u, 17203u, 17207u, 17209u, 17231u, 17239u, 17257u, 17291u, 17293u, + 17299u, 17317u, 17321u, 17327u, 17333u, 17341u, 17351u, 17359u, 17377u, + 17383u, 17387u, 17389u, 17393u, 17401u, 17417u, 17419u, 17431u, 17443u, + 17449u, 17467u, 17471u, 17477u, 17483u, 17489u, 17491u, 17497u, 17509u, + 17519u, 17539u, 17551u, 17569u, 17573u, 17579u, 17581u, 17597u, 17599u, + 17609u, 17623u, 17627u, 17657u, 17659u, 17669u, 17681u, 17683u, 17707u, + 17713u, 17729u, 17737u, 17747u, 17749u, 17761u, 17783u, 17789u, 17791u, + 17807u, 17827u, 17837u, 17839u, 17851u, 17863u, 17881u, 17891u, 17903u, + 17909u, 17911u, 17921u, 17923u, 17929u, 17939u, 17957u, 17959u, 17971u, + 17977u, 17981u, 17987u, 17989u, 18013u, 18041u, 18043u, 18047u, 18049u, + 18059u, 18061u, 18077u, 18089u, 18097u, 18119u, 18121u, 18127u, 18131u, + 18133u, 18143u, 18149u, 18169u, 18181u, 18191u, 18199u, 18211u, 18217u, + 18223u, 18229u, 18233u, 18251u, 18253u, 18257u, 18269u, 18287u, 18289u, + 18301u, 18307u, 18311u, 18313u, 18329u, 18341u, 18353u, 18367u, 18371u, + 18379u, 18397u, 18401u, 18413u, 18427u, 18433u, 18439u, 18443u, 18451u, + 18457u, 18461u, 18481u, 18493u, 18503u, 18517u, 18521u, 18523u, 18539u, + 18541u, 18553u, 18583u, 18587u, 18593u, 18617u, 18637u, 18661u, 18671u, + 18679u, 18691u, 18701u, 18713u, 18719u, 18731u, 18743u, 18749u, 18757u, + 18773u, 18787u, 18793u, 18797u, 18803u, 18839u, 18859u, 18869u, 18899u, + 18911u, 18913u, 18917u, 18919u, 18947u, 18959u, 18973u, 18979u, 19001u, + 19009u, 19013u, 19031u, 19037u, 19051u, 19069u, 19073u, 19079u, 19081u, + 19087u, 19121u, 19139u, 19141u, 19157u, 19163u, 19181u, 19183u, 19207u, + 19211u, 19213u, 19219u, 19231u, 19237u, 19249u, 19259u, 19267u, 19273u, + 19289u, 19301u, 19309u, 19319u, 19333u, 19373u, 19379u, 19381u, 19387u, + 19391u, 19403u, 19417u, 19421u, 19423u, 19427u, 19429u, 19433u, 19441u, + 19447u, 19457u, 19463u, 19469u, 19471u, 19477u, 19483u, 19489u, 19501u, + 19507u, 19531u, 19541u, 19543u, 19553u, 19559u, 19571u, 19577u, 19583u, + 19597u, 19603u, 19609u, 19661u, 19681u, 19687u, 19697u, 19699u, 19709u, + 19717u, 19727u, 19739u, 19751u, 19753u, 19759u, 19763u, 19777u, 19793u, + 19801u, 19813u, 19819u, 19841u, 19843u, 19853u, 19861u, 19867u, 19889u, + 19891u, 19913u, 19919u, 19927u, 19937u, 19949u, 19961u, 19963u, 19973u, + 19979u, 19991u, 19993u, 19997u, 20011u, 20021u, 20023u, 20029u, 20047u, + 20051u, 20063u, 20071u, 20089u, 20101u, 20107u, 20113u, 20117u, 20123u, + 20129u, 20143u, 20147u, 20149u, 20161u, 20173u, 20177u, 20183u, 20201u, + 20219u, 20231u, 20233u, 20249u, 20261u, 20269u, 20287u, 20297u, 20323u, + 20327u, 20333u, 20341u, 20347u, 20353u, 20357u, 20359u, 20369u, 20389u, + 20393u, 20399u, 20407u, 20411u, 20431u, 20441u, 20443u, 20477u, 20479u, + 20483u, 20507u, 20509u, 20521u, 20533u, 20543u, 20549u, 20551u, 20563u, + 20593u, 20599u, 20611u, 20627u, 20639u, 20641u, 20663u, 20681u, 20693u, + 20707u, 20717u, 20719u, 20731u, 20743u, 20747u, 20749u, 20753u, 20759u, + 20771u, 20773u, 20789u, 20807u, 20809u, 20849u, 20857u, 20873u, 20879u, + 20887u, 20897u, 20899u, 20903u, 20921u, 20929u, 20939u, 20947u, 20959u, + 20963u, 20981u, 20983u, 21001u, 21011u, 21013u, 21017u, 21019u, 21023u, + 21031u, 21059u, 21061u, 21067u, 21089u, 21101u, 21107u, 21121u, 21139u, + 21143u, 21149u, 21157u, 21163u, 21169u, 21179u, 21187u, 21191u, 21193u, + 21211u, 21221u, 21227u, 21247u, 21269u, 21277u, 21283u, 21313u, 21317u, + 21319u, 21323u, 21341u, 21347u, 21377u, 21379u, 21383u, 21391u, 21397u, + 21401u, 21407u, 21419u, 21433u, 21467u, 21481u, 21487u, 21491u, 21493u, + 21499u, 21503u, 21517u, 21521u, 21523u, 21529u, 21557u, 21559u, 21563u, + 21569u, 21577u, 21587u, 21589u, 21599u, 21601u, 21611u, 21613u, 21617u, + 21647u, 21649u, 21661u, 21673u, 21683u, 21701u, 21713u, 21727u, 21737u, + 21739u, 21751u, 21757u, 21767u, 21773u, 21787u, 21799u, 21803u, 21817u, + 21821u, 21839u, 21841u, 21851u, 21859u, 21863u, 21871u, 21881u, 21893u, + 21911u, 21929u, 21937u, 21943u, 21961u, 21977u, 21991u, 21997u, 22003u, + 22013u, 22027u, 22031u, 22037u, 22039u, 22051u, 22063u, 22067u, 22073u, + 22079u, 22091u, 22093u, 22109u, 22111u, 22123u, 22129u, 22133u, 22147u, + 22153u, 22157u, 22159u, 22171u, 22189u, 22193u, 22229u, 22247u, 22259u, + 22271u, 22273u, 22277u, 22279u, 22283u, 22291u, 22303u, 22307u, 22343u, + 22349u, 22367u, 22369u, 22381u, 22391u, 22397u, 22409u, 22433u, 22441u, + 22447u, 22453u, 22469u, 22481u, 22483u, 22501u, 22511u, 22531u, 22541u, + 22543u, 22549u, 22567u, 22571u, 22573u, 22613u, 22619u, 22621u, 22637u, + 22639u, 22643u, 22651u, 22669u, 22679u, 22691u, 22697u, 22699u, 22709u, + 22717u, 22721u, 22727u, 22739u, 22741u, 22751u, 22769u, 22777u, 22783u, + 22787u, 22807u, 22811u, 22817u, 22853u, 22859u, 22861u, 22871u, 22877u, + 22901u, 22907u, 22921u, 22937u, 22943u, 22961u, 22963u, 22973u, 22993u, + 23003u, 23011u, 23017u, 23021u, 23027u, 23029u, 23039u, 23041u, 23053u, + 23057u, 23059u, 23063u, 23071u, 23081u, 23087u, 23099u, 23117u, 23131u, + 23143u, 23159u, 23167u, 23173u, 23189u, 23197u, 23201u, 23203u, 23209u, + 23227u, 23251u, 23269u, 23279u, 23291u, 23293u, 23297u, 23311u, 23321u, + 23327u, 23333u, 23339u, 23357u, 23369u, 23371u, 23399u, 23417u, 23431u, + 23447u, 23459u, 23473u, 23497u, 23509u, 23531u, 23537u, 23539u, 23549u, + 23557u, 23561u, 23563u, 23567u, 23581u, 23593u, 23599u, 23603u, 23609u, + 23623u, 23627u, 23629u, 23633u, 23663u, 23669u, 23671u, 23677u, 23687u, + 23689u, 23719u, 23741u, 23743u, 23747u, 23753u, 23761u, 23767u, 23773u, + 23789u, 23801u, 23813u, 23819u, 23827u, 23831u, 23833u, 23857u, 23869u, + 23873u, 23879u, 23887u, 23893u, 23899u, 23909u, 23911u, 23917u, 23929u, + 23957u, 23971u, 23977u, 23981u, 23993u, 24001u, 24007u, 24019u, 24023u, + 24029u, 24043u, 24049u, 24061u, 24071u, 24077u, 24083u, 24091u, 24097u, + 24103u, 24107u, 24109u, 24113u, 24121u, 24133u, 24137u, 24151u, 24169u, + 24179u, 24181u, 24197u, 24203u, 24223u, 24229u, 24239u, 24247u, 24251u, + 24281u, 24317u, 24329u, 24337u, 24359u, 24371u, 24373u, 24379u, 24391u, + 24407u, 24413u, 24419u, 24421u, 24439u, 24443u, 24469u, 24473u, 24481u, + 24499u, 24509u, 24517u, 24527u, 24533u, 24547u, 24551u, 24571u, 24593u, + 24611u, 24623u, 24631u, 24659u, 24671u, 24677u, 24683u, 24691u, 24697u, + 24709u, 24733u, 24749u, 24763u, 24767u, 24781u, 24793u, 24799u, 24809u, + 24821u, 24841u, 24847u, 24851u, 24859u, 24877u, 24889u, 24907u, 24917u, + 24919u, 24923u, 24943u, 24953u, 24967u, 24971u, 24977u, 24979u, 24989u, + 25013u, 25031u, 25033u, 25037u, 25057u, 25073u, 25087u, 25097u, 25111u, + 25117u, 25121u, 25127u, 25147u, 25153u, 25163u, 25169u, 25171u, 25183u, + 25189u, 25219u, 25229u, 25237u, 25243u, 25247u, 25253u, 25261u, 25301u, + 25303u, 25307u, 25309u, 25321u, 25339u, 25343u, 25349u, 25357u, 25367u, + 25373u, 25391u, 25409u, 25411u, 25423u, 25439u, 25447u, 25453u, 25457u, + 25463u, 25469u, 25471u, 25523u, 25537u, 25541u, 25561u, 25577u, 25579u, + 25583u, 25589u, 25601u, 25603u, 25609u, 25621u, 25633u, 25639u, 25643u, + 25657u, 25667u, 25673u, 25679u, 25693u, 25703u, 25717u, 25733u, 25741u, + 25747u, 25759u, 25763u, 25771u, 25793u, 25799u, 25801u, 25819u, 25841u, + 25847u, 25849u, 25867u, 25873u, 25889u, 25903u, 25913u, 25919u, 25931u, + 25933u, 25939u, 25943u, 25951u, 25969u, 25981u, 25997u, 25999u, 26003u, + 26017u, 26021u, 26029u, 26041u, 26053u, 26083u, 26099u, 26107u, 26111u, + 26113u, 26119u, 26141u, 26153u, 26161u, 26171u, 26177u, 26183u, 26189u, + 26203u, 26209u, 26227u, 26237u, 26249u, 26251u, 26261u, 26263u, 26267u, + 26293u, 26297u, 26309u, 26317u, 26321u, 26339u, 26347u, 26357u, 26371u, + 26387u, 26393u, 26399u, 26407u, 26417u, 26423u, 26431u, 26437u, 26449u, + 26459u, 26479u, 26489u, 26497u, 26501u, 26513u, 26539u, 26557u, 26561u, + 26573u, 26591u, 26597u, 26627u, 26633u, 26641u, 26647u, 26669u, 26681u, + 26683u, 26687u, 26693u, 26699u, 26701u, 26711u, 26713u, 26717u, 26723u, + 26729u, 26731u, 26737u, 26759u, 26777u, 26783u, 26801u, 26813u, 26821u, + 26833u, 26839u, 26849u, 26861u, 26863u, 26879u, 26881u, 26891u, 26893u, + 26903u, 26921u, 26927u, 26947u, 26951u, 26953u, 26959u, 26981u, 26987u, + 26993u, 27011u, 27017u, 27031u, 27043u, 27059u, 27061u, 27067u, 27073u, + 27077u, 27091u, 27103u, 27107u, 27109u, 27127u, 27143u, 27179u, 27191u, + 27197u, 27211u, 27239u, 27241u, 27253u, 27259u, 27271u, 27277u, 27281u, + 27283u, 27299u, 27329u, 27337u, 27361u, 27367u, 27397u, 27407u, 27409u, + 27427u, 27431u, 27437u, 27449u, 27457u, 27479u, 27481u, 27487u, 27509u, + 27527u, 27529u, 27539u, 27541u, 27551u, 27581u, 27583u, 27611u, 27617u, + 27631u, 27647u, 27653u, 27673u, 27689u, 27691u, 27697u, 27701u, 27733u, + 27737u, 27739u, 27743u, 27749u, 27751u, 27763u, 27767u, 27773u, 27779u, + 27791u, 27793u, 27799u, 27803u, 27809u, 27817u, 27823u, 27827u, 27847u, + 27851u, 27883u, 27893u, 27901u, 27917u, 27919u, 27941u, 27943u, 27947u, + 27953u, 27961u, 27967u, 27983u, 27997u, 28001u, 28019u, 28027u, 28031u, + 28051u, 28057u, 28069u, 28081u, 28087u, 28097u, 28099u, 28109u, 28111u, + 28123u, 28151u, 28163u, 28181u, 28183u, 28201u, 28211u, 28219u, 28229u, + 28277u, 28279u, 28283u, 28289u, 28297u, 28307u, 28309u, 28319u, 28349u, + 28351u, 28387u, 28393u, 28403u, 28409u, 28411u, 28429u, 28433u, 28439u, + 28447u, 28463u, 28477u, 28493u, 28499u, 28513u, 28517u, 28537u, 28541u, + 28547u, 28549u, 28559u, 28571u, 28573u, 28579u, 28591u, 28597u, 28603u, + 28607u, 28619u, 28621u, 28627u, 28631u, 28643u, 28649u, 28657u, 28661u, + 28663u, 28669u, 28687u, 28697u, 28703u, 28711u, 28723u, 28729u, 28751u, + 28753u, 28759u, 28771u, 28789u, 28793u, 28807u, 28813u, 28817u, 28837u, + 28843u, 28859u, 28867u, 28871u, 28879u, 28901u, 28909u, 28921u, 28927u, + 28933u, 28949u, 28961u, 28979u, 29009u, 29017u, 29021u, 29023u, 29027u, + 29033u, 29059u, 29063u, 29077u, 29101u, 29123u, 29129u, 29131u, 29137u, + 29147u, 29153u, 29167u, 29173u, 29179u, 29191u, 29201u, 29207u, 29209u, + 29221u, 29231u, 29243u, 29251u, 29269u, 29287u, 29297u, 29303u, 29311u, + 29327u, 29333u, 29339u, 29347u, 29363u, 29383u, 29387u, 29389u, 29399u, + 29401u, 29411u, 29423u, 29429u, 29437u, 29443u, 29453u, 29473u, 29483u, + 29501u, 29527u, 29531u, 29537u, 29567u, 29569u, 29573u, 29581u, 29587u, + 29599u, 29611u, 29629u, 29633u, 29641u, 29663u, 29669u, 29671u, 29683u, + 29717u, 29723u, 29741u, 29753u, 29759u, 29761u, 29789u, 29803u, 29819u, + 29833u, 29837u, 29851u, 29863u, 29867u, 29873u, 29879u, 29881u, 29917u, + 29921u, 29927u, 29947u, 29959u, 29983u, 29989u, 30011u, 30013u, 30029u, + 30047u, 30059u, 30071u, 30089u, 30091u, 30097u, 30103u, 30109u, 30113u, + 30119u, 30133u, 30137u, 30139u, 30161u, 30169u, 30181u, 30187u, 30197u, + 30203u, 30211u, 30223u, 30241u, 30253u, 30259u, 30269u, 30271u, 30293u, + 30307u, 30313u, 30319u, 30323u, 30341u, 30347u, 30367u, 30389u, 30391u, + 30403u, 30427u, 30431u, 30449u, 30467u, 30469u, 30491u, 30493u, 30497u, + 30509u, 30517u, 30529u, 30539u, 30553u, 30557u, 30559u, 30577u, 30593u, + 30631u, 30637u, 30643u, 30649u, 30661u, 30671u, 30677u, 30689u, 30697u, + 30703u, 30707u, 30713u, 30727u, 30757u, 30763u, 30773u, 30781u, 30803u, + 30809u, 30817u, 30829u, 30839u, 30841u, 30851u, 30853u, 30859u, 30869u, + 30871u, 30881u, 30893u, 30911u, 30931u, 30937u, 30941u, 30949u, 30971u, + 30977u, 30983u, 31013u, 31019u, 31033u, 31039u, 31051u, 31063u, 31069u, + 31079u, 31081u, 31091u, 31121u, 31123u, 31139u, 31147u, 31151u, 31153u, + 31159u, 31177u, 31181u, 31183u, 31189u, 31193u, 31219u, 31223u, 31231u, + 31237u, 31247u, 31249u, 31253u, 31259u, 31267u, 31271u, 31277u, 31307u, + 31319u, 31321u, 31327u, 31333u, 31337u, 31357u, 31379u, 31387u, 31391u, + 31393u, 31397u, 31469u, 31477u, 31481u, 31489u, 31511u, 31513u, 31517u, + 31531u, 31541u, 31543u, 31547u, 31567u, 31573u, 31583u, 31601u, 31607u, + 31627u, 31643u, 31649u, 31657u, 31663u, 31667u, 31687u, 31699u, 31721u, + 31723u, 31727u, 31729u, 31741u, 31751u, 31769u, 31771u, 31793u, 31799u, + 31817u, 31847u, 31849u, 31859u, 31873u, 31883u, 31891u, 31907u, 31957u, + 31963u, 31973u, 31981u, 31991u, 32003u, 32009u, 32027u, 32029u, 32051u, + 32057u, 32059u, 32063u, 32069u, 32077u, 32083u, 32089u, 32099u, 32117u, + 32119u, 32141u, 32143u, 32159u, 32173u, 32183u, 32189u, 32191u, 32203u, + 32213u, 32233u, 32237u, 32251u, 32257u, 32261u, 32297u, 32299u, 32303u, + 32309u, 32321u, 32323u, 32327u, 32341u, 32353u, 32359u, 32363u, 32369u, + 32371u, 32377u, 32381u, 32401u, 32411u, 32413u, 32423u, 32429u, 32441u, + 32443u, 32467u, 32479u, 32491u, 32497u, 32503u, 32507u, 32531u, 32533u, + 32537u, 32561u, 32563u, 32569u, 32573u, 32579u, 32587u, 32603u, 32609u, + 32611u, 32621u, 32633u, 32647u, 32653u, 32687u, 32693u, 32707u, 32713u, + 32717u, 32719u, 32749u, 32771u, 32779u, 32783u, 32789u, 32797u, 32801u, + 32803u, 32831u, 32833u, 32839u, 32843u, 32869u, 32887u, 32909u, 32911u, + 32917u, 32933u, 32939u, 32941u, 32957u, 32969u, 32971u, 32983u, 32987u, + 32993u, 32999u, 33013u, 33023u, 33029u, 33037u, 33049u, 33053u, 33071u, + 33073u, 33083u, 33091u, 33107u, 33113u, 33119u, 33149u, 33151u, 33161u, + 33179u, 33181u, 33191u, 33199u, 33203u, 33211u, 33223u, 33247u, 33287u, + 33289u, 33301u, 33311u, 33317u, 33329u, 33331u, 33343u, 33347u, 33349u, + 33353u, 33359u, 33377u, 33391u, 33403u, 33409u, 33413u, 33427u, 33457u, + 33461u, 33469u, 33479u, 33487u, 33493u, 33503u, 33521u, 33529u, 33533u, + 33547u, 33563u, 33569u, 33577u, 33581u, 33587u, 33589u, 33599u, 33601u, + 33613u, 33617u, 33619u, 33623u, 33629u, 33637u, 33641u, 33647u, 33679u, + 33703u, 33713u, 33721u, 33739u, 33749u, 33751u, 33757u, 33767u, 33769u, + 33773u, 33791u, 33797u, 33809u, 33811u, 33827u, 33829u, 33851u, 33857u, + 33863u, 33871u, 33889u, 33893u, 33911u, 33923u, 33931u, 33937u, 33941u, + 33961u, 33967u, 33997u, 34019u, 34031u, 34033u, 34039u, 34057u, 34061u, + 34123u, 34127u, 34129u, 34141u, 34147u, 34157u, 34159u, 34171u, 34183u, + 34211u, 34213u, 34217u, 34231u, 34253u, 34259u, 34261u, 34267u, 34273u, + 34283u, 34297u, 34301u, 34303u, 34313u, 34319u, 34327u, 34337u, 34351u, + 34361u, 34367u, 34369u, 34381u, 34403u, 34421u, 34429u, 34439u, 34457u, + 34469u, 34471u, 34483u, 34487u, 34499u, 34501u, 34511u, 34513u, 34519u, + 34537u, 34543u, 34549u, 34583u, 34589u, 34591u, 34603u, 34607u, 34613u, + 34631u, 34649u, 34651u, 34667u, 34673u, 34679u, 34687u, 34693u, 34703u, + 34721u, 34729u, 34739u, 34747u, 34757u, 34759u, 34763u, 34781u, 34807u, + 34819u, 34841u, 34843u, 34847u, 34849u, 34871u, 34877u, 34883u, 34897u, + 34913u, 34919u, 34939u, 34949u, 34961u, 34963u, 34981u, 35023u, 35027u, + 35051u, 35053u, 35059u, 35069u, 35081u, 35083u, 35089u, 35099u, 35107u, + 35111u, 35117u, 35129u, 35141u, 35149u, 35153u, 35159u, 35171u, 35201u, + 35221u, 35227u, 35251u, 35257u, 35267u, 35279u, 35281u, 35291u, 35311u, + 35317u, 35323u, 35327u, 35339u, 35353u, 35363u, 35381u, 35393u, 35401u, + 35407u, 35419u, 35423u, 35437u, 35447u, 35449u, 35461u, 35491u, 35507u, + 35509u, 35521u, 35527u, 35531u, 35533u, 35537u, 35543u, 35569u, 35573u, + 35591u, 35593u, 35597u, 35603u, 35617u, 35671u, 35677u, 35729u, 35731u, + 35747u, 35753u, 35759u, 35771u, 35797u, 35801u, 35803u, 35809u, 35831u, + 35837u, 35839u, 35851u, 35863u, 35869u, 35879u, 35897u, 35899u, 35911u, + 35923u, 35933u, 35951u, 35963u, 35969u, 35977u, 35983u, 35993u, 35999u, + 36007u, 36011u, 36013u, 36017u, 36037u, 36061u, 36067u, 36073u, 36083u, + 36097u, 36107u, 36109u, 36131u, 36137u, 36151u, 36161u, 36187u, 36191u, + 36209u, 36217u, 36229u, 36241u, 36251u, 36263u, 36269u, 36277u, 36293u, + 36299u, 36307u, 36313u, 36319u, 36341u, 36343u, 36353u, 36373u, 36383u, + 36389u, 36433u, 36451u, 36457u, 36467u, 36469u, 36473u, 36479u, 36493u, + 36497u, 36523u, 36527u, 36529u, 36541u, 36551u, 36559u, 36563u, 36571u, + 36583u, 36587u, 36599u, 36607u, 36629u, 36637u, 36643u, 36653u, 36671u, + 36677u, 36683u, 36691u, 36697u, 36709u, 36713u, 36721u, 36739u, 36749u, + 36761u, 36767u, 36779u, 36781u, 36787u, 36791u, 36793u, 36809u, 36821u, + 36833u, 36847u, 36857u, 36871u, 36877u, 36887u, 36899u, 36901u, 36913u, + 36919u, 36923u, 36929u, 36931u, 36943u, 36947u, 36973u, 36979u, 36997u, + 37003u, 37013u, 37019u, 37021u, 37039u, 37049u, 37057u, 37061u, 37087u, + 37097u, 37117u, 37123u, 37139u, 37159u, 37171u, 37181u, 37189u, 37199u, + 37201u, 37217u, 37223u, 37243u, 37253u, 37273u, 37277u, 37307u, 37309u, + 37313u, 37321u, 37337u, 37339u, 37357u, 37361u, 37363u, 37369u, 37379u, + 37397u, 37409u, 37423u, 37441u, 37447u, 37463u, 37483u, 37489u, 37493u, + 37501u, 37507u, 37511u, 37517u, 37529u, 37537u, 37547u, 37549u, 37561u, + 37567u, 37571u, 37573u, 37579u, 37589u, 37591u, 37607u, 37619u, 37633u, + 37643u, 37649u, 37657u, 37663u, 37691u, 37693u, 37699u, 37717u, 37747u, + 37781u, 37783u, 37799u, 37811u, 37813u, 37831u, 37847u, 37853u, 37861u, + 37871u, 37879u, 37889u, 37897u, 37907u, 37951u, 37957u, 37963u, 37967u, + 37987u, 37991u, 37993u, 37997u, 38011u, 38039u, 38047u, 38053u, 38069u, + 38083u, 38113u, 38119u, 38149u, 38153u, 38167u, 38177u, 38183u, 38189u, + 38197u, 38201u, 38219u, 38231u, 38237u, 38239u, 38261u, 38273u, 38281u, + 38287u, 38299u, 38303u, 38317u, 38321u, 38327u, 38329u, 38333u, 38351u, + 38371u, 38377u, 38393u, 38431u, 38447u, 38449u, 38453u, 38459u, 38461u, + 38501u, 38543u, 38557u, 38561u, 38567u, 38569u, 38593u, 38603u, 38609u, + 38611u, 38629u, 38639u, 38651u, 38653u, 38669u, 38671u, 38677u, 38693u, + 38699u, 38707u, 38711u, 38713u, 38723u, 38729u, 38737u, 38747u, 38749u, + 38767u, 38783u, 38791u, 38803u, 38821u, 38833u, 38839u, 38851u, 38861u, + 38867u, 38873u, 38891u, 38903u, 38917u, 38921u, 38923u, 38933u, 38953u, + 38959u, 38971u, 38977u, 38993u, 39019u, 39023u, 39041u, 39043u, 39047u, + 39079u, 39089u, 39097u, 39103u, 39107u, 39113u, 39119u, 39133u, 39139u, + 39157u, 39161u, 39163u, 39181u, 39191u, 39199u, 39209u, 39217u, 39227u, + 39229u, 39233u, 39239u, 39241u, 39251u, 39293u, 39301u, 39313u, 39317u, + 39323u, 39341u, 39343u, 39359u, 39367u, 39371u, 39373u, 39383u, 39397u, + 39409u, 39419u, 39439u, 39443u, 39451u, 39461u, 39499u, 39503u, 39509u, + 39511u, 39521u, 39541u, 39551u, 39563u, 39569u, 39581u, 39607u, 39619u, + 39623u, 39631u, 39659u, 39667u, 39671u, 39679u, 39703u, 39709u, 39719u, + 39727u, 39733u, 39749u, 39761u, 39769u, 39779u, 39791u, 39799u, 39821u, + 39827u, 39829u, 39839u, 39841u, 39847u, 39857u, 39863u, 39869u, 39877u, + 39883u, 39887u, 39901u, 39929u, 39937u, 39953u, 39971u, 39979u, 39983u, + 39989u, 40009u, 40013u, 40031u, 40037u, 40039u, 40063u, 40087u, 40093u, + 40099u, 40111u, 40123u, 40127u, 40129u, 40151u, 40153u, 40163u, 40169u, + 40177u, 40189u, 40193u, 40213u, 40231u, 40237u, 40241u, 40253u, 40277u, + 40283u, 40289u, 40343u, 40351u, 40357u, 40361u, 40387u, 40423u, 40427u, + 40429u, 40433u, 40459u, 40471u, 40483u, 40487u, 40493u, 40499u, 40507u, + 40519u, 40529u, 40531u, 40543u, 40559u, 40577u, 40583u, 40591u, 40597u, + 40609u, 40627u, 40637u, 40639u, 40693u, 40697u, 40699u, 40709u, 40739u, + 40751u, 40759u, 40763u, 40771u, 40787u, 40801u, 40813u, 40819u, 40823u, + 40829u, 40841u, 40847u, 40849u, 40853u, 40867u, 40879u, 40883u, 40897u, + 40903u, 40927u, 40933u, 40939u, 40949u, 40961u, 40973u, 40993u, 41011u, + 41017u, 41023u, 41039u, 41047u, 41051u, 41057u, 41077u, 41081u, 41113u, + 41117u, 41131u, 41141u, 41143u, 41149u, 41161u, 41177u, 41179u, 41183u, + 41189u, 41201u, 41203u, 41213u, 41221u, 41227u, 41231u, 41233u, 41243u, + 41257u, 41263u, 41269u, 41281u, 41299u, 41333u, 41341u, 41351u, 41357u, + 41381u, 41387u, 41389u, 41399u, 41411u, 41413u, 41443u, 41453u, 41467u, + 41479u, 41491u, 41507u, 41513u, 41519u, 41521u, 41539u, 41543u, 41549u, + 41579u, 41593u, 41597u, 41603u, 41609u, 41611u, 41617u, 41621u, 41627u, + 41641u, 41647u, 41651u, 41659u, 41669u, 41681u, 41687u, 41719u, 41729u, + 41737u, 41759u, 41761u, 41771u, 41777u, 41801u, 41809u, 41813u, 41843u, + 41849u, 41851u, 41863u, 41879u, 41887u, 41893u, 41897u, 41903u, 41911u, + 41927u, 41941u, 41947u, 41953u, 41957u, 41959u, 41969u, 41981u, 41983u, + 41999u, 42013u, 42017u, 42019u, 42023u, 42043u, 42061u, 42071u, 42073u, + 42083u, 42089u, 42101u, 42131u, 42139u, 42157u, 42169u, 42179u, 42181u, + 42187u, 42193u, 42197u, 42209u, 42221u, 42223u, 42227u, 42239u, 42257u, + 42281u, 42283u, 42293u, 42299u, 42307u, 42323u, 42331u, 42337u, 42349u, + 42359u, 42373u, 42379u, 42391u, 42397u, 42403u, 42407u, 42409u, 42433u, + 42437u, 42443u, 42451u, 42457u, 42461u, 42463u, 42467u, 42473u, 42487u, + 42491u, 42499u, 42509u, 42533u, 42557u, 42569u, 42571u, 42577u, 42589u, + 42611u, 42641u, 42643u, 42649u, 42667u, 42677u, 42683u, 42689u, 42697u, + 42701u, 42703u, 42709u, 42719u, 42727u, 42737u, 42743u, 42751u, 42767u, + 42773u, 42787u, 42793u, 42797u, 42821u, 42829u, 42839u, 42841u, 42853u, + 42859u, 42863u, 42899u, 42901u, 42923u, 42929u, 42937u, 42943u, 42953u, + 42961u, 42967u, 42979u, 42989u, 43003u, 43013u, 43019u, 43037u, 43049u, + 43051u, 43063u, 43067u, 43093u, 43103u, 43117u, 43133u, 43151u, 43159u, + 43177u, 43189u, 43201u, 43207u, 43223u, 43237u, 43261u, 43271u, 43283u, + 43291u, 43313u, 43319u, 43321u, 43331u, 43391u, 43397u, 43399u, 43403u, + 43411u, 43427u, 43441u, 43451u, 43457u, 43481u, 43487u, 43499u, 43517u, + 43541u, 43543u, 43573u, 43577u, 43579u, 43591u, 43597u, 43607u, 43609u, + 43613u, 43627u, 43633u, 43649u, 43651u, 43661u, 43669u, 43691u, 43711u, + 43717u, 43721u, 43753u, 43759u, 43777u, 43781u, 43783u, 43787u, 43789u, + 43793u, 43801u, 43853u, 43867u, 43889u, 43891u, 43913u, 43933u, 43943u, + 43951u, 43961u, 43963u, 43969u, 43973u, 43987u, 43991u, 43997u, 44017u, + 44021u, 44027u, 44029u, 44041u, 44053u, 44059u, 44071u, 44087u, 44089u, + 44101u, 44111u, 44119u, 44123u, 44129u, 44131u, 44159u, 44171u, 44179u, + 44189u, 44201u, 44203u, 44207u, 44221u, 44249u, 44257u, 44263u, 44267u, + 44269u, 44273u, 44279u, 44281u, 44293u, 44351u, 44357u, 44371u, 44381u, + 44383u, 44389u, 44417u, 44449u, 44453u, 44483u, 44491u, 44497u, 44501u, + 44507u, 44519u, 44531u, 44533u, 44537u, 44543u, 44549u, 44563u, 44579u, + 44587u, 44617u, 44621u, 44623u, 44633u, 44641u, 44647u, 44651u, 44657u, + 44683u, 44687u, 44699u, 44701u, 44711u, 44729u, 44741u, 44753u, 44771u, + 44773u, 44777u, 44789u, 44797u, 44809u, 44819u, 44839u, 44843u, 44851u, + 44867u, 44879u, 44887u, 44893u, 44909u, 44917u, 44927u, 44939u, 44953u, + 44959u, 44963u, 44971u, 44983u, 44987u, 45007u, 45013u, 45053u, 45061u, + 45077u, 45083u, 45119u, 45121u, 45127u, 45131u, 45137u, 45139u, 45161u, + 45179u, 45181u, 45191u, 45197u, 45233u, 45247u, 45259u, 45263u, 45281u, + 45289u, 45293u, 45307u, 45317u, 45319u, 45329u, 45337u, 45341u, 45343u, + 45361u, 45377u, 45389u, 45403u, 45413u, 45427u, 45433u, 45439u, 45481u, + 45491u, 45497u, 45503u, 45523u, 45533u, 45541u, 45553u, 45557u, 45569u, + 45587u, 45589u, 45599u, 45613u, 45631u, 45641u, 45659u, 45667u, 45673u, + 45677u, 45691u, 45697u, 45707u, 45737u, 45751u, 45757u, 45763u, 45767u, + 45779u, 45817u, 45821u, 45823u, 45827u, 45833u, 45841u, 45853u, 45863u, + 45869u, 45887u, 45893u, 45943u, 45949u, 45953u, 45959u, 45971u, 45979u, + 45989u, 46021u, 46027u, 46049u, 46051u, 46061u, 46073u, 46091u, 46093u, + 46099u, 46103u, 46133u, 46141u, 46147u, 46153u, 46171u, 46181u, 46183u, + 46187u, 46199u, 46219u, 46229u, 46237u, 46261u, 46271u, 46273u, 46279u, + 46301u, 46307u, 46309u, 46327u, 46337u, 46349u, 46351u, 46381u, 46399u, + 46411u, 46439u, 46441u, 46447u, 46451u, 46457u, 46471u, 46477u, 46489u, + 46499u, 46507u, 46511u, 46523u, 46549u, 46559u, 46567u, 46573u, 46589u, + 46591u, 46601u, 46619u, 46633u, 46639u, 46643u, 46649u, 46663u, 46679u, + 46681u, 46687u, 46691u, 46703u, 46723u, 46727u, 46747u, 46751u, 46757u, + 46769u, 46771u, 46807u, 46811u, 46817u, 46819u, 46829u, 46831u, 46853u, + 46861u, 46867u, 46877u, 46889u, 46901u, 46919u, 46933u, 46957u, 46993u, + 46997u, 47017u, 47041u, 47051u, 47057u, 47059u, 47087u, 47093u, 47111u, + 47119u, 47123u, 47129u, 47137u, 47143u, 47147u, 47149u, 47161u, 47189u, + 47207u, 47221u, 47237u, 47251u, 47269u, 47279u, 47287u, 47293u, 47297u, + 47303u, 47309u, 47317u, 47339u, 47351u, 47353u, 47363u, 47381u, 47387u, + 47389u, 47407u, 47417u, 47419u, 47431u, 47441u, 47459u, 47491u, 47497u, + 47501u, 47507u, 47513u, 47521u, 47527u, 47533u, 47543u, 47563u, 47569u, + 47581u, 47591u, 47599u, 47609u, 47623u, 47629u, 47639u, 47653u, 47657u, + 47659u, 47681u, 47699u, 47701u, 47711u, 47713u, 47717u, 47737u, 47741u, + 47743u, 47777u, 47779u, 47791u, 47797u, 47807u, 47809u, 47819u, 47837u, + 47843u, 47857u, 47869u, 47881u, 47903u, 47911u, 47917u, 47933u, 47939u, + 47947u, 47951u, 47963u, 47969u, 47977u, 47981u, 48017u, 48023u, 48029u, + 48049u, 48073u, 48079u, 48091u, 48109u, 48119u, 48121u, 48131u, 48157u, + 48163u, 48179u, 48187u, 48193u, 48197u, 48221u, 48239u, 48247u, 48259u, + 48271u, 48281u, 48299u, 48311u, 48313u, 48337u, 48341u, 48353u, 48371u, + 48383u, 48397u, 48407u, 48409u, 48413u, 48437u, 48449u, 48463u, 48473u, + 48479u, 48481u, 48487u, 48491u, 48497u, 48523u, 48527u, 48533u, 48539u, + 48541u, 48563u, 48571u, 48589u, 48593u, 48611u, 48619u, 48623u, 48647u, + 48649u, 48661u, 48673u, 48677u, 48679u, 48731u, 48733u, 48751u, 48757u, + 48761u, 48767u, 48779u, 48781u, 48787u, 48799u, 48809u, 48817u, 48821u, + 48823u, 48847u, 48857u, 48859u, 48869u, 48871u, 48883u, 48889u, 48907u, + 48947u, 48953u, 48973u, 48989u, 48991u, 49003u, 49009u, 49019u, 49031u, + 49033u, 49037u, 49043u, 49057u, 49069u, 49081u, 49103u, 49109u, 49117u, + 49121u, 49123u, 49139u, 49157u, 49169u, 49171u, 49177u, 49193u, 49199u, + 49201u, 49207u, 49211u, 49223u, 49253u, 49261u, 49277u, 49279u, 49297u, + 49307u, 49331u, 49333u, 49339u, 49363u, 49367u, 49369u, 49391u, 49393u, + 49409u, 49411u, 49417u, 49429u, 49433u, 49451u, 49459u, 49463u, 49477u, + 49481u, 49499u, 49523u, 49529u, 49531u, 49537u, 49547u, 49549u, 49559u, + 49597u, 49603u, 49613u, 49627u, 49633u, 49639u, 49663u, 49667u, 49669u, + 49681u, 49697u, 49711u, 49727u, 49739u, 49741u, 49747u, 49757u, 49783u, + 49787u, 49789u, 49801u, 49807u, 49811u, 49823u, 49831u, 49843u, 49853u, + 49871u, 49877u, 49891u, 49919u, 49921u, 49927u, 49937u, 49939u, 49943u, + 49957u, 49991u, 49993u, 49999u, 50021u, 50023u, 50033u, 50047u, 50051u, + 50053u, 50069u, 50077u, 50087u, 50093u, 50101u, 50111u, 50119u, 50123u, + 50129u, 50131u, 50147u, 50153u, 50159u, 50177u, 50207u, 50221u, 50227u, + 50231u, 50261u, 50263u, 50273u, 50287u, 50291u, 50311u, 50321u, 50329u, + 50333u, 50341u, 50359u, 50363u, 50377u, 50383u, 50387u, 50411u, 50417u, + 50423u, 50441u, 50459u, 50461u, 50497u, 50503u, 50513u, 50527u, 50539u, + 50543u, 50549u, 50551u, 50581u, 50587u, 50591u, 50593u, 50599u, 50627u, + 50647u, 50651u, 50671u, 50683u, 50707u, 50723u, 50741u, 50753u, 50767u, + 50773u, 50777u, 50789u, 50821u, 50833u, 50839u, 50849u, 50857u, 50867u, + 50873u, 50891u, 50893u, 50909u, 50923u, 50929u, 50951u, 50957u, 50969u, + 50971u, 50989u, 50993u, 51001u, 51031u, 51043u, 51047u, 51059u, 51061u, + 51071u, 51109u, 51131u, 51133u, 51137u, 51151u, 51157u, 51169u, 51193u, + 51197u, 51199u, 51203u, 51217u, 51229u, 51239u, 51241u, 51257u, 51263u, + 51283u, 51287u, 51307u, 51329u, 51341u, 51343u, 51347u, 51349u, 51361u, + 51383u, 51407u, 51413u, 51419u, 51421u, 51427u, 51431u, 51437u, 51439u, + 51449u, 51461u, 51473u, 51479u, 51481u, 51487u, 51503u, 51511u, 51517u, + 51521u, 51539u, 51551u, 51563u, 51577u, 51581u, 51593u, 51599u, 51607u, + 51613u, 51631u, 51637u, 51647u, 51659u, 51673u, 51679u, 51683u, 51691u, + 51713u, 51719u, 51721u, 51749u, 51767u, 51769u, 51787u, 51797u, 51803u, + 51817u, 51827u, 51829u, 51839u, 51853u, 51859u, 51869u, 51871u, 51893u, + 51899u, 51907u, 51913u, 51929u, 51941u, 51949u, 51971u, 51973u, 51977u, + 51991u, 52009u, 52021u, 52027u, 52051u, 52057u, 52067u, 52069u, 52081u, + 52103u, 52121u, 52127u, 52147u, 52153u, 52163u, 52177u, 52181u, 52183u, + 52189u, 52201u, 52223u, 52237u, 52249u, 52253u, 52259u, 52267u, 52289u, + 52291u, 52301u, 52313u, 52321u, 52361u, 52363u, 52369u, 52379u, 52387u, + 52391u, 52433u, 52453u, 52457u, 52489u, 52501u, 52511u, 52517u, 52529u, + 52541u, 52543u, 52553u, 52561u, 52567u, 52571u, 52579u, 52583u, 52609u, + 52627u, 52631u, 52639u, 52667u, 52673u, 52691u, 52697u, 52709u, 52711u, + 52721u, 52727u, 52733u, 52747u, 52757u, 52769u, 52783u, 52807u, 52813u, + 52817u, 52837u, 52859u, 52861u, 52879u, 52883u, 52889u, 52901u, 52903u, + 52919u, 52937u, 52951u, 52957u, 52963u, 52967u, 52973u, 52981u, 52999u, + 53003u, 53017u, 53047u, 53051u, 53069u, 53077u, 53087u, 53089u, 53093u, + 53101u, 53113u, 53117u, 53129u, 53147u, 53149u, 53161u, 53171u, 53173u, + 53189u, 53197u, 53201u, 53231u, 53233u, 53239u, 53267u, 53269u, 53279u, + 53281u, 53299u, 53309u, 53323u, 53327u, 53353u, 53359u, 53377u, 53381u, + 53401u, 53407u, 53411u, 53419u, 53437u, 53441u, 53453u, 53479u, 53503u, + 53507u, 53527u, 53549u, 53551u, 53569u, 53591u, 53593u, 53597u, 53609u, + 53611u, 53617u, 53623u, 53629u, 53633u, 53639u, 53653u, 53657u, 53681u, + 53693u, 53699u, 53717u, 53719u, 53731u, 53759u, 53773u, 53777u, 53783u, + 53791u, 53813u, 53819u, 53831u, 53849u, 53857u, 53861u, 53881u, 53887u, + 53891u, 53897u, 53899u, 53917u, 53923u, 53927u, 53939u, 53951u, 53959u, + 53987u, 53993u, 54001u, 54011u, 54013u, 54037u, 54049u, 54059u, 54083u, + 54091u, 54101u, 54121u, 54133u, 54139u, 54151u, 54163u, 54167u, 54181u, + 54193u, 54217u, 54251u, 54269u, 54277u, 54287u, 54293u, 54311u, 54319u, + 54323u, 54331u, 54347u, 54361u, 54367u, 54371u, 54377u, 54401u, 54403u, + 54409u, 54413u, 54419u, 54421u, 54437u, 54443u, 54449u, 54469u, 54493u, + 54497u, 54499u, 54503u, 54517u, 54521u, 54539u, 54541u, 54547u, 54559u, + 54563u, 54577u, 54581u, 54583u, 54601u, 54617u, 54623u, 54629u, 54631u, + 54647u, 54667u, 54673u, 54679u, 54709u, 54713u, 54721u, 54727u, 54751u, + 54767u, 54773u, 54779u, 54787u, 54799u, 54829u, 54833u, 54851u, 54869u, + 54877u, 54881u, 54907u, 54917u, 54919u, 54941u, 54949u, 54959u, 54973u, + 54979u, 54983u, 55001u, 55009u, 55021u, 55049u, 55051u, 55057u, 55061u, + 55073u, 55079u, 55103u, 55109u, 55117u, 55127u, 55147u, 55163u, 55171u, + 55201u, 55207u, 55213u, 55217u, 55219u, 55229u, 55243u, 55249u, 55259u, + 55291u, 55313u, 55331u, 55333u, 55337u, 55339u, 55343u, 55351u, 55373u, + 55381u, 55399u, 55411u, 55439u, 55441u, 55457u, 55469u, 55487u, 55501u, + 55511u, 55529u, 55541u, 55547u, 55579u, 55589u, 55603u, 55609u, 55619u, + 55621u, 55631u, 55633u, 55639u, 55661u, 55663u, 55667u, 55673u, 55681u, + 55691u, 55697u, 55711u, 55717u, 55721u, 55733u, 55763u, 55787u, 55793u, + 55799u, 55807u, 55813u, 55817u, 55819u, 55823u, 55829u, 55837u, 55843u, + 55849u, 55871u, 55889u, 55897u, 55901u, 55903u, 55921u, 55927u, 55931u, + 55933u, 55949u, 55967u, 55987u, 55997u, 56003u, 56009u, 56039u, 56041u, + 56053u, 56081u, 56087u, 56093u, 56099u, 56101u, 56113u, 56123u, 56131u, + 56149u, 56167u, 56171u, 56179u, 56197u, 56207u, 56209u, 56237u, 56239u, + 56249u, 56263u, 56267u, 56269u, 56299u, 56311u, 56333u, 56359u, 56369u, + 56377u, 56383u, 56393u, 56401u, 56417u, 56431u, 56437u, 56443u, 56453u, + 56467u, 56473u, 56477u, 56479u, 56489u, 56501u, 56503u, 56509u, 56519u, + 56527u, 56531u, 56533u, 56543u, 56569u, 56591u, 56597u, 56599u, 56611u, + 56629u, 56633u, 56659u, 56663u, 56671u, 56681u, 56687u, 56701u, 56711u, + 56713u, 56731u, 56737u, 56747u, 56767u, 56773u, 56779u, 56783u, 56807u, + 56809u, 56813u, 56821u, 56827u, 56843u, 56857u, 56873u, 56891u, 56893u, + 56897u, 56909u, 56911u, 56921u, 56923u, 56929u, 56941u, 56951u, 56957u, + 56963u, 56983u, 56989u, 56993u, 56999u, 57037u, 57041u, 57047u, 57059u, + 57073u, 57077u, 57089u, 57097u, 57107u, 57119u, 57131u, 57139u, 57143u, + 57149u, 57163u, 57173u, 57179u, 57191u, 57193u, 57203u, 57221u, 57223u, + 57241u, 57251u, 57259u, 57269u, 57271u, 57283u, 57287u, 57301u, 57329u, + 57331u, 57347u, 57349u, 57367u, 57373u, 57383u, 57389u, 57397u, 57413u, + 57427u, 57457u, 57467u, 57487u, 57493u, 57503u, 57527u, 57529u, 57557u, + 57559u, 57571u, 57587u, 57593u, 57601u, 57637u, 57641u, 57649u, 57653u, + 57667u, 57679u, 57689u, 57697u, 57709u, 57713u, 57719u, 57727u, 57731u, + 57737u, 57751u, 57773u, 57781u, 57787u, 57791u, 57793u, 57803u, 57809u, + 57829u, 57839u, 57847u, 57853u, 57859u, 57881u, 57899u, 57901u, 57917u, + 57923u, 57943u, 57947u, 57973u, 57977u, 57991u, 58013u, 58027u, 58031u, + 58043u, 58049u, 58057u, 58061u, 58067u, 58073u, 58099u, 58109u, 58111u, + 58129u, 58147u, 58151u, 58153u, 58169u, 58171u, 58189u, 58193u, 58199u, + 58207u, 58211u, 58217u, 58229u, 58231u, 58237u, 58243u, 58271u, 58309u, + 58313u, 58321u, 58337u, 58363u, 58367u, 58369u, 58379u, 58391u, 58393u, + 58403u, 58411u, 58417u, 58427u, 58439u, 58441u, 58451u, 58453u, 58477u, + 58481u, 58511u, 58537u, 58543u, 58549u, 58567u, 58573u, 58579u, 58601u, + 58603u, 58613u, 58631u, 58657u, 58661u, 58679u, 58687u, 58693u, 58699u, + 58711u, 58727u, 58733u, 58741u, 58757u, 58763u, 58771u, 58787u, 58789u, + 58831u, 58889u, 58897u, 58901u, 58907u, 58909u, 58913u, 58921u, 58937u, + 58943u, 58963u, 58967u, 58979u, 58991u, 58997u, 59009u, 59011u, 59021u, + 59023u, 59029u, 59051u, 59053u, 59063u, 59069u, 59077u, 59083u, 59093u, + 59107u, 59113u, 59119u, 59123u, 59141u, 59149u, 59159u, 59167u, 59183u, + 59197u, 59207u, 59209u, 59219u, 59221u, 59233u, 59239u, 59243u, 59263u, + 59273u, 59281u, 59333u, 59341u, 59351u, 59357u, 59359u, 59369u, 59377u, + 59387u, 59393u, 59399u, 59407u, 59417u, 59419u, 59441u, 59443u, 59447u, + 59453u, 59467u, 59471u, 59473u, 59497u, 59509u, 59513u, 59539u, 59557u, + 59561u, 59567u, 59581u, 59611u, 59617u, 59621u, 59627u, 59629u, 59651u, + 59659u, 59663u, 59669u, 59671u, 59693u, 59699u, 59707u, 59723u, 59729u, + 59743u, 59747u, 59753u, 59771u, 59779u, 59791u, 59797u, 59809u, 59833u, + 59863u, 59879u, 59887u, 59921u, 59929u, 59951u, 59957u, 59971u, 59981u, + 59999u, 60013u, 60017u, 60029u, 60037u, 60041u, 60077u, 60083u, 60089u, + 60091u, 60101u, 60103u, 60107u, 60127u, 60133u, 60139u, 60149u, 60161u, + 60167u, 60169u, 60209u, 60217u, 60223u, 60251u, 60257u, 60259u, 60271u, + 60289u, 60293u, 60317u, 60331u, 60337u, 60343u, 60353u, 60373u, 60383u, + 60397u, 60413u, 60427u, 60443u, 60449u, 60457u, 60493u, 60497u, 60509u, + 60521u, 60527u, 60539u, 60589u, 60601u, 60607u, 60611u, 60617u, 60623u, + 60631u, 60637u, 60647u, 60649u, 60659u, 60661u, 60679u, 60689u, 60703u, + 60719u, 60727u, 60733u, 60737u, 60757u, 60761u, 60763u, 60773u, 60779u, + 60793u, 60811u, 60821u, 60859u, 60869u, 60887u, 60889u, 60899u, 60901u, + 60913u, 60917u, 60919u, 60923u, 60937u, 60943u, 60953u, 60961u, 61001u, + 61007u, 61027u, 61031u, 61043u, 61051u, 61057u, 61091u, 61099u, 61121u, + 61129u, 61141u, 61151u, 61153u, 61169u, 61211u, 61223u, 61231u, 61253u, + 61261u, 61283u, 61291u, 61297u, 61331u, 61333u, 61339u, 61343u, 61357u, + 61363u, 61379u, 61381u, 61403u, 61409u, 61417u, 61441u, 61463u, 61469u, + 61471u, 61483u, 61487u, 61493u, 61507u, 61511u, 61519u, 61543u, 61547u, + 61553u, 61559u, 61561u, 61583u, 61603u, 61609u, 61613u, 61627u, 61631u, + 61637u, 61643u, 61651u, 61657u, 61667u, 61673u, 61681u, 61687u, 61703u, + 61717u, 61723u, 61729u, 61751u, 61757u, 61781u, 61813u, 61819u, 61837u, + 61843u, 61861u, 61871u, 61879u, 61909u, 61927u, 61933u, 61949u, 61961u, + 61967u, 61979u, 61981u, 61987u, 61991u, 62003u, 62011u, 62017u, 62039u, + 62047u, 62053u, 62057u, 62071u, 62081u, 62099u, 62119u, 62129u, 62131u, + 62137u, 62141u, 62143u, 62171u, 62189u, 62191u, 62201u, 62207u, 62213u, + 62219u, 62233u, 62273u, 62297u, 62299u, 62303u, 62311u, 62323u, 62327u, + 62347u, 62351u, 62383u, 62401u, 62417u, 62423u, 62459u, 62467u, 62473u, + 62477u, 62483u, 62497u, 62501u, 62507u, 62533u, 62539u, 62549u, 62563u, + 62581u, 62591u, 62597u, 62603u, 62617u, 62627u, 62633u, 62639u, 62653u, + 62659u, 62683u, 62687u, 62701u, 62723u, 62731u, 62743u, 62753u, 62761u, + 62773u, 62791u, 62801u, 62819u, 62827u, 62851u, 62861u, 62869u, 62873u, + 62897u, 62903u, 62921u, 62927u, 62929u, 62939u, 62969u, 62971u, 62981u, + 62983u, 62987u, 62989u, 63029u, 63031u, 63059u, 63067u, 63073u, 63079u, + 63097u, 63103u, 63113u, 63127u, 63131u, 63149u, 63179u, 63197u, 63199u, + 63211u, 63241u, 63247u, 63277u, 63281u, 63299u, 63311u, 63313u, 63317u, + 63331u, 63337u, 63347u, 63353u, 63361u, 63367u, 63377u, 63389u, 63391u, + 63397u, 63409u, 63419u, 63421u, 63439u, 63443u, 63463u, 63467u, 63473u, + 63487u, 63493u, 63499u, 63521u, 63527u, 63533u, 63541u, 63559u, 63577u, + 63587u, 63589u, 63599u, 63601u, 63607u, 63611u, 63617u, 63629u, 63647u, + 63649u, 63659u, 63667u, 63671u, 63689u, 63691u, 63697u, 63703u, 63709u, + 63719u, 63727u, 63737u, 63743u, 63761u, 63773u, 63781u, 63793u, 63799u, + 63803u, 63809u, 63823u, 63839u, 63841u, 63853u, 63857u, 63863u, 63901u, + 63907u, 63913u, 63929u, 63949u, 63977u, 63997u, 64007u, 64013u, 64019u, + 64033u, 64037u, 64063u, 64067u, 64081u, 64091u, 64109u, 64123u, 64151u, + 64153u, 64157u, 64171u, 64187u, 64189u, 64217u, 64223u, 64231u, 64237u, + 64271u, 64279u, 64283u, 64301u, 64303u, 64319u, 64327u, 64333u, 64373u, + 64381u, 64399u, 64403u, 64433u, 64439u, 64451u, 64453u, 64483u, 64489u, + 64499u, 64513u, 64553u, 64567u, 64577u, 64579u, 64591u, 64601u, 64609u, + 64613u, 64621u, 64627u, 64633u, 64661u, 64663u, 64667u, 64679u, 64693u, + 64709u, 64717u, 64747u, 64763u, 64781u, 64783u, 64793u, 64811u, 64817u, + 64849u, 64853u, 64871u, 64877u, 64879u, 64891u, 64901u, 64919u, 64921u, + 64927u, 64937u, 64951u, 64969u, 64997u, 65003u, 65011u, 65027u, 65029u, + 65033u, 65053u, 65063u, 65071u, 65089u, 65099u, 65101u, 65111u, 65119u, + 65123u, 65129u, 65141u, 65147u, 65167u, 65171u, 65173u, 65179u, 65183u, + 65203u, 65213u, 65239u, 65257u, 65267u, 65269u, 65287u, 65293u, 65309u, + 65323u, 65327u, 65353u, 65357u, 65371u, 65381u, 65393u, 65407u, 65413u, + 65419u, 65423u, 65437u, 65447u, 65449u, 65479u, 65497u, 65519u, 65521u + }}; + template + const std::array prime_data_imp::a3 = {{ + 2u, 4u, 8u, 16u, 22u, 28u, 44u, + 46u, 52u, 64u, 74u, 82u, 94u, 98u, 112u, + 116u, 122u, 142u, 152u, 164u, 166u, 172u, 178u, + 182u, 184u, 194u, 196u, 226u, 242u, 254u, 274u, + 292u, 296u, 302u, 304u, 308u, 316u, 332u, 346u, + 364u, 386u, 392u, 394u, 416u, 422u, 428u, 446u, + 448u, 458u, 494u, 502u, 506u, 512u, 532u, 536u, + 548u, 554u, 568u, 572u, 574u, 602u, 626u, 634u, + 638u, 644u, 656u, 686u, 704u, 736u, 758u, 766u, + 802u, 808u, 812u, 824u, 826u, 838u, 842u, 848u, + 868u, 878u, 896u, 914u, 922u, 928u, 932u, 956u, + 964u, 974u, 988u, 994u, 998u, 1006u, 1018u, 1034u, + 1036u, 1052u, 1058u, 1066u, 1082u, 1094u, 1108u, 1118u, + 1148u, 1162u, 1166u, 1178u, 1186u, 1198u, 1204u, 1214u, + 1216u, 1228u, 1256u, 1262u, 1274u, 1286u, 1306u, 1316u, + 1318u, 1328u, 1342u, 1348u, 1354u, 1384u, 1388u, 1396u, + 1408u, 1412u, 1414u, 1424u, 1438u, 1442u, 1468u, 1486u, + 1498u, 1508u, 1514u, 1522u, 1526u, 1538u, 1544u, 1568u, + 1586u, 1594u, 1604u, 1606u, 1618u, 1622u, 1634u, 1646u, + 1652u, 1654u, 1676u, 1678u, 1682u, 1684u, 1696u, 1712u, + 1726u, 1736u, 1738u, 1754u, 1772u, 1804u, 1808u, 1814u, + 1834u, 1856u, 1864u, 1874u, 1876u, 1886u, 1892u, 1894u, + 1898u, 1912u, 1918u, 1942u, 1946u, 1954u, 1958u, 1964u, + 1976u, 1988u, 1996u, 2002u, 2012u, 2024u, 2032u, 2042u, + 2044u, 2054u, 2066u, 2072u, 2084u, 2096u, 2116u, 2144u, + 2164u, 2174u, 2188u, 2198u, 2206u, 2216u, 2222u, 2224u, + 2228u, 2242u, 2248u, 2254u, 2266u, 2272u, 2284u, 2294u, + 2308u, 2318u, 2332u, 2348u, 2356u, 2366u, 2392u, 2396u, + 2398u, 2404u, 2408u, 2422u, 2426u, 2432u, 2444u, 2452u, + 2458u, 2488u, 2506u, 2518u, 2524u, 2536u, 2552u, 2564u, + 2576u, 2578u, 2606u, 2612u, 2626u, 2636u, 2672u, 2674u, + 2678u, 2684u, 2692u, 2704u, 2726u, 2744u, 2746u, 2776u, + 2794u, 2816u, 2836u, 2854u, 2864u, 2902u, 2908u, 2912u, + 2914u, 2938u, 2942u, 2948u, 2954u, 2956u, 2966u, 2972u, + 2986u, 2996u, 3004u, 3008u, 3032u, 3046u, 3062u, 3076u, + 3098u, 3104u, 3124u, 3134u, 3148u, 3152u, 3164u, 3176u, + 3178u, 3194u, 3202u, 3208u, 3214u, 3232u, 3236u, 3242u, + 3256u, 3278u, 3284u, 3286u, 3328u, 3344u, 3346u, 3356u, + 3362u, 3364u, 3368u, 3374u, 3382u, 3392u, 3412u, 3428u, + 3458u, 3466u, 3476u, 3484u, 3494u, 3496u, 3526u, 3532u, + 3538u, 3574u, 3584u, 3592u, 3608u, 3614u, 3616u, 3628u, + 3656u, 3658u, 3662u, 3668u, 3686u, 3698u, 3704u, 3712u, + 3722u, 3724u, 3728u, 3778u, 3782u, 3802u, 3806u, 3836u, + 3844u, 3848u, 3854u, 3866u, 3868u, 3892u, 3896u, 3904u, + 3922u, 3928u, 3932u, 3938u, 3946u, 3956u, 3958u, 3962u, + 3964u, 4004u, 4022u, 4058u, 4088u, 4118u, 4126u, 4142u, + 4156u, 4162u, 4174u, 4202u, 4204u, 4226u, 4228u, 4232u, + 4244u, 4274u, 4286u, 4292u, 4294u, 4298u, 4312u, 4322u, + 4324u, 4342u, 4364u, 4376u, 4394u, 4396u, 4406u, 4424u, + 4456u, 4462u, 4466u, 4468u, 4474u, 4484u, 4504u, 4516u, + 4526u, 4532u, 4544u, 4564u, 4576u, 4582u, 4586u, 4588u, + 4604u, 4606u, 4622u, 4628u, 4642u, 4646u, 4648u, 4664u, + 4666u, 4672u, 4688u, 4694u, 4702u, 4706u, 4714u, 4736u, + 4754u, 4762u, 4774u, 4778u, 4786u, 4792u, 4816u, 4838u, + 4844u, 4846u, 4858u, 4888u, 4894u, 4904u, 4916u, 4922u, + 4924u, 4946u, 4952u, 4954u, 4966u, 4972u, 4994u, 5002u, + 5014u, 5036u, 5038u, 5048u, 5054u, 5072u, 5084u, 5086u, + 5092u, 5104u, 5122u, 5128u, 5132u, 5152u, 5174u, 5182u, + 5194u, 5218u, 5234u, 5248u, 5258u, 5288u, 5306u, 5308u, + 5314u, 5318u, 5332u, 5342u, 5344u, 5356u, 5366u, 5378u, + 5384u, 5386u, 5402u, 5414u, 5416u, 5422u, 5434u, 5444u, + 5446u, 5456u, 5462u, 5464u, 5476u, 5488u, 5504u, 5524u, + 5534u, 5546u, 5554u, 5584u, 5594u, 5608u, 5612u, 5618u, + 5626u, 5632u, 5636u, 5656u, 5674u, 5698u, 5702u, 5714u, + 5722u, 5726u, 5728u, 5752u, 5758u, 5782u, 5792u, 5794u, + 5798u, 5804u, 5806u, 5812u, 5818u, 5824u, 5828u, 5852u, + 5854u, 5864u, 5876u, 5878u, 5884u, 5894u, 5902u, 5908u, + 5918u, 5936u, 5938u, 5944u, 5948u, 5968u, 5992u, 6002u, + 6014u, 6016u, 6028u, 6034u, 6058u, 6062u, 6098u, 6112u, + 6128u, 6136u, 6158u, 6164u, 6172u, 6176u, 6178u, 6184u, + 6206u, 6226u, 6242u, 6254u, 6272u, 6274u, 6286u, 6302u, + 6308u, 6314u, 6326u, 6332u, 6344u, 6346u, 6352u, 6364u, + 6374u, 6382u, 6398u, 6406u, 6412u, 6428u, 6436u, 6448u, + 6452u, 6458u, 6464u, 6484u, 6496u, 6508u, 6512u, 6518u, + 6538u, 6542u, 6554u, 6556u, 6566u, 6568u, 6574u, 6604u, + 6626u, 6632u, 6634u, 6638u, 6676u, 6686u, 6688u, 6692u, + 6694u, 6716u, 6718u, 6734u, 6736u, 6742u, 6752u, 6772u, + 6778u, 6802u, 6806u, 6818u, 6832u, 6844u, 6848u, 6886u, + 6896u, 6926u, 6932u, 6934u, 6946u, 6958u, 6962u, 6968u, + 6998u, 7012u, 7016u, 7024u, 7042u, 7078u, 7082u, 7088u, + 7108u, 7112u, 7114u, 7126u, 7136u, 7138u, 7144u, 7154u, + 7166u, 7172u, 7184u, 7192u, 7198u, 7204u, 7228u, 7232u, + 7262u, 7282u, 7288u, 7324u, 7334u, 7336u, 7348u, 7354u, + 7358u, 7366u, 7372u, 7376u, 7388u, 7396u, 7402u, 7414u, + 7418u, 7424u, 7438u, 7442u, 7462u, 7474u, 7478u, 7484u, + 7502u, 7504u, 7508u, 7526u, 7528u, 7544u, 7556u, 7586u, + 7592u, 7598u, 7606u, 7646u, 7654u, 7702u, 7708u, 7724u, + 7742u, 7756u, 7768u, 7774u, 7792u, 7796u, 7816u, 7826u, + 7828u, 7834u, 7844u, 7852u, 7882u, 7886u, 7898u, 7918u, + 7924u, 7936u, 7942u, 7948u, 7982u, 7988u, 7994u, 8012u, + 8018u, 8026u, 8036u, 8048u, 8054u, 8062u, 8072u, 8074u, + 8078u, 8102u, 8108u, 8116u, 8138u, 8144u, 8146u, 8158u, + 8164u, 8174u, 8186u, 8192u, 8216u, 8222u, 8236u, 8248u, + 8284u, 8288u, 8312u, 8314u, 8324u, 8332u, 8342u, 8348u, + 8362u, 8372u, 8404u, 8408u, 8416u, 8426u, 8438u, 8464u, + 8482u, 8486u, 8492u, 8512u, 8516u, 8536u, 8542u, 8558u, + 8564u, 8566u, 8596u, 8608u, 8614u, 8624u, 8626u, 8632u, + 8642u, 8654u, 8662u, 8666u, 8668u, 8674u, 8684u, 8696u, + 8722u, 8744u, 8752u, 8758u, 8762u, 8776u, 8782u, 8788u, + 8818u, 8822u, 8828u, 8842u, 8846u, 8848u, 8876u, 8878u, + 8884u, 8906u, 8914u, 8918u, 8936u, 8954u, 8972u, 8974u, + 8986u, 8992u, 8996u, 9016u, 9026u, 9032u, 9038u, 9052u, + 9062u, 9074u, 9076u, 9088u, 9118u, 9152u, 9164u, 9172u, + 9178u, 9182u, 9184u, 9194u, 9196u, 9212u, 9224u, 9226u, + 9236u, 9244u, 9262u, 9286u, 9292u, 9296u, 9308u, 9322u, + 9326u, 9334u, 9338u, 9352u, 9356u, 9362u, 9368u, 9388u, + 9394u, 9398u, 9406u, 9424u, 9476u, 9478u, 9482u, 9494u, + 9502u, 9506u, 9544u, 9548u, 9574u, 9598u, 9614u, 9626u, + 9632u, 9634u, 9646u, 9658u, 9674u, 9676u, 9682u, 9688u, + 9692u, 9704u, 9718u, 9734u, 9742u, 9754u, 9772u, 9788u, + 9794u, 9802u, 9812u, 9818u, 9832u, 9842u, 9854u, 9856u, + 9866u, 9868u, 9872u, 9896u, 9902u, 9944u, 9968u, 9976u, + 9986u, 9992u, 9998u, 10004u, 10006u, 10018u, 10022u, 10036u, + 10042u, 10048u, 10076u, 10082u, 10084u, 10094u, 10106u, 10118u, + 10124u, 10144u, 10148u, 10154u, 10168u, 10172u, 10174u, 10186u, + 10196u, 10208u, 10232u, 10238u, 10246u, 10252u, 10258u, 10262u, + 10286u, 10298u, 10318u, 10334u, 10348u, 10378u, 10396u, 10402u, + 10406u, 10432u, 10444u, 10448u, 10454u, 10456u, 10462u, 10466u, + 10468u, 10496u, 10504u, 10544u, 10546u, 10556u, 10564u, 10568u, + 10588u, 10594u, 10612u, 10622u, 10624u, 10628u, 10672u, 10678u, + 10696u, 10708u, 10714u, 10718u, 10724u, 10726u, 10748u, 10754u, + 10768u, 10798u, 10808u, 10832u, 10834u, 10844u, 10852u, 10868u, + 10886u, 10888u, 10906u, 10928u, 10936u, 10946u, 10952u, 10958u, + 10972u, 10976u, 10984u, 11002u, 11006u, 11008u, 11026u, 11044u, + 11062u, 11068u, 11072u, 11096u, 11114u, 11116u, 11132u, 11138u, + 11144u, 11162u, 11182u, 11198u, 11218u, 11222u, 11236u, 11242u, + 11246u, 11266u, 11284u, 11294u, 11296u, 11302u, 11312u, 11336u, + 11338u, 11348u, 11372u, 11378u, 11384u, 11408u, 11414u, 11426u, + 11428u, 11456u, 11468u, 11482u, 11488u, 11494u, 11506u, 11512u, + 11534u, 11546u, 11558u, 11566u, 11602u, 11606u, 11618u, 11632u, + 11636u, 11656u, 11666u, 11678u, 11702u, 11704u, 11708u, 11714u, + 11726u, 11728u, 11732u, 11734u, 11744u, 11756u, 11782u, 11788u, + 11804u, 11812u, 11816u, 11824u, 11834u, 11842u, 11848u, 11882u, + 11884u, 11896u, 11912u, 11936u, 11942u, 11944u, 11954u, 11956u, + 11974u, 11978u, 11986u, 11992u, 12008u, 12014u, 12016u, 12022u, + 12028u, 12034u, 12038u, 12052u, 12056u, 12076u, 12082u, 12086u, + 12106u, 12112u, 12124u, 12146u, 12152u, 12154u, 12164u, 12176u, + 12178u, 12184u, 12188u, 12196u, 12208u, 12212u, 12226u, 12238u, + 12248u, 12262u, 12266u, 12278u, 12304u, 12314u, 12328u, 12332u, + 12358u, 12364u, 12394u, 12398u, 12416u, 12434u, 12442u, 12448u, + 12464u, 12472u, 12482u, 12496u, 12506u, 12514u, 12524u, 12544u, + 12566u, 12586u, 12602u, 12604u, 12622u, 12628u, 12632u, 12638u, + 12644u, 12656u, 12658u, 12668u, 12694u, 12698u, 12706u, 12724u, + 12742u, 12748u, 12766u, 12772u, 12776u, 12782u, 12806u, 12812u, + 12832u, 12866u, 12892u, 12902u, 12904u, 12932u, 12944u, 12952u, + 12962u, 12974u, 12976u, 12982u, 13004u, 13006u, 13018u, 13034u, + 13036u, 13042u, 13048u, 13058u, 13072u, 13088u, 13108u, 13114u, + 13118u, 13156u, 13162u, 13172u, 13178u, 13186u, 13202u, 13244u, + 13246u, 13252u, 13256u, 13262u, 13268u, 13274u, 13288u, 13304u, + 13318u, 13322u, 13342u, 13352u, 13354u, 13358u, 13366u, 13384u, + 13394u, 13406u, 13442u, 13444u, 13454u, 13496u, 13504u, 13508u, + 13528u, 13552u, 13568u, 13576u, 13598u, 13604u, 13612u, 13616u, + 13618u, 13624u, 13646u, 13652u, 13658u, 13666u, 13694u, 13696u, + 13706u, 13724u, 13738u, 13744u, 13748u, 13766u, 13774u, 13784u, + 13798u, 13802u, 13814u, 13822u, 13832u, 13844u, 13858u, 13862u, + 13864u, 13876u, 13888u, 13892u, 13898u, 13916u, 13946u, 13958u, + 13996u, 14002u, 14014u, 14024u, 14026u, 14044u, 14054u, 14066u, + 14074u, 14078u, 14086u, 14092u, 14096u, 14098u, 14122u, 14134u, + 14152u, 14156u, 14158u, 14162u, 14164u, 14222u, 14234u, 14242u, + 14266u, 14276u, 14278u, 14282u, 14288u, 14294u, 14306u, 14308u, + 14312u, 14326u, 14332u, 14338u, 14354u, 14366u, 14368u, 14372u, + 14404u, 14408u, 14432u, 14438u, 14444u, 14452u, 14462u, 14464u, + 14486u, 14504u, 14516u, 14536u, 14542u, 14572u, 14576u, 14606u, + 14612u, 14614u, 14618u, 14632u, 14638u, 14642u, 14656u, 14672u, + 14674u, 14686u, 14696u, 14698u, 14704u, 14716u, 14728u, 14738u, + 14744u, 14752u, 14774u, 14782u, 14794u, 14806u, 14812u, 14828u, + 14834u, 14852u, 14872u, 14894u, 14912u, 14914u, 14936u, 14938u, + 14954u, 14956u, 14978u, 14992u, 15002u, 15022u, 15032u, 15064u, + 15068u, 15076u, 15086u, 15092u, 15094u, 15116u, 15122u, 15134u, + 15136u, 15142u, 15146u, 15148u, 15152u, 15166u, 15178u, 15202u, + 15212u, 15214u, 15226u, 15242u, 15244u, 15248u, 15254u, 15268u, + 15274u, 15284u, 15296u, 15298u, 15314u, 15328u, 15362u, 15374u, + 15376u, 15382u, 15388u, 15394u, 15398u, 15418u, 15428u, 15454u, + 15466u, 15478u, 15482u, 15484u, 15488u, 15496u, 15506u, 15508u, + 15512u, 15514u, 15536u, 15542u, 15548u, 15562u, 15566u, 15584u, + 15596u, 15622u, 15628u, 15638u, 15646u, 15662u, 15664u, 15668u, + 15688u, 15698u, 15704u, 15746u, 15748u, 15758u, 15764u, 15772u, + 15796u, 15808u, 15814u, 15818u, 15824u, 15836u, 15838u, 15866u, + 15874u, 15886u, 15904u, 15922u, 15928u, 15974u, 15982u, 15992u, + 15998u, 16012u, 16016u, 16018u, 16024u, 16028u, 16034u, 16076u, + 16084u, 16094u, 16102u, 16112u, 16114u, 16132u, 16136u, 16142u, + 16154u, 16166u, 16168u, 16172u, 16192u, 16202u, 16214u, 16226u, + 16234u, 16238u, 16264u, 16282u, 16304u, 16312u, 16318u, 16334u, + 16348u, 16364u, 16366u, 16384u, 16394u, 16396u, 16402u, 16408u, + 16418u, 16432u, 16436u, 16438u, 16468u, 16472u, 16474u, 16478u, + 16486u, 16496u, 16502u, 16504u, 16516u, 16532u, 16538u, 16594u, + 16604u, 16606u, 16618u, 16628u, 16636u, 16648u, 16654u, 16658u, + 16672u, 16682u, 16684u, 16688u, 16696u, 16702u, 16706u, 16726u, + 16732u, 16744u, 16766u, 16772u, 16804u, 16814u, 16816u, 16826u, + 16838u, 16852u, 16858u, 16886u, 16922u, 16928u, 16934u, 16936u, + 16948u, 16952u, 16958u, 16964u, 16972u, 16994u, 16996u, 17014u, + 17024u, 17026u, 17032u, 17036u, 17056u, 17066u, 17074u, 17078u, + 17084u, 17098u, 17116u, 17122u, 17164u, 17186u, 17188u, 17192u, + 17194u, 17222u, 17224u, 17228u, 17246u, 17252u, 17258u, 17264u, + 17276u, 17278u, 17302u, 17312u, 17348u, 17354u, 17356u, 17368u, + 17378u, 17404u, 17428u, 17446u, 17462u, 17468u, 17474u, 17488u, + 17512u, 17524u, 17528u, 17536u, 17542u, 17554u, 17558u, 17566u, + 17582u, 17602u, 17642u, 17668u, 17672u, 17684u, 17686u, 17692u, + 17696u, 17698u, 17708u, 17722u, 17732u, 17734u, 17738u, 17764u, + 17776u, 17804u, 17806u, 17822u, 17848u, 17854u, 17864u, 17866u, + 17872u, 17882u, 17888u, 17896u, 17902u, 17908u, 17914u, 17924u, + 17936u, 17942u, 17962u, 18002u, 18022u, 18026u, 18028u, 18044u, + 18056u, 18062u, 18074u, 18082u, 18086u, 18104u, 18106u, 18118u, + 18128u, 18154u, 18166u, 18182u, 18184u, 18202u, 18226u, 18238u, + 18242u, 18256u, 18278u, 18298u, 18308u, 18322u, 18334u, 18338u, + 18356u, 18368u, 18376u, 18386u, 18398u, 18404u, 18434u, 18448u, + 18452u, 18476u, 18482u, 18512u, 18518u, 18524u, 18526u, 18532u, + 18554u, 18586u, 18592u, 18596u, 18602u, 18608u, 18628u, 18644u, + 18646u, 18656u, 18664u, 18676u, 18686u, 18688u, 18694u, 18704u, + 18712u, 18728u, 18764u, 18772u, 18778u, 18782u, 18784u, 18812u, + 18814u, 18842u, 18854u, 18856u, 18866u, 18872u, 18886u, 18896u, + 18902u, 18908u, 18914u, 18922u, 18928u, 18932u, 18946u, 18964u, + 18968u, 18974u, 18986u, 18988u, 18998u, 19016u, 19024u, 19054u, + 19094u, 19096u, 19114u, 19118u, 19124u, 19138u, 19156u, 19162u, + 19166u, 19178u, 19184u, 19196u, 19202u, 19216u, 19226u, 19252u, + 19258u, 19274u, 19276u, 19292u, 19322u, 19324u, 19334u, 19336u, + 19378u, 19384u, 19412u, 19426u, 19432u, 19442u, 19444u, 19456u, + 19474u, 19486u, 19492u, 19502u, 19514u, 19526u, 19546u, 19552u, + 19556u, 19558u, 19568u, 19574u, 19586u, 19598u, 19612u, 19624u, + 19658u, 19664u, 19666u, 19678u, 19688u, 19694u, 19702u, 19708u, + 19712u, 19724u, 19762u, 19768u, 19778u, 19796u, 19798u, 19826u, + 19828u, 19834u, 19846u, 19876u, 19892u, 19894u, 19904u, 19912u, + 19916u, 19918u, 19934u, 19952u, 19978u, 19982u, 19988u, 19996u, + 20014u, 20036u, 20042u, 20062u, 20066u, 20072u, 20084u, 20086u, + 20092u, 20104u, 20108u, 20126u, 20132u, 20134u, 20156u, 20168u, + 20176u, 20182u, 20198u, 20216u, 20246u, 20258u, 20282u, 20284u, + 20294u, 20296u, 20302u, 20308u, 20312u, 20318u, 20354u, 20368u, + 20374u, 20396u, 20398u, 20456u, 20464u, 20476u, 20482u, 20492u, + 20494u, 20534u, 20542u, 20548u, 20576u, 20578u, 20582u, 20596u, + 20602u, 20608u, 20626u, 20636u, 20644u, 20648u, 20662u, 20666u, + 20674u, 20704u, 20708u, 20714u, 20722u, 20728u, 20734u, 20752u, + 20756u, 20758u, 20762u, 20776u, 20788u, 20806u, 20816u, 20818u, + 20822u, 20834u, 20836u, 20846u, 20854u, 20864u, 20878u, 20888u, + 20906u, 20918u, 20926u, 20932u, 20942u, 20956u, 20966u, 20974u, + 20996u, 20998u, 21004u, 21026u, 21038u, 21044u, 21052u, 21064u, + 21092u, 21094u, 21142u, 21154u, 21158u, 21176u, 21184u, 21194u, + 21208u, 21218u, 21232u, 21236u, 21248u, 21278u, 21302u, 21308u, + 21316u, 21322u, 21326u, 21334u, 21388u, 21392u, 21394u, 21404u, + 21416u, 21424u, 21434u, 21446u, 21458u, 21476u, 21478u, 21502u, + 21506u, 21514u, 21536u, 21548u, 21568u, 21572u, 21584u, 21586u, + 21598u, 21614u, 21616u, 21644u, 21646u, 21652u, 21676u, 21686u, + 21688u, 21716u, 21718u, 21722u, 21742u, 21746u, 21758u, 21764u, + 21778u, 21782u, 21788u, 21802u, 21824u, 21848u, 21868u, 21872u, + 21886u, 21892u, 21898u, 21908u, 21938u, 21946u, 21956u, 21974u, + 21976u, 21982u, 21988u, 22004u, 22006u, 22012u, 22018u, 22022u, + 22024u, 22048u, 22052u, 22054u, 22078u, 22088u, 22094u, 22096u, + 22106u, 22108u, 22114u, 22136u, 22144u, 22148u, 22156u, 22162u, + 22166u, 22184u, 22186u, 22204u, 22208u, 22216u, 22232u, 22258u, + 22262u, 22268u, 22276u, 22298u, 22318u, 22334u, 22342u, 22346u, + 22352u, 22376u, 22382u, 22396u, 22408u, 22424u, 22426u, 22438u, + 22442u, 22456u, 22466u, 22468u, 22472u, 22484u, 22502u, 22534u, + 22544u, 22558u, 22582u, 22594u, 22634u, 22642u, 22676u, 22688u, + 22702u, 22706u, 22724u, 22726u, 22754u, 22766u, 22786u, 22792u, + 22802u, 22804u, 22844u, 22862u, 22876u, 22888u, 22892u, 22928u, + 22934u, 22936u, 22958u, 22964u, 22978u, 22988u, 23012u, 23054u, + 23056u, 23072u, 23074u, 23108u, 23116u, 23122u, 23126u, 23128u, + 23132u, 23146u, 23186u, 23194u, 23206u, 23212u, 23236u, 23254u, + 23258u, 23264u, 23266u, 23272u, 23276u, 23278u, 23282u, 23284u, + 23308u, 23318u, 23326u, 23332u, 23338u, 23348u, 23362u, 23368u, + 23384u, 23402u, 23416u, 23434u, 23458u, 23462u, 23468u, 23474u, + 23482u, 23486u, 23506u, 23516u, 23522u, 23534u, 23536u, 23548u, + 23552u, 23566u, 23572u, 23578u, 23584u, 23588u, 23602u, 23618u, + 23654u, 23668u, 23674u, 23678u, 23692u, 23696u, 23702u, 23726u, + 23734u, 23738u, 23758u, 23768u, 23782u, 23794u, 23828u, 23836u, + 23846u, 23852u, 23858u, 23864u, 23878u, 23882u, 23896u, 23908u, + 23914u, 23924u, 23942u, 23956u, 23966u, 23978u, 23984u, 23986u, + 23992u, 23998u, 24026u, 24028u, 24032u, 24056u, 24062u, 24064u, + 24068u, 24076u, 24092u, 24098u, 24118u, 24122u, 24124u, 24134u, + 24136u, 24146u, 24154u, 24218u, 24224u, 24232u, 24244u, 24248u, + 24262u, 24274u, 24284u, 24286u, 24298u, 24304u, 24314u, 24332u, + 24356u, 24362u, 24364u, 24374u, 24382u, 24388u, 24404u, 24424u, + 24428u, 24442u, 24448u, 24454u, 24466u, 24472u, 24476u, 24482u, + 24484u, 24488u, 24496u, 24518u, 24524u, 24532u, 24536u, 24538u, + 24554u, 24572u, 24586u, 24592u, 24614u, 24628u, 24638u, 24652u, + 24656u, 24662u, 24664u, 24668u, 24682u, 24692u, 24704u, 24712u, + 24728u, 24736u, 24746u, 24754u, 24778u, 24818u, 24824u, 24836u, + 24838u, 24844u, 24862u, 24866u, 24868u, 24872u, 24902u, 24904u, + 24934u, 24938u, 24946u, 24964u, 24976u, 24988u, 24992u, 24994u, + 24998u, 25012u, 25048u, 25064u, 25082u, 25084u, 25096u, 25106u, + 25112u, 25124u, 25142u, 25144u, 25162u, 25168u, 25174u, 25196u, + 25214u, 25252u, 25258u, 25268u, 25286u, 25288u, 25298u, 25306u, + 25312u, 25328u, 25352u, 25366u, 25372u, 25376u, 25382u, 25396u, + 25412u, 25436u, 25442u, 25454u, 25462u, 25474u, 25484u, 25498u, + 25544u, 25546u, 25562u, 25564u, 25586u, 25592u, 25594u, 25604u, + 25606u, 25616u, 25618u, 25624u, 25628u, 25648u, 25658u, 25664u, + 25694u, 25702u, 25708u, 25714u, 25718u, 25748u, 25756u, 25762u, + 25768u, 25774u, 25796u, 25832u, 25834u, 25838u, 25846u, 25852u, + 25858u, 25862u, 25876u, 25888u, 25898u, 25918u, 25922u, 25924u, + 25928u, 25958u, 25964u, 25978u, 25994u, 26006u, 26036u, 26038u, + 26042u, 26048u, 26056u, 26086u, 26096u, 26104u, 26138u, 26156u, + 26168u, 26176u, 26198u, 26218u, 26222u, 26236u, 26246u, 26266u, + 26272u, 26276u, 26278u, 26288u, 26302u, 26306u, 26332u, 26338u, + 26374u, 26386u, 26404u, 26408u, 26416u, 26422u, 26426u, 26432u, + 26434u, 26462u, 26468u, 26474u, 26498u, 26506u, 26516u, 26542u, + 26548u, 26572u, 26576u, 26584u, 26608u, 26618u, 26638u, 26642u, + 26644u, 26654u, 26668u, 26684u, 26686u, 26692u, 26698u, 26702u, + 26708u, 26716u, 26734u, 26762u, 26776u, 26782u, 26798u, 26812u, + 26818u, 26822u, 26828u, 26834u, 26842u, 26846u, 26848u, 26852u, + 26864u, 26866u, 26878u, 26884u, 26896u, 26924u, 26926u, 26932u, + 26944u, 26954u, 26968u, 26972u, 27016u, 27022u, 27032u, 27034u, + 27046u, 27058u, 27088u, 27092u, 27104u, 27106u, 27112u, 27122u, + 27134u, 27136u, 27146u, 27148u, 27158u, 27164u, 27172u, 27182u, + 27188u, 27202u, 27218u, 27226u, 27232u, 27244u, 27254u, 27256u, + 27266u, 27274u, 27286u, 27296u, 27314u, 27322u, 27326u, 27328u, + 27332u, 27358u, 27364u, 27386u, 27392u, 27406u, 27416u, 27422u, + 27424u, 27452u, 27458u, 27466u, 27512u, 27518u, 27524u, 27542u, + 27548u, 27554u, 27562u, 27568u, 27578u, 27596u, 27598u, 27604u, + 27616u, 27634u, 27644u, 27652u, 27664u, 27694u, 27704u, 27706u, + 27716u, 27718u, 27722u, 27728u, 27746u, 27748u, 27752u, 27772u, + 27784u, 27788u, 27794u, 27802u, 27836u, 27842u, 27848u, 27872u, + 27884u, 27892u, 27928u, 27944u, 27946u, 27952u, 27956u, 27958u, + 27962u, 27968u, 27988u, 27994u, 28018u, 28022u, 28024u, 28028u, + 28046u, 28066u, 28072u, 28094u, 28102u, 28148u, 28166u, 28168u, + 28184u, 28204u, 28226u, 28228u, 28252u, 28274u, 28276u, 28292u, + 28316u, 28336u, 28352u, 28354u, 28358u, 28366u, 28376u, 28378u, + 28388u, 28402u, 28406u, 28414u, 28432u, 28436u, 28444u, 28448u, + 28462u, 28472u, 28474u, 28498u, 28514u, 28522u, 28528u, 28544u, + 28564u, 28574u, 28576u, 28582u, 28586u, 28616u, 28618u, 28634u, + 28666u, 28672u, 28684u, 28694u, 28718u, 28726u, 28738u, 28756u, + 28772u, 28774u, 28786u, 28792u, 28796u, 28808u, 28814u, 28816u, + 28844u, 28862u, 28864u, 28886u, 28892u, 28898u, 28904u, 28906u, + 28912u, 28928u, 28942u, 28948u, 28978u, 28994u, 28996u, 29006u, + 29008u, 29012u, 29024u, 29026u, 29038u, 29048u, 29062u, 29068u, + 29078u, 29086u, 29114u, 29116u, 29152u, 29158u, 29174u, 29188u, + 29192u, 29212u, 29236u, 29242u, 29246u, 29254u, 29258u, 29276u, + 29284u, 29288u, 29302u, 29306u, 29312u, 29314u, 29338u, 29354u, + 29368u, 29372u, 29398u, 29414u, 29416u, 29426u, 29458u, 29464u, + 29468u, 29474u, 29486u, 29492u, 29528u, 29536u, 29548u, 29552u, + 29554u, 29558u, 29566u, 29572u, 29576u, 29596u, 29608u, 29618u, + 29642u, 29654u, 29656u, 29668u, 29678u, 29684u, 29696u, 29698u, + 29704u, 29722u, 29726u, 29732u, 29738u, 29744u, 29752u, 29776u, + 29782u, 29792u, 29804u, 29834u, 29848u, 29858u, 29866u, 29878u, + 29884u, 29894u, 29906u, 29908u, 29926u, 29932u, 29936u, 29944u, + 29948u, 29972u, 29992u, 29996u, 30004u, 30014u, 30026u, 30034u, + 30046u, 30062u, 30068u, 30082u, 30086u, 30094u, 30098u, 30116u, + 30166u, 30172u, 30178u, 30182u, 30188u, 30196u, 30202u, 30212u, + 30238u, 30248u, 30254u, 30256u, 30266u, 30268u, 30278u, 30284u, + 30322u, 30334u, 30338u, 30346u, 30356u, 30376u, 30382u, 30388u, + 30394u, 30412u, 30422u, 30424u, 30436u, 30452u, 30454u, 30466u, + 30478u, 30482u, 30508u, 30518u, 30524u, 30544u, 30562u, 30602u, + 30614u, 30622u, 30632u, 30644u, 30646u, 30664u, 30676u, 30686u, + 30688u, 30698u, 30724u, 30728u, 30734u, 30746u, 30754u, 30758u, + 30788u, 30794u, 30796u, 30802u, 30818u, 30842u, 30866u, 30884u, + 30896u, 30908u, 30916u, 30922u, 30926u, 30934u, 30944u, 30952u, + 30958u, 30962u, 30982u, 30992u, 31018u, 31022u, 31046u, 31052u, + 31054u, 31066u, 31108u, 31126u, 31132u, 31136u, 31162u, 31168u, + 31196u, 31202u, 31204u, 31214u, 31222u, 31228u, 31234u, 31244u, + 31252u, 31262u, 31264u, 31286u, 31288u, 31292u, 31312u, 31316u, + 31322u, 31358u, 31372u, 31376u, 31396u, 31418u, 31424u, 31438u, + 31444u, 31454u, 31462u, 31466u, 31468u, 31472u, 31486u, 31504u, + 31538u, 31546u, 31568u, 31582u, 31592u, 31616u, 31622u, 31624u, + 31634u, 31636u, 31642u, 31652u, 31678u, 31696u, 31706u, 31724u, + 31748u, 31766u, 31768u, 31792u, 31832u, 31834u, 31838u, 31844u, + 31846u, 31852u, 31862u, 31888u, 31894u, 31906u, 31918u, 31924u, + 31928u, 31964u, 31966u, 31976u, 31988u, 32012u, 32014u, 32018u, + 32026u, 32036u, 32042u, 32044u, 32048u, 32072u, 32074u, 32078u, + 32114u, 32116u, 32138u, 32152u, 32176u, 32194u, 32236u, 32242u, + 32252u, 32254u, 32278u, 32294u, 32306u, 32308u, 32312u, 32314u, + 32324u, 32326u, 32336u, 32344u, 32348u, 32384u, 32392u, 32396u, + 32408u, 32426u, 32432u, 32438u, 32452u, 32474u, 32476u, 32482u, + 32506u, 32512u, 32522u, 32546u, 32566u, 32588u, 32594u, 32608u, + 32644u, 32672u, 32678u, 32686u, 32692u, 32716u, 32722u, 32734u, + 32762u, 32764u, 32782u, 32786u, 32788u, 32792u, 32812u, 32834u, + 32842u, 32852u, 32854u, 32872u, 32876u, 32884u, 32894u, 32908u, + 32918u, 32924u, 32932u, 32938u, 32944u, 32956u, 32972u, 32984u, + 32998u, 33008u, 33026u, 33028u, 33038u, 33062u, 33086u, 33092u, + 33104u, 33106u, 33128u, 33134u, 33154u, 33176u, 33178u, 33182u, + 33194u, 33196u, 33202u, 33238u, 33244u, 33266u, 33272u, 33274u, + 33302u, 33314u, 33332u, 33334u, 33338u, 33352u, 33358u, 33362u, + 33364u, 33374u, 33376u, 33392u, 33394u, 33404u, 33412u, 33418u, + 33428u, 33446u, 33458u, 33464u, 33478u, 33482u, 33488u, 33506u, + 33518u, 33544u, 33548u, 33554u, 33568u, 33574u, 33584u, 33596u, + 33598u, 33602u, 33604u, 33614u, 33638u, 33646u, 33656u, 33688u, + 33698u, 33706u, 33716u, 33722u, 33724u, 33742u, 33754u, 33782u, + 33812u, 33814u, 33832u, 33836u, 33842u, 33856u, 33862u, 33866u, + 33874u, 33896u, 33904u, 33934u, 33952u, 33962u, 33988u, 33992u, + 33994u, 34016u, 34024u, 34028u, 34036u, 34042u, 34046u, 34072u, + 34076u, 34088u, 34108u, 34126u, 34132u, 34144u, 34154u, 34172u, + 34174u, 34178u, 34184u, 34186u, 34198u, 34226u, 34232u, 34252u, + 34258u, 34274u, 34282u, 34288u, 34294u, 34298u, 34304u, 34324u, + 34336u, 34342u, 34346u, 34366u, 34372u, 34388u, 34394u, 34426u, + 34436u, 34454u, 34456u, 34468u, 34484u, 34508u, 34514u, 34522u, + 34534u, 34568u, 34574u, 34594u, 34616u, 34618u, 34634u, 34648u, + 34654u, 34658u, 34672u, 34678u, 34702u, 34732u, 34736u, 34744u, + 34756u, 34762u, 34778u, 34798u, 34808u, 34822u, 34826u, 34828u, + 34844u, 34856u, 34858u, 34868u, 34876u, 34882u, 34912u, 34924u, + 34934u, 34948u, 34958u, 34966u, 34976u, 34982u, 34984u, 34988u, + 35002u, 35012u, 35014u, 35024u, 35056u, 35074u, 35078u, 35086u, + 35114u, 35134u, 35138u, 35158u, 35164u, 35168u, 35198u, 35206u, + 35212u, 35234u, 35252u, 35264u, 35266u, 35276u, 35288u, 35294u, + 35312u, 35318u, 35372u, 35378u, 35392u, 35396u, 35402u, 35408u, + 35422u, 35446u, 35452u, 35464u, 35474u, 35486u, 35492u, 35516u, + 35528u, 35546u, 35554u, 35572u, 35576u, 35578u, 35582u, 35584u, + 35606u, 35614u, 35624u, 35626u, 35638u, 35648u, 35662u, 35668u, + 35672u, 35674u, 35686u, 35732u, 35738u, 35744u, 35746u, 35752u, + 35758u, 35788u, 35798u, 35806u, 35812u, 35824u, 35828u, 35842u, + 35848u, 35864u, 35876u, 35884u, 35894u, 35914u, 35932u, 35942u, + 35948u, 35954u, 35966u, 35968u, 35978u, 35992u, 35996u, 35998u, + 36002u, 36026u, 36038u, 36046u, 36064u, 36068u, 36076u, 36092u, + 36106u, 36118u, 36128u, 36146u, 36158u, 36166u, 36184u, 36188u, + 36202u, 36206u, 36212u, 36214u, 36236u, 36254u, 36262u, 36272u, + 36298u, 36302u, 36304u, 36328u, 36334u, 36338u, 36344u, 36356u, + 36382u, 36386u, 36394u, 36404u, 36422u, 36428u, 36442u, 36452u, + 36464u, 36466u, 36478u, 36484u, 36488u, 36496u, 36508u, 36524u, + 36526u, 36536u, 36542u, 36544u, 36566u, 36568u, 36572u, 36586u, + 36604u, 36614u, 36626u, 36646u, 36656u, 36662u, 36664u, 36668u, + 36682u, 36694u, 36698u, 36706u, 36716u, 36718u, 36724u, 36758u, + 36764u, 36766u, 36782u, 36794u, 36802u, 36824u, 36832u, 36862u, + 36872u, 36874u, 36898u, 36902u, 36916u, 36926u, 36946u, 36962u, + 36964u, 36968u, 36988u, 36998u, 37004u, 37012u, 37016u, 37024u, + 37028u, 37052u, 37058u, 37072u, 37076u, 37108u, 37112u, 37118u, + 37132u, 37138u, 37142u, 37144u, 37166u, 37226u, 37228u, 37234u, + 37258u, 37262u, 37276u, 37294u, 37306u, 37324u, 37336u, 37342u, + 37346u, 37376u, 37378u, 37394u, 37396u, 37418u, 37432u, 37448u, + 37466u, 37472u, 37508u, 37514u, 37532u, 37534u, 37544u, 37552u, + 37556u, 37558u, 37564u, 37588u, 37606u, 37636u, 37642u, 37648u, + 37682u, 37696u, 37702u, 37754u, 37756u, 37772u, 37784u, 37798u, + 37814u, 37822u, 37852u, 37856u, 37858u, 37864u, 37874u, 37886u, + 37888u, 37916u, 37922u, 37936u, 37948u, 37976u, 37994u, 38014u, + 38018u, 38026u, 38032u, 38038u, 38042u, 38048u, 38056u, 38078u, + 38084u, 38108u, 38116u, 38122u, 38134u, 38146u, 38152u, 38164u, + 38168u, 38188u, 38234u, 38252u, 38266u, 38276u, 38278u, 38302u, + 38306u, 38308u, 38332u, 38354u, 38368u, 38378u, 38384u, 38416u, + 38428u, 38432u, 38434u, 38444u, 38446u, 38456u, 38458u, 38462u, + 38468u, 38474u, 38486u, 38498u, 38512u, 38518u, 38524u, 38552u, + 38554u, 38572u, 38578u, 38584u, 38588u, 38612u, 38614u, 38626u, + 38638u, 38644u, 38648u, 38672u, 38696u, 38698u, 38704u, 38708u, + 38746u, 38752u, 38762u, 38774u, 38776u, 38788u, 38792u, 38812u, + 38834u, 38846u, 38848u, 38858u, 38864u, 38882u, 38924u, 38936u, + 38938u, 38944u, 38956u, 38978u, 38992u, 39002u, 39008u, 39014u, + 39016u, 39026u, 39044u, 39058u, 39062u, 39088u, 39104u, 39116u, + 39124u, 39142u, 39146u, 39148u, 39158u, 39166u, 39172u, 39176u, + 39182u, 39188u, 39194u + }}; +#else +template +constexpr std::array prime_data_imp::a1; +template +constexpr std::array prime_data_imp::a2; +template +constexpr std::array prime_data_imp::a3; +#endif + + using prime_data = prime_data_imp; + + template + BOOST_MATH_CONSTEXPR_TABLE_FUNCTION std::uint32_t prime(unsigned n, const Policy& pol) + { + + if(n <= prime_data::b1) + return prime_data::a1[n]; + if(n <= prime_data::b2) + return prime_data::a2[n - prime_data::b1 - 1]; + if(n >= prime_data::b3) + { + return boost::math::policies::raise_domain_error("boost::math::prime<%1%>", "Argument n out of range: got %1%", n, pol); + } + return static_cast(prime_data::a3[n - prime_data::b2 - 1]) + 0xFFFFu; + } + + inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION std::uint32_t prime(unsigned n) + { + return boost::math::prime(n, boost::math::policies::policy<>()); + } + + static const unsigned max_prime = 9999; + +}} // namespace boost and math + +#endif // BOOST_MATH_SF_PRIME_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/relative_difference.hpp b/third-party/boost-math/include/boost/math/special_functions/relative_difference.hpp new file mode 100644 index 0000000000000..f0f02a893cc50 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/relative_difference.hpp @@ -0,0 +1,134 @@ +// (C) Copyright John Maddock 2006, 2015 +// 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) + +#ifndef BOOST_MATH_RELATIVE_ERROR +#define BOOST_MATH_RELATIVE_ERROR + +#include +#include +#include + +namespace boost{ + namespace math{ + + template + typename boost::math::tools::promote_args::type relative_difference(const T& arg_a, const U& arg_b) + { + typedef typename boost::math::tools::promote_args::type result_type; + result_type a = arg_a; + result_type b = arg_b; + BOOST_MATH_STD_USING +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + // + // If math.h has no long double support we can't rely + // on the math functions generating exponents outside + // the range of a double: + // + result_type min_val = (std::max)( + tools::min_value(), + static_cast((std::numeric_limits::min)())); + result_type max_val = (std::min)( + tools::max_value(), + static_cast((std::numeric_limits::max)())); +#else + result_type min_val = tools::min_value(); + result_type max_val = tools::max_value(); +#endif + // Screen out NaN's first, if either value is a NaN then the distance is "infinite": + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + return max_val; + // Screen out infinities: + if(fabs(b) > max_val) + { + if(fabs(a) > max_val) + return (a < 0) == (b < 0) ? 0 : max_val; // one infinity is as good as another! + else + return max_val; // one infinity and one finite value implies infinite difference + } + else if(fabs(a) > max_val) + return max_val; // one infinity and one finite value implies infinite difference + + // + // If the values have different signs, treat as infinite difference: + // + if(((a < 0) != (b < 0)) && (a != 0) && (b != 0)) + return max_val; + a = fabs(a); + b = fabs(b); + // + // Now deal with zero's, if one value is zero (or denorm) then treat it the same as + // min_val for the purposes of the calculation that follows: + // + if(a < min_val) + a = min_val; + if(b < min_val) + b = min_val; + + return (std::max)(fabs((a - b) / a), fabs((a - b) / b)); + } + +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (LDBL_MAX_EXP <= DBL_MAX_EXP) + template <> + inline boost::math::tools::promote_args::type relative_difference(const double& arg_a, const double& arg_b) + { + BOOST_MATH_STD_USING + double a = arg_a; + double b = arg_b; + // + // On Mac OS X we evaluate "double" functions at "long double" precision, + // but "long double" actually has a very slightly narrower range than "double"! + // Therefore use the range of "long double" as our limits since results outside + // that range may have been truncated to 0 or INF: + // + double min_val = (std::max)((double)tools::min_value(), tools::min_value()); + double max_val = (std::min)((double)tools::max_value(), tools::max_value()); + + // Screen out NaN's first, if either value is a NaN then the distance is "infinite": + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + return max_val; + // Screen out infinities: + if(fabs(b) > max_val) + { + if(fabs(a) > max_val) + return 0; // one infinity is as good as another! + else + return max_val; // one infinity and one finite value implies infinite difference + } + else if(fabs(a) > max_val) + return max_val; // one infinity and one finite value implies infinite difference + + // + // If the values have different signs, treat as infinite difference: + // + if(((a < 0) != (b < 0)) && (a != 0) && (b != 0)) + return max_val; + a = fabs(a); + b = fabs(b); + // + // Now deal with zero's, if one value is zero (or denorm) then treat it the same as + // min_val for the purposes of the calculation that follows: + // + if(a < min_val) + a = min_val; + if(b < min_val) + b = min_val; + + return (std::max)(fabs((a - b) / a), fabs((a - b) / b)); + } +#endif + + template + inline typename boost::math::tools::promote_args::type epsilon_difference(const T& arg_a, const U& arg_b) + { + typedef typename boost::math::tools::promote_args::type result_type; + result_type r = relative_difference(arg_a, arg_b); + if(tools::max_value() * boost::math::tools::epsilon() < r) + return tools::max_value(); + return r / boost::math::tools::epsilon(); + } +} // namespace math +} // namespace boost + +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/round.hpp b/third-party/boost-math/include/boost/math/special_functions/round.hpp new file mode 100644 index 0000000000000..bb99da7e31717 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/round.hpp @@ -0,0 +1,353 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2023. +// 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) + +#ifndef BOOST_MATH_ROUND_HPP +#define BOOST_MATH_ROUND_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MATH_NO_CCMATH) && !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION) +#include +# define BOOST_MATH_HAS_CONSTEXPR_LDEXP +#endif + +namespace boost{ namespace math{ + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t round(const T& v, const Policy& pol, const std::false_type&) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + if(!(boost::math::isfinite)(v)) + { + return policies::raise_rounding_error("boost::math::round<%1%>(%1%)", nullptr, static_cast(v), static_cast(v), pol); + } + // + // The logic here is rather convoluted, but avoids a number of traps, + // see discussion here https://github.com/boostorg/math/pull/8 + // + if (T(-0.5) < v && v < T(0.5)) + { + // special case to avoid rounding error on the direct + // predecessor of +0.5 resp. the direct successor of -0.5 in + // IEEE floating point types + return static_cast(0); + } + else if (v > 0) + { + // subtract v from ceil(v) first in order to avoid rounding + // errors on largest representable integer numbers + result_type c(ceil(v)); + return T(0.5) < c - v ? c - 1 : c; + } + else + { + // see former branch + result_type f(floor(v)); + return T(0.5) < v - f ? f + 1 : f; + } +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t round(const T& v, const Policy&, const std::true_type&) +{ + return v; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t round(const T& v, const Policy& pol) +{ + return detail::round(v, pol, std::integral_constant::value>()); +} +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t round(const T& v) +{ + return round(v, policies::policy<>()); +} +// +// The following functions will not compile unless T has an +// implicit conversion to the integer types. For user-defined +// number types this will likely not be the case. In that case +// these functions should either be specialized for the UDT in +// question, or else overloads should be placed in the same +// namespace as the UDT: these will then be found via argument +// dependent lookup. See our concept archetypes for examples. +// +// Non-standard numeric limits syntax "(std::numeric_limits::max)()" +// is to avoid macro substiution from MSVC +// https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax +// +template +inline int iround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + result_type r = boost::math::round(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} +template +BOOST_MATH_GPU_ENABLED inline int iround(const T& v) +{ + return iround(v, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline long lround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + result_type r = boost::math::round(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} +template +BOOST_MATH_GPU_ENABLED inline long lround(const T& v) +{ + return lround(v, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline long long llround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = boost::math::tools::promote_args_t; + + result_type r = boost::math::round(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} +template +BOOST_MATH_GPU_ENABLED inline long long llround(const T& v) +{ + return llround(v, policies::policy<>()); +} + +}} // namespaces + +#else // Specialized NVRTC overloads + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED T round(T x) +{ + return ::round(x); +} + +template <> +BOOST_MATH_GPU_ENABLED float round(float x) +{ + return ::roundf(x); +} + +template +BOOST_MATH_GPU_ENABLED T round(T x, const Policy&) +{ + return ::round(x); +} + +template +BOOST_MATH_GPU_ENABLED float round(float x, const Policy&) +{ + return ::roundf(x); +} + +template +BOOST_MATH_GPU_ENABLED int iround(T x) +{ + return static_cast(::lround(x)); +} + +template <> +BOOST_MATH_GPU_ENABLED int iround(float x) +{ + return static_cast(::lroundf(x)); +} + +template +BOOST_MATH_GPU_ENABLED int iround(T x, const Policy&) +{ + return static_cast(::lround(x)); +} + +template +BOOST_MATH_GPU_ENABLED int iround(float x, const Policy&) +{ + return static_cast(::lroundf(x)); +} + +template +BOOST_MATH_GPU_ENABLED long lround(T x) +{ + return ::lround(x); +} + +template <> +BOOST_MATH_GPU_ENABLED long lround(float x) +{ + return ::lroundf(x); +} + +template +BOOST_MATH_GPU_ENABLED long lround(T x, const Policy&) +{ + return ::lround(x); +} + +template +BOOST_MATH_GPU_ENABLED long lround(float x, const Policy&) +{ + return ::lroundf(x); +} + +template +BOOST_MATH_GPU_ENABLED long long llround(T x) +{ + return ::llround(x); +} + +template <> +BOOST_MATH_GPU_ENABLED long long llround(float x) +{ + return ::llroundf(x); +} + +template +BOOST_MATH_GPU_ENABLED long long llround(T x, const Policy&) +{ + return ::llround(x); +} + +template +BOOST_MATH_GPU_ENABLED long long llround(float x, const Policy&) +{ + return ::llroundf(x); +} + +} // Namespace math +} // Namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif // BOOST_MATH_ROUND_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/rsqrt.hpp b/third-party/boost-math/include/boost/math/special_functions/rsqrt.hpp new file mode 100644 index 0000000000000..b42fa12bc8365 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/rsqrt.hpp @@ -0,0 +1,52 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_RSQRT_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_RSQRT_HPP +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +# include +# ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +# error "The header can only be used in C++17 and later." +# endif +#endif + +namespace boost::math { + +template +inline Real rsqrt(Real const & x) +{ + using std::sqrt; + if constexpr (std::is_arithmetic_v && !std::is_integral_v) + { + return 1/sqrt(x); + } + else + { + // if it's so tiny it rounds to 0 as long double, + // no performance gains are possible: + if (x < std::numeric_limits::denorm_min() || x > (std::numeric_limits::max)()) { + return 1/sqrt(x); + } + Real x0 = 1/sqrt(static_cast(x)); + // Divide by 512 for leeway: + Real s = sqrt(std::numeric_limits::epsilon())*x0/512; + Real x1 = x0 + x0*(1-x*x0*x0)/2; + while(abs(x1 - x0) > s) { + x0 = x1; + x1 = x0 + x0*(1-x*x0*x0)/2; + } + // Final iteration get ~2ULPs: + return x1 + x1*(1-x*x1*x1)/2;; + } +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/special_functions/sign.hpp b/third-party/boost-math/include/boost/math/special_functions/sign.hpp new file mode 100644 index 0000000000000..4f76522654fb5 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/sign.hpp @@ -0,0 +1,241 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Johan Rade 2006. +// (C) Copyright Paul A. Bristow 2011 (added changesign). +// (C) Copyright Matt Borland 2024 + +// 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) + +#ifndef BOOST_MATH_TOOLS_SIGN_HPP +#define BOOST_MATH_TOOLS_SIGN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#ifndef __CUDACC_RTC__ + +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail { + + // signbit + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + BOOST_MATH_GPU_ENABLED inline int signbit_impl(T x, native_tag const&) + { + using std::signbit; + return (signbit)(x) ? 1 : 0; + } +#endif + + // Generic versions first, note that these do not handle + // signed zero or NaN. + + template + BOOST_MATH_GPU_ENABLED inline int signbit_impl(T x, generic_tag const&) + { + return x < 0; + } + + template + BOOST_MATH_GPU_ENABLED inline int signbit_impl(T x, generic_tag const&) + { + return x < 0; + } + +#if defined(__GNUC__) && (LDBL_MANT_DIG == 106) + // + // Special handling for GCC's "double double" type, + // in this case the sign is the same as the sign we + // get by casting to double, no overflow/underflow + // can occur since the exponents are the same magnitude + // for the two types: + // + inline int signbit_impl(long double x, generic_tag const&) + { + return (boost::math::signbit)(static_cast(x)); + } + inline int signbit_impl(long double x, generic_tag const&) + { + return (boost::math::signbit)(static_cast(x)); + } +#endif + + template + BOOST_MATH_GPU_ENABLED inline int signbit_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + return a & traits::sign ? 1 : 0; + } + + template + BOOST_MATH_GPU_ENABLED inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + + return a & traits::sign ? 1 : 0; + } + + // Changesign + + // Generic versions first, note that these do not handle + // signed zero or NaN. + + template + BOOST_MATH_GPU_ENABLED inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } + + template + BOOST_MATH_GPU_ENABLED inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } +#if defined(__GNUC__) && (LDBL_MANT_DIG == 106) + // + // Special handling for GCC's "double double" type, + // in this case we need to change the sign of both + // components of the "double double": + // + inline long double (changesign_impl)(long double x, generic_tag const&) + { + double* pd = reinterpret_cast(&x); + pd[0] = boost::math::changesign(pd[0]); + pd[1] = boost::math::changesign(pd[1]); + return x; + } + inline long double (changesign_impl)(long double x, generic_tag const&) + { + double* pd = reinterpret_cast(&x); + pd[0] = boost::math::changesign(pd[0]); + pd[1] = boost::math::changesign(pd[1]); + return x; + } +#endif + + template + BOOST_MATH_GPU_ENABLED inline T changesign_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::sign_change_type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + template + BOOST_MATH_GPU_ENABLED inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::sign_change_type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED int (signbit)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + return detail::signbit_impl(static_cast(x), method()); +} + +template +BOOST_MATH_GPU_ENABLED inline int sign BOOST_NO_MACRO_EXPAND(const T& z) +{ + return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1; +} + +template +BOOST_MATH_GPU_ENABLED typename tools::promote_args_permissive::type (changesign)(const T& x) +{ //!< \brief return unchanged binary pattern of x, except for change of sign bit. + typedef typename detail::fp_traits::sign_change_type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + + return detail::changesign_impl(static_cast(x), method()); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args_permissive::type + copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y) +{ + BOOST_MATH_STD_USING + typedef typename tools::promote_args_permissive::type result_type; + return (boost::math::signbit)(static_cast(x)) != (boost::math::signbit)(static_cast(y)) + ? (boost::math::changesign)(static_cast(x)) : static_cast(x); +} + +} // namespace math +} // namespace boost + +#else // NVRTC alias versions + +#include + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED int signbit(T x) +{ + return ::signbit(x); +} + +template +BOOST_MATH_GPU_ENABLED T changesign(T x) +{ + return -x; +} + +template +BOOST_MATH_GPU_ENABLED T copysign(T x, T y) +{ + return ::copysign(x, y); +} + +template <> +BOOST_MATH_GPU_ENABLED float copysign(float x, float y) +{ + return ::copysignf(x, y); +} + +template +BOOST_MATH_GPU_ENABLED T sign(T z) +{ + return (z == 0) ? 0 : ::signbit(z) ? -1 : 1; +} + +} // namespace math +} // namespace boost + +#endif // __CUDACC_RTC__ + +#endif // BOOST_MATH_TOOLS_SIGN_HPP + + diff --git a/third-party/boost-math/include/boost/math/special_functions/sin_pi.hpp b/third-party/boost-math/include/boost/math/special_functions/sin_pi.hpp new file mode 100644 index 0000000000000..e59e232e6dd23 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/sin_pi.hpp @@ -0,0 +1,136 @@ +// Copyright (c) 2007 John Maddock +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_SIN_PI_HPP +#define BOOST_MATH_SIN_PI_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline T sin_pi_imp(T x, const Policy&) +{ + BOOST_MATH_STD_USING // ADL of std names + // sin of pi*x: + if(x < T(0.5)) + return sin(constants::pi() * x); + bool invert; + if(x < 1) + { + invert = true; + x = -x; + } + else + invert = false; + + T rem = floor(x); + if(abs(floor(rem/2)*2 - rem) > boost::math::numeric_limits::epsilon()) + { + invert = !invert; + } + rem = x - rem; + if(rem > 0.5f) + rem = 1 - rem; + if(rem == 0.5f) + return static_cast(invert ? -1 : 1); + + rem = sin(constants::pi() * rem); + return invert ? T(-rem) : rem; +} + +template +BOOST_MATH_GPU_ENABLED inline T sin_pi_dispatch(T x, const Policy& pol) +{ + if (x < T(0)) + { + return -sin_pi_imp(T(-x), pol); + } + else + { + return sin_pi_imp(T(x), pol); + } +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type sin_pi(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<>, + // We want to ignore overflows since the result is in [-1,1] and the + // check slows the code down considerably. + policies::overflow_error >::type forwarding_policy; + return policies::checked_narrowing_cast(boost::math::detail::sin_pi_dispatch(x, forwarding_policy()), "sin_pi"); +} + +template +inline typename tools::promote_args::type sin_pi(T x) +{ + return boost::math::sin_pi(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#else // Special handling for NVRTC + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED auto sin_pi(T x) +{ + return ::sinpi(x); +} + +template <> +BOOST_MATH_GPU_ENABLED auto sin_pi(float x) +{ + return ::sinpif(x); +} + +template +BOOST_MATH_GPU_ENABLED auto sin_pi(T x, const Policy&) +{ + return ::sinpi(x); +} + +template +BOOST_MATH_GPU_ENABLED auto sin_pi(float x, const Policy&) +{ + return ::sinpif(x); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif + diff --git a/third-party/boost-math/include/boost/math/special_functions/sinc.hpp b/third-party/boost-math/include/boost/math/special_functions/sinc.hpp new file mode 100644 index 0000000000000..0c18ac34685e8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/sinc.hpp @@ -0,0 +1,123 @@ +// boost sinc.hpp header file + +// (C) Copyright Hubert Holin 2001. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_SINC_HPP +#define BOOST_SINC_HPP + + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +// These are the the "Sinus Cardinal" functions. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the "Sinus Cardinal" of index Pi. + + template + BOOST_MATH_GPU_ENABLED inline T sinc_pi_imp(const T x) + { + BOOST_MATH_STD_USING + + if ((boost::math::isinf)(x)) + { + return 0; + } + else if (abs(x) >= T(3.3) * tools::forth_root_epsilon()) + { + return(sin(x)/x); + } + else + { + // |x| < (eps*120)^(1/4) + return 1 - x * x / 6; + } + } + + } // namespace detail + + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type sinc_pi(T x) + { + typedef typename tools::promote_args::type result_type; + return detail::sinc_pi_imp(static_cast(x)); + } + + template + BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type sinc_pi(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + return detail::sinc_pi_imp(static_cast(x)); + } + + template class U> + BOOST_MATH_GPU_ENABLED inline U sinc_pi(const U x) + { + BOOST_MATH_STD_USING + + T const taylor_0_bound = tools::epsilon(); + T const taylor_2_bound = tools::root_epsilon(); + T const taylor_n_bound = tools::forth_root_epsilon(); + + if (abs(x) >= taylor_n_bound) + { + return(sin(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 + #ifdef __MWERKS__ + U result = static_cast >(1); + #else + U result = U(1); + #endif + + if (abs(x) >= taylor_0_bound) + { + U x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result -= x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + + template class U, class Policy> + BOOST_MATH_GPU_ENABLED inline U sinc_pi(const U x, const Policy&) + { + return sinc_pi(x); + } + } +} + +#endif /* BOOST_SINC_HPP */ + diff --git a/third-party/boost-math/include/boost/math/special_functions/sinhc.hpp b/third-party/boost-math/include/boost/math/special_functions/sinhc.hpp new file mode 100644 index 0000000000000..b8c5f9f2e4f1c --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/sinhc.hpp @@ -0,0 +1,142 @@ +// boost sinhc.hpp header file + +// (C) Copyright Hubert Holin 2001. +// 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_SINHC_HPP +#define BOOST_SINHC_HPP + + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// These are the the "Hyperbolic Sinus Cardinal" functions. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the "Hyperbolic Sinus Cardinal" of index Pi. + + template + inline T sinhc_pi_imp(const T x, const Policy&) + { + using ::std::abs; + using ::std::sinh; + using ::std::sqrt; + + static T const taylor_0_bound = tools::epsilon(); + static T const taylor_2_bound = sqrt(taylor_0_bound); + static T const taylor_n_bound = sqrt(taylor_2_bound); + + if((boost::math::isinf)(x)) + { + return policies::raise_overflow_error("sinhc(%1%)", nullptr, Policy()); + } + if (abs(x) >= taylor_n_bound) + { + return(sinh(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 + T result = static_cast(1); + + if (abs(x) >= taylor_0_bound) + { + T x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result += x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + + } // namespace detail + + template + inline typename tools::promote_args::type sinhc_pi(T x, const Policy& pol) + { + typedef typename tools::promote_args::type result_type; + return policies::checked_narrowing_cast(detail::sinhc_pi_imp(static_cast(x), pol), "sinhc(%1%)"); + } + + template + inline typename tools::promote_args::type sinhc_pi(T x) + { + typedef typename tools::promote_args::type result_type; + return sinhc_pi(static_cast(x), policies::policy<>()); + } + + template class U> + inline U sinhc_pi(const U x) + { + using std::abs; + using std::sinh; + using std::sqrt; + + using ::std::numeric_limits; + + static T const taylor_0_bound = tools::epsilon(); + static T const taylor_2_bound = sqrt(taylor_0_bound); + static T const taylor_n_bound = sqrt(taylor_2_bound); + + if (abs(x) >= taylor_n_bound) + { + return(sinh(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 +#ifdef __MWERKS__ + U result = static_cast >(1); +#else + U result = U(1); +#endif + + if (abs(x) >= taylor_0_bound) + { + U x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result += x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + } +} + +#endif /* BOOST_SINHC_HPP */ + diff --git a/third-party/boost-math/include/boost/math/special_functions/spherical_harmonic.hpp b/third-party/boost-math/include/boost/math/special_functions/spherical_harmonic.hpp new file mode 100644 index 0000000000000..5da926575789f --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/spherical_harmonic.hpp @@ -0,0 +1,205 @@ + +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SPECIAL_SPHERICAL_HARMONIC_HPP +#define BOOST_MATH_SPECIAL_SPHERICAL_HARMONIC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +namespace detail{ + +// +// Calculates the prefix term that's common to the real +// and imaginary parts. Does *not* fix up the sign of the result +// though. +// +template +inline T spherical_harmonic_prefix(unsigned n, unsigned m, T theta, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(m > n) + return 0; + + T sin_theta = sin(theta); + T x = cos(theta); + + T leg = detail::legendre_p_imp(n, m, x, static_cast(pow(fabs(sin_theta), T(m))), pol); + + T prefix = boost::math::tgamma_delta_ratio(static_cast(n - m + 1), static_cast(2 * m), pol); + prefix *= (2 * n + 1) / (4 * constants::pi()); + prefix = sqrt(prefix); + return prefix * leg; +} +// +// Real Part: +// +template +T spherical_harmonic_r(unsigned n, int m, T theta, T phi, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions + + bool sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + sign = m&1; + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + T mod = boost::math::tools::fmod_workaround(theta, T(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + sign = !sign; + } + // Get the value and adjust sign as required: + T prefix = spherical_harmonic_prefix(n, m, theta, pol); + prefix *= cos(m * phi); + return sign ? T(-prefix) : prefix; +} + +template +T spherical_harmonic_i(unsigned n, int m, T theta, T phi, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions + + bool sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + sign = !(m&1); + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + T mod = boost::math::tools::fmod_workaround(theta, T(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + sign = !sign; + } + // Get the value and adjust sign as required: + T prefix = spherical_harmonic_prefix(n, m, theta, pol); + prefix *= sin(m * phi); + return sign ? T(-prefix) : prefix; +} + +template +std::complex spherical_harmonic(unsigned n, int m, U theta, U phi, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Sort out the signs: + // + bool r_sign = false; + bool i_sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + r_sign = m&1; + i_sign = !(m&1); + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + U mod = boost::math::tools::fmod_workaround(theta, U(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + { + r_sign = !r_sign; + i_sign = !i_sign; + } + } + // + // Calculate the value: + // + U prefix = spherical_harmonic_prefix(n, m, theta, pol); + U r = prefix * cos(m * phi); + U i = prefix * sin(m * phi); + // + // Add in the signs: + // + if(r_sign) + r = -r; + if(i_sign) + i = -i; + static const char* function = "boost::math::spherical_harmonic<%1%>(int, int, %1%, %1%)"; + return std::complex(policies::checked_narrowing_cast(r, function), policies::checked_narrowing_cast(i, function)); +} + +} // namespace detail + +template +inline std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return detail::spherical_harmonic(n, m, static_cast(theta), static_cast(phi), pol); +} + +template +inline std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic(n, m, theta, phi, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::spherical_harmonic_r(n, m, static_cast(theta), static_cast(phi), pol), "boost::math::spherical_harmonic_r<%1%>(unsigned, int, %1%, %1%)"); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic_r(n, m, theta, phi, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::spherical_harmonic_i(n, m, static_cast(theta), static_cast(phi), pol), "boost::math::spherical_harmonic_i<%1%>(unsigned, int, %1%, %1%)"); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic_i(n, m, theta, phi, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_SPHERICAL_HARMONIC_HPP + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/sqrt1pm1.hpp b/third-party/boost-math/include/boost/math/special_functions/sqrt1pm1.hpp new file mode 100644 index 0000000000000..4d8aeb38cf3bf --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/sqrt1pm1.hpp @@ -0,0 +1,49 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_SQRT1PM1 +#define BOOST_MATH_SQRT1PM1 + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +// +// This algorithm computes sqrt(1+x)-1 for small x: +// + +namespace boost{ namespace math{ + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type sqrt1pm1(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + + if(fabs(result_type(val)) > result_type(0.75)) + return sqrt(1 + result_type(val)) - 1; + return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type sqrt1pm1(const T& val) +{ + return sqrt1pm1(val, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SQRT1PM1 + + + + + diff --git a/third-party/boost-math/include/boost/math/special_functions/trigamma.hpp b/third-party/boost-math/include/boost/math/special_functions/trigamma.hpp new file mode 100644 index 0000000000000..7ac99466cb14d --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/trigamma.hpp @@ -0,0 +1,448 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_SF_TRIGAMMA_HPP +#define BOOST_MATH_SF_TRIGAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ +namespace math{ +namespace detail{ + +// TODO(mborland): Temporary for NVRTC +#ifndef BOOST_MATH_HAS_NVRTC +template +T polygamma_imp(const int n, T x, const Policy &pol); + +template +T trigamma_prec(T x, const Policy& pol, const boost::math::integral_constant&) +{ + return polygamma_imp(1, x, pol); +} +#endif + +template +BOOST_MATH_GPU_ENABLED T trigamma_prec(T x, const Policy&, const boost::math::integral_constant&) +{ + // Max error in interpolated form: 3.736e-017 + BOOST_MATH_STATIC const T offset = BOOST_MATH_BIG_CONSTANT(T, 53, 2.1093254089355469); + BOOST_MATH_STATIC const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -1.1093280605946045), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.8310674472619321), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.3703848401898283), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.28080574467981213), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.6638069578676164), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468386819102836), + }; + BOOST_MATH_STATIC const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 3.4535389668541151), + BOOST_MATH_BIG_CONSTANT(T, 53, 4.5208926987851437), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.7012734178351534), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468798399785611), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.20314516859987728e-6), + }; + // Max error in interpolated form: 1.159e-017 + BOOST_MATH_STATIC const T P_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.13803835004508849e-7), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.50000049158540261), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.6077979838469348), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.5645435828098254), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.0534873203680393), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.74566981111565923), + }; + BOOST_MATH_STATIC const T Q_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.8822787662376169), + BOOST_MATH_BIG_CONSTANT(T, 53, 4.1681660554090917), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.7853527819234466), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.74967671848044792), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00057069112416246805), + }; + // Maximum Deviation Found: 6.896e-018 + // Expected Error Term : -6.895e-018 + // Maximum Relative Change in Control Points : 8.497e-004 + BOOST_MATH_STATIC const T P_4_inf[] = { + static_cast(0.68947581948701249e-17L), + static_cast(0.49999999999998975L), + static_cast(1.0177274392923795L), + static_cast(2.498208511343429L), + static_cast(2.1921221359427595L), + static_cast(1.5897035272532764L), + static_cast(0.40154388356961734L), + }; + BOOST_MATH_STATIC const T Q_4_inf[] = { + static_cast(1.0L), + static_cast(1.7021215452463932L), + static_cast(4.4290431747556469L), + static_cast(2.9745631894384922L), + static_cast(2.3013614809773616L), + static_cast(0.28360399799075752L), + static_cast(0.022892987908906897L), + }; + + if(x <= 2) + { + return (offset + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 4) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_2_4, y) / tools::evaluate_polynomial(Q_2_4, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_4_inf, y) / tools::evaluate_polynomial(Q_4_inf, y)) / x; +} + +template +BOOST_MATH_GPU_ENABLED T trigamma_prec(T x, const Policy&, const boost::math::integral_constant&) +{ + // Max error in interpolated form: 1.178e-020 + BOOST_MATH_STATIC const T offset_1_2 = BOOST_MATH_BIG_CONSTANT(T, 64, 2.109325408935546875); + BOOST_MATH_STATIC const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10932535608960258341), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.18793841543017129052), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.63865531898487734531), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.919832884430500908047), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.68074038333180423012), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.21172611429185622377), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635673503366427284), + }; + BOOST_MATH_STATIC const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.77521119359546982995), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.664338024578956321), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.25995134879278028361), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.62956638448940402182), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635512844691089868), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.629642219810618032207e-8), + }; + // Max error in interpolated form: 3.912e-020 + BOOST_MATH_STATIC const T P_2_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.387540035162952880976e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000276430504), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.21926880986360957306), + BOOST_MATH_BIG_CONSTANT(T, 64, 10.2550347708483445775), + BOOST_MATH_BIG_CONSTANT(T, 64, 18.9002075150709144043), + BOOST_MATH_BIG_CONSTANT(T, 64, 21.0357215832399705625), + BOOST_MATH_BIG_CONSTANT(T, 64, 13.4346512182925923978), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98656291026448279118), + }; + BOOST_MATH_STATIC const T Q_2_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.10520430478613667724), + BOOST_MATH_BIG_CONSTANT(T, 64, 18.475001060603645512), + BOOST_MATH_BIG_CONSTANT(T, 64, 31.7087534567758405638), + BOOST_MATH_BIG_CONSTANT(T, 64, 31.908814523890465398), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.4175479039227084798), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98749106958394941276), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000115917322224411128566), + }; + // Maximum Deviation Found: 2.635e-020 + // Expected Error Term : 2.635e-020 + // Maximum Relative Change in Control Points : 1.791e-003 + BOOST_MATH_STATIC const T P_8_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.263527875092466899848e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000000000058145), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0730121433777364138677), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.94505878379957149534), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0517092358874932620529), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.07995383547483921121), + }; + BOOST_MATH_STATIC const T Q_8_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.187309046577818095504), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.95255391645238842975), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.14743283327078949087), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.52989799376344914499), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.627414303172402506396), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.141554248216425512536), + }; + + if(x <= 2) + { + return (offset_1_2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 8) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_2_8, y) / tools::evaluate_polynomial(Q_2_8, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_8_inf, y) / tools::evaluate_polynomial(Q_8_inf, y)) / x; +} + +template +BOOST_MATH_GPU_ENABLED T trigamma_prec(T x, const Policy&, const boost::math::integral_constant&) +{ + // Max error in interpolated form: 1.916e-035 + + static const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999082554457936871832533), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.71237311120865266379041700054847734), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.94125711970499027763789342500817316), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.74657746697664735258222071695644535), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.404213349456398905981223965160595687), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.47877781178642876561595890095758896), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.07714151702455125992166949812126433), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.858877899162360138844032265418028567), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.20499222604410032375789018837922397), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0272103140348194747360175268778415049), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0015764849020876949848954081173520686), + }; + static const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.71237311120863419878375031457715223), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.58619118655339853449127952145877467), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.0940067269829372437561421279054968), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.09075424749327792073276309969037885), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.87705890159891405185343806884451286), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.22758678701914477836330837816976782), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.249092040606385004109672077814668716), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0295750413900655597027079600025569048), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157648490200498142247694709728858139), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.161264050344059471721062360645432809e-14), + }; + + // Max error in interpolated form: 8.958e-035 + static const T P_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -2.55843734739907925764326773972215085), + BOOST_MATH_BIG_CONSTANT(T, 113, -12.2830208240542011967952466273455887), + BOOST_MATH_BIG_CONSTANT(T, 113, -23.9195022162767993526575786066414403), + BOOST_MATH_BIG_CONSTANT(T, 113, -24.9256431504823483094158828285470862), + BOOST_MATH_BIG_CONSTANT(T, 113, -14.7979122765478779075108064826412285), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.46654453928610666393276765059122272), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0191439033405649675717082465687845002), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.515412052554351265708917209749037352), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.195378348786064304378247325360320038), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0334761282624174313035014426794245393), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.002373665205942206348500250056602687), + }; + static const T Q_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.80098558454419907830670928248659245), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.99220727843170133895059300223445265), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.8896146167631330735386697123464976), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.96613256683809091593793565879092581), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.47254136149624110878909334574485751), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.48600982028196527372434773913633152), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.319570735766764237068541501137990078), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0407358345787680953107374215319322066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00237366520593271641375755486420859837), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.239554887903526152679337256236302116e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.294749244740618656265237072002026314e-17), + }; + + static const T y_offset_2_4 = BOOST_MATH_BIG_CONSTANT(T, 113, 3.558437347412109375); + + // Max error in interpolated form: 4.319e-035 + static const T P_4_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.166626112697021464248967707021688845e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.499999999999997739552090249208808197), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.40270945019053817915772473771553187), + BOOST_MATH_BIG_CONSTANT(T, 113, 41.3833374155000608013677627389343329), + BOOST_MATH_BIG_CONSTANT(T, 113, 166.803341854562809335667241074035245), + BOOST_MATH_BIG_CONSTANT(T, 113, 453.39964786925369319960722793414521), + BOOST_MATH_BIG_CONSTANT(T, 113, 851.153712317697055375935433362983944), + BOOST_MATH_BIG_CONSTANT(T, 113, 1097.70657567285059133109286478004458), + BOOST_MATH_BIG_CONSTANT(T, 113, 938.431232478455316020076349367632922), + BOOST_MATH_BIG_CONSTANT(T, 113, 487.268001604651932322080970189930074), + BOOST_MATH_BIG_CONSTANT(T, 113, 119.953445242335730062471193124820659), + }; + static const T Q_4_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 12.4720855670474488978638945855932398), + BOOST_MATH_BIG_CONSTANT(T, 113, 78.6093129753298570701376952709727391), + BOOST_MATH_BIG_CONSTANT(T, 113, 307.470246050318322489781182863190127), + BOOST_MATH_BIG_CONSTANT(T, 113, 805.140686101151538537565264188630079), + BOOST_MATH_BIG_CONSTANT(T, 113, 1439.12019760292146454787601409644413), + BOOST_MATH_BIG_CONSTANT(T, 113, 1735.6105285756048831268586001383127), + BOOST_MATH_BIG_CONSTANT(T, 113, 1348.32500712856328019355198611280536), + BOOST_MATH_BIG_CONSTANT(T, 113, 607.225985860570846699704222144650563), + BOOST_MATH_BIG_CONSTANT(T, 113, 119.952317857277045332558673164517227), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000140165918355036060868680809129436084), + }; + + // Maximum Deviation Found: 2.867e-035 + // Expected Error Term : 2.866e-035 + // Maximum Relative Change in Control Points : 2.662e-004 + static const T P_8_16[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.184828315274146610610872315609837439e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000004122475157735807738), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.02533865247313349284875558880415875), + BOOST_MATH_BIG_CONSTANT(T, 113, 13.5995927517457371243039532492642734), + BOOST_MATH_BIG_CONSTANT(T, 113, 35.3132224283087906757037999452941588), + BOOST_MATH_BIG_CONSTANT(T, 113, 67.1639424550714159157603179911505619), + BOOST_MATH_BIG_CONSTANT(T, 113, 83.5767733658513967581959839367419891), + BOOST_MATH_BIG_CONSTANT(T, 113, 71.073491212235705900866411319363501), + BOOST_MATH_BIG_CONSTANT(T, 113, 35.8621515614725564575893663483998663), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.72152231639983491987779743154333318), + }; + static const T Q_8_16[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.71734397161293452310624822415866372), + BOOST_MATH_BIG_CONSTANT(T, 113, 25.293404179620438179337103263274815), + BOOST_MATH_BIG_CONSTANT(T, 113, 62.2619767967468199111077640625328469), + BOOST_MATH_BIG_CONSTANT(T, 113, 113.955048909238993473389714972250235), + BOOST_MATH_BIG_CONSTANT(T, 113, 130.807138328938966981862203944329408), + BOOST_MATH_BIG_CONSTANT(T, 113, 102.423146902337654110717764213057753), + BOOST_MATH_BIG_CONSTANT(T, 113, 44.0424772805245202514468199602123565), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.89898032477904072082994913461386099), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0296627336872039988632793863671456398), + }; + // Maximum Deviation Found: 1.079e-035 + // Expected Error Term : -1.079e-035 + // Maximum Relative Change in Control Points : 7.884e-003 + static const T P_16_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000000000000000000087317), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.345625669885456215194494735902663968), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.62895499360842232127552650044647769), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.5936085382439026269301003761320812), + BOOST_MATH_BIG_CONSTANT(T, 113, 49.459599118438883265036646019410669), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.77519237321893917784735690560496607), + BOOST_MATH_BIG_CONSTANT(T, 113, 74.4536074488178075948642351179304121), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.75209340397069050436806159297952699), + BOOST_MATH_BIG_CONSTANT(T, 113, 23.9292359711471667884504840186561598), + }; + static const T Q_16_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.357918006437579097055656138920742037), + BOOST_MATH_BIG_CONSTANT(T, 113, 19.1386039850709849435325005484512944), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.874349081464143606016221431763364517), + BOOST_MATH_BIG_CONSTANT(T, 113, 98.6516097434855572678195488061432509), + BOOST_MATH_BIG_CONSTANT(T, 113, -16.1051972833382893468655223662534306), + BOOST_MATH_BIG_CONSTANT(T, 113, 154.316860216253720989145047141653727), + BOOST_MATH_BIG_CONSTANT(T, 113, -40.2026880424378986053105969312264534), + BOOST_MATH_BIG_CONSTANT(T, 113, 60.1679136674264778074736441126810223), + BOOST_MATH_BIG_CONSTANT(T, 113, -13.3414844622256422644504472438320114), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.53795636200649908779512969030363442), + }; + + if(x <= 2) + { + return (2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 4) + { + return (y_offset_2_4 + boost::math::tools::evaluate_polynomial(P_2_4, x) / tools::evaluate_polynomial(Q_2_4, x)) / (x * x); + } + else if(x <= 8) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_4_8, y) / tools::evaluate_polynomial(Q_4_8, y)) / x; + } + else if(x <= 16) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_8_16, y) / tools::evaluate_polynomial(Q_8_16, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_16_inf, y) / tools::evaluate_polynomial(Q_16_inf, y)) / x; +} + +template +BOOST_MATH_GPU_ENABLED T trigamma_dispatch(T x, const Policy& pol, const Tag& tag) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= 0) + { + // Reflect: + T z = 1 - x; + + BOOST_MATH_ASSERT(z >= 1); + + // Argument reduction for tan: + if(floor(x) == x) + { + return policies::raise_pole_error("boost::math::trigamma<%1%>(%1%)", nullptr, (1-x), pol); + } + T s = fabs(x) < fabs(z) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(z, pol); + return result - trigamma_prec(T(z), pol, tag) + boost::math::pow<2>(constants::pi()) / (s * s); + } + if(x < 1) + { + result = 1 / (x * x); + x += 1; + } + return result + trigamma_prec(x, pol, tag); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + trigamma(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef boost::math::integral_constant tag_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::trigamma_dispatch(static_cast(x), forwarding_policy(), tag_type()), "boost::math::trigamma<%1%>(%1%)"); +} + +template +BOOST_MATH_GPU_ENABLED inline typename tools::promote_args::type + trigamma(T x) +{ + return trigamma(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost +#endif + diff --git a/third-party/boost-math/include/boost/math/special_functions/trunc.hpp b/third-party/boost-math/include/boost/math/special_functions/trunc.hpp new file mode 100644 index 0000000000000..b52f4f321cf95 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/trunc.hpp @@ -0,0 +1,385 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2023. +// 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) + +#ifndef BOOST_MATH_TRUNC_HPP +#define BOOST_MATH_TRUNC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MATH_NO_CCMATH) && !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION) +#include +# define BOOST_MATH_HAS_CONSTEXPR_LDEXP +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t trunc(const T& v, const Policy& pol, const std::false_type&) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + if(!(boost::math::isfinite)(v)) + { + return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", nullptr, static_cast(v), static_cast(v), pol); + } + return (v >= 0) ? static_cast(floor(v)) : static_cast(ceil(v)); +} + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t trunc(const T& v, const Policy&, const std::true_type&) +{ + return v; +} + +} // Namespace detail + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t trunc(const T& v, const Policy& pol) +{ + return detail::trunc(v, pol, std::integral_constant::value>()); +} + +template +BOOST_MATH_GPU_ENABLED inline tools::promote_args_t trunc(const T& v) +{ + return trunc(v, policies::policy<>()); +} + +#else // Special handling for nvrtc + +namespace boost { +namespace math { + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED double trunc_impl(T x) +{ + return static_cast(x); +} + +BOOST_MATH_GPU_ENABLED inline float trunc_impl(float x) +{ + return ::truncf(x); +} + +BOOST_MATH_GPU_ENABLED inline double trunc_impl(double x) +{ + return ::trunc(x); +} + +} // Namespace detail + +template +BOOST_MATH_GPU_ENABLED auto trunc(T x, const Policy&) +{ + return detail::trunc_impl(x); +} + +template +BOOST_MATH_GPU_ENABLED auto trunc(T x) +{ + return detail::trunc_impl(x); +} + +#endif + +#ifndef BOOST_MATH_HAS_NVRTC + +// +// The following functions will not compile unless T has an +// implicit conversion to the integer types. For user-defined +// number types this will likely not be the case. In that case +// these functions should either be specialized for the UDT in +// question, or else overloads should be placed in the same +// namespace as the UDT: these will then be found via argument +// dependent lookup. See our concept archetypes for examples. +// +// Non-standard numeric limits syntax "(std::numeric_limits::max)()" +// is to avoid macro substiution from MSVC +// https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax +// +template +BOOST_MATH_GPU_ENABLED inline int itrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} + +template +BOOST_MATH_GPU_ENABLED inline int itrunc(const T& v) +{ + return itrunc(v, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline long ltrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} + +template +BOOST_MATH_GPU_ENABLED inline long ltrunc(const T& v) +{ + return ltrunc(v, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline long long lltrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + + #if defined(BOOST_MATH_HAS_CONSTEXPR_LDEXP) && !defined(BOOST_MATH_HAS_GPU_SUPPORT) + if constexpr (std::is_arithmetic_v + #ifdef BOOST_MATH_FLOAT128_TYPE + && !std::is_same_v + #endif + ) + { + constexpr result_type max_val = boost::math::ccmath::ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + else + { + static const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + } + #else + BOOST_MATH_STATIC_LOCAL_VARIABLE const result_type max_val = ldexp(static_cast(1), std::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + return static_cast(boost::math::policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + #endif + + return static_cast(r); +} + +template +BOOST_MATH_GPU_ENABLED inline long long lltrunc(const T& v) +{ + return lltrunc(v, policies::policy<>()); +} + +#else // Reduced impl specifically for NVRTC platform + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED TargetType integer_trunc_impl(T v) +{ + double r = boost::math::trunc(v); + + const double max_val = ldexp(1.0, boost::math::numeric_limits::digits); + + if (r >= max_val || r < -max_val) + { + r = 0; + } + + return static_cast(r); +} + +} // Namespace detail + +template +BOOST_MATH_GPU_ENABLED int itrunc(T v) +{ + return detail::integer_trunc_impl(v); +} + +template +BOOST_MATH_GPU_ENABLED int itrunc(T v, const Policy&) +{ + return detail::integer_trunc_impl(v); +} + +template +BOOST_MATH_GPU_ENABLED long ltrunc(T v) +{ + return detail::integer_trunc_impl(v); +} + +template +BOOST_MATH_GPU_ENABLED long ltrunc(T v, const Policy&) +{ + return detail::integer_trunc_impl(v); +} + +template +BOOST_MATH_GPU_ENABLED long long lltrunc(T v) +{ + return detail::integer_trunc_impl(v); +} + +template +BOOST_MATH_GPU_ENABLED long long lltrunc(T v, const Policy&) +{ + return detail::integer_trunc_impl(v); +} + +#endif // BOOST_MATH_HAS_NVRTC + +template +BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t, int> + iconvert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t, int> + iconvert(const T& v, const Policy& pol) +{ + using boost::math::itrunc; + return itrunc(v, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t, long> + lconvert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t, long> + lconvert(const T& v, const Policy& pol) +{ + using boost::math::ltrunc; + return ltrunc(v, pol); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::enable_if_t, long long> + llconvert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +BOOST_MATH_GPU_ENABLED inline typename boost::math::enable_if_t, long long> + llconvert(const T& v, const Policy& pol) +{ + using boost::math::lltrunc; + return lltrunc(v, pol); +} + +template +BOOST_MATH_GPU_ENABLED [[deprecated("Use llconvert")]] inline boost::math::enable_if_t, long long> + llconvertert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +BOOST_MATH_GPU_ENABLED [[deprecated("Use llconvert")]] inline typename boost::math::enable_if_t, long long> + llconvertert(const T& v, const Policy& pol) +{ + using boost::math::lltrunc; + return lltrunc(v, pol); +} + +}} // namespaces + +#endif // BOOST_MATH_TRUNC_HPP diff --git a/third-party/boost-math/include/boost/math/special_functions/ulp.hpp b/third-party/boost-math/include/boost/math/special_functions/ulp.hpp new file mode 100644 index 0000000000000..5805c171a3f3a --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/ulp.hpp @@ -0,0 +1,102 @@ +// (C) Copyright John Maddock 2015. +// 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) + +#ifndef BOOST_MATH_SPECIAL_ULP_HPP +#define BOOST_MATH_SPECIAL_ULP_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T ulp_imp(const T& val, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + int expon; + static const char* function = "ulp<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if(fpclass == FP_NAN) + { + return policies::raise_domain_error(function, "Argument must be finite, but got %1%", val, pol); + } + else if((fpclass == (int)FP_INFINITE) || (fabs(val) >= tools::max_value())) + { + return (val < 0 ? -1 : 1) * policies::raise_overflow_error(function, nullptr, pol); + } + else if(fpclass == FP_ZERO) + return detail::get_smallest_value(); + // + // This code is almost the same as that for float_next, except for negative integers, + // where we preserve the relation ulp(x) == ulp(-x) as does Java: + // + frexp(fabs(val), &expon); + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return diff; +} +// non-binary version: +template +T ulp_imp(const T& val, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + BOOST_MATH_STD_USING + int expon; + static const char* function = "ulp<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if(fpclass == FP_NAN) + { + return policies::raise_domain_error(function,"Argument must be finite, but got %1%", val, pol); + } + else if((fpclass == FP_INFINITE) || (fabs(val) >= tools::max_value())) + { + return (val < 0 ? -1 : 1) * policies::raise_overflow_error(function, nullptr, pol); + } + else if(fpclass == FP_ZERO) + return detail::get_smallest_value(); + // + // This code is almost the same as that for float_next, except for negative integers, + // where we preserve the relation ulp(x) == ulp(-x) as does Java: + // + expon = 1 + ilogb(fabs(val)); + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return diff; // LCOV_EXCL_LINE previous lines are covered so this one must be too. +} + +} + +template +inline typename tools::promote_args::type ulp(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::ulp_imp(static_cast(val), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +template +inline typename tools::promote_args::type ulp(const T& val) +{ + return ulp(val, policies::policy<>()); +} + + +}} // namespaces + +#endif // BOOST_MATH_SPECIAL_ULP_HPP + diff --git a/third-party/boost-math/include/boost/math/special_functions/zeta.hpp b/third-party/boost-math/include/boost/math/special_functions/zeta.hpp new file mode 100644 index 0000000000000..4a374cdd5fdf8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/special_functions/zeta.hpp @@ -0,0 +1,1081 @@ +// Copyright John Maddock 2007, 2014. +// 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) + +#ifndef BOOST_MATH_ZETA_HPP +#define BOOST_MATH_ZETA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace detail{ + +#if 0 +// +// This code is commented out because we have a better more rapidly converging series +// now. Retained for future reference and in case the new code causes any issues down the line.... +// + +template +struct zeta_series_cache_size +{ + // + // Work how large to make our cache size when evaluating the series + // evaluation: normally this is just large enough for the series + // to have converged, but for arbitrary precision types we need a + // really large cache to achieve reasonable precision in a reasonable + // time. This is important when constructing rational approximations + // to zeta for example. + // + typedef typename boost::math::policies::precision::type precision_type; + typedef typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + std::integral_constant + >::type + >::type + >::type type; +}; + +template +T zeta_series_imp(T s, T sc, const Policy&) +{ + // + // Series evaluation from: + // Havil, J. Gamma: Exploring Euler's Constant. + // Princeton, NJ: Princeton University Press, 2003. + // + // See also http://mathworld.wolfram.com/RiemannZetaFunction.html + // + BOOST_MATH_STD_USING + T sum = 0; + T mult = 0.5; + T change; + typedef typename zeta_series_cache_size::type cache_size; + T powers[cache_size::value] = { 0, }; + unsigned n = 0; + do{ + T binom = -static_cast(n); + T nested_sum = 1; + if(n < sizeof(powers) / sizeof(powers[0])) + powers[n] = pow(static_cast(n + 1), -s); + for(unsigned k = 1; k <= n; ++k) + { + T p; + if(k < sizeof(powers) / sizeof(powers[0])) + { + p = powers[k]; + //p = pow(k + 1, -s); + } + else + p = pow(static_cast(k + 1), -s); + nested_sum += binom * p; + binom *= (k - static_cast(n)) / (k + 1); + } + change = mult * nested_sum; + sum += change; + mult /= 2; + ++n; + }while(fabs(change / sum) > tools::epsilon()); + + return sum * 1 / -boost::math::powm1(T(2), sc); +} + +// +// Classical p-series: +// +template +struct zeta_series2 +{ + typedef T result_type; + zeta_series2(T _s) : s(-_s), k(1){} + T operator()() + { + BOOST_MATH_STD_USING + return pow(static_cast(k++), s); + } +private: + T s; + unsigned k; +}; + +template +inline T zeta_series2_imp(T s, const Policy& pol) +{ + std::uintmax_t max_iter = policies::get_max_series_iterations();; + zeta_series2 f(s); + T result = tools::sum_series( + f, + policies::get_epsilon(), + max_iter); + policies::check_series_iterations("boost::math::zeta_series2<%1%>(%1%)", max_iter, pol); + return result; +} +#endif + +template +T zeta_polynomial_series(T s, T sc, Policy const &) +{ + // + // This is algorithm 3 from: + // + // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, + // Canadian Mathematical Society, Conference Proceedings. + // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf + // + BOOST_MATH_STD_USING + int n = itrunc(T(log(boost::math::tools::epsilon()) / -2)); + T sum = 0; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + T two_n = ldexp(T(1), n); + int ej_sign = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + for(int j = 0; j < n; ++j) + { + sum += ej_sign * -two_n / pow(T(j + 1), s); + ej_sign = -ej_sign; + } + T ej_sum = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + T ej_term = 1; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + for(int j = n; j <= 2 * n - 1; ++j) + { + sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s); + ej_sign = -ej_sign; + ej_term *= 2 * n - j; + ej_term /= j - n + 1; + ej_sum += ej_term; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + } + return -sum / (two_n * (-powm1(T(2), sc))); +} +// +// MP only, verified as covered by the full tests: +// LCOV_EXCL_START +template +T zeta_imp_prec(T s, T sc, const Policy& pol, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s >= policies::digits()) + return 1; + result = zeta_polynomial_series(s, sc, pol); +#if 0 + // Old code archived for future reference: + + // + // Only use power series if it will converge in 100 + // iterations or less: the more iterations it consumes + // the slower convergence becomes so we have to be very + // careful in it's usage. + // + if (s > -log(tools::epsilon()) / 4.5) + result = detail::zeta_series2_imp(s, pol); + else + result = detail::zeta_series_imp(s, sc, pol); +#endif + return result; +} +// LCOV_EXCL_STOP + +template +inline T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 2.020e-18 + // Expected Error Term: -2.020e-18 + // Max error found at double precision: 3.994987e-17 + // LCOV_EXCL_START + static const T P[6] = { + static_cast(0.24339294433593750202L), + static_cast(-0.49092470516353571651L), + static_cast(0.0557616214776046784287L), + static_cast(-0.00320912498879085894856L), + static_cast(0.000451534528645796438704L), + static_cast(-0.933241270357061460782e-5L), + }; + static const T Q[6] = { + static_cast(1L), + static_cast(-0.279960334310344432495L), + static_cast(0.0419676223309986037706L), + static_cast(-0.00413421406552171059003L), + static_cast(0.00024978985622317935355L), + static_cast(-0.101855788418564031874e-4L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result -= 1.2433929443359375F; + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 9.007e-20 + // Expected Error Term: 9.007e-20 + // LCOV_EXCL_START + static const T P[6] = { + static_cast(0.577215664901532860516L), + static_cast(0.243210646940107164097L), + static_cast(0.0417364673988216497593L), + static_cast(0.00390252087072843288378L), + static_cast(0.000249606367151877175456L), + static_cast(0.110108440976732897969e-4L), + }; + static const T Q[6] = { + static_cast(1.0), + static_cast(0.295201277126631761737L), + static_cast(0.043460910607305495864L), + static_cast(0.00434930582085826330659L), + static_cast(0.000255784226140488490982L), + static_cast(0.10991819782396112081e-4L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 5.946e-22 + // Expected Error Term: -5.946e-22 + // LCOV_EXCL_START + static const float Y = 0.6986598968505859375; + static const T P[6] = { + static_cast(-0.0537258300023595030676L), + static_cast(0.0445163473292365591906L), + static_cast(0.0128677673534519952905L), + static_cast(0.00097541770457391752726L), + static_cast(0.769875101573654070925e-4L), + static_cast(0.328032510000383084155e-5L), + }; + static const T Q[7] = { + 1.0f, + static_cast(0.33383194553034051422L), + static_cast(0.0487798431291407621462L), + static_cast(0.00479039708573558490716L), + static_cast(0.000270776703956336357707L), + static_cast(0.106951867532057341359e-4L), + static_cast(0.236276623974978646399e-7L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 7) + { + // Maximum Deviation Found: 2.955e-17 + // Expected Error Term: 2.955e-17 + // Max error found at double precision: 2.009135e-16 + // LCOV_EXCL_START + static const T P[6] = { + static_cast(-2.49710190602259410021L), + static_cast(-2.60013301809475665334L), + static_cast(-0.939260435377109939261L), + static_cast(-0.138448617995741530935L), + static_cast(-0.00701721240549802377623L), + static_cast(-0.229257310594893932383e-4L), + }; + static const T Q[9] = { + 1.0f, + static_cast(0.706039025937745133628L), + static_cast(0.15739599649558626358L), + static_cast(0.0106117950976845084417L), + static_cast(-0.36910273311764618902e-4L), + static_cast(0.493409563927590008943e-5L), + static_cast(-0.234055487025287216506e-6L), + static_cast(0.718833729365459760664e-8L), + static_cast(-0.1129200113474947419e-9L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result = 1 + exp(result); + } + else if(s < 15) + { + // Maximum Deviation Found: 7.117e-16 + // Expected Error Term: 7.117e-16 + // Max error found at double precision: 9.387771e-16 + // LCOV_EXCL_START + static const T P[7] = { + static_cast(-4.78558028495135619286L), + static_cast(-1.89197364881972536382L), + static_cast(-0.211407134874412820099L), + static_cast(-0.000189204758260076688518L), + static_cast(0.00115140923889178742086L), + static_cast(0.639949204213164496988e-4L), + static_cast(0.139348932445324888343e-5L), + }; + static const T Q[9] = { + 1.0f, + static_cast(0.244345337378188557777L), + static_cast(0.00873370754492288653669L), + static_cast(-0.00117592765334434471562L), + static_cast(-0.743743682899933180415e-4L), + static_cast(-0.21750464515767984778e-5L), + static_cast(0.471001264003076486547e-8L), + static_cast(-0.833378440625385520576e-10L), + static_cast(0.699841545204845636531e-12L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7)); + result = 1 + exp(result); + } + else if(s < 36) + { + // Max error in interpolated form: 1.668e-17 + // Max error found at long double precision: 1.669714e-17 + // LCOV_EXCL_START + static const T P[8] = { + static_cast(-10.3948950573308896825L), + static_cast(-2.85827219671106697179L), + static_cast(-0.347728266539245787271L), + static_cast(-0.0251156064655346341766L), + static_cast(-0.00119459173416968685689L), + static_cast(-0.382529323507967522614e-4L), + static_cast(-0.785523633796723466968e-6L), + static_cast(-0.821465709095465524192e-8L), + }; + static const T Q[10] = { + 1.0f, + static_cast(0.208196333572671890965L), + static_cast(0.0195687657317205033485L), + static_cast(0.00111079638102485921877L), + static_cast(0.408507746266039256231e-4L), + static_cast(0.955561123065693483991e-6L), + static_cast(0.118507153474022900583e-7L), + static_cast(0.222609483627352615142e-14L), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15)); + result = 1 + exp(result); + } + else + { + result = 1 + pow(T(2), -s); + } + return result; +} + +template +T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 3.099e-20 + // Expected Error Term: 3.099e-20 + // Max error found at long double precision: 5.890498e-20 + // LCOV_EXCL_START + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.243392944335937499969), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.496837806864865688082), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0680008039723709987107), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00511620413006619942112), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000455369899250053003335), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.279496685273033761927e-4), + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.30425480068225790522), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.050052748580371598736), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00519355671064700627862), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000360623385771198350257), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.159600883054550987633e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.339770279812410586032e-6), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result -= 1.2433929443359375F; + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 1.059e-21 + // Expected Error Term: 1.059e-21 + // Max error found at long double precision: 1.626303e-19 + // LCOV_EXCL_START + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.577215664901532860605), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.222537368917162139445), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0356286324033215682729), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00304465292366350081446), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000178102511649069421904), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.700867470265983665042e-5), + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259385759149531030085), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0373974962106091316854), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00332735159183332820617), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000188690420706998606469), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.635994377921861930071e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.226583954978371199405e-7), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 5.946e-22 + // Expected Error Term: -5.946e-22 + // LCOV_EXCL_START + static const float Y = 0.6986598968505859375; + static const T P[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.053725830002359501027), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0470551187571475844778), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0101339410415759517471), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00100240326666092854528), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.685027119098122814867e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.390972820219765942117e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.540319769113543934483e-7), + }; + static const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.286577739726542730421), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0447355811517733225843), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00430125107610252363302), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000284956969089786662045), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.116188101609848411329e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.278090318191657278204e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.19683620233222028478e-8), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 7) + { + // Max error found at long double precision: 8.132216e-19 + // LCOV_EXCL_START + static const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -2.49710190602259407065), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.36664913245960625334), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.77180020623777595452), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.464717885249654313933), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0643694921293579472583), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00464265386202805715487), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000165556579779704340166), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252884970740994069582e-5), + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.01300131390690459085), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.387898115758643503827), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0695071490045701135188), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00586908595251442839291), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000217752974064612188616), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.397626583349419011731e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.927884739284359700764e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.119810501805618894381e-9), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result = 1 + exp(result); + } + else if(s < 15) + { + // Max error in interpolated form: 1.133e-18 + // Max error found at long double precision: 2.183198e-18 + // LCOV_EXCL_START + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -4.78558028495135548083), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.23873322238609358947), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.892338582881021799922), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.131326296217965913809), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0115651591773783712996), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000657728968362695775205), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252051328129449973047e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.626503445372641798925e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.815696314790853893484e-8), + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.525765665400123515036), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.10852641753657122787), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0115669945375362045249), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000732896513858274091966), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.30683952282420248448e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.819649214609633126119e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.117957556472335968146e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.193432300973017671137e-12), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7)); + result = 1 + exp(result); + } + else if(s < 42) + { + // Max error in interpolated form: 1.668e-17 + // Max error found at long double precision: 1.669714e-17 + // LCOV_EXCL_START + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -10.3948950573308861781), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.82646012777913950108), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.342144362739570333665), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0249285145498722647472), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00122493108848097114118), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.423055371192592850196e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.1025215577185967488e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.165096762663509467061e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.145392555873022044329e-9), + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.205135978585281988052), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0192359357875879453602), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00111496452029715514119), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.434928449016693986857e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.116911068726610725891e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.206704342290235237475e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.209772836100827647474e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.939798249922234703384e-16), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.264584017421245080294e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15)); + result = 1 + exp(result); + } + else + { + result = 1 + pow(T(2), -s); + } + return result; +} + +template +T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 9.493e-37 + // Expected Error Term: 9.492e-37 + // Max error found at long double precision: 7.281332e-31 + // LCOV_EXCL_START + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0353008629988648122808504280990313668), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0107795651204927743049369868548706909), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000523961870530500751114866884685172975), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.661805838304910731947595897966487515e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.658932670403818558510656304189164638e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.103437265642266106533814021041010453e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.116818787212666457105375746642927737e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.660690993901506912123512551294239036e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113103113698388531428914333768142527e-10), + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.387483472099602327112637481818565459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0802265315091063135271497708694776875), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0110727276164171919280036408995078164), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00112552716946286252000434849173787243), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.874554160748626916455655180296834352e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.530097847491828379568636739662278322e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.248461553590496154705565904497247452e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.881834921354014787309644951507523899e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.217062446168217797598596496310953025e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.315823200002384492377987848307151168e-11), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 1.616e-37 + // Expected Error Term: -1.615e-37 + // LCOV_EXCL_START + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.577215664901532860606512090082402431), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.255597968739771510415479842335906308), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0494056503552807274142218876983542205), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00551372778611700965268920983472292325), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00043667616723970574871427830895192731), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.268562259154821957743669387915239528e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.109249633923016310141743084480436612e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.273895554345300227466534378753023924e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.583103205551702720149237384027795038e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.835774625259919268768735944711219256e-11), + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.316661751179735502065583176348292881), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0540401806533507064453851182728635272), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00598621274107420237785899476374043797), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000474907812321704156213038740142079615), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.272125421722314389581695715835862418e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.112649552156479800925522445229212933e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.301838975502992622733000078063330461e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.422960728687211282539769943184270106e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.377105263588822468076813329270698909e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.581926559304525152432462127383600681e-13), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 1.891e-36 + // Expected Error Term: -1.891e-36 + // Max error found: 2.171527e-35 + // LCOV_EXCL_START + static const float Y = 0.6986598968505859375; + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0537258300023595010275848333539748089), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0429086930802630159457448174466342553), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0136148228754303412510213395034056857), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190231601036042925183751238033763915), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000186880390916311438818302549192456581), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.145347370745893262394287982691323657e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.805843276446813106414036600485884885e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.340818159286739137503297172091882574e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.115762357488748996526167305116837246e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.231904754577648077579913403645767214e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.340169592866058506675897646629036044e-12), + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.363755247765087100018556983050520554), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0696581979014242539385695131258321598), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00882208914484611029571547753782014817), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000815405623261946661762236085660996718), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.571366167062457197282642344940445452e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.309278269271853502353954062051797838e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.12822982083479010834070516053794262e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.397876357325018976733953479182110033e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.8484432107648683277598472295289279e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.105677416606909614301995218444080615e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.547223964564003701979951154093005354e-15), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 6) + { + // Max error in interpolated form: 1.510e-37 + // Max error found at long double precision: 2.769266e-34 + // LCOV_EXCL_START + static const T Y = 3.28348541259765625F; + + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.786383506575062179339611614117697622), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.495766593395271370974685959652073976), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.409116737851754766422360889037532228), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.57340744006238263817895456842655987), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.280479899797421910694892949057963111), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0753148409447590257157585696212649869), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0122934003684672788499099362823748632), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126148398446193639247961370266962927), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.828465038179772939844657040917364896e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.361008916706050977143208468690645684e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.109879825497910544424797771195928112e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.214539416789686920918063075528797059e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.15090220092460596872172844424267351e-10), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69490865837142338462982225731926485), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.22697696630994080733321401255942464), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.495409420862526540074366618006341533), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.122368084916843823462872905024259633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0191412993625268971656513890888208623), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00191401538628980617753082598351559642), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000123318142456272424148930280876444459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.531945488232526067889835342277595709e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.161843184071894368337068779669116236e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.305796079600152506743828859577462778e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233582592298450202680170811044408894e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.275363878344548055574209713637734269e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.221564186807357535475441900517843892e-15), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result -= Y; + result = 1 + exp(result); + } + else if(s < 10) + { + // Max error in interpolated form: 1.999e-34 + // Max error found at long double precision: 2.156186e-33 + // LCOV_EXCL_START + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -4.0545627381873738086704293881227365), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.70088348734699134347906176097717782), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.36921550900925512951976617607678789), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.684322583796369508367726293719322866), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.126026534540165129870721937592996324), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.015636903921778316147260572008619549), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00135442294754728549644376325814460807), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.842793965853572134365031384646117061e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.385602133791111663372015460784978351e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.130458500394692067189883214401478539e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.315861074947230418778143153383660035e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.500334720512030826996373077844707164e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.420204769185233365849253969097184005e-12), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.97663511666410096104783358493318814), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.40878780231201806504987368939673249), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0963890666609396058945084107597727252), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0142207619090854604824116070866614505), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139010220902667918476773423995750877), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.940669540194694997889636696089994734e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.458220848507517004399292480807026602e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.16345521617741789012782420625435495e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.414007452533083304371566316901024114e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.68701473543366328016953742622661377e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.603461891080716585087883971886075863e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.294670713571839023181857795866134957e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.147003914536437243143096875069813451e-18), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 6)) / tools::evaluate_polynomial(Q, T(s - 6)); + result = 1 + exp(result); + } + else if(s < 17) + { + // Max error in interpolated form: 1.641e-32 + // Max error found at long double precision: 1.696121e-32 + // LCOV_EXCL_START + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -6.91319491921722925920883787894829678), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.65491257639481960248690596951049048), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.813557553449954526442644544105257881), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0994317301685870959473658713841138083), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00726896610245676520248617014211734906), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000317253318715075854811266230916762929), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.66851422826636750855184211580127133e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.879464154730985406003332577806849971e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113838903158254250631678791998294628e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.379184410304927316385211327537817583e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.612992858643904887150527613446403867e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.347873737198164757035457841688594788e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.289187187441625868404494665572279364e-15), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.427310044448071818775721584949868806), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.074602514873055756201435421385243062), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00688651562174480772901425121653945942), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000360174847635115036351323894321880445), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.973556847713307543918865405758248777e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.853455848314516117964634714780874197e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.118203513654855112421673192194622826e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.462521662511754117095006543363328159e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.834212591919475633107355719369463143e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.5354594751002702935740220218582929e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.406451690742991192964889603000756203e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.887948682401000153828241615760146728e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.34980761098820347103967203948619072e-21), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 10)) / tools::evaluate_polynomial(Q, T(s - 10)); + result = 1 + exp(result); + } + else if(s < 30) + { + // Max error in interpolated form: 1.563e-31 + // Max error found at long double precision: 1.562725e-31 + // LCOV_EXCL_START + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -11.7824798233959252791987402769438322), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.36131215284987731928174218354118102), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.732260980060982349410898496846972204), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0744985185694913074484248803015717388), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00517228281320594683022294996292250527), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000260897206152101522569969046299309939), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.989553462123121764865178453128769948e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.286916799741891410827712096608826167e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.637262477796046963617949532211619729e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.106796831465628373325491288787760494e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.129343095511091870860498356205376823e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.102397936697965977221267881716672084e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.402663128248642002351627980255756363e-16), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.311288325355705609096155335186466508), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0438318468940415543546769437752132748), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00374396349183199548610264222242269536), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000218707451200585197339671707189281302), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.927578767487930747532953583797351219e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.294145760625753561951137473484889639e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.704618586690874460082739479535985395e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.126333332872897336219649130062221257e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.16317315713773503718315435769352765e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137846712823719515148344938160275695e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.580975420554224366450994232723910583e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.291354445847552426900293580511392459e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.73614324724785855925025452085443636e-25), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 17)) / tools::evaluate_polynomial(Q, T(s - 17)); + result = 1 + exp(result); + } + else if(s < 74) + { + // Max error in interpolated form: 2.311e-27 + // Max error found at long double precision: 2.297544e-27 + // LCOV_EXCL_START + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -20.7944102007844314586649688802236072), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.95759941987499442499908748130192187), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.563290752832461751889194629200298688), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0406197001137935911912457120706122877), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0020846534789473022216888863613422293), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.808095978462109173749395599401375667e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.244706022206249301640890603610060959e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.589477682919645930544382616501666572e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.113699573675553496343617442433027672e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.174767860183598149649901223128011828e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210051620306761367764549971980026474e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.189187969537370950337212675466400599e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.116313253429564048145641663778121898e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.376708747782400769427057630528578187e-19), + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.205076752981410805177554569784219717), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0202526722696670378999575738524540269), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.001278305290005994980069466658219057), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.576404779858501791742255670403304787e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.196477049872253010859712483984252067e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.521863830500876189501054079974475762e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.109524209196868135198775445228552059e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.181698713448644481083966260949267825e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234793316975091282090312036524695562e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.227490441461460571047545264251399048e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.151500292036937400913870642638520668e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.543475775154780935815530649335936121e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.241647013434111434636554455083309352e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.557103423021951053707162364713587374e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.618708773442584843384712258199645166e-34), + }; + // LCOV_EXCL_STOP + result = tools::evaluate_polynomial(P, T(s - 30)) / tools::evaluate_polynomial(Q, T(s - 30)); + result = 1 + exp(result); + } + else + { + result = 1 + pow(T(2), -s); + } + return result; +} + +template +T zeta_imp_odd_integer(int s, const T&, const Policy&, const std::true_type&) +{ + // LCOV_EXCL_START + static const T results[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2020569031595942853997381615114500), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0369277551433699263313654864570342), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0083492773819228268397975498497968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0020083928260822144178527692324121), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0004941886041194645587022825264699), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0001227133475784891467518365263574), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000305882363070204935517285106451), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000076371976378997622736002935630), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000019082127165539389256569577951), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000004769329867878064631167196044), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000001192199259653110730677887189), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000298035035146522801860637051), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000074507117898354294919810042), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000018626597235130490064039099), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000004656629065033784072989233), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000001164155017270051977592974), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000291038504449709968692943), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000072759598350574810145209), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000018189896503070659475848), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000004547473783042154026799), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000001136868407680227849349), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000284217097688930185546), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000071054273952108527129), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000017763568435791203275), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000004440892103143813364), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000001110223025141066134), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000277555756213612417), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000069388939045441537), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000017347234760475766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000004336808690020650), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000001084202172494241), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000271050543122347), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000067762635780452), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000016940658945098), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000004235164736273), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000001058791184068), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000264697796017), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000066174449004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000016543612251), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000004135903063), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000001033975766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000258493941), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000064623485), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000016155871), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000004038968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000001009742), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000252435), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000063109), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000015777), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000003944), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000986), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000247), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000062), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000015), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000001), + }; + // LCOV_EXCL_STOP + return s > 113 ? 1 : results[(s - 3) / 2]; +} + +template +T zeta_imp_odd_integer(int s, const T& sc, const Policy& pol, const std::false_type&) +{ +#ifdef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES + static_assert(std::is_trivially_destructible::value, "Your platform does not support thread_local with non-trivial types, last checked with Mingw-x64-8.1, Jan 2021. Please try a Mingw build with the POSIX threading model, see https://sourceforge.net/p/mingw-w64/bugs/527/"); +#endif + // LCOV_EXCL_START + static BOOST_MATH_THREAD_LOCAL bool is_init = false; + static BOOST_MATH_THREAD_LOCAL T results[50] = {}; + static BOOST_MATH_THREAD_LOCAL int digits = tools::digits(); + // LCOV_EXCL_STOP + int current_digits = tools::digits(); // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + if(digits != current_digits) + { + // Oh my precision has changed... + is_init = false; // LCOV_EXCL_LINE variable precision MP case only, not included in coverage tests. + } + if(!is_init) + { + is_init = true; + digits = current_digits; + for(unsigned k = 0; k < sizeof(results) / sizeof(results[0]); ++k) + { + T arg = k * 2 + 3; + T c_arg = 1 - arg; // LCOV_EXCL_LINE spurious miss as surrounding lines hit. + results[k] = zeta_polynomial_series(arg, c_arg, pol); + } + } + const unsigned index = static_cast((s - 3) / 2); + return index >= sizeof(results) / sizeof(results[0]) ? zeta_polynomial_series(T(s), sc, pol): results[index]; +} + +template +T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::zeta<%1%>"; + if(sc == 0) + return policies::raise_pole_error(function, "Evaluation of zeta function at pole %1%", s, pol); + T result; // LCOV_EXCL_LINE + // + // Trivial case: + // + if(s > policies::digits()) + return 1; + // + // Start by seeing if we have a simple closed form: + // + if(floor(s) == s) + { +#ifndef BOOST_MATH_NO_EXCEPTIONS + // Without exceptions we expect itrunc to return INT_MAX on overflow + // and we fall through anyway. + try + { +#endif + int v = itrunc(s); + if(v == s) + { + if(v < 0) + { + if(((-v) & 1) == 0) + return 0; + int n = (-v + 1) / 2; + if(n <= (int)boost::math::max_bernoulli_b2n::value) + return T((-v & 1) ? -1 : 1) * boost::math::unchecked_bernoulli_b2n(n) / (1 - v); + } + else if((v & 1) == 0) + { + if(((v / 2) <= (int)boost::math::max_bernoulli_b2n::value) && (v <= (int)boost::math::max_factorial::value)) + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), T(v))) * + boost::math::unchecked_bernoulli_b2n(v / 2) / boost::math::unchecked_factorial(v); + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * static_cast(pow(constants::pi(), T(v))) * + boost::math::bernoulli_b2n(v / 2) / boost::math::factorial(v, pol); + } + else + return zeta_imp_odd_integer(v, sc, pol, std::integral_constant()); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(const boost::math::rounding_error&){} // Just fall through, s is too large to round + catch(const std::overflow_error&){} // LCOV_EXCL_LINE We can only get here for "strange" MP types with small exponents and very large digit counts. +#endif + } + + if(fabs(s) < tools::root_epsilon()) + { + result = -0.5f - constants::log_root_two_pi() * s; + } + else if(s < 0) + { + std::swap(s, sc); + if(floor(sc/2) == sc/2) + result = 0; + else + { + if(s > max_factorial::value) + { + T mult = boost::math::sin_pi(0.5f * sc, pol) * 2 * zeta_imp(s, sc, pol, tag); + result = boost::math::lgamma(s, pol); + result -= s * log(2 * constants::pi()); + if(result > tools::log_max_value()) + return sign(mult) * policies::raise_overflow_error(function, nullptr, pol); + result = exp(result); + // + // Whether this if branch can be triggered is very type dependent, we need + // result to be just on the verge of overflow when /s/ is very close to a + // half integer. + // + if(tools::max_value() / fabs(mult) < result) + return boost::math::sign(mult) * policies::raise_overflow_error(function, nullptr, pol); // LCOV_EXCL_LINE + result *= mult; + } + else + { + result = boost::math::sin_pi(0.5f * sc, pol) + * 2 * pow(2 * constants::pi(), -s) + * boost::math::tgamma(s, pol) + * zeta_imp(s, sc, pol, tag); + } + } + } + else + { + result = zeta_imp_prec(s, sc, pol, tag); + } + return result; +} + +} // detail + +template +inline typename tools::promote_args::type zeta(T s, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef std::integral_constant tag_type; + + return policies::checked_narrowing_cast(detail::zeta_imp( + static_cast(s), + static_cast(1 - static_cast(s)), + forwarding_policy(), + tag_type()), "boost::math::zeta<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type zeta(T s) +{ + return zeta(s, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ZETA_HPP + + + diff --git a/third-party/boost-math/include/boost/math/statistics/anderson_darling.hpp b/third-party/boost-math/include/boost/math/statistics/anderson_darling.hpp new file mode 100644 index 0000000000000..f892f27e0f6b3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/anderson_darling.hpp @@ -0,0 +1,112 @@ +/* + * Copyright Nick Thompson, 2019 + * 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) + */ + +#ifndef BOOST_MATH_STATISTICS_ANDERSON_DARLING_HPP +#define BOOST_MATH_STATISTICS_ANDERSON_DARLING_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { + +template +auto anderson_darling_normality_statistic(RandomAccessContainer const & v, + typename RandomAccessContainer::value_type mu = std::numeric_limits::quiet_NaN(), + typename RandomAccessContainer::value_type sd = std::numeric_limits::quiet_NaN()) +{ + using Real = typename RandomAccessContainer::value_type; + using std::log; + using std::sqrt; + using boost::math::erfc; + + if (std::isnan(mu)) { + mu = boost::math::statistics::mean(v); + } + if (std::isnan(sd)) { + sd = sqrt(boost::math::statistics::sample_variance(v)); + } + + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + // This is where Knuth's literate programming could really come in handy! + // I need some LaTeX. The idea is that before any observation, the ecdf is identically zero. + // So we need to compute: + // \int_{-\infty}^{v_0} \frac{F(x)F'(x)}{1- F(x)} \, \mathrm{d}x, where F(x) := \frac{1}{2}[1+\erf(\frac{x-\mu}{\sigma \sqrt{2}})] + // Astonishingly, there is an analytic evaluation to this integral, as you can validate with the following Mathematica command: + // Integrate[(1/2 (1 + Erf[(x - mu)/Sqrt[2*sigma^2]])*Exp[-(x - mu)^2/(2*sigma^2)]*1/Sqrt[2*\[Pi]*sigma^2])/(1 - 1/2 (1 + Erf[(x - mu)/Sqrt[2*sigma^2]])), + // {x, -Infinity, x0}, Assumptions -> {x0 \[Element] Reals && mu \[Element] Reals && sigma > 0}] + // This gives (for s = x-mu/sqrt(2sigma^2)) + // -1/2 + erf(s) + log(2/(1+erf(s))) + + + Real inv_var_scale = 1/(sd*sqrt(Real(2))); + Real s0 = (v[0] - mu)*inv_var_scale; + Real erfcs0 = erfc(s0, no_promote_policy()); + // Note that if erfcs0 == 0, then left_tail = inf (numerically), and hence the entire integral is numerically infinite: + if (erfcs0 <= 0) { + return std::numeric_limits::infinity(); + } + + // Note that we're going to add erfcs0/2 when we compute the integral over [x_0, x_1], so drop it here: + Real left_tail = -1 + log(Real(2)); + + + // For the right tail, the ecdf is identically 1. + // Hence we need the integral: + // \int_{v_{n-1}}^{\infty} \frac{(1-F(x))F'(x)}{F(x)} \, \mathrm{d}x + // This also has an analytic evaluation! It can be found via the following Mathematica command: + // Integrate[(E^(-(z^2/2)) *(1 - 1/2 (1 + Erf[z/Sqrt[2]])))/(Sqrt[2 \[Pi]] (1/2 (1 + Erf[z/Sqrt[2]]))), + // {z, zn, \[Infinity]}, Assumptions -> {zn \[Element] Reals && mu \[Element] Reals}] + // This gives (for sf = xf-mu/sqrt(2sigma^2)) + // -1/2 + erf(sf)/2 + 2log(2/(1+erf(sf))) + + Real sf = (v[v.size()-1] - mu)*inv_var_scale; + //Real erfcsf = erfc(sf, no_promote_policy()); + // This is the actual value of the tail integral. However, the -erfcsf/2 cancels from the integral over [v_{n-2}, v_{n-1}]: + //Real right_tail = -erfcsf/2 + log(Real(2)) - log(2-erfcsf); + + // Use erfc(-x) = 2 - erfc(x) + Real erfcmsf = erfc(-sf, no_promote_policy()); + // Again if this is precisely zero then the integral is numerically infinite: + if (erfcmsf == 0) { + return std::numeric_limits::infinity(); + } + Real right_tail = log(2/erfcmsf); + + // Now we need each integral: + // \int_{v_i}^{v_{i+1}} \frac{(i+1/n - F(x))^2F'(x)}{F(x)(1-F(x))} \, \mathrm{d}x + // Again we get an analytical evaluation via the following Mathematica command: + // Integrate[((E^(-(z^2/2))/Sqrt[2 \[Pi]])*(k1 - F[z])^2)/(F[z]*(1 - F[z])), + // {z, z1, z2}, Assumptions -> {z1 \[Element] Reals && z2 \[Element] Reals &&k1 \[Element] Reals}] // FullSimplify + + Real integrals = 0; + int64_t N = v.size(); + for (int64_t i = 0; i < N - 1; ++i) { + if (v[i] > v[i+1]) { + throw std::domain_error("Input data must be sorted in increasing order v[0] <= v[1] <= . . . <= v[n-1]"); + } + + Real k = (i+1)/Real(N); + Real s1 = (v[i+1]-mu)*inv_var_scale; + Real erfcs1 = erfc(s1, no_promote_policy()); + Real term = k*(k*log(erfcs0*(-2 + erfcs1)/(erfcs1*(-2 + erfcs0))) + 2*log(erfcs1/erfcs0)); + + integrals += term; + s0 = s1; + erfcs0 = erfcs1; + } + integrals -= log(erfcs0); + return v.size()*(left_tail + right_tail + integrals); +} + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/bivariate_statistics.hpp b/third-party/boost-math/include/boost/math/statistics/bivariate_statistics.hpp new file mode 100644 index 0000000000000..d6f91faa93b6d --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/bivariate_statistics.hpp @@ -0,0 +1,470 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_STATISTICS_BIVARIATE_STATISTICS_HPP +#define BOOST_MATH_STATISTICS_BIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#include +#include +#endif + +namespace boost{ namespace math{ namespace statistics { namespace detail { + +// See Equation III.9 of "Numerically Stable, Single-Pass, Parallel Statistics Algorithms", Bennet et al. +template +ReturnType means_and_covariance_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + Real cov = 0; + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + Real mu_u = *u_it++; + Real mu_v = *v_it++; + std::size_t i = 1; + + while(u_it != u_end && v_it != v_end) + { + Real u_temp = (*u_it++ - mu_u)/(i+1); + Real v_temp = *v_it++ - mu_v; + cov += i*u_temp*v_temp; + mu_u = mu_u + u_temp; + mu_v = mu_v + v_temp/(i+1); + i = i + 1; + } + + if(u_it != u_end || v_it != v_end) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + return std::make_tuple(mu_u, mu_v, cov/i, Real(i)); +} + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +// Numerically stable parallel computation of (co-)variance +// https://dl.acm.org/doi/10.1145/3221269.3223036 +template +ReturnType means_and_covariance_parallel_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto u_elements = std::distance(u_begin, u_end); + const auto v_elements = std::distance(v_begin, v_end); + + if(u_elements != v_elements) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // 5.16 comes from benchmarking. See boost/math/reporting/performance/bivariate_statistics_performance.cpp + // Threading is faster for: 10 + 5.16e-3 N/j <= 5.16e-3N => N >= 10^4j/5.16(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(5.16*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/5.16; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(u_elements < parallel_lower_bound) + { + return means_and_covariance_seq_impl(u_begin, u_end, v_begin, v_end); + } + else if(u_elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(5.16*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(u_elements)/num_threads); + + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + + for(std::size_t i = 0; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, v_it, elements_per_thread]() -> ReturnType + { + return means_and_covariance_seq_impl(u_it, std::next(u_it, elements_per_thread), v_it, std::next(v_it, elements_per_thread)); + })); + u_it = std::next(u_it, elements_per_thread); + v_it = std::next(v_it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, u_end, v_it, v_end]() -> ReturnType + { + return means_and_covariance_seq_impl(u_it, u_end, v_it, v_end); + })); + + ReturnType temp = future_manager[0].get(); + Real mu_u_a = std::get<0>(temp); + Real mu_v_a = std::get<1>(temp); + Real cov_a = std::get<2>(temp); + Real n_a = std::get<3>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real mu_u_b = std::get<0>(temp); + Real mu_v_b = std::get<1>(temp); + Real cov_b = std::get<2>(temp); + Real n_b = std::get<3>(temp); + + const Real n_ab = n_a + n_b; + const Real delta_u = mu_u_b - mu_u_a; + const Real delta_v = mu_v_b - mu_v_a; + + cov_a = cov_a + cov_b + (-delta_u)*(-delta_v)*((n_a*n_b)/n_ab); + mu_u_a = mu_u_a + delta_u*(n_b/n_ab); + mu_v_a = mu_v_a + delta_v*(n_b/n_ab); + n_a = n_ab; + } + + return std::make_tuple(mu_u_a, mu_v_a, cov_a, n_a); +} + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +template +ReturnType correlation_coefficient_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + + Real cov = 0; + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + Real mu_u = *u_it++; + Real mu_v = *v_it++; + Real Qu = 0; + Real Qv = 0; + std::size_t i = 1; + + while(u_it != u_end && v_it != v_end) + { + Real u_tmp = *u_it++ - mu_u; + Real v_tmp = *v_it++ - mu_v; + Qu = Qu + (i*u_tmp*u_tmp)/(i+1); + Qv = Qv + (i*v_tmp*v_tmp)/(i+1); + cov += i*u_tmp*v_tmp/(i+1); + mu_u = mu_u + u_tmp/(i+1); + mu_v = mu_v + v_tmp/(i+1); + ++i; + } + + + // If one dataset is constant, then the correlation coefficient is undefined. + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu == 0 || Qv == 0) + { + return std::make_tuple(mu_u, Qu, mu_v, Qv, cov, std::numeric_limits::quiet_NaN(), Real(i)); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov/sqrt(Qu*Qv); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + + return std::make_tuple(mu_u, Qu, mu_v, Qv, cov, rho, Real(i)); +} + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +// Numerically stable parallel computation of (co-)variance: +// https://dl.acm.org/doi/10.1145/3221269.3223036 +// +// Parallel computation of variance: +// http://i.stanford.edu/pub/cstr/reports/cs/tr/79/773/CS-TR-79-773.pdf +template +ReturnType correlation_coefficient_parallel_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto u_elements = std::distance(u_begin, u_end); + const auto v_elements = std::distance(v_begin, v_end); + + if(u_elements != v_elements) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // 3.25 comes from benchmarking. See boost/math/reporting/performance/bivariate_statistics_performance.cpp + // Threading is faster for: 10 + 3.25e-3 N/j <= 3.25e-3N => N >= 10^4j/3.25(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(3.25*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/3.25; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(u_elements < parallel_lower_bound) + { + return correlation_coefficient_seq_impl(u_begin, u_end, v_begin, v_end); + } + else if(u_elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(3.25*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(u_elements)/num_threads); + + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + + for(std::size_t i = 0; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, v_it, elements_per_thread]() -> ReturnType + { + return correlation_coefficient_seq_impl(u_it, std::next(u_it, elements_per_thread), v_it, std::next(v_it, elements_per_thread)); + })); + u_it = std::next(u_it, elements_per_thread); + v_it = std::next(v_it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, u_end, v_it, v_end]() -> ReturnType + { + return correlation_coefficient_seq_impl(u_it, u_end, v_it, v_end); + })); + + ReturnType temp = future_manager[0].get(); + Real mu_u_a = std::get<0>(temp); + Real Qu_a = std::get<1>(temp); + Real mu_v_a = std::get<2>(temp); + Real Qv_a = std::get<3>(temp); + Real cov_a = std::get<4>(temp); + Real n_a = std::get<6>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real mu_u_b = std::get<0>(temp); + Real Qu_b = std::get<1>(temp); + Real mu_v_b = std::get<2>(temp); + Real Qv_b = std::get<3>(temp); + Real cov_b = std::get<4>(temp); + Real n_b = std::get<6>(temp); + + const Real n_ab = n_a + n_b; + const Real delta_u = mu_u_b - mu_u_a; + const Real delta_v = mu_v_b - mu_v_a; + + cov_a = cov_a + cov_b + (-delta_u)*(-delta_v)*((n_a*n_b)/n_ab); + mu_u_a = mu_u_a + delta_u*(n_b/n_ab); + mu_v_a = mu_v_a + delta_v*(n_b/n_ab); + Qu_a = Qu_a + Qu_b + delta_u*delta_u*((n_a*n_b)/n_ab); + Qv_b = Qv_a + Qv_b + delta_v*delta_v*((n_a*n_b)/n_ab); + n_a = n_ab; + } + + // If one dataset is constant, then the correlation coefficient is undefined. + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu_a == 0 || Qv_a == 0) + { + return std::make_tuple(mu_u_a, Qu_a, mu_v_a, Qv_a, cov_a, std::numeric_limits::quiet_NaN(), n_a); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov_a/sqrt(Qu_a*Qv_a); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + + return std::make_tuple(mu_u_a, Qu_a, mu_v_a, Qv_a, cov_a, rho, n_a); +} + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +} // namespace detail + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +template +inline auto means_and_covariance(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + else + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + } + else + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + else + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + } +} + +template +inline auto means_and_covariance(Container const & u, Container const & v) +{ + return means_and_covariance(std::execution::seq, u, v); +} + +template +inline auto covariance(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + return std::get<2>(means_and_covariance(exec, u, v)); +} + +template +inline auto covariance(Container const & u, Container const & v) +{ + return covariance(std::execution::seq, u, v); +} + +template +inline auto correlation_coefficient(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + else + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + } + else + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + else + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + } +} + +template +inline auto correlation_coefficient(Container const & u, Container const & v) +{ + return correlation_coefficient(std::execution::seq, u, v); +} + +#else // C++11 and single threaded bindings + +template::value, bool>::type = true> +inline auto means_and_covariance(Container const & u, Container const & v) -> std::tuple +{ + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); +} + +template::value, bool>::type = true> +inline auto means_and_covariance(Container const & u, Container const & v) -> std::tuple +{ + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); +} + +template::value, bool>::type = true> +inline double covariance(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<2>(detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline Real covariance(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<2>(detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline double correlation_coefficient(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline Real correlation_coefficient(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +#endif + +}}} // namespace boost::math::statistics + +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/chatterjee_correlation.hpp b/third-party/boost-math/include/boost/math/statistics/chatterjee_correlation.hpp new file mode 100644 index 0000000000000..ad0b33a429f63 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/chatterjee_correlation.hpp @@ -0,0 +1,159 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_STATISTICS_CHATTERJEE_CORRELATION_HPP +#define BOOST_MATH_STATISTICS_CHATTERJEE_CORRELATION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#include +#include +#endif + +namespace boost { namespace math { namespace statistics { + +namespace detail { + +template +std::size_t chatterjee_transform(BDIter begin, BDIter end) +{ + std::size_t sum = 0; + + while(++begin != end) + { + if(*begin > *std::prev(begin)) + { + sum += *begin - *std::prev(begin); + } + else + { + sum += *std::prev(begin) - *begin; + } + } + + return sum; +} + +template +ReturnType chatterjee_correlation_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using std::abs; + + BOOST_MATH_ASSERT_MSG(std::is_sorted(u_begin, u_end), "The x values must be sorted in order to use this functionality"); + + const std::vector rank_vector = rank(v_begin, v_end); + + std::size_t sum = chatterjee_transform(rank_vector.begin(), rank_vector.end()); + + ReturnType result = static_cast(1) - (static_cast(3 * sum) / static_cast(rank_vector.size() * rank_vector.size() - 1)); + + // If the result is 1 then Y is constant and all the elements must be ties + if (abs(result - static_cast(1)) < std::numeric_limits::epsilon()) + { + return std::numeric_limits::quiet_NaN(); + } + + return result; +} + +} // Namespace detail + +template ::value, double, Real>::type> +inline ReturnType chatterjee_correlation(const Container& u, const Container& v) +{ + return detail::chatterjee_correlation_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // Namespace boost::math::statistics + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +namespace boost::math::statistics { + +namespace detail { + +template +ReturnType chatterjee_correlation_par_impl(ExecutionPolicy&& exec, ForwardIterator u_begin, ForwardIterator u_end, + ForwardIterator v_begin, ForwardIterator v_end) +{ + using std::abs; + BOOST_MATH_ASSERT_MSG(std::is_sorted(std::forward(exec), u_begin, u_end), "The x values must be sorted in order to use this functionality"); + + auto rank_vector = rank(std::forward(exec), v_begin, v_end); + + const auto num_threads = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + std::vector> future_manager {}; + const auto elements_per_thread = std::ceil(static_cast(rank_vector.size()) / num_threads); + + auto it = rank_vector.begin(); + auto end = rank_vector.end(); + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread]() -> std::size_t + { + return chatterjee_transform(it, std::next(it, elements_per_thread)); + })); + it = std::next(it, elements_per_thread - 1); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, end]() -> std::size_t + { + return chatterjee_transform(it, end); + })); + + std::size_t sum {}; + for(std::size_t i {}; i < future_manager.size(); ++i) + { + sum += future_manager[i].get(); + } + + ReturnType result = static_cast(1) - (static_cast(3 * sum) / static_cast(rank_vector.size() * rank_vector.size() - 1)); + + // If the result is 1 then Y is constant and all the elements must be ties + if (abs(result - static_cast(1)) < std::numeric_limits::epsilon()) + { + return std::numeric_limits::quiet_NaN(); + } + + return result; +} + +} // Namespace detail + +template , double, Real>> +inline ReturnType chatterjee_correlation(ExecutionPolicy&& exec, const Container& u, const Container& v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::chatterjee_correlation_seq_impl(std::cbegin(u), std::cend(u), + std::cbegin(v), std::cend(v)); + } + else + { + return detail::chatterjee_correlation_par_impl(std::forward(exec), + std::cbegin(u), std::cend(u), + std::cbegin(v), std::cend(v)); + } +} + +} // Namespace boost::math::statistics + +#endif + +#endif // BOOST_MATH_STATISTICS_CHATTERJEE_CORRELATION_HPP diff --git a/third-party/boost-math/include/boost/math/statistics/detail/rank.hpp b/third-party/boost-math/include/boost/math/statistics/detail/rank.hpp new file mode 100644 index 0000000000000..4e5211607e7a2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/detail/rank.hpp @@ -0,0 +1,140 @@ +// (C) Copyright Matt Borland 2022 +// 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) + +#ifndef BOOST_MATH_STATISTICS_DETAIL_RANK_HPP +#define BOOST_MATH_STATISTICS_DETAIL_RANK_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#endif + +namespace boost { namespace math { namespace statistics { namespace detail { + +struct pair_equal +{ + template + bool operator()(const std::pair& a, const std::pair& b) const + { + return a.first == b.first; + } +}; + +}}}} // Namespaces + +#ifndef BOOST_MATH_EXEC_COMPATIBLE + +namespace boost { namespace math { namespace statistics { namespace detail { + +template ::value_type> +auto rank(ForwardIterator first, ForwardIterator last) -> std::vector +{ + std::size_t elements = std::distance(first, last); + + std::vector> rank_vector(elements); + std::size_t i = 0; + while (first != last) + { + rank_vector[i] = std::make_pair(*first, i); + ++i; + ++first; + } + + std::sort(rank_vector.begin(), rank_vector.end()); + + // Remove duplicates + rank_vector.erase(std::unique(rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end()); + elements = rank_vector.size(); + + std::pair rank; + std::vector result(elements); + for (i = 0; i < elements; ++i) + { + if (rank_vector[i].first != rank.first) + { + rank = std::make_pair(rank_vector[i].first, i); + } + result[rank_vector[i].second] = rank.second; + } + + return result; +} + +template +inline auto rank(const Container& c) -> std::vector +{ + return rank(std::begin(c), std::end(c)); +} + +}}}} // Namespaces + +#else + +namespace boost::math::statistics::detail { + +template ::value_type> +auto rank(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + std::size_t elements = std::distance(first, last); + + std::vector> rank_vector(elements); + std::size_t i = 0; + while (first != last) + { + rank_vector[i] = std::make_pair(*first, i); + ++i; + ++first; + } + + std::sort(exec, rank_vector.begin(), rank_vector.end()); + + // Remove duplicates + rank_vector.erase(std::unique(exec, rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end()); + elements = rank_vector.size(); + + std::pair rank; + std::vector result(elements); + for (i = 0; i < elements; ++i) + { + if (rank_vector[i].first != rank.first) + { + rank = std::make_pair(rank_vector[i].first, i); + } + result[rank_vector[i].second] = rank.second; + } + + return result; +} + +template +inline auto rank(ExecutionPolicy&& exec, const Container& c) +{ + return rank(exec, std::cbegin(c), std::cend(c)); +} + +template ::value_type> +inline auto rank(ForwardIterator first, ForwardIterator last) +{ + return rank(std::execution::seq, first, last); +} + +template +inline auto rank(const Container& c) +{ + return rank(std::execution::seq, std::cbegin(c), std::cend(c)); +} + +} // Namespaces + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +#endif // BOOST_MATH_STATISTICS_DETAIL_RANK_HPP diff --git a/third-party/boost-math/include/boost/math/statistics/detail/single_pass.hpp b/third-party/boost-math/include/boost/math/statistics/detail/single_pass.hpp new file mode 100644 index 0000000000000..015021f2b3e75 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/detail/single_pass.hpp @@ -0,0 +1,401 @@ +// (C) Copyright Nick Thompson 2018 +// (C) Copyright Matt Borland 2020 +// 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) + +#ifndef BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP +#define BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include +#include +#endif + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType mean_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + const std::size_t elements {static_cast(std::distance(first, last))}; + std::valarray mu {0, 0, 0, 0}; + std::valarray temp {0, 0, 0, 0}; + ReturnType i {1}; + const ForwardIterator end {std::next(first, elements - (elements % 4))}; + ForwardIterator it {first}; + + while(it != end) + { + const ReturnType inv {ReturnType(1) / i}; + temp = {static_cast(*it++), static_cast(*it++), static_cast(*it++), static_cast(*it++)}; + temp -= mu; + mu += (temp *= inv); + i += 1; + } + + const ReturnType num1 {ReturnType(elements - (elements % 4))/ReturnType(4)}; + const ReturnType num2 {num1 + ReturnType(elements % 4)}; + + while(it != last) + { + mu[3] += (*it-mu[3])/i; + i += 1; + ++it; + } + + return (num1 * std::valarray(mu[std::slice(0,3,1)]).sum() + num2 * mu[3]) / ReturnType(elements); +} + +// Higham, Accuracy and Stability, equation 1.6a and 1.6b: +// Calculates Mean, M2, and variance +template +ReturnType variance_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + Real M = *first; + Real Q = 0; + Real k = 2; + Real M2 = 0; + std::size_t n = 1; + + for(auto it = std::next(first); it != last; ++it) + { + Real tmp = (*it - M) / k; + Real delta_1 = *it - M; + Q += k*(k-1)*tmp*tmp; + M += tmp; + k += 1; + Real delta_2 = *it - M; + M2 += delta_1 * delta_2; + ++n; + } + + return std::make_tuple(M, M2, Q/(k-1), Real(n)); +} + +// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics +template +ReturnType first_four_moments_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using Size = typename std::tuple_element<4, ReturnType>::type; + + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real M4 = 0; + Size n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2, M3, M4, n-1); +} + +#ifdef BOOST_MATH_HAS_THREADS + +// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics +// EQN 3.1: https://www.osti.gov/servlets/purl/1426900 +template +ReturnType first_four_moments_parallel_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto elements = std::distance(first, last); + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // Threading is faster for: 10 + 5.13e-3 N/j <= 5.13e-3N => N >= 10^4j/5.13(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(5.13*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/5.13; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(elements < parallel_lower_bound) + { + return detail::first_four_moments_sequential_impl(first, last); + } + else if(elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(5.13*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(elements) / num_threads); + + auto it = first; + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread]() -> ReturnType + { + return first_four_moments_sequential_impl(it, std::next(it, elements_per_thread)); + })); + it = std::next(it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, last]() -> ReturnType + { + return first_four_moments_sequential_impl(it, last); + })); + + auto temp = future_manager[0].get(); + Real M1_a = std::get<0>(temp); + Real M2_a = std::get<1>(temp); + Real M3_a = std::get<2>(temp); + Real M4_a = std::get<3>(temp); + Real range_a = std::get<4>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real M1_b = std::get<0>(temp); + Real M2_b = std::get<1>(temp); + Real M3_b = std::get<2>(temp); + Real M4_b = std::get<3>(temp); + Real range_b = std::get<4>(temp); + + const Real n_ab = range_a + range_b; + const Real delta = M1_b - M1_a; + + M1_a = (range_a * M1_a + range_b * M1_b) / n_ab; + M2_a = M2_a + M2_b + delta * delta * (range_a * range_b / n_ab); + M3_a = M3_a + M3_b + (delta * delta * delta) * range_a * range_b * (range_a - range_b) / (n_ab * n_ab) + + Real(3) * delta * (range_a * M2_b - range_b * M2_a) / n_ab; + M4_a = M4_a + M4_b + (delta * delta * delta * delta) * range_a * range_b * (range_a * range_a - range_a * range_b + range_b * range_b) / (n_ab * n_ab * n_ab) + + Real(6) * delta * delta * (range_a * range_a * M2_b + range_b * range_b * M2_a) / (n_ab * n_ab) + + Real(4) * delta * (range_a * M3_b - range_b * M3_a) / n_ab; + range_a = n_ab; + } + + return std::make_tuple(M1_a, M2_a, M3_a, M4_a, elements); +} + +#endif // BOOST_MATH_HAS_THREADS + +// Follows equation 1.5 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +ReturnType skewness_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute skewness."); + + ReturnType M1 = *first; + ReturnType M2 = 0; + ReturnType M3 = 0; + ReturnType n = 2; + + for (auto it = std::next(first); it != last; ++it) + { + ReturnType delta21 = *it - M1; + ReturnType tmp = delta21/n; + M3 += tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 += tmp*(n-1)*delta21; + M1 += tmp; + n += 1; + } + + ReturnType var = M2/(n-1); + + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return ReturnType(0); + } + + ReturnType skew = M3/(M2*sqrt(var)); + return skew; +} + +template +ReturnType gini_coefficient_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + ReturnType i = 1; + ReturnType num = 0; + ReturnType denom = 0; + + for(auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if(denom == 0) + { + return ReturnType(0); + } + else + { + return ((2*num)/denom - i)/(i-1); + } +} + +template +ReturnType gini_range_fraction(ForwardIterator first, ForwardIterator last, std::size_t starting_index) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + std::size_t i = starting_index + 1; + Real num = 0; + Real denom = 0; + + for(auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + return std::make_tuple(num, denom, i); +} + +#ifdef BOOST_MATH_HAS_THREADS + +template +ReturnType gini_coefficient_parallel_impl(ExecutionPolicy&&, ForwardIterator first, ForwardIterator last) +{ + using range_tuple = std::tuple; + + const auto elements = std::distance(first, last); + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // Threading is faster for: 10 + 10.12e-3 N/j <= 10.12e-3N => N >= 10^4j/10.12(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(10.12*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/10.12; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(elements < parallel_lower_bound) + { + return gini_coefficient_sequential_impl(first, last); + } + else if(elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(10.12*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(elements) / num_threads); + + auto it = first; + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread, i]() -> range_tuple + { + return gini_range_fraction(it, std::next(it, elements_per_thread), i*elements_per_thread); + })); + it = std::next(it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, last, num_threads, elements_per_thread]() -> range_tuple + { + return gini_range_fraction(it, last, (num_threads - 1)*elements_per_thread); + })); + + ReturnType num = 0; + ReturnType denom = 0; + + for(std::size_t i = 0; i < future_manager.size(); ++i) + { + auto temp = future_manager[i].get(); + num += std::get<0>(temp); + denom += std::get<1>(temp); + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if(denom == 0) + { + return ReturnType(0); + } + else + { + return ((2*num)/denom - elements)/(elements-1); + } +} + +#endif // BOOST_MATH_HAS_THREADS + +template +OutputIterator mode_impl(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + using Z = typename std::iterator_traits::value_type; + using Size = typename std::iterator_traits::difference_type; + + std::vector modes {}; + modes.reserve(16); + Size max_counter {0}; + + while(first != last) + { + Size current_count {0}; + ForwardIterator end_it {first}; + while(end_it != last && *end_it == *first) + { + ++current_count; + ++end_it; + } + + if(current_count > max_counter) + { + modes.resize(1); + modes[0] = *first; + max_counter = current_count; + } + + else if(current_count == max_counter) + { + modes.emplace_back(*first); + } + + first = end_it; + } + + return std::move(modes.begin(), modes.end(), output); +} +}}}} + +#endif // BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP diff --git a/third-party/boost-math/include/boost/math/statistics/linear_regression.hpp b/third-party/boost-math/include/boost/math/statistics/linear_regression.hpp new file mode 100644 index 0000000000000..2def7ab7ea7d7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/linear_regression.hpp @@ -0,0 +1,133 @@ +/* + * Copyright Nick Thompson, 2019 + * Copyright Matt Borland, 2021 + * 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) + */ + +#ifndef BOOST_MATH_STATISTICS_LINEAR_REGRESSION_HPP +#define BOOST_MATH_STATISTICS_LINEAR_REGRESSION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + + +template +ReturnType simple_ordinary_least_squares_impl(RandomAccessContainer const & x, + RandomAccessContainer const & y) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + if (x.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to perform a linear regression."); + } + + if (x.size() != y.size()) + { + throw std::domain_error("The same number of samples must be in the independent and dependent variable."); + } + std::tuple temp = boost::math::statistics::means_and_covariance(x, y); + Real mu_x = std::get<0>(temp); + Real mu_y = std::get<1>(temp); + Real cov_xy = std::get<2>(temp); + + Real var_x = boost::math::statistics::variance(x); + + if (var_x <= 0) { + throw std::domain_error("Independent variable has no variance; this breaks linear regression."); + } + + + Real c1 = cov_xy/var_x; + Real c0 = mu_y - c1*mu_x; + + return std::make_pair(c0, c1); +} + +template +ReturnType simple_ordinary_least_squares_with_R_squared_impl(RandomAccessContainer const & x, + RandomAccessContainer const & y) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + if (x.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to perform a linear regression."); + } + + if (x.size() != y.size()) + { + throw std::domain_error("The same number of samples must be in the independent and dependent variable."); + } + std::tuple temp = boost::math::statistics::means_and_covariance(x, y); + Real mu_x = std::get<0>(temp); + Real mu_y = std::get<1>(temp); + Real cov_xy = std::get<2>(temp); + + Real var_x = boost::math::statistics::variance(x); + + if (var_x <= 0) { + throw std::domain_error("Independent variable has no variance; this breaks linear regression."); + } + + + Real c1 = cov_xy/var_x; + Real c0 = mu_y - c1*mu_x; + + Real squared_residuals = 0; + Real squared_mean_deviation = 0; + for(decltype(y.size()) i = 0; i < y.size(); ++i) { + squared_mean_deviation += (y[i] - mu_y)*(y[i]-mu_y); + Real ei = (c0 + c1*x[i]) - y[i]; + squared_residuals += ei*ei; + } + + Real Rsquared; + if (squared_mean_deviation == 0) { + // Then y = constant, so the linear regression is perfect. + Rsquared = 1; + } else { + Rsquared = 1 - squared_residuals/squared_mean_deviation; + } + + return std::make_tuple(c0, c1, Rsquared); +} +} // namespace detail + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::pair +{ + return detail::simple_ordinary_least_squares_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::pair +{ + return detail::simple_ordinary_least_squares_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares_with_R_squared(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::tuple +{ + return detail::simple_ordinary_least_squares_with_R_squared_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares_with_R_squared(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::tuple +{ + return detail::simple_ordinary_least_squares_with_R_squared_impl>(x, y); +} +}}} // namespace boost::math::statistics +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/ljung_box.hpp b/third-party/boost-math/include/boost/math/statistics/ljung_box.hpp new file mode 100644 index 0000000000000..6417665ce4baa --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/ljung_box.hpp @@ -0,0 +1,70 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_STATISTICS_LJUNG_BOX_HPP +#define BOOST_MATH_STATISTICS_LJUNG_BOX_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::statistics { + +template +auto ljung_box(RandomAccessIterator begin, RandomAccessIterator end, int64_t lags = -1, int64_t fit_dof = 0) { + using Real = typename std::iterator_traits::value_type; + int64_t n = std::distance(begin, end); + if (lags >= n) { + throw std::domain_error("Number of lags must be < number of elements in array."); + } + + if (lags == -1) { + // This is the same default as Mathematica; it seems sensible enough . . . + lags = static_cast(std::ceil(std::log(Real(n)))); + } + + if (lags <= 0) { + throw std::domain_error("Must have at least one lag."); + } + + auto mu = boost::math::statistics::mean(begin, end); + + std::vector r(lags + 1, Real(0)); + for (size_t i = 0; i < r.size(); ++i) { + for (auto it = begin + i; it != end; ++it) { + Real ak = *(it) - mu; + Real akml = *(it-i) - mu; + r[i] += ak*akml; + } + } + + Real Q = 0; + + for (size_t k = 1; k < r.size(); ++k) { + Q += r[k]*r[k]/(r[0]*r[0]*(n-k)); + } + Q *= n*(n+2); + + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + auto chi = boost::math::chi_squared_distribution(Real(lags - fit_dof)); + + Real pvalue = 1 - boost::math::cdf(chi, Q); + return std::make_pair(Q, pvalue); +} + + +template +auto ljung_box(RandomAccessContainer const & v, int64_t lags = -1, int64_t fit_dof = 0) { + return ljung_box(v.begin(), v.end(), lags, fit_dof); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/runs_test.hpp b/third-party/boost-math/include/boost/math/statistics/runs_test.hpp new file mode 100644 index 0000000000000..dc1a6ecf68c60 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/runs_test.hpp @@ -0,0 +1,121 @@ +/* + * Copyright Nick Thompson, 2019 + * 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) + */ + +#ifndef BOOST_MATH_STATISTICS_RUNS_TEST_HPP +#define BOOST_MATH_STATISTICS_RUNS_TEST_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::statistics { + +template +auto runs_above_and_below_threshold(RandomAccessContainer const & v, + typename RandomAccessContainer::value_type threshold) +{ + using Real = typename RandomAccessContainer::value_type; + using std::sqrt; + using std::abs; + if (v.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to get number of runs."); + } + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + decltype(v.size()) nabove = 0; + decltype(v.size()) nbelow = 0; + + decltype(v.size()) imin = 0; + + // Take care of the case that v[0] == threshold: + while (imin < v.size() && v[imin] == threshold) { + ++imin; + } + + // Take care of the constant vector case: + if (imin == v.size()) { + return std::make_pair(std::numeric_limits::quiet_NaN(), Real(0)); + } + + bool run_up = (v[imin] > threshold); + if (run_up) { + ++nabove; + } else { + ++nbelow; + } + decltype(v.size()) runs = 1; + for (decltype(v.size()) i = imin + 1; i < v.size(); ++i) { + if (v[i] == threshold) { + // skip values precisely equal to threshold (following R's randtests package) + continue; + } + bool above = (v[i] > threshold); + if (above) { + ++nabove; + } else { + ++nbelow; + } + if (run_up == above) { + continue; + } + else { + run_up = above; + runs++; + } + } + + // If you make n an int, the subtraction is gonna be bad in the variance: + Real n = nabove + nbelow; + + Real expected_runs = Real(1) + Real(2*nabove*nbelow)/Real(n); + Real variance = 2*nabove*nbelow*(2*nabove*nbelow-n)/Real(n*n*(n-1)); + + // Bizarre, pathological limits: + if (variance == 0) + { + if (runs == expected_runs) + { + Real statistic = 0; + Real pvalue = 1; + return std::make_pair(statistic, pvalue); + } + else + { + return std::make_pair(std::numeric_limits::quiet_NaN(), Real(0)); + } + } + + Real sd = sqrt(variance); + Real statistic = (runs - expected_runs)/sd; + + auto normal = boost::math::normal_distribution(0,1); + Real pvalue = 2*boost::math::cdf(normal, -abs(statistic)); + return std::make_pair(statistic, pvalue); +} + +template +auto runs_above_and_below_median(RandomAccessContainer const & v) +{ + using Real = typename RandomAccessContainer::value_type; + using std::log; + using std::sqrt; + + // We have to memcpy v because the median does a partial sort, + // and that would be catastrophic for the runs test. + auto w = v; + Real median = boost::math::statistics::median(w); + return runs_above_and_below_threshold(v, median); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/signal_statistics.hpp b/third-party/boost-math/include/boost/math/statistics/signal_statistics.hpp new file mode 100644 index 0000000000000..d2ded721cef2b --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/signal_statistics.hpp @@ -0,0 +1,350 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP +#define BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math::statistics { + +template +auto absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + using std::abs; + using RealOrComplex = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last, [](RealOrComplex a, RealOrComplex b) { return abs(b) > abs(a); }); + + + decltype(abs(*first)) i = 1; + decltype(abs(*first)) num = 0; + decltype(abs(*first)) denom = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + num += tmp*i; + denom += tmp; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + decltype(abs(*first)) zero = 0; + return zero; + } + return ((2*num)/denom - i)/(i-1); +} + +template +inline auto absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::statistics::absolute_gini_coefficient(v.begin(), v.end()); +} + +template +auto sample_absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + return n*boost::math::statistics::absolute_gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::statistics::sample_absolute_gini_coefficient(v.begin(), v.end()); +} + + +// The Hoyer sparsity measure is defined in: +// https://arxiv.org/pdf/0811.4706.pdf +template +auto hoyer_sparsity(const ForwardIterator first, const ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Hoyer sparsity requires at least two samples."); + + if constexpr (std::is_unsigned::value) + { + T l1 = 0; + T l2 = 0; + size_t n = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + l2 += (*it)*(*it); + n += 1; + } + + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else { + decltype(abs(*first)) l1 = 0; + decltype(abs(*first)) l2 = 0; + // We wouldn't need to count the elements if it was a random access iterator, + // but our only constraint is that it's a forward iterator. + size_t n = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + l1 += tmp; + l2 += tmp*tmp; + n += 1; + } + if constexpr (std::is_integral::value) + { + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else + { + decltype(abs(*first)) rootn = sqrt(static_cast(n)); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + } +} + +template +inline auto hoyer_sparsity(Container const & v) +{ + return boost::math::statistics::hoyer_sparsity(v.cbegin(), v.cend()); +} + + +template +auto oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), + "Signal and noisy_signal must be have the same number of elements."); + if constexpr (std::is_integral::value) + { + double numerator = 0; + double denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (noisy_signal[i] - signal[i])*(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + return numerator/denominator; + } + else if constexpr (boost::math::tools::is_complex_type::value) + + { + using std::norm; + typename Real::value_type numerator = 0; + typename Real::value_type denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += norm(signal[i]); + denominator += norm(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } + else + { + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } +} + +template +auto mean_invariant_oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), "Signal and noisy signal must be have the same number of elements."); + + Real mu = boost::math::statistics::mean(signal); + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + Real tmp = signal[i] - mu; + numerator += tmp*tmp; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + +} + +template +auto mean_invariant_oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::statistics::mean_invariant_oracle_snr(signal, noisy_signal)); +} + + +// Follows the definition of SNR given in Mallat, A Wavelet Tour of Signal Processing, equation 11.16. +template +auto oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::statistics::oracle_snr(signal, noisy_signal)); +} + +// A good reference on the M2M4 estimator: +// D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR estimation techniques for the AWGN channel," IEEE Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. +// A nice python implementation: +// https://github.com/gnuradio/gnuradio/blob/master/gr-digital/examples/snr_estimators.py +template +auto m2m4_snr_estimator(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + BOOST_MATH_ASSERT_MSG(estimated_signal_kurtosis > 0, "The estimated signal kurtosis must be positive"); + BOOST_MATH_ASSERT_MSG(estimated_noise_kurtosis > 0, "The estimated noise kurtosis must be positive."); + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + if constexpr (std::is_floating_point::value || std::numeric_limits::max_exponent) + { + // If we first eliminate N, we obtain the quadratic equation: + // (ka+kw-6)S^2 + 2M2(3-kw)S + kw*M2^2 - M4 = 0 =: a*S^2 + bs*N + cs = 0 + // If we first eliminate S, we obtain the quadratic equation: + // (ka+kw-6)N^2 + 2M2(3-ka)N + ka*M2^2 - M4 = 0 =: a*N^2 + bn*N + cn = 0 + // I believe these equations are totally independent quadratics; + // if one has a complex solution it is not necessarily the case that the other must also. + // However, I can't prove that, so there is a chance that this does unnecessary work. + // Future improvements: There are algorithms which can solve quadratics much more effectively than the naive implementation found here. + // See: https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711#50065711 + auto [M1, M2, M3, M4] = boost::math::statistics::first_four_moments(first, last); + if (M4 == 0) + { + // The signal is constant. There is no noise: + return std::numeric_limits::infinity(); + } + // Change to notation in Pauluzzi, equation 41: + auto kw = estimated_noise_kurtosis; + auto ka = estimated_signal_kurtosis; + // A common case, since it's the default: + Real a = (ka+kw-6); + Real bs = 2*M2*(3-kw); + Real cs = kw*M2*M2 - M4; + Real bn = 2*M2*(3-ka); + Real cn = ka*M2*M2 - M4; + auto [S0, S1] = boost::math::tools::quadratic_roots(a, bs, cs); + if (S1 > 0) + { + auto N = M2 - S1; + if (N > 0) + { + return S1/N; + } + if (S0 > 0) + { + N = M2 - S0; + if (N > 0) + { + return S0/N; + } + } + } + auto [N0, N1] = boost::math::tools::quadratic_roots(a, bn, cn); + if (N1 > 0) + { + auto S = M2 - N1; + if (S > 0) + { + return S/N1; + } + if (N0 > 0) + { + S = M2 - N0; + if (S > 0) + { + return S/N0; + } + } + } + // This happens distressingly often. It's a limitation of the method. + return std::numeric_limits::quiet_NaN(); + } + else + { + BOOST_MATH_ASSERT_MSG(false, "The M2M4 estimator has not been implemented for this type."); + return std::numeric_limits::quiet_NaN(); + } +} + +template +inline auto m2m4_snr_estimator(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + return m2m4_snr_estimator(noisy_signal.cbegin(), noisy_signal.cend(), estimated_signal_kurtosis, estimated_noise_kurtosis); +} + +template +inline auto m2m4_snr_estimator_db(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(first, last, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + + +template +inline auto m2m4_snr_estimator_db(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(noisy_signal, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/t_test.hpp b/third-party/boost-math/include/boost/math/statistics/t_test.hpp new file mode 100644 index 0000000000000..ec06bda8c345f --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/t_test.hpp @@ -0,0 +1,275 @@ +// (C) Copyright Nick Thompson 2019. +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_STATISTICS_T_TEST_HPP +#define BOOST_MATH_STATISTICS_T_TEST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType one_sample_t_test_impl(T sample_mean, T sample_variance, T num_samples, T assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + Real test_statistic = (sample_mean - assumed_mean)/sqrt(sample_variance/num_samples); + auto student = boost::math::students_t_distribution(num_samples - 1); + Real pvalue; + if (test_statistic > 0) { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType one_sample_t_test_impl(ForwardIterator begin, ForwardIterator end, typename std::iterator_traits::value_type assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + std::pair temp = mean_and_sample_variance(begin, end); + Real mu = std::get<0>(temp); + Real s_sq = std::get<1>(temp); + return one_sample_t_test_impl(mu, s_sq, Real(std::distance(begin, end)), Real(assumed_mean)); +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes,_unequal_variances_(sX1_%3E_2sX2_or_sX2_%3E_2sX1) +template +ReturnType welchs_t_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + Real dof_num = (variance_1/size_1 + variance_2/size_2) * (variance_1/size_1 + variance_2/size_2); + Real dof_denom = ((variance_1/size_1) * (variance_1/size_1))/(size_1 - 1) + + ((variance_2/size_2) * (variance_2/size_2))/(size_2 - 1); + Real dof = dof_num / dof_denom; + + Real s_estimator = sqrt((variance_1/size_1) + (variance_2/size_2)); + + Real test_statistic = (static_cast(mean_1) - static_cast(mean_2))/s_estimator; + auto student = boost::math::students_t_distribution(dof); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes,_similar_variances_(1/2_%3C_sX1/sX2_%3C_2) +template +ReturnType two_sample_t_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + Real dof = size_1 + size_2 - 2; + Real pooled_std_dev = sqrt(((size_1-1)*variance_1 + (size_2-1)*variance_2) / dof); + Real test_statistic = (mean_1-mean_2) / (pooled_std_dev*sqrt(1.0/static_cast(size_1) + 1.0/static_cast(size_2))); + + auto student = boost::math::students_t_distribution(dof); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType two_sample_t_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + auto n1 = std::distance(begin_1, end_1); + auto n2 = std::distance(begin_2, end_2); + + ReturnType temp_1 = mean_and_sample_variance(begin_1, end_1); + Real mean_1 = std::get<0>(temp_1); + Real variance_1 = std::get<1>(temp_1); + Real std_dev_1 = sqrt(variance_1); + + ReturnType temp_2 = mean_and_sample_variance(begin_2, end_2); + Real mean_2 = std::get<0>(temp_2); + Real variance_2 = std::get<1>(temp_2); + Real std_dev_2 = sqrt(variance_2); + + if(std_dev_1 > 2 * std_dev_2 || std_dev_2 > 2 * std_dev_1) + { + return welchs_t_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); + } + else + { + return two_sample_t_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); + } +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Dependent_t-test_for_paired_samples +template +ReturnType paired_samples_t_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + std::vector delta; + ForwardIterator it_1 = begin_1; + ForwardIterator it_2 = begin_2; + std::size_t n = 0; + while(it_1 != end_1 && it_2 != end_2) + { + delta.emplace_back(static_cast(*it_1++) - static_cast(*it_2++)); + ++n; + } + + if(it_1 != end_1 || it_2 != end_2) + { + throw std::domain_error("Both sets must have the same number of values."); + } + + std::pair temp = mean_and_sample_variance(delta.begin(), delta.end()); + Real delta_mean = std::get<0>(temp); + Real delta_std_dev = sqrt(std::get<1>(temp)); + + Real test_statistic = delta_mean/(delta_std_dev/sqrt(n)); + + auto student = boost::math::students_t_distribution(n - 1); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} +} // namespace detail + +template::value, bool>::type = true> +inline auto one_sample_t_test(Real sample_mean, Real sample_variance, Real num_samples, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(sample_mean, sample_variance, num_samples, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Real sample_mean, Real sample_variance, Real num_samples, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(sample_mean, sample_variance, num_samples, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_t_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(begin, end, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_t_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(begin, end, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto two_sample_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto two_sample_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto paired_samples_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::paired_samples_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto paired_samples_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::paired_samples_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto paired_samples_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::paired_samples_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto paired_samples_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::paired_samples_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // namespace boost::math::statistics +#endif diff --git a/third-party/boost-math/include/boost/math/statistics/univariate_statistics.hpp b/third-party/boost-math/include/boost/math/statistics/univariate_statistics.hpp new file mode 100644 index 0000000000000..20acd635727e6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/univariate_statistics.hpp @@ -0,0 +1,1184 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2020. +// 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) + +#ifndef BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_HPP +#define BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include + +namespace boost::math::statistics { + +template +inline auto mean(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::mean_sequential_impl(first, last); + } + else + { + return std::reduce(exec, first, last, 0.0) / std::distance(first, last); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::mean_sequential_impl(first, last); + } + else + { + return std::reduce(exec, first, last, Real(0.0)) / Real(std::distance(first, last)); + } + } +} + +template +inline auto mean(ExecutionPolicy&& exec, Container const & v) +{ + return mean(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean(ForwardIterator first, ForwardIterator last) +{ + return mean(std::execution::seq, first, last); +} + +template +inline auto mean(Container const & v) +{ + return mean(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return std::get<2>(detail::variance_sequential_impl>(first, last)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::get<1>(results) / std::get<4>(results); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return std::get<2>(detail::variance_sequential_impl>(first, last)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::get<1>(results) / std::get<4>(results); + } + } +} + +template +inline auto variance(ExecutionPolicy&& exec, Container const & v) +{ + return variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto variance(ForwardIterator first, ForwardIterator last) +{ + return variance(std::execution::seq, first, last); +} + +template +inline auto variance(Container const & v) +{ + return variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto sample_variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(exec, first, last)/(n-1); +} + +template +inline auto sample_variance(ExecutionPolicy&& exec, Container const & v) +{ + return sample_variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto sample_variance(ForwardIterator first, ForwardIterator last) +{ + return sample_variance(std::execution::seq, first, last); +} + +template +inline auto sample_variance(Container const & v) +{ + return sample_variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean_and_sample_variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<2>(results)*std::get<3>(results)/(std::get<3>(results)-1.0)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<1>(results) / (std::get<4>(results)-1.0)); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<2>(results)*std::get<3>(results)/(std::get<3>(results)-Real(1))); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<1>(results) / (std::get<4>(results)-Real(1))); + } + } +} + +template +inline auto mean_and_sample_variance(ExecutionPolicy&& exec, Container const & v) +{ + return mean_and_sample_variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean_and_sample_variance(ForwardIterator first, ForwardIterator last) +{ + return mean_and_sample_variance(std::execution::seq, first, last); +} + +template +inline auto mean_and_sample_variance(Container const & v) +{ + return mean_and_sample_variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto first_four_moments(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + } +} + +template +inline auto first_four_moments(ExecutionPolicy&& exec, Container const & v) +{ + return first_four_moments(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto first_four_moments(ForwardIterator first, ForwardIterator last) +{ + return first_four_moments(std::execution::seq, first, last); +} + +template +inline auto first_four_moments(Container const & v) +{ + return first_four_moments(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +inline auto skewness(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + return detail::skewness_sequential_impl(first, last); + } + else + { + return detail::skewness_sequential_impl(first, last); + } + } + else + { + const auto [M1, M2, M3, M4] = first_four_moments(exec, first, last); + const auto n = std::distance(first, last); + const auto var = M2/(n-1); + + if (M2 == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + if constexpr (std::is_integral_v) + { + return static_cast(0); + } + else + { + return Real(0); + } + } + else + { + return M3/(M2*sqrt(var)) / Real(2); + } + } +} + +template +inline auto skewness(ExecutionPolicy&& exec, Container & v) +{ + return skewness(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto skewness(ForwardIterator first, ForwardIterator last) +{ + return skewness(std::execution::seq, first, last); +} + +template +inline auto skewness(Container const & v) +{ + return skewness(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +// Follows equation 1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +inline auto kurtosis(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + const auto [M1, M2, M3, M4] = first_four_moments(exec, first, last); + if (M2 == 0) + { + return M2; + } + return M4/(M2*M2); +} + +template +inline auto kurtosis(ExecutionPolicy&& exec, Container const & v) +{ + return kurtosis(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto kurtosis(ForwardIterator first, ForwardIterator last) +{ + return kurtosis(std::execution::seq, first, last); +} + +template +inline auto kurtosis(Container const & v) +{ + return kurtosis(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto excess_kurtosis(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + return kurtosis(exec, first, last) - 3; +} + +template +inline auto excess_kurtosis(ExecutionPolicy&& exec, Container const & v) +{ + return excess_kurtosis(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto excess_kurtosis(ForwardIterator first, ForwardIterator last) +{ + return excess_kurtosis(std::execution::seq, first, last); +} + +template +inline auto excess_kurtosis(Container const & v) +{ + return excess_kurtosis(std::execution::seq, std::cbegin(v), std::cend(v)); +} + + +template +auto median(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(exec, first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(exec, first, middle, last); + std::nth_element(exec, middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + + +template +inline auto median(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return median(exec, std::begin(v), std::end(v)); +} + +template +inline auto median(RandomAccessIterator first, RandomAccessIterator last) +{ + return median(std::execution::seq, first, last); +} + +template +inline auto median(RandomAccessContainer & v) +{ + return median(std::execution::seq, std::begin(v), std::end(v)); +} + +#if 0 +// +// Parallel gini calculation is curently broken, see: +// https://github.com/boostorg/math/issues/585 +// We will fix this at a later date, for now just use a serial implementation: +// +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if(!std::is_sorted(exec, first, last)) + { + std::sort(exec, first, last); + } + + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_sequential_impl(first, last); + } + else + { + return detail::gini_coefficient_sequential_impl(first, last); + } + } + + else if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_parallel_impl(exec, first, last); + } + + else + { + return detail::gini_coefficient_parallel_impl(exec, first, last); + } +} +#else +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if (!std::is_sorted(exec, first, last)) + { + std::sort(exec, first, last); + } + + if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_sequential_impl(first, last); + } + else + { + return detail::gini_coefficient_sequential_impl(first, last); + } +} +#endif + +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return gini_coefficient(exec, std::begin(v), std::end(v)); +} + +template +inline auto gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + return gini_coefficient(std::execution::seq, first, last); +} + +template +inline auto gini_coefficient(RandomAccessContainer & v) +{ + return gini_coefficient(std::execution::seq, std::begin(v), std::end(v)); +} + +template +inline auto sample_gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(exec, first, last)/(n-1); +} + +template +inline auto sample_gini_coefficient(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return sample_gini_coefficient(exec, std::begin(v), std::end(v)); +} + +template +inline auto sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + return sample_gini_coefficient(std::execution::seq, first, last); +} + +template +inline auto sample_gini_coefficient(RandomAccessContainer & v) +{ + return sample_gini_coefficient(std::execution::seq, std::begin(v), std::end(v)); +} + +template +auto median_absolute_deviation(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, + typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using Real = typename std::iterator_traits::value_type; + using std::isnan; + if (isnan(center)) + { + center = boost::math::statistics::median(exec, first, last); + } + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(exec, first, middle, last, comparator); + return abs(*middle-center); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(exec, first, middle, last, comparator); + std::nth_element(exec, middle, middle+1, last, comparator); + return (abs(*middle-center) + abs(*(middle+1)-center))/abs(static_cast(2)); + } +} + +template +inline auto median_absolute_deviation(ExecutionPolicy&& exec, RandomAccessContainer & v, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(exec, std::begin(v), std::end(v), center); +} + +template +inline auto median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, + typename RandomAccessIterator::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::execution::seq, first, last, center); +} + +template +inline auto median_absolute_deviation(RandomAccessContainer & v, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::execution::seq, std::begin(v), std::end(v), center); +} + +template +auto interquartile_range(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + static_assert(!std::is_integral_v, "Integer values have not yet been implemented."); + auto m = std::distance(first,last); + BOOST_MATH_ASSERT_MSG(m >= 3, "At least 3 samples are required to compute the interquartile range."); + auto k = m/4; + auto j = m - (4*k); + // m = 4k+j. + // If j = 0 or j = 1, then there are an even number of samples below the median, and an even number above the median. + // Then we must average adjacent elements to get the quartiles. + // If j = 2 or j = 3, there are an odd number of samples above and below the median, these elements may be directly extracted to get the quartiles. + + if (j==2 || j==3) + { + auto q1 = first + k; + auto q3 = first + 3*k + j - 1; + std::nth_element(exec, first, q1, last); + Real Q1 = *q1; + std::nth_element(exec, q1, q3, last); + Real Q3 = *q3; + return Q3 - Q1; + } else { + // j == 0 or j==1: + auto q1 = first + k - 1; + auto q3 = first + 3*k - 1 + j; + std::nth_element(exec, first, q1, last); + Real a = *q1; + std::nth_element(exec, q1, q1 + 1, last); + Real b = *(q1 + 1); + Real Q1 = (a+b)/2; + std::nth_element(exec, q1, q3, last); + a = *q3; + std::nth_element(exec, q3, q3 + 1, last); + b = *(q3 + 1); + Real Q3 = (a+b)/2; + return Q3 - Q1; + } +} + +template +inline auto interquartile_range(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return interquartile_range(exec, std::begin(v), std::end(v)); +} + +template +inline auto interquartile_range(RandomAccessIterator first, RandomAccessIterator last) +{ + return interquartile_range(std::execution::seq, first, last); +} + +template +inline auto interquartile_range(RandomAccessContainer & v) +{ + return interquartile_range(std::execution::seq, std::begin(v), std::end(v)); +} + +template +inline OutputIterator mode(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(exec, first, last)) + { + if constexpr (std::is_same_v::iterator_category(), std::random_access_iterator_tag>) + { + std::sort(exec, first, last); + } + else + { + BOOST_MATH_ASSERT("Data must be sorted for sequential mode calculation"); + } + } + + return detail::mode_impl(first, last, output); +} + +template +inline OutputIterator mode(ExecutionPolicy&& exec, Container & v, OutputIterator output) +{ + return mode(exec, std::begin(v), std::end(v), output); +} + +template +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + return mode(std::execution::seq, first, last, output); +} + +// Requires enable_if_t to not clash with impl that returns std::list +// Very ugly. std::is_execution_policy_v returns false for the std::execution objects and decltype of the objects (e.g. std::execution::seq) +template && + !std::is_convertible_v && + !std::is_convertible_v + #if __cpp_lib_execution > 201900 + && !std::is_convertible_v + #endif + , bool> = true> +inline OutputIterator mode(Container & v, OutputIterator output) +{ + return mode(std::execution::seq, std::begin(v), std::end(v), output); +} + +// std::list is the return type for the proposed STL stats library + +template::value_type> +inline auto mode(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + std::list modes; + mode(exec, first, last, std::inserter(modes, modes.begin())); + return modes; +} + +template +inline auto mode(ExecutionPolicy&& exec, Container & v) +{ + return mode(exec, std::begin(v), std::end(v)); +} + +template +inline auto mode(ForwardIterator first, ForwardIterator last) +{ + return mode(std::execution::seq, first, last); +} + +template +inline auto mode(Container & v) +{ + return mode(std::execution::seq, std::begin(v), std::end(v)); +} + +} // Namespace boost::math::statistics + +#else // Backwards compatible bindings for C++11 or execution is not implemented + +namespace boost { namespace math { namespace statistics { + +template +using enable_if_t = typename std::enable_if::type; + +template::value_type, + enable_if_t::value, bool> = true> +inline double mean(const ForwardIterator first, const ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + return detail::mean_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double mean(const Container& c) +{ + return mean(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real mean(const ForwardIterator first, const ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + return detail::mean_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real mean(const Container& c) +{ + return mean(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double variance(const ForwardIterator first, const ForwardIterator last) +{ + return std::get<2>(detail::variance_sequential_impl>(first, last)); +} + +template::value, bool> = true> +inline double variance(const Container& c) +{ + return variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real variance(const ForwardIterator first, const ForwardIterator last) +{ + return std::get<2>(detail::variance_sequential_impl>(first, last)); + +} + +template::value, bool> = true> +inline Real variance(const Container& c) +{ + return variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template::value, bool> = true> +inline double sample_variance(const Container& c) +{ + return sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template::value, bool> = true> +inline Real sample_variance(const Container& c) +{ + return sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::pair mean_and_sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<3>(results)*std::get<2>(results)/(std::get<3>(results)-1.0)); +} + +template::value, bool> = true> +inline std::pair mean_and_sample_variance(const Container& c) +{ + return mean_and_sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::pair mean_and_sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<3>(results)*std::get<2>(results)/(std::get<3>(results)-Real(1))); +} + +template::value, bool> = true> +inline std::pair mean_and_sample_variance(const Container& c) +{ + return mean_and_sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::tuple first_four_moments(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); +} + +template::value, bool> = true> +inline std::tuple first_four_moments(const Container& c) +{ + return first_four_moments(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::tuple first_four_moments(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); +} + +template::value, bool> = true> +inline std::tuple first_four_moments(const Container& c) +{ + return first_four_moments(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double skewness(const ForwardIterator first, const ForwardIterator last) +{ + return detail::skewness_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double skewness(const Container& c) +{ + return skewness(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real skewness(const ForwardIterator first, const ForwardIterator last) +{ + return detail::skewness_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real skewness(const Container& c) +{ + return skewness(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + std::tuple M = first_four_moments(first, last); + + if(std::get<1>(M) == 0) + { + return std::get<1>(M); + } + else + { + return std::get<3>(M)/(std::get<1>(M)*std::get<1>(M)); + } +} + +template::value, bool> = true> +inline double kurtosis(const Container& c) +{ + return kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + std::tuple M = first_four_moments(first, last); + + if(std::get<1>(M) == 0) + { + return std::get<1>(M); + } + else + { + return std::get<3>(M)/(std::get<1>(M)*std::get<1>(M)); + } +} + +template::value, bool> = true> +inline Real kurtosis(const Container& c) +{ + return kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double excess_kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template::value, bool> = true> +inline double excess_kurtosis(const Container& c) +{ + return excess_kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real excess_kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template::value, bool> = true> +inline Real excess_kurtosis(const Container& c) +{ + return excess_kurtosis(std::begin(c), std::end(c)); +} + +template::value_type> +Real median(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last); + std::nth_element(middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + +template +inline Real median(RandomAccessContainer& c) +{ + return median(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::gini_coefficient_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double gini_coefficient(RandomAccessContainer& c) +{ + return gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::gini_coefficient_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real gini_coefficient(RandomAccessContainer& c) +{ + return gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template::value, bool> = true> +inline double sample_gini_coefficient(RandomAccessContainer& c) +{ + return sample_gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template::value, bool> = true> +inline Real sample_gini_coefficient(RandomAccessContainer& c) +{ + return sample_gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type> +Real median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, + typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using std::isnan; + if (isnan(center)) + { + center = boost::math::statistics::median(first, last); + } + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last, comparator); + return abs(*middle-center); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last, comparator); + std::nth_element(middle, middle+1, last, comparator); + return (abs(*middle-center) + abs(*(middle+1)-center))/abs(static_cast(2)); + } +} + +template +inline Real median_absolute_deviation(RandomAccessContainer& c, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::begin(c), std::end(c), center); +} + +template::value_type> +Real interquartile_range(ForwardIterator first, ForwardIterator last) +{ + static_assert(!std::is_integral::value, "Integer values have not yet been implemented."); + auto m = std::distance(first,last); + BOOST_MATH_ASSERT_MSG(m >= 3, "At least 3 samples are required to compute the interquartile range."); + auto k = m/4; + auto j = m - (4*k); + // m = 4k+j. + // If j = 0 or j = 1, then there are an even number of samples below the median, and an even number above the median. + // Then we must average adjacent elements to get the quartiles. + // If j = 2 or j = 3, there are an odd number of samples above and below the median, these elements may be directly extracted to get the quartiles. + + if (j==2 || j==3) + { + auto q1 = first + k; + auto q3 = first + 3*k + j - 1; + std::nth_element(first, q1, last); + Real Q1 = *q1; + std::nth_element(q1, q3, last); + Real Q3 = *q3; + return Q3 - Q1; + } + else + { + // j == 0 or j==1: + auto q1 = first + k - 1; + auto q3 = first + 3*k - 1 + j; + std::nth_element(first, q1, last); + Real a = *q1; + std::nth_element(q1, q1 + 1, last); + Real b = *(q1 + 1); + Real Q1 = (a+b)/2; + std::nth_element(q1, q3, last); + a = *q3; + std::nth_element(q3, q3 + 1, last); + b = *(q3 + 1); + Real Q3 = (a+b)/2; + return Q3 - Q1; + } +} + +template +Real interquartile_range(Container& c) +{ + return interquartile_range(std::begin(c), std::end(c)); +} + +template::iterator_category(), std::random_access_iterator_tag>::value, bool> = true> +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::mode_impl(first, last, output); +} + +template::iterator_category(), std::random_access_iterator_tag>::value, bool> = true> +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(first, last)) + { + BOOST_MATH_ASSERT("Data must be sorted for mode calculation"); + } + + return detail::mode_impl(first, last, output); +} + +template +inline OutputIterator mode(Container& c, OutputIterator output) +{ + return mode(std::begin(c), std::end(c), output); +} + +template::value_type> +inline std::list mode(ForwardIterator first, ForwardIterator last) +{ + std::list modes; + mode(first, last, std::inserter(modes, modes.begin())); + return modes; +} + +template +inline std::list mode(Container& c) +{ + return mode(std::begin(c), std::end(c)); +} +}}} +#endif +#endif // BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_HPP diff --git a/third-party/boost-math/include/boost/math/statistics/z_test.hpp b/third-party/boost-math/include/boost/math/statistics/z_test.hpp new file mode 100644 index 0000000000000..a8ef838e40bf1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/statistics/z_test.hpp @@ -0,0 +1,161 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_STATISTICS_Z_TEST_HPP +#define BOOST_MATH_STATISTICS_Z_TEST_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType one_sample_z_test_impl(T sample_mean, T sample_variance, T sample_size, T assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + + Real test_statistic = (sample_mean - assumed_mean) / (sample_variance / sqrt(sample_size)); + auto z = boost::math::normal_distribution(sample_size - 1); + Real pvalue; + if(test_statistic > 0) + { + pvalue = 2*boost::math::cdf(z, -test_statistic); + } + else + { + pvalue = 2*boost::math::cdf(z, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType one_sample_z_test_impl(ForwardIterator begin, ForwardIterator end, typename std::iterator_traits::value_type assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + std::pair temp = mean_and_sample_variance(begin, end); + Real mu = std::get<0>(temp); + Real s_sq = std::get<1>(temp); + return one_sample_z_test_impl(mu, s_sq, Real(std::distance(begin, end)), Real(assumed_mean)); +} + +template +ReturnType two_sample_z_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + + Real test_statistic = (mean_1 - mean_2) / sqrt(variance_1/size_1 + variance_2/size_2); + auto z = boost::math::normal_distribution(size_1 + size_2 - 1); + Real pvalue; + if(test_statistic > 0) + { + pvalue = 2*boost::math::cdf(z, -test_statistic); + } + else + { + pvalue = 2*boost::math::cdf(z, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType two_sample_z_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + auto n1 = std::distance(begin_1, end_1); + auto n2 = std::distance(begin_2, end_2); + + ReturnType temp_1 = mean_and_sample_variance(begin_1, end_1); + Real mean_1 = std::get<0>(temp_1); + Real variance_1 = std::get<1>(temp_1); + + ReturnType temp_2 = mean_and_sample_variance(begin_2, end_2); + Real mean_2 = std::get<0>(temp_2); + Real variance_2 = std::get<1>(temp_2); + + return two_sample_z_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); +} + +} // detail + +template::value, bool>::type = true> +inline auto one_sample_z_test(Real sample_mean, Real sample_variance, Real sample_size, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(sample_mean, sample_variance, sample_size, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Real sample_mean, Real sample_variance, Real sample_size, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(sample_mean, sample_variance, sample_size, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_z_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(begin, end, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_z_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(begin, end, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_z_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_z_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_z_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_z_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto two_sample_z_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_z_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto two_sample_z_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_z_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // boost::math::statistics + +#endif // BOOST_MATH_STATISTICS_Z_TEST_HPP diff --git a/third-party/boost-math/include/boost/math/tools/agm.hpp b/third-party/boost-math/include/boost/math/tools/agm.hpp new file mode 100644 index 0000000000000..2b5a06be5dffa --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/agm.hpp @@ -0,0 +1,47 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_AGM_HPP +#define BOOST_MATH_TOOLS_AGM_HPP +#include +#include + +namespace boost { namespace math { namespace tools { + +template +Real agm(Real a, Real g) +{ + using std::sqrt; + + if (a < g) + { + // Mathematica, mpfr, and mpmath are all symmetric functions: + return agm(g, a); + } + // Use: M(rx, ry) = rM(x,y) + if (a <= 0 || g <= 0) { + if (a < 0 || g < 0) { + return std::numeric_limits::quiet_NaN(); + } + return Real(0); + } + + // The number of correct digits doubles on each iteration. + // Divide by 512 for some leeway: + const Real scale = sqrt(std::numeric_limits::epsilon())/512; + while (a-g > scale*g) + { + Real anp1 = (a + g)/2; + g = sqrt(a*g); + a = anp1; + } + + // Final cleanup iteration recovers down to ~2ULPs: + return (a + g)/2; +} + + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/array.hpp b/third-party/boost-math/include/boost/math/tools/array.hpp new file mode 100644 index 0000000000000..23e666673c10a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/array.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2024 Matt Borland +// 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) +// +// Regular use of std::array functions can not be used on +// GPU platforms like CUDA since they are missing the __device__ marker +// Alias as needed to get correct support + +#ifndef BOOST_MATH_TOOLS_ARRAY_HPP +#define BOOST_MATH_TOOLS_ARRAY_HPP + +#include + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include + +namespace boost { +namespace math { + +using cuda::std::array; + +} // namespace math +} // namespace boost + +#else + +#include + +namespace boost { +namespace math { + +using std::array; + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif // BOOST_MATH_TOOLS_ARRAY_HPP diff --git a/third-party/boost-math/include/boost/math/tools/assert.hpp b/third-party/boost-math/include/boost/math/tools/assert.hpp new file mode 100644 index 0000000000000..3f57351fc15f6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/assert.hpp @@ -0,0 +1,49 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// We deliberately use assert in here: +// +// boost-no-inspect + +#ifndef BOOST_MATH_TOOLS_ASSERT_HPP +#define BOOST_MATH_TOOLS_ASSERT_HPP + +#include + +#ifdef BOOST_MATH_HAS_GPU_SUPPORT + +// Run time asserts are generally unsupported + +#define BOOST_MATH_ASSERT(expr) +#define BOOST_MATH_ASSERT_MSG(expr, msg) +#define BOOST_MATH_STATIC_ASSERT(expr) static_assert(expr, #expr " failed") +#define BOOST_MATH_STATIC_ASSERT_MSG(expr, msg) static_assert(expr, msg) + +#else + +#include + +#ifndef BOOST_MATH_STANDALONE + +#include +#include +#define BOOST_MATH_ASSERT(expr) BOOST_ASSERT(expr) +#define BOOST_MATH_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg) +#define BOOST_MATH_STATIC_ASSERT(expr) BOOST_STATIC_ASSERT(expr) +#define BOOST_MATH_STATIC_ASSERT_MSG(expr, msg) BOOST_STATIC_ASSERT_MSG(expr, msg) + +#else // Standalone mode - use cassert + +#include +#define BOOST_MATH_ASSERT(expr) assert(expr) +#define BOOST_MATH_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#define BOOST_MATH_STATIC_ASSERT(expr) static_assert(expr, #expr " failed") +#define BOOST_MATH_STATIC_ASSERT_MSG(expr, msg) static_assert(expr, msg) + +#endif // Is standalone + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +#endif // BOOST_MATH_TOOLS_ASSERT_HPP diff --git a/third-party/boost-math/include/boost/math/tools/atomic.hpp b/third-party/boost-math/include/boost/math/tools/atomic.hpp new file mode 100644 index 0000000000000..f558bd63ae758 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/atomic.hpp @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 John Maddock +// 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) + +#ifndef BOOST_MATH_ATOMIC_DETAIL_HPP +#define BOOST_MATH_ATOMIC_DETAIL_HPP + +#include +#include + +#ifdef BOOST_MATH_HAS_THREADS +#include + +namespace boost { + namespace math { + namespace detail { +#if (ATOMIC_INT_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_counter_type; + typedef std::atomic atomic_unsigned_type; + typedef int atomic_integer_type; + typedef unsigned atomic_unsigned_integer_type; +#elif (ATOMIC_SHORT_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_counter_type; + typedef std::atomic atomic_unsigned_type; + typedef short atomic_integer_type; + typedef unsigned short atomic_unsigned_type; +#elif (ATOMIC_LONG_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_unsigned_integer_type; + typedef std::atomic atomic_unsigned_type; + typedef unsigned long atomic_unsigned_type; + typedef long atomic_integer_type; +#elif (ATOMIC_LLONG_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_unsigned_integer_type; + typedef std::atomic atomic_unsigned_type; + typedef long long atomic_integer_type; + typedef unsigned long long atomic_unsigned_integer_type; +#elif !defined(BOOST_MATH_NO_ATOMIC_INT) +# define BOOST_MATH_NO_ATOMIC_INT +#endif + } // Namespace detail + } // Namespace math +} // Namespace boost + +#else +# define BOOST_MATH_NO_ATOMIC_INT +#endif // BOOST_MATH_HAS_THREADS + +#endif // BOOST_MATH_ATOMIC_DETAIL_HPP diff --git a/third-party/boost-math/include/boost/math/tools/big_constant.hpp b/third-party/boost-math/include/boost/math/tools/big_constant.hpp new file mode 100644 index 0000000000000..8e731c090ef34 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/big_constant.hpp @@ -0,0 +1,110 @@ + +// Copyright (c) 2011 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) + +#ifndef BOOST_MATH_TOOLS_BIG_CONSTANT_HPP +#define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP + +#include + +// On NVRTC we don't need any of this +// We just have a simple definition of the macro since the largest float +// type on the platform is a 64-bit double +#ifndef BOOST_MATH_HAS_NVRTC + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +#include +#include +#include + +namespace boost{ namespace math{ + +namespace tools{ + +template +struct numeric_traits : public std::numeric_limits< T > {}; + +#ifdef BOOST_MATH_USE_FLOAT128 +typedef __float128 largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q +template <> +struct numeric_traits<__float128> +{ + static const int digits = 113; + static const int digits10 = 33; + static const int max_exponent = 16384; + static const bool is_specialized = true; +}; +#elif LDBL_DIG > DBL_DIG +typedef long double largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x##L +#else +typedef double largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x +#endif + +template +BOOST_MATH_GPU_ENABLED constexpr T make_big_value(largest_float v, const char*, std::true_type const&, std::false_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return static_cast(v); +} +template +BOOST_MATH_GPU_ENABLED constexpr T make_big_value(largest_float v, const char*, std::true_type const&, std::true_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return static_cast(v); +} +#ifndef BOOST_MATH_NO_LEXICAL_CAST +template +inline T make_big_value(largest_float, const char* s, std::false_type const&, std::false_type const&) +{ + return boost::lexical_cast(s); +} +#else +template +inline T make_big_value(largest_float, const char*, std::false_type const&, std::false_type const&) +{ + static_assert(sizeof(T) == 0, "Type is unsupported in standalone mode. Please disable and try again."); +} +#endif +template +inline constexpr T make_big_value(largest_float, const char* s, std::false_type const&, std::true_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return T(s); +} + +// +// For constants which might fit in a long double (if it's big enough): +// +// Note that gcc-13 has std::is_convertible::value false, likewise +// std::is_constructible::value, even though the conversions do +// actually work. Workaround is the || std::is_floating_point::value part which thankfully is true. +// +#define BOOST_MATH_BIG_CONSTANT(T, D, x)\ + boost::math::tools::make_big_value(\ + BOOST_MATH_LARGEST_FLOAT_C(x), \ + BOOST_MATH_STRINGIZE(x), \ + std::integral_constant::value || std::is_floating_point::value) && \ + ((D <= boost::math::tools::numeric_traits::digits) \ + || std::is_floating_point::value \ + || (boost::math::tools::numeric_traits::is_specialized && \ + (boost::math::tools::numeric_traits::digits10 <= boost::math::tools::numeric_traits::digits10))) >(), \ + std::is_constructible()) +// +// For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such): +// +#define BOOST_MATH_HUGE_CONSTANT(T, D, x)\ + boost::math::tools::make_big_value(0.0L, BOOST_MATH_STRINGIZE(x), \ + std::integral_constant::value || (boost::math::tools::numeric_traits::is_specialized && boost::math::tools::numeric_traits::max_exponent <= boost::math::tools::numeric_traits::max_exponent && boost::math::tools::numeric_traits::digits <= boost::math::tools::numeric_traits::digits)>(), \ + std::is_constructible()) + +}}} // namespaces + +#endif // BOOST_MATH_HAS_NVRTC + +#endif + diff --git a/third-party/boost-math/include/boost/math/tools/bivariate_statistics.hpp b/third-party/boost-math/include/boost/math/tools/bivariate_statistics.hpp new file mode 100644 index 0000000000000..eaed5838ea968 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/bivariate_statistics.hpp @@ -0,0 +1,96 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_BIVARIATE_STATISTICS_HPP +#define BOOST_MATH_TOOLS_BIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost{ namespace math{ namespace tools { + +template +auto means_and_covariance(Container const & u, Container const & v) +{ + using Real = typename Container::value_type; + using std::size; + BOOST_MATH_ASSERT_MSG(size(u) == size(v), "The size of each vector must be the same to compute covariance."); + BOOST_MATH_ASSERT_MSG(size(u) > 0, "Computing covariance requires at least one sample."); + + // See Equation III.9 of "Numerically Stable, Single-Pass, Parallel Statistics Algorithms", Bennet et al. + Real cov = 0; + Real mu_u = u[0]; + Real mu_v = v[0]; + + for(size_t i = 1; i < size(u); ++i) + { + Real u_tmp = (u[i] - mu_u)/(i+1); + Real v_tmp = v[i] - mu_v; + cov += i*u_tmp*v_tmp; + mu_u = mu_u + u_tmp; + mu_v = mu_v + v_tmp/(i+1); + } + + return std::make_tuple(mu_u, mu_v, cov/size(u)); +} + +template +auto covariance(Container const & u, Container const & v) +{ + auto [mu_u, mu_v, cov] = boost::math::tools::means_and_covariance(u, v); + return cov; +} + +template +auto correlation_coefficient(Container const & u, Container const & v) +{ + using Real = typename Container::value_type; + using std::size; + BOOST_MATH_ASSERT_MSG(size(u) == size(v), "The size of each vector must be the same to compute covariance."); + BOOST_MATH_ASSERT_MSG(size(u) > 0, "Computing covariance requires at least two samples."); + + Real cov = 0; + Real mu_u = u[0]; + Real mu_v = v[0]; + Real Qu = 0; + Real Qv = 0; + + for(size_t i = 1; i < size(u); ++i) + { + Real u_tmp = u[i] - mu_u; + Real v_tmp = v[i] - mu_v; + Qu = Qu + (i*u_tmp*u_tmp)/(i+1); + Qv = Qv + (i*v_tmp*v_tmp)/(i+1); + cov += i*u_tmp*v_tmp/(i+1); + mu_u = mu_u + u_tmp/(i+1); + mu_v = mu_v + v_tmp/(i+1); + } + + // If one dataset is constant, then they have no correlation: + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu == 0 || Qv == 0) + { + return std::numeric_limits::quiet_NaN(); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov/sqrt(Qu*Qv); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + return rho; +} + +}}} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/centered_continued_fraction.hpp b/third-party/boost-math/include/boost/math/tools/centered_continued_fraction.hpp new file mode 100644 index 0000000000000..87e76b51b39d2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/centered_continued_fraction.hpp @@ -0,0 +1,173 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_CENTERED_CONTINUED_FRACTION_HPP +#define BOOST_MATH_TOOLS_CENTERED_CONTINUED_FRACTION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace boost::math::tools { + +template +class centered_continued_fraction { +public: + centered_continued_fraction(Real x) : x_{x} { + static_assert(std::is_integral_v && std::is_signed_v, + "Centered continued fractions require signed integer types."); + using std::round; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into continued fractions."); + } + b_.reserve(50); + Real bj = round(x); + b_.push_back(static_cast(bj)); + if (bj == x) + { + b_.shrink_to_fit(); + return; + } + x = 1/(x-bj); + Real f = bj; + if (bj == 0) + { + f = 16*(std::numeric_limits::min)(); + } + Real C = f; + Real D = 0; + int i = 0; + while (abs(f - x_) >= (1 + i++)*std::numeric_limits::epsilon()*abs(x_)) + { + bj = round(x); + b_.push_back(static_cast(bj)); + x = 1/(x-bj); + D += bj; + if (D == 0) { + D = 16*(std::numeric_limits::min)(); + } + C = bj + 1/C; + if (C==0) + { + C = 16*(std::numeric_limits::min)(); + } + D = 1/D; + f *= (C*D); + } + // Deal with non-uniqueness of continued fractions: [a0; a1, ..., an, 1] = a0; a1, ..., an + 1]. + if (b_.size() > 2 && b_.back() == 1) + { + b_[b_.size() - 2] += 1; + b_.resize(b_.size() - 1); + } + b_.shrink_to_fit(); + + for (size_t i = 1; i < b_.size(); ++i) + { + if (b_[i] == 0) { + std::ostringstream oss; + oss << "Found a zero partial denominator: b[" << i << "] = " << b_[i] << "." + #ifndef BOOST_MATH_STANDALONE + << " This means the integer type '" << boost::core::demangle(typeid(Z).name()) + #else + << " This means the integer type '" << typeid(Z).name() + #endif + << "' has overflowed and you need to use a wider type," + << " or there is a bug."; + throw std::overflow_error(oss.str()); + } + } + } + + Real khinchin_geometric_mean() const { + if (b_.size() == 1) + { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + using std::abs; + const std::array logs{std::numeric_limits::quiet_NaN(), Real(0), log(static_cast(2)), log(static_cast(3)), log(static_cast(4)), log(static_cast(5)), log(static_cast(6))}; + Real log_prod = 0; + for (size_t i = 1; i < b_.size(); ++i) + { + if (abs(b_[i]) < static_cast(logs.size())) + { + log_prod += logs[abs(b_[i])]; + } + else + { + log_prod += log(static_cast(abs(b_[i]))); + } + } + log_prod /= (b_.size()-1); + return exp(log_prod); + } + + const std::vector& partial_denominators() const { + return b_; + } + + template + friend std::ostream& operator<<(std::ostream& out, centered_continued_fraction& ccf); + +private: + const Real x_; + std::vector b_; +}; + + +template +std::ostream& operator<<(std::ostream& out, centered_continued_fraction& scf) { + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(scf.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "[" << scf.b_.front(); + if (scf.b_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < scf.b_.size() -1; ++i) + { + out << scf.b_[i] << ", "; + } + out << scf.b_.back(); + } + out << "]"; + return out; +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/cohen_acceleration.hpp b/third-party/boost-math/include/boost/math/tools/cohen_acceleration.hpp new file mode 100644 index 0000000000000..2e76a75f8b6cc --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/cohen_acceleration.hpp @@ -0,0 +1,51 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_COHEN_ACCELERATION_HPP +#define BOOST_MATH_TOOLS_COHEN_ACCELERATION_HPP +#include +#include +#include + +namespace boost::math::tools { + +// Algorithm 1 of https://people.mpim-bonn.mpg.de/zagier/files/exp-math-9/fulltext.pdf +// Convergence Acceleration of Alternating Series: Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier +template +auto cohen_acceleration(G& generator, std::int64_t n = -1) +{ + using Real = decltype(generator()); + // This test doesn't pass for float128, sad! + //static_assert(std::is_floating_point_v, "Real must be a floating point type."); + using std::log; + using std::pow; + using std::ceil; + using std::sqrt; + + auto n_ = static_cast(n); + if (n < 0) + { + // relative error grows as 2*5.828^-n; take 5.828^-n < eps/4 => -nln(5.828) < ln(eps/4) => n > ln(4/eps)/ln(5.828). + // Is there a way to do it rapidly with std::log2? (Yes, of course; but for primitive types it's computed at compile-time anyway.) + n_ = static_cast(ceil(log(Real(4)/std::numeric_limits::epsilon())*Real(0.5672963285532555))); + n = static_cast(n_); + } + // d can get huge and overflow if you pick n too large: + auto d = static_cast(pow(Real(3 + sqrt(Real(8))), n_)); + d = (d + Real(1)/d)/2; + Real b = -1; + Real c = -d; + Real s = 0; + for (Real k = 0; k < n_; ++k) { + c = b - c; + s += c*generator(); + b = (k+n_)*(k-n_)*b/((k+Real(1)/Real(2))*(k+1)); + } + + return s/d; +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/color_maps.hpp b/third-party/boost-math/include/boost/math/tools/color_maps.hpp new file mode 100644 index 0000000000000..e3cc8b9b09e26 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/color_maps.hpp @@ -0,0 +1,1943 @@ +// (C) Copyright Nick Thompson 2021. +// (C) Copyright Matt Borland 2022. +// 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) + +#ifndef BOOST_MATH_COLOR_MAPS_HPP +#define BOOST_MATH_COLOR_MAPS_HPP +#include // for std::clamp +#include // for table data +#include // for std::floor +#include // fixed width integer types +#include + +#if __has_include("lodepng.h") + +#include "lodepng.h" +#include +#include +#include + +namespace boost::math::tools { + +// In lodepng, the vector is expected to be row major, with the top row +// specified first. Note that this is a bit confusing sometimes as it's more +// natural to let y increase moving *up*. +unsigned write_png(const std::string &filename, + const std::vector &img, std::size_t width, + std::size_t height) { + unsigned error = lodepng::encode(filename, img, width, height, + LodePNGColorType::LCT_RGBA, 8); + if (error) { + std::cerr << "Error encoding png: " << lodepng_error_text(error) << "\n"; + } + return error; +} + +} // Namespace boost::math::tools +#endif // __has_include("lodepng.h") + +namespace boost::math::tools { + +namespace detail { + +// Data taken from: https://www.kennethmoreland.com/color-advice +template +static constexpr std::array, 256> extended_kindlmann_data_ = {{ + {0.0, 0.0, 0.0}, + {0.01780246283347332, 0.0008750907117329381, 0.01626889466306607}, + {0.03532931821571093, 0.001701802855992888, 0.03371323527689844}, + {0.05144940541667612, 0.0024840651967150905, 0.05129428731410766}, + {0.0645621163212177, 0.0032248645766847638, 0.06656239137344208}, + {0.07579594587865912, 0.0038635326859125735, 0.08040589852559868}, + {0.08560873187665013, 0.004465497712210337, 0.0932078727850277}, + {0.0942303824351094, 0.005050242022804749, 0.10546097842833466}, + {0.10126270743754426, 0.005684892741078179, 0.1185281778831713}, + {0.10670728559557496, 0.006372379780229372, 0.1327264977880264}, + {0.11057848107867363, 0.00711002225409038, 0.1481009557210271}, + {0.11345334766875653, 0.007801930722079915, 0.16375632363209905}, + {0.11546967754116774, 0.008551159105416175, 0.17919646921236213}, + {0.11670723282215431, 0.009290109551844812, 0.19453816576504604}, + {0.11719317716660224, 0.010053390003759367, 0.2096941755954832}, + {0.11698590922074067, 0.010738982214965748, 0.2248153138735493}, + {0.11610841583017484, 0.011423659103765034, 0.2397105899482299}, + {0.11462189563389044, 0.012116630983625478, 0.2543011097912221}, + {0.11260886490150057, 0.012821489721377753, 0.26850817678211986}, + {0.11014892407081325, 0.013468369062412165, 0.28238564749171374}, + {0.1073826713115642, 0.014119392392571815, 0.29573128232180523}, + {0.10439994774781663, 0.014757514745798027, 0.3086071932061514}, + {0.10102122555390916, 0.015343280218838306, 0.3215039849422961}, + {0.0973378808050489, 0.015957600087593806, 0.33424777423118057}, + {0.09343083659118528, 0.016584962806154634, 0.34680083232754255}, + {0.08930170392567455, 0.01713482653380763, 0.35927335578767955}, + {0.08525050060408929, 0.0177409908749586, 0.3713432638745381}, + {0.08133294699659654, 0.018315663017042745, 0.3831259644824107}, + {0.07770620978910117, 0.018846472161798116, 0.3945981112365364}, + {0.07453843004300356, 0.019323310547852572, 0.4057423733826484}, + {0.07234014248177378, 0.019905434286220342, 0.4162427930814269}, + {0.07070739337749535, 0.020358202603665252, 0.4265710517267966}, + {0.06795561424010746, 0.020880774373512326, 0.4372263626095861}, + {0.05495344243231267, 0.02153229240969933, 0.4511422122889977}, + {0.03272243214743511, 0.022251621841318136, 0.4663539858995716}, + {0.022542079629107543, 0.030087469482649072, 0.47217057965768244}, + {0.022458068304623265, 0.043510017517847034, 0.47110682779300844}, + {0.022335095562005403, 0.057612064160193856, 0.4678570071198978}, + {0.022116548807623634, 0.07134877081764332, 0.46268236332653717}, + {0.021827538746008197, 0.08452599623053175, 0.4558745921468776}, + {0.02152986717396973, 0.09703540427752388, 0.44774032508967526}, + {0.02094627101890751, 0.1088025513135693, 0.4387215006543877}, + {0.02045606049512309, 0.11985098869691474, 0.4289709820913745}, + {0.02004833311662032, 0.13019611448976093, 0.418764250948481}, + {0.019665629961975118, 0.13987346436551024, 0.4083506364708954}, + {0.019207577360338738, 0.14893167904386712, 0.39794947927856517}, + {0.018537140772831598, 0.15742727919356447, 0.38774823408835746}, + {0.01809424185998195, 0.16542627229987475, 0.3776911843959934}, + {0.01766141281376398, 0.1729786761988682, 0.3679328135626787}, + {0.01730286273144011, 0.18013597770041306, 0.3585022095429489}, + {0.016765513848818806, 0.18694679199155506, 0.3495097966827364}, + {0.016370126207011747, 0.19345202807035153, 0.3408690453055597}, + {0.016125995919003662, 0.19968741140572166, 0.3325877811713702}, + {0.015743835848192653, 0.20569130878531383, 0.32474294907403245}, + {0.01521780170762751, 0.21149505980303446, 0.31731795633577514}, + {0.014826523924383142, 0.21711739930665275, 0.31022963838193685}, + {0.01455583202575653, 0.22257980137551625, 0.3034714591858722}, + {0.014390286122102107, 0.2279012896050861, 0.29703484457819845}, + {0.014011918932944173, 0.23311039219433838, 0.29095765923101685}, + {0.013696545884500274, 0.23821209907670415, 0.28517017024142427}, + {0.013424574431729107, 0.24321964058367318, 0.2796599788292758}, + {0.013175868771764966, 0.2481448283322712, 0.27441390646690217}, + {0.01292963716411873, 0.2529982361555283, 0.2694181731856298}, + {0.012664284210951764, 0.25778935856659907, 0.2646585394556099}, + {0.012715975678052705, 0.26251129306552407, 0.26008624607226105}, + {0.012935277312292002, 0.26721180456135596, 0.25537236409530106}, + {0.013151828277929324, 0.2719132248379506, 0.25038669592493334}, + {0.013365797957379829, 0.2766141217472141, 0.24512715790174772}, + {0.013577263863962, 0.28131308067549815, 0.23959178395846548}, + {0.01378615567948453, 0.2860087090215386, 0.2337787381698218}, + {0.013992194922389659, 0.290699640854686, 0.22768632911662062}, + {0.014194831158161888, 0.2953845417355913, 0.22131302646406403}, + {0.014393175927633691, 0.3000621136791825, 0.21465748025951026}, + {0.014585935863149577, 0.3047311002377708, 0.20771854359069752}, + {0.014771346788489043, 0.3093902916806014, 0.2004952994228159}, + {0.015316330980203078, 0.314019615719643, 0.19303372895005055}, + {0.015485867479267465, 0.318655599270661, 0.18524675366655605}, + {0.015639979963365892, 0.32327849834847494, 0.17717467982889423}, + {0.015774461623191554, 0.32788734271858383, 0.16881795823876974}, + {0.01588440162820881, 0.33248123546361147, 0.16017753232003507}, + {0.016371319978387793, 0.3370394958269932, 0.15133715480703355}, + {0.016424021691114017, 0.34160094506458616, 0.14214299485979426}, + {0.01686035446719742, 0.3461250509254044, 0.13277234235578353}, + {0.016830214158745957, 0.35065150775079285, 0.12304027310946478}, + {0.017189890203442686, 0.3551393166240582, 0.11316410079747846}, + {0.0175057105195252, 0.35960835629733406, 0.10305638071018988}, + {0.017770106546070377, 0.36405841970084374, 0.09273371145052256}, + {0.01797534767005524, 0.3684894220401705, 0.08221895294189338}, + {0.018113811240203243, 0.37290140979305425, 0.07154410587314339}, + {0.01817830121675857, 0.37729457180004805, 0.060754926838460115}, + {0.018678925823257978, 0.3816479795981337, 0.05016037872247533}, + {0.01858851921615119, 0.38600461104105177, 0.039408863532102954}, + {0.018946886533322625, 0.39032256740422405, 0.0299653011886783}, + {0.019234421105765478, 0.3946241249528643, 0.022430553487672214}, + {0.023922664243633134, 0.39873762922211814, 0.019079643738415406}, + {0.032696329777136775, 0.40268821797442356, 0.01927104403025176}, + {0.04029295620970803, 0.40668863206181144, 0.019627058713507277}, + {0.0445051772107334, 0.4108066755028012, 0.019605221754402217}, + {0.05023033461306361, 0.4148702424589703, 0.019837552743924382}, + {0.05751407234865658, 0.4188712020471279, 0.01998429281648217}, + {0.06662959400279314, 0.42277996280066904, 0.020350820236973332}, + {0.07687976931053314, 0.42661141097115085, 0.02061535207978936}, + {0.08808647489550425, 0.4303590557627002, 0.02076563040362206}, + {0.10009395068503488, 0.4340168594615687, 0.020789592249385695}, + {0.11305049861381905, 0.43755751986676594, 0.021011622748947127}, + {0.1265170163106781, 0.440997674167719, 0.021092771828857385}, + {0.14064355039494827, 0.44431106175406876, 0.021367147770030247}, + {0.15509985051348987, 0.4475149894903065, 0.021487010699090946}, + {0.17002834364548297, 0.4505843077306851, 0.02179659002621885}, + {0.18517425344416824, 0.4535369003239919, 0.021939140218683366}, + {0.2005125857975878, 0.4563695433411364, 0.02190396156431214}, + {0.2161609253409036, 0.459058907077816, 0.022051019673724737}, + {0.23193556411255867, 0.46162347760839634, 0.022009915914684375}, + {0.24793825797637276, 0.4640413181325817, 0.022151516874270333}, + {0.26412488725558203, 0.4663117397956657, 0.022482129570858295}, + {0.2803606712938716, 0.4684536010278855, 0.02261757765237555}, + {0.296637938074376, 0.47046590244093683, 0.0225494975844844}, + {0.31302849974924285, 0.47232989838033596, 0.022671977207001336}, + {0.3294300351704986, 0.4740642435062818, 0.0225864988960952}, + {0.3459012409505257, 0.475652007794974, 0.022699138396783294}, + {0.3624157976623936, 0.4770953196310352, 0.02302034933556348}, + {0.37889809766361104, 0.47841222515883747, 0.02313701355469799}, + {0.39534430178227603, 0.4796035027123265, 0.023043880179838123}, + {0.41179003849439816, 0.48065635396111855, 0.023172253504396497}, + {0.42818080415815335, 0.4815874024816033, 0.02309359581707615}, + {0.4445420271983608, 0.48238619597444804, 0.02325212759648816}, + {0.46083197524945735, 0.48306807922963163, 0.023208795520823236}, + {0.477066527169599, 0.4836251567552959, 0.023421052378504333}, + {0.49330882182932195, 0.48404259768616237, 0.02351307077213582}, + {0.5101341569176142, 0.4841269939874597, 0.02474700862397102}, + {0.5276083798119485, 0.4838477594175364, 0.025493073746431755}, + {0.5457675808274345, 0.4831581006215279, 0.026232895897136985}, + {0.5646323060116551, 0.48201590123588106, 0.02698278973250526}, + {0.5842072626155643, 0.4803756805891137, 0.02819024072200311}, + {0.6045266103850581, 0.4781882736718959, 0.028981783530659853}, + {0.6255919000983664, 0.47539734049324306, 0.02979697562508809}, + {0.6473800379403847, 0.47195081918673226, 0.031044032153032777}, + {0.6699068794902967, 0.4677815168730453, 0.03227150878455887}, + {0.6932001837200186, 0.46280562738356607, 0.03304163325898518}, + {0.7171335868744761, 0.4569883986979126, 0.034530544840017025}, + {0.7417906038430161, 0.4502061037239105, 0.035463650965058914}, + {0.7670484685327643, 0.4424084941387379, 0.03656485419201359}, + {0.7927923527600884, 0.4335431093764269, 0.038110096816360045}, + {0.8190538618349916, 0.4234676649184017, 0.03921665123224114}, + {0.845635547462146, 0.4121565351852396, 0.040504503887090086}, + {0.8724273941843113, 0.399532161591502, 0.04177752341186975}, + {0.8993071734347423, 0.38551601321374424, 0.04288218868653492}, + {0.9259938049276442, 0.3701581656966096, 0.0443028413484576}, + {0.95240006413475, 0.3533630589382493, 0.045512688804357486}, + {0.9573302263433631, 0.356573181832402, 0.10485176035519561}, + {0.9593762651267365, 0.3625998458005728, 0.14695621074226434}, + {0.9609003469257634, 0.3691267599755898, 0.17919496865835138}, + {0.9621556849513918, 0.37591169845314204, 0.20542079832986643}, + {0.9631644672895096, 0.3829300179877212, 0.22750885439024698}, + {0.964095792386828, 0.39002737893200634, 0.24632170224175154}, + {0.9648793311938041, 0.3972605885272423, 0.26263686798960245}, + {0.9655077342802952, 0.40462643797868664, 0.2769429329997333}, + {0.9660587860054425, 0.41205105448230417, 0.2895251327064319}, + {0.9665994127853909, 0.4194734509128834, 0.3006180918171856}, + {0.9671516506858119, 0.4268421716026803, 0.31083965567414507}, + {0.9677276657441855, 0.4338269194529401, 0.3245165284653611}, + {0.968504522437997, 0.44042580568421147, 0.33966351784918897}, + {0.9692871734210263, 0.4467701596827656, 0.3565758064426104}, + {0.9702540772004374, 0.45269977328586647, 0.37534236971527246}, + {0.9712179772934669, 0.45837869586824703, 0.39562556319119124}, + {0.9722317464026985, 0.4637976195449472, 0.41693497643767774}, + {0.9732263821032568, 0.46903038930488866, 0.438958844869214}, + {0.9742462614418889, 0.4740678468975709, 0.46139896139324615}, + {0.9750871661398574, 0.4790671203997809, 0.48416548522290065}, + {0.9754147288760454, 0.4842669015553663, 0.5072296427052377}, + {0.9756180439862371, 0.48941330245201103, 0.5302646150938287}, + {0.975842338006588, 0.49442037450446213, 0.5531433026983604}, + {0.9761081874822527, 0.4992854244201668, 0.5758237590340696}, + {0.9763112164847584, 0.5040877038326032, 0.5983033566276463}, + {0.9765888685497933, 0.5087442572698033, 0.6205369331248914}, + {0.9767110237468087, 0.5134164774149236, 0.642535156682777}, + {0.9769336559396905, 0.5179413879764756, 0.6642639445578681}, + {0.97714593184672, 0.5224000733132641, 0.6857254497050739}, + {0.9773578783172437, 0.5267928368807481, 0.7069126158797037}, + {0.9775785758579868, 0.5311203562318053, 0.7278211218920855}, + {0.9778162437300041, 0.5353836351919077, 0.7484486916246914}, + {0.9779596006498089, 0.5396657970725794, 0.7687562310971295}, + {0.9782535179019477, 0.5438049537609145, 0.7888137943375886}, + {0.9784674751508416, 0.5479668227414403, 0.8085390020370261}, + {0.9786094914349676, 0.5521542299695001, 0.8279128914232778}, + {0.978802652274665, 0.5562873882925448, 0.8469838693949315}, + {0.9790515109370453, 0.5603687136966451, 0.8657552952207226}, + {0.9792467908639096, 0.5644843583828043, 0.884150643372716}, + {0.979395255578016, 0.5686380796177348, 0.902153526529961}, + {0.9796145283071062, 0.5727494207545081, 0.9198418221195682}, + {0.9797975302508571, 0.5769060493757885, 0.9371197812002375}, + {0.9799502605574898, 0.581112131921931, 0.9539723226660747}, + {0.9802283260758732, 0.5851928436561017, 0.9708243730936762}, + {0.9738084905670951, 0.5944815591203718, 0.9806690105429076}, + {0.9601472511008894, 0.609371508764095, 0.9813253841505029}, + {0.9478379001570983, 0.6230463820702153, 0.9820290537295789}, + {0.9366516898009005, 0.6357832537301149, 0.9826041912890565}, + {0.926560589527891, 0.647678912888478, 0.9831062604022219}, + {0.917620083682068, 0.6587517109196314, 0.9837253021469462}, + {0.9095356769991322, 0.6692646118840428, 0.9841128740419515}, + {0.9024501226204644, 0.6791460846603548, 0.9845858176159193}, + {0.8962465735427142, 0.6885075377321772, 0.9850533329169425}, + {0.8908928004592865, 0.6973907065167453, 0.9855589168505193}, + {0.8862829519968738, 0.7058867599470733, 0.9859932359170603}, + {0.8823207949642251, 0.7140769556818014, 0.9862329988164894}, + {0.8791184292035925, 0.7218801604700443, 0.9866187467737363}, + {0.876573928783208, 0.729373858466773, 0.9870301106239344}, + {0.8745946211951233, 0.7366283504729199, 0.9873335856528983}, + {0.8732148850190337, 0.7436116593104639, 0.9877197983463958}, + {0.8723449314581001, 0.7503888453166406, 0.9880489690947681}, + {0.871958051266914, 0.7569736347405297, 0.988343697831869}, + {0.8720269380214271, 0.7633787505197638, 0.9886267968388239}, + {0.872524018161346, 0.7696159559904953, 0.9889212756286642}, + {0.8734217880637981, 0.7756960853936921, 0.9892503149320232}, + {0.8746431257299938, 0.7816733363052604, 0.989454685042798}, + {0.8762135041761673, 0.7875116467112275, 0.9897367010924504}, + {0.878107018520635, 0.7932193523390607, 0.9901203210173019}, + {0.880203346150829, 0.798890286193674, 0.9902546300884126}, + {0.8825765528541782, 0.8044436600674107, 0.9905332036399778}, + {0.885156863735442, 0.8099282584935031, 0.9907909519806376}, + {0.8879236719089479, 0.815348848661961, 0.9910495231926625}, + {0.890857185433795, 0.8207097106633178, 0.9913312422092354}, + {0.8939377339865693, 0.8260147864401665, 0.9916599021959583}, + {0.8970530658331168, 0.8313161221171385, 0.9919275427432451}, + {0.8995688302115749, 0.8368229403489976, 0.9920969557419316}, + {0.9019890025620054, 0.8423510813517494, 0.9923144994581347}, + {0.9041189751589628, 0.8479541784289291, 0.992640232246134}, + {0.9058973525369924, 0.8536784698518803, 0.9928660652275899}, + {0.9073992963543378, 0.8594712199063077, 0.9931944239168621}, + {0.9086279741575543, 0.8653520270780298, 0.993459751831716}, + {0.9096655096337553, 0.8712669417189164, 0.9938665873784843}, + {0.9105035986931571, 0.8772607309343242, 0.9940839016190398}, + {0.9112280528710646, 0.8832787634425558, 0.994319531984062}, + {0.9118856791641718, 0.8893033549283489, 0.9945972975280256}, + {0.9125160989249034, 0.8953200253413901, 0.994937094070283}, + {0.9131521110159186, 0.9013364967475651, 0.9952011954414587}, + {0.9138294807228358, 0.907320474034156, 0.9955652276122916}, + {0.9145934489263029, 0.9132934622711121, 0.9957533433444864}, + {0.9154721624193913, 0.9192261671429544, 0.9959406615249712}, + {0.9165162261152294, 0.9251182443147156, 0.9960169412606291}, + {0.9177621627085478, 0.9309558310395318, 0.9960174468690394}, + {0.9192000090908993, 0.9367250258396427, 0.9960919139576695}, + {0.920883428013182, 0.9424235334496841, 0.9961424557894082}, + {0.922780751860871, 0.9480459375852194, 0.9963020587068238}, + {0.9250092107169314, 0.9535821762261815, 0.9963856518750184}, + {0.9275356684808912, 0.9590268903215627, 0.996529920191361}, + {0.9304408284972104, 0.9643654252860402, 0.996676965947248}, + {0.9338239050383462, 0.9695749605431102, 0.9967943472276378}, + {0.9376406019134518, 0.97465362230454, 0.9970154826822965}, + {0.9421630827040032, 0.9795433335221727, 0.9971921136372807}, + {0.9473578426139436, 0.9842358767121905, 0.9974820554788658}, + {0.9536370282349044, 0.9886296256370345, 0.9977639971129887}, + {0.961277626215249, 0.9926367016857381, 0.9981081638729355}, + {0.9706782225332987, 0.996129580837985, 0.9985982664103797}, + {0.982998706722621, 0.9987706424331216, 0.9991799080785383}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> kindlmann_data_ = {{ + {0.0, 0.0, 0.0}, + {0.017846074066284252, 0.0009158559874893362, 0.016056295374498146}, + {0.03572864786642702, 0.0017291229250328806, 0.03302143519907636}, + {0.05220741890989234, 0.002509857835251149, 0.04992588792612627}, + {0.06579320887318146, 0.0031951554951018895, 0.06457251900523656}, + {0.07760358429899875, 0.003724534058880596, 0.07776920342353211}, + {0.08789358790850602, 0.004294574826048965, 0.0897198393739522}, + {0.09712335630575433, 0.004842625166895046, 0.10086394984030281}, + {0.10521029512901023, 0.005373953338851922, 0.11223547956850252}, + {0.11206559338234914, 0.005946169553289608, 0.12432777397900399}, + {0.11777117178354526, 0.006573754050745371, 0.13716171084354922}, + {0.12274092212849055, 0.007190967398920267, 0.15010297798342745}, + {0.12721746956233745, 0.007765930791621213, 0.1628260628965371}, + {0.13120675065695167, 0.008361505755992952, 0.17526973313157249}, + {0.13476383339950823, 0.008965513206303781, 0.1874768588728739}, + {0.1379416850964659, 0.009551513984339633, 0.1995014270040738}, + {0.14078915018940993, 0.010080340518883863, 0.21140807652685528}, + {0.14328800070233533, 0.010654292784112113, 0.22305086172802313}, + {0.1454925697745392, 0.011223945666441406, 0.23450000042491753}, + {0.14744975665550916, 0.01172962096468942, 0.24583568409411483}, + {0.14915607230438568, 0.012265761398485226, 0.2569125532571454}, + {0.15064370028657081, 0.012825896285586958, 0.2678146545485108}, + {0.15192214754665317, 0.013340464397739584, 0.27899859238410224}, + {0.1529680602403743, 0.01383169406084123, 0.29046429953683084}, + {0.15375355050540976, 0.014469905953793126, 0.3019580272214856}, + {0.1542908116514455, 0.014991396474282258, 0.313852441550019}, + {0.15455584740256964, 0.015566553274758022, 0.3258902207027679}, + {0.15454470889937796, 0.01619279407587136, 0.3380624435826929}, + {0.15424074730776174, 0.01677345343135211, 0.3504951935746775}, + {0.15362513362574176, 0.01730005530615292, 0.3631847587056686}, + {0.15272770714157807, 0.017955417060815455, 0.3758470094405716}, + {0.15150259153104584, 0.018542834077193353, 0.3887481108848792}, + {0.14996750216169222, 0.019150121523940637, 0.4017384234617481}, + {0.1481223688773872, 0.019769579646988222, 0.4148055969839783}, + {0.14596849097254724, 0.02039268583437749, 0.42793691410477086}, + {0.14350871584895447, 0.021010135344188375, 0.4411193724446502}, + {0.14081675084553444, 0.021716621813360978, 0.4541885105212106}, + {0.13777021342781093, 0.022293516296525755, 0.4674318891638602}, + {0.13452661891393936, 0.022940593473192553, 0.48053217251642305}, + {0.13103033265010522, 0.023541432666866674, 0.49362776425328886}, + {0.12740778581316103, 0.024195126427194676, 0.5065484866366465}, + {0.12359314328868806, 0.024781571830105195, 0.5194370648731684}, + {0.11974712167592705, 0.025403149292983516, 0.5321219022221657}, + {0.1159404877051333, 0.0260531205128538, 0.5445888017818501}, + {0.11209206787148834, 0.02660656407054731, 0.5569877413493692}, + {0.10842241040440373, 0.02717266184945997, 0.5691469684334989}, + {0.1050253848722921, 0.027746789078543728, 0.5810568608426063}, + {0.101999609017976, 0.02832560680437759, 0.5927097735404816}, + {0.09922826785261996, 0.028779550542447317, 0.6042668353483279}, + {0.09722602817414985, 0.02936178919960733, 0.6153923636579981}, + {0.09528935573037353, 0.029890777438344337, 0.6264955320241609}, + {0.0930823731478326, 0.030438044833523397, 0.6376509097116411}, + {0.0781891239412737, 0.031121586300131683, 0.6525577781586464}, + {0.05857961917089497, 0.031924832133126, 0.6676204841351329}, + {0.03284057845765246, 0.03469657698669593, 0.6813738713631898}, + {0.032679442069734624, 0.04697971049610799, 0.6849034147771731}, + {0.033207560139530704, 0.05995495438213944, 0.6868241583911188}, + {0.033317187200492364, 0.07300667062971217, 0.6874759761236308}, + {0.033087445334472984, 0.08601513051125326, 0.6868754153808352}, + {0.03265381069556877, 0.09888929701373608, 0.6850522082772128}, + {0.03277467744530855, 0.11161079522124029, 0.6818870111240353}, + {0.0325022291000698, 0.1240111603824268, 0.6777553638535389}, + {0.032066045593596146, 0.13606903293962488, 0.6727110790151253}, + {0.03227600851941834, 0.14780096691985975, 0.6666596846794193}, + {0.031649331579416705, 0.15909372791133777, 0.6601264529755937}, + {0.03155801725217711, 0.17001566158899392, 0.6528643797965168}, + {0.0310838330844518, 0.18051935094604918, 0.6452318387821873}, + {0.030432973047734187, 0.19062325974122588, 0.6372784105620277}, + {0.030338619295788537, 0.20036054096647732, 0.6289128168374558}, + {0.029853960367767295, 0.20971568331952556, 0.6204629562646412}, + {0.02966850358552374, 0.2187242415010579, 0.6118301548875958}, + {0.02882374869999708, 0.2273866229818785, 0.603314553849001}, + {0.028500638040224537, 0.2357441994433061, 0.5946825020006182}, + {0.028245919974351025, 0.24380777892174738, 0.5860925629625072}, + {0.02760771294131195, 0.2515940717685919, 0.5776869157187913}, + {0.02717197158834595, 0.25912806556578544, 0.5693601411266609}, + {0.026982221792628543, 0.266427065214078, 0.5611305112918692}, + {0.026559642397133442, 0.27350794101395076, 0.5531226098917067}, + {0.02644787880084816, 0.2803874742418932, 0.5452351099365369}, + {0.02564842515734134, 0.2870852596241667, 0.5376830481507792}, + {0.02570596827933925, 0.29360869815637475, 0.5301627048805485}, + {0.025105902288682952, 0.2999809743840178, 0.5229767137199569}, + {0.024870375536254246, 0.30620709089548, 0.5159307080617925}, + {0.024495137563131944, 0.3123034508268453, 0.5091188274555094}, + {0.02397954323509251, 0.3182816255246543, 0.502536537756261}, + {0.023829708770758788, 0.32414426165027227, 0.4960985638991457}, + {0.023532604704116965, 0.32990776857516413, 0.48988582950117815}, + {0.02307993829976581, 0.3355813090448093, 0.4838916171846975}, + {0.022979595210601424, 0.3411632670690572, 0.47803935490382515}, + {0.022707635361622264, 0.3466702701862077, 0.4723976815702628}, + {0.022250414084789737, 0.352109624090965, 0.4669584702823865}, + {0.022124477998067993, 0.3574761812445124, 0.46165444016667906}, + {0.021791069977336153, 0.3627869887174417, 0.45654262929804507}, + {0.021776256319502838, 0.3680348834809229, 0.45156215250307846}, + {0.02152936248024083, 0.3732373044965933, 0.44676258718151424}, + {0.02158822978060292, 0.37838527471660577, 0.44208955676541317}, + {0.021388037427047302, 0.38349668536630105, 0.43758535324043873}, + {0.020906126379826747, 0.3885760631680783, 0.4332402802381849}, + {0.02070114401850818, 0.3936120031480679, 0.4290098739833766}, + {0.020774708005350834, 0.3986070226842801, 0.4248945065220385}, + {0.020526909471275397, 0.4035800658477305, 0.4209222889365068}, + {0.01993018897938756, 0.4085347069464005, 0.4170831873583663}, + {0.02020289046425452, 0.4134392235922892, 0.41332502021802126}, + {0.020207032023267582, 0.41834155873012324, 0.40954621812568487}, + {0.020205716119178502, 0.42324888777657366, 0.4055896035873459}, + {0.020829051716263414, 0.42814253234088623, 0.4014443452785458}, + {0.020817169253550774, 0.4330580290829061, 0.3971329152020192}, + {0.02143446555544063, 0.437958395126164, 0.3926385324661419}, + {0.02140951927285399, 0.44287991873506705, 0.38796855906767097}, + {0.021375101041108045, 0.4478037488631326, 0.3831160408679206}, + {0.021978368208421244, 0.45271034115960945, 0.3780894735135355}, + {0.021925941019470395, 0.45763704847590275, 0.372873157602702}, + {0.022518324495068114, 0.4625451606740822, 0.3674890229173533}, + {0.0224439650744986, 0.4674727059721964, 0.3619056954025697}, + {0.02302262600613305, 0.47238034113781563, 0.3561610413615427}, + {0.022921527380028887, 0.4773067430685342, 0.350207729192515}, + {0.023482745772902724, 0.4822119663418752, 0.34409988145088766}, + {0.02334902491772799, 0.48713531181669306, 0.3377738746272117}, + {0.023887996465323004, 0.4920362610259304, 0.33130046883268455}, + {0.023714510501347055, 0.4969547158806737, 0.32459934406811614}, + {0.024225153974701766, 0.5018496124079483, 0.3177583627477745}, + {0.024723266142386315, 0.5067407770624851, 0.31073519425545465}, + {0.02447812509827954, 0.5116485921195848, 0.3034698224412634}, + {0.02493648885622696, 0.5165312197695955, 0.2960768968333586}, + {0.0253764023681478, 0.5214089374064284, 0.28850111378145044}, + {0.025795626075147713, 0.5262813821767296, 0.28074244497417117}, + {0.025421474545393858, 0.5311694950761902, 0.2727216863169472}, + {0.025780309667251394, 0.53603048885089, 0.2645922829614648}, + {0.02610999696637235, 0.5408852158877796, 0.25628033494817076}, + {0.026407437583934296, 0.5457333806719771, 0.2477862504464216}, + {0.02666932808870506, 0.5505747064434545, 0.2391105880601489}, + {0.02689217252655957, 0.5554089359982296, 0.2302540772313253}, + {0.027072298940817408, 0.5602358325123109, 0.22121764273058586}, + {0.027205880727598008, 0.5650551803951163, 0.2120024343570966}, + {0.027288963146258696, 0.5698667861810437, 0.20260986337352}, + {0.028204203304642753, 0.5746482086659772, 0.19318007629151898}, + {0.028188559261174452, 0.5794437480873181, 0.18344751604265283}, + {0.0281103207218881, 0.5842311106814237, 0.17354484850307106}, + {0.028896130485080208, 0.5889876510327495, 0.16364429504261102}, + {0.028695320134244477, 0.5937583183864393, 0.1534244803870241}, + {0.029380675523176917, 0.5984978909930776, 0.14324398649586118}, + {0.029041895792470927, 0.6032517278747106, 0.13273404723048013}, + {0.029612109748158165, 0.6079743365463844, 0.12231515476812047}, + {0.030127173837479853, 0.6126885119214123, 0.1118109733754355}, + {0.029563230689198295, 0.6174173890888045, 0.10096978844729684}, + {0.029944189232757292, 0.6221151405821017, 0.09035027988372307}, + {0.030261789165931138, 0.6268049184840729, 0.07974541336580176}, + {0.030514080739125825, 0.6314869729283614, 0.06921734345076924}, + {0.030699652650745195, 0.6361616116842398, 0.05885329347452114}, + {0.0308177148230897, 0.6408292087724975, 0.04877724313606999}, + {0.03086818674766468, 0.6454902160815501, 0.03915677764354433}, + {0.03197034466002908, 0.6501217563441514, 0.031444380194868886}, + {0.046293996677654235, 0.6544720579771781, 0.031637291074855106}, + {0.058794558570863804, 0.6588271549701028, 0.0317521581310916}, + {0.06503863628200135, 0.6633055777623768, 0.03209873268943441}, + {0.07023149742711651, 0.6678120145394701, 0.03183433002082528}, + {0.0767138128414942, 0.6722807177648771, 0.032132076596637124}, + {0.08432067120858369, 0.6767139870108101, 0.032338563602709626}, + {0.09294277780722546, 0.6811085964562938, 0.032444071987208487}, + {0.10305233592409935, 0.6854378106573311, 0.03307401108271617}, + {0.11331609119127764, 0.6897459817142692, 0.03295480891791886}, + {0.12476614069574826, 0.6939830479703625, 0.033353619722170935}, + {0.13673711440841982, 0.6981699856866227, 0.03362590965526557}, + {0.1491636843492167, 0.7023042408994585, 0.033762275984369046}, + {0.16199129317074465, 0.706383361101949, 0.03375336199700755}, + {0.17553308151438088, 0.7103815097863063, 0.03426353710068628}, + {0.18933948484375165, 0.7143200103636559, 0.03462289684303036}, + {0.20338652270943824, 0.7181967154976012, 0.03482214714504671}, + {0.21765378276012448, 0.7220095660591789, 0.0348520554844732}, + {0.23212369587552023, 0.7257565893785501, 0.03470346402383256}, + {0.24702985279407214, 0.7294127796374531, 0.03507444712661609}, + {0.2620775705935113, 0.7329996606625439, 0.035262260320886224}, + {0.2772591134255436, 0.7365155484918555, 0.03525791814557077}, + {0.2927712616124238, 0.7399360689986639, 0.035780536388425606}, + {0.3083781576598969, 0.7432827601590504, 0.03610724156995657}, + {0.3240763123743059, 0.746554228453955, 0.036229314118799705}, + {0.33986207442019495, 0.7497491625691519, 0.03613819725600252}, + {0.3558907708679886, 0.7528442021403842, 0.036581966518590206}, + {0.3718311425153303, 0.7558826557986548, 0.036046421794990055}, + {0.38813047246050614, 0.7587977057098403, 0.03681458696854892}, + {0.4043371221939297, 0.7616541995826684, 0.03658736257615303}, + {0.42072356025646707, 0.7644081013195043, 0.03690635392025313}, + {0.43714739423907745, 0.7670803847862102, 0.03699298731846738}, + {0.45360699836908186, 0.769670380372701, 0.03683987811183992}, + {0.4702051248974935, 0.7721571183110766, 0.03724796925537228}, + {0.4868227556665157, 0.7745610930844775, 0.0374172194555026}, + {0.503458588002791, 0.7768819000929792, 0.03734086718256391}, + {0.5201979969654729, 0.779099877137358, 0.03784362950139135}, + {0.5368601535092656, 0.7812537776842732, 0.03726439057607977}, + {0.5536883905115004, 0.7832866691953926, 0.0381141962950549}, + {0.570436957512631, 0.7852552273306327, 0.03787015508826886}, + {0.5872524511360537, 0.787122879084239, 0.03822846891183527}, + {0.604057585524296, 0.7889082049024678, 0.03833696358570872}, + {0.6208512632987039, 0.7906113236317394, 0.03819060762615894}, + {0.6376323001265665, 0.7922323958682111, 0.03778469202199975}, + {0.654448292617523, 0.7937561555975436, 0.03800948341735075}, + {0.6712409304097, 0.7951995038068883, 0.03798214896623336}, + {0.6880499867367655, 0.7965485565944844, 0.038610111469974305}, + {0.7047891048851465, 0.7978328175913231, 0.03807498680487568}, + {0.7215350356575515, 0.7990249426739793, 0.03820456984010566}, + {0.7382756146491691, 0.8001275152547487, 0.03902092612392253}, + {0.7549478024082115, 0.8011661514812047, 0.03865607007534288}, + {0.7716059891201252, 0.8021178857956822, 0.038989380941084874}, + {0.7882203132421456, 0.8029955440735611, 0.03908165535934637}, + {0.8047902362352904, 0.8037997989252117, 0.03893065650816213}, + {0.8215523268463777, 0.8044555316790379, 0.03926557049926157}, + {0.8387398480023723, 0.8048817689898747, 0.04067065212316836}, + {0.856341544941598, 0.8050796719349672, 0.04123085284140562}, + {0.8743768083538662, 0.8050267567672601, 0.0419261583900458}, + {0.8928528884736874, 0.8047076768017004, 0.0427644722591047}, + {0.911776412947498, 0.8041062177363495, 0.04375041022498651}, + {0.9311533128855841, 0.8032052518345966, 0.044885135667359986}, + {0.9510015669358057, 0.8019861521093661, 0.04532603899543026}, + {0.962930103481011, 0.8014439331866959, 0.22169249312004036}, + {0.9683410354743099, 0.8024669332735311, 0.3358446858430373}, + {0.9719380800534977, 0.8044065772211566, 0.4114102805053895}, + {0.9746751561332506, 0.8069447701330453, 0.46819081680773716}, + {0.9768136632655356, 0.8099358552525316, 0.5140546510678895}, + {0.978649037790159, 0.8132574705132256, 0.5522569503355605}, + {0.9802036704451057, 0.8168594951941832, 0.5851451968636262}, + {0.981554091047551, 0.8206924722262127, 0.6139795814385243}, + {0.9827732625825781, 0.8247142837530934, 0.6395746026568098}, + {0.9839157453834834, 0.8288914274285599, 0.6625186328985215}, + {0.9848784092487323, 0.8332318824714189, 0.6834911738162105}, + {0.9858320115191356, 0.8376808147738173, 0.7025706724123436}, + {0.9866558657916994, 0.8422559436774792, 0.7202399867839039}, + {0.9873677995679001, 0.8469433249862409, 0.7366844886107697}, + {0.9881805379141889, 0.8516804941618812, 0.7518089864773918}, + {0.9887611047789485, 0.8565442781873747, 0.7661909960366566}, + {0.9894043443414985, 0.8614528824718757, 0.7795879261784779}, + {0.9900758649057856, 0.8664087680409848, 0.7921604870664645}, + {0.99059092673338, 0.8714545088111433, 0.8041942791071222}, + {0.9911277189421445, 0.8765391108526217, 0.8155756474332213}, + {0.9916061462381213, 0.8816790723671002, 0.8264519900822266}, + {0.9922158985563451, 0.8868207617131697, 0.836709699896381}, + {0.9925679440918894, 0.8920625188742286, 0.8467473851492474}, + {0.9931424279738416, 0.8972751802406753, 0.8561933859696547}, + {0.9935217736048007, 0.9025652348682511, 0.8654402820837326}, + {0.9938879084327678, 0.9078821573987383, 0.874370338308405}, + {0.99427342946785, 0.9132148454645382, 0.8829927351962013}, + {0.9947111506654817, 0.918552416162813, 0.8913160852881722}, + {0.995056938233056, 0.9239302650640105, 0.8994722486725081}, + {0.995512287532556, 0.9292939740928252, 0.9073439419102849}, + {0.9959250022023757, 0.9346812618630085, 0.9150611281410694}, + {0.9961274042213023, 0.9401333891345969, 0.9227518397011023}, + {0.9965143545143408, 0.9455470167979051, 0.9301752047442942}, + {0.996922153842586, 0.9509629844614244, 0.9374587708548032}, + {0.9971731694726661, 0.9564250004713418, 0.9447286698401807}, + {0.9976825719783714, 0.9618265695993463, 0.9517442599956717}, + {0.9978661370132459, 0.967313947090583, 0.958874650466398}, + {0.9983489942212443, 0.972728972574113, 0.9657569772496776}, + {0.9985297770627254, 0.9782208004653724, 0.9727591013871136}, + {0.9988366714262512, 0.9836818403108719, 0.9796396969161855}, + {0.999287652981863, 0.989107488582374, 0.9864006969015998}, + {0.9994697671436109, 0.9945977204425903, 0.9932874563643866}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> inferno_data_ = {{ + {0.0014619955811715805, 0.0004659913919114934, 0.013866005775115809}, + {0.0022669056023600243, 0.001269897101615975, 0.018569490325902337}, + {0.003299036110031063, 0.0022490183451722313, 0.024239243465136288}, + {0.004546896852350439, 0.0033918841632656804, 0.03090851258977682}, + {0.006006105056993791, 0.004692061241092744, 0.038558624443389096}, + {0.007675918804434457, 0.006135891503856028, 0.046835705273408614}, + {0.009561203394731096, 0.0077131160510677, 0.05514393874236257}, + {0.011662968995142865, 0.0094169153553472, 0.06345998081431048}, + {0.013994707785115502, 0.011224701548363442, 0.07186110007643282}, + {0.01656105637139426, 0.01313595377716254, 0.08028228905271992}, + {0.019372742788596516, 0.01513271743178829, 0.08876637381708319}, + {0.02244719411002579, 0.017198996785303594, 0.09732759285010725}, + {0.02579282311826555, 0.01933074318511054, 0.10592963918696552}, + {0.029432387489373633, 0.02150303695278668, 0.11462190156591848}, + {0.03338491092042817, 0.023701776954208033, 0.12339694246694158}, + {0.03766747608151851, 0.025920506649278047, 0.13223096637532075}, + {0.042253067017337005, 0.028138807463796305, 0.1411412582171954}, + {0.04691458399133113, 0.030323540520811973, 0.15016326468244964}, + {0.05164425209311529, 0.03247382729611796, 0.15925458396315}, + {0.05644871419547314, 0.03456857075460381, 0.16841357852522199}, + {0.06134044494312783, 0.03658982977294056, 0.17764292167289156}, + {0.06633085137688166, 0.038503594004715896, 0.18696190141292804}, + {0.07142826458096291, 0.04029339894981024, 0.19635286429314014}, + {0.07663702254956387, 0.04190461115902603, 0.2057992341013456}, + {0.08196142528164385, 0.043327451450508585, 0.2152881892106146}, + {0.087411214696131, 0.04455560411873583, 0.22481357132253754}, + {0.09298959953890884, 0.04558246689176038, 0.23435752319694075}, + {0.0987024276165075, 0.0464015612109181, 0.24390490595057124}, + {0.1045507907963224, 0.04700744862572622, 0.2534298623464375}, + {0.11053667232221573, 0.04739845362551404, 0.26291322780905574}, + {0.11665600122383982, 0.04757339371302694, 0.27232119603015154}, + {0.12290731198945251, 0.04753536748517837, 0.2816231724086292}, + {0.12928523040832837, 0.04729230240096718, 0.2907885083783503}, + {0.13577751583663375, 0.046855310502846824, 0.29977552118778034}, + {0.14237847430795506, 0.04624117675574093, 0.30855378680836465}, + {0.1490727384829781, 0.04546721023082908, 0.3170848511067041}, + {0.1558507266503708, 0.044558026492337664, 0.32533901695859424}, + {0.1626889760379725, 0.0435530737190721, 0.3332771435961689}, + {0.16957421944883505, 0.042488139902889556, 0.3408733080618529}, + {0.17649322158660016, 0.04140091975980204, 0.3481113785987225}, + {0.18342846019226636, 0.04032795978956832, 0.35497062509269495}, + {0.19036746731312684, 0.03930776663057157, 0.36144755914871207}, + {0.19729670678394517, 0.03839881405885271, 0.3675348910966813}, + {0.20420970925948218, 0.03763066869776516, 0.3732386865741054}, + {0.21109495319112997, 0.0370286796745015, 0.3785631007654439}, + {0.21794820252834113, 0.036613674395490264, 0.38352155568816976}, + {0.22476319518924603, 0.03640357374688182, 0.38812924842856483}, + {0.2315374529310898, 0.03640351817286241, 0.39239977934534576}, + {0.2382734320696066, 0.03661949264330557, 0.3963533531157254}, + {0.2449666980359304, 0.03705338654185691, 0.4000069520159531}, + {0.2516206637792285, 0.037703436097523746, 0.4033784221656792}, + {0.2582339375612672, 0.038569281262784215, 0.4064850812186898}, + {0.2648092188471272, 0.039645098963587894, 0.4093447670552162}, + {0.27134717156688476, 0.040920248896872104, 0.41197616680691795}, + {0.27784945989435444, 0.04235106621674233, 0.41439190152253697}, + {0.2843214014200332, 0.043931272334442044, 0.4166082251959268}, + {0.2907626953161, 0.04564206683863344, 0.41863700244674007}, + {0.2971786279866803, 0.04746832221255668, 0.42049126153840694}, + {0.3035679263767977, 0.04939409900213965, 0.42218207588627776}, + {0.3099342310464275, 0.05140486616668636, 0.4237209077370659}, + {0.3162821544923382, 0.0534881537223529, 0.42511612281358585}, + {0.3226094622720638, 0.05563191003781664, 0.42637698442915734}, + {0.32892138033063256, 0.057825220219243655, 0.4275111514018109}, + {0.33521669037969953, 0.060057968826412046, 0.42852404020939816}, + {0.34150060454122194, 0.06232329248965957, 0.42942516526482805}, + {0.34777091610802874, 0.06461403589398387, 0.43021707827304073}, + {0.35403123226470046, 0.06692277585963113, 0.43090600382653765}, + {0.3602841408353374, 0.06924510666507289, 0.4314970989990494}, + {0.366528457743285, 0.07157684449494817, 0.4319940445656597}, + {0.3727683648145053, 0.0739131776252345, 0.4324001060667602}, + {0.37900068183696356, 0.07625091481761018, 0.432719071099916}, + {0.3852285882170877, 0.07858924726823341, 0.43295510186497294}, + {0.391452904966983, 0.08092498458487726, 0.4331090849213901}, + {0.3976732251941389, 0.08325472094735673, 0.43318307823977154}, + {0.4038941281371945, 0.08557805215845263, 0.4331790858011016}, + {0.4101124478324236, 0.08789378949993748, 0.43309809489281975}, + {0.41633135152767126, 0.09020111672608602, 0.4329430750225925}, + {0.4225486702204431, 0.09249885580078815, 0.43271410026220614}, + {0.42876857492222104, 0.09478817843783055, 0.43241205420979634}, + {0.43498689244861954, 0.09706691940470738, 0.43203909514551403}, + {0.4412077984093083, 0.09933623724389631, 0.4315940236596366}, + {0.447428115165217, 0.10159497990744795, 0.43108007898556605}, + {0.453650434334324, 0.10384572179396404, 0.4304981431533577}, + {0.4598753385411611, 0.10608703735300581, 0.4298460517373555}, + {0.4660996564728312, 0.10831978115925261, 0.42912513104437605}, + {0.47232856222023284, 0.11054509253877559, 0.428334014815688}, + {0.47855787863379246, 0.11276183809637635, 0.42747510913916503}, + {0.4847897859200844, 0.11497214601360681, 0.42654796832755787}, + {0.49102210135850827, 0.11717689277568918, 0.4255520769077051}, + {0.4972564191293403, 0.11937663835804257, 0.42448819407856125}, + {0.5034933248743276, 0.12157294554931822, 0.42335603351162365}, + {0.5097296414881407, 0.12376669200308499, 0.4221561654704694}, + {0.5159675484473075, 0.12595799741934913, 0.42088698041253036}, + {0.522205863946251, 0.1281477445657914, 0.4195491273628126}, + {0.5284447718500154, 0.1303390492990618, 0.41814191774726495}, + {0.5346830866012935, 0.1325317964071948, 0.4166670792419288}, + {0.5409194040751939, 0.13472654160063324, 0.4151232492186141}, + {0.5471573097689081, 0.1369268480746088, 0.41351101955274133}, + {0.5533916265944651, 0.13913159264204145, 0.4118292045095448}, + {0.5596245324931008, 0.14134390081316123, 0.41007795018698034}, + {0.565853849035322, 0.14356464417843176, 0.408258150100951}, + {0.5720817545692755, 0.14579495531212058, 0.40636887114816594}, + {0.5783040710826255, 0.1480366969821801, 0.4044110859921461}, + {0.5845203906718561, 0.15029143569692027, 0.4023853090317509}, + {0.5907342930011564, 0.15256075186424045, 0.40029001001388526}, + {0.5969396129909775, 0.1548454880249755, 0.3981252481044335}, + {0.6031395137899174, 0.15714880993418692, 0.39589092443931145}, + {0.6093298346523712, 0.15947154274866268, 0.3935891773266438}, + {0.6155137330265519, 0.1618148719991605, 0.3912188293792153}, + {0.6216850552354126, 0.1641816008624372, 0.38878109691187235}, + {0.6278463807173074, 0.1665723257656469, 0.3862763730397491}, + {0.6339982745553374, 0.16898966363736537, 0.3837040052607365}, + {0.6401346020827624, 0.17143538357408133, 0.3810652955393134}, + {0.6462604918955885, 0.17391173185514677, 0.3783589039476966}, + {0.6523688217818822, 0.17641844614159138, 0.37558620861598563}, + {0.6584637067856558, 0.17895980652738866, 0.37274779377320805}, + {0.6645400395062868, 0.1815365142239986, 0.36984611221667457}, + {0.6705983762227489, 0.18415021667573447, 0.36687943961906233}, + {0.6766382547106133, 0.18680458958736995, 0.3638490055304848}, + {0.6826555952415246, 0.1894982847225483, 0.3607573457624624}, + {0.6886534667732338, 0.1922366729397742, 0.3576028897156723}, + {0.6946268114822389, 0.19501835963153946, 0.35438824300823807}, + {0.7005766750861048, 0.19784876490425912, 0.35111276552861453}, + {0.7065000246724039, 0.20072544237887552, 0.34777713155969964}, + {0.7123953793054851, 0.20365311312098916, 0.34438350640978904}, + {0.7182642339188836, 0.20663353472537765, 0.34093101094395056}, + {0.7241025940115757, 0.20966719575096354, 0.3374243970752363}, + {0.7299094384556731, 0.21275663751205837, 0.33386088208499215}, + {0.7356828051012506, 0.21590328739196812, 0.3302452795512392}, + {0.7414236378808644, 0.2191097508283441, 0.32657574613398255}, + {0.7471270116731434, 0.2223753888240187, 0.32285615422841446}, + {0.7527948315414559, 0.22570387532426378, 0.31908460363536006}, + {0.7584222127903781, 0.22909450162198797, 0.31526602130047027}, + {0.7640096003184447, 0.23255111985362076, 0.3113994474823908}, + {0.769556407505972, 0.236074626914262, 0.30748488142933444}, + {0.7750588038588068, 0.23966423164432504, 0.3035263167932573}, + {0.780517595641067, 0.24332476411029125, 0.29952273568573573}, + {0.7859290015238034, 0.2470533545534328, 0.29547717944438406}, + {0.7912937764432374, 0.25085391354890735, 0.29138958485956357}, + {0.7966071922843984, 0.25472548987486643, 0.28726403596779526}, + {0.8018706152376446, 0.2586710580118296, 0.28309949569184917}, + {0.8070823747046473, 0.26268963921769606, 0.27889788734079896}, + {0.8122388089759692, 0.26678319189183297, 0.2746613536242391}, + {0.8173415491080798, 0.27095180082645115, 0.27038973420543944}, + {0.8223859952913317, 0.27519433772522317, 0.2660852062616442}, + {0.8273727148541918, 0.2795149750247453, 0.26174957724469494}, + {0.8322991733910813, 0.2839104959497832, 0.25738305415913015}, + {0.8371646398804131, 0.2883820094161365, 0.252988540402642}, + {0.8419693412456319, 0.29293066888944563, 0.2485638989415601}, + {0.846708821213788, 0.29755616578042293, 0.2441133893753179}, + {0.8513844997023888, 0.3022578538064719, 0.23963574040066615}, + {0.855991993845198, 0.3070353341236893, 0.23513323409260284}, + {0.8605336484626919, 0.31189005054876767, 0.230605578997568}, + {0.865006157141607, 0.316819514079576, 0.2260550749407627}, + {0.8694086743123614, 0.3218239712798184, 0.2214825826370368}, + {0.873741308408031, 0.32690370860531126, 0.21688591478628577}, + {0.8780008409852356, 0.33205714927467816, 0.212268424608822}, + {0.8821884493306369, 0.33728491405873967, 0.20762775209164724}, + {0.8863019976673894, 0.3425833384271254, 0.20296826303399285}, + {0.8903415794934312, 0.3479551300484793, 0.19828558691030201}, + {0.894305144045262, 0.3533965381592675, 0.19358409819949085}, + {0.8981917181039129, 0.35890794053186803, 0.1888606247963219}, + {0.902003277546344, 0.36448975074745, 0.18411593340897883}, + {0.9057348680145032, 0.37013713800749826, 0.17935046113406727}, + {0.9093903996647411, 0.3758539732830311, 0.17456276670706064}, + {0.9129660070101344, 0.38163334525219944, 0.1697552941505453}, + {0.9164625104530708, 0.3874792047452722, 0.16492359727200515}, + {0.9198791350013626, 0.39338656173222386, 0.16007012382758104}, + {0.9232147698912994, 0.3993559137889013, 0.1551936703489871}, + {0.9264702498113229, 0.40538678902429115, 0.15029195385198924}, + {0.9296439014941755, 0.41147612778815296, 0.14536750158970949}, + {0.9327373523126056, 0.4176250250322833, 0.14041678247519898}, + {0.9357470217364718, 0.42382835018615, 0.13544032915276746}, + {0.9386754432346461, 0.4300892683482416, 0.13043760827101122}, + {0.9415211303729047, 0.4364025802485547, 0.12540915246812306}, + {0.9442848284617543, 0.4427688880476121, 0.12035472282994122}, + {0.9469652258626157, 0.44918881902600133, 0.11527197615350762}, + {0.9495619408937822, 0.4556571156219838, 0.11016454791032279}, + {0.9520753085089858, 0.4621760654003351, 0.10503080049999589}, + {0.9545060414475516, 0.468741350075834, 0.09987436834002841}, + {0.9568523791775677, 0.4753543175690524, 0.09469462335752518}, + {0.9591141303022052, 0.4820115908490303, 0.08949918430671361}, + {0.9612934380573407, 0.4887145750891598, 0.08428844691950368}, + {0.9633872061002898, 0.4954598384326913, 0.07907300229562086}, + {0.9653969856405892, 0.5022460991811288, 0.07385959127645336}, + {0.9673222685246364, 0.5090760925737746, 0.06865882956308128}, + {0.9691630662078553, 0.5159433430954236, 0.06348840124042007}, + {0.970919318954511, 0.5228513513717987, 0.05836666742473027}, + {0.9725901348141913, 0.529795592113789, 0.053324210911405455}, + {0.9741763574084353, 0.5367786143884726, 0.04839153015610343}, + {0.975677190645675, 0.5437958464199314, 0.043618036090846}, + {0.9770920356520277, 0.5508470769374313, 0.03905055303111867}, + {0.9784222326450961, 0.5579351064433469, 0.034930916546532825}, + {0.979666095876416, 0.5650543281731687, 0.0314092990272324}, + {0.9808242624402922, 0.5722073701062071, 0.028507883553058225}, + {0.9818951440117506, 0.5793895836320366, 0.02625012573179964}, + {0.982881280054488, 0.5866046371076197, 0.024660950197297846}, + {0.9837791795198422, 0.5938468430754209, 0.023770046474572596}, + {0.9845910909683125, 0.6011190480992957, 0.023606059102018802}, + {0.9853152007413414, 0.608420107478453, 0.02420209240341553}, + {0.9859521306674056, 0.6157473052058917, 0.025591934272695092}, + {0.9865022096405148, 0.6231033747802108, 0.027814257478890377}, + {0.9869641579064014, 0.6304825655882533, 0.030907915000313535}, + {0.9873372060008064, 0.6378886447799842, 0.034916559619452406}, + {0.987622172670732, 0.6453178289458518, 0.039886017500422775}, + {0.9878191520033638, 0.6527700129448509, 0.045580403012790684}, + {0.9879261727372323, 0.6602480965501968, 0.05175024605159847}, + {0.9879451706317489, 0.6677452744424257, 0.05832852598609512}, + {0.9878741601998459, 0.675265366380739, 0.06525752407999996}, + {0.9877141765851464, 0.6828045385569567, 0.07248872059669512}, + {0.9874641349558363, 0.690364638021527, 0.07999083430127826}, + {0.9871241697382241, 0.6979418049868507, 0.08773096280857864}, + {0.9866942187047217, 0.7055369718171162, 0.09569310480416554}, + {0.9861751485274827, 0.7131510743985874, 0.103863256330502}, + {0.9855662155788282, 0.7207792367356154, 0.11222834433058854}, + {0.9848651143109276, 0.7284253454782301, 0.12078557949263882}, + {0.9840751996931422, 0.7360845034258754, 0.12952661474987895}, + {0.9831960676449997, 0.7437566173190143, 0.13845392837069237}, + {0.9822281707577935, 0.7514397717174452, 0.14756491297187693}, + {0.9811732892122574, 0.7591319265002779, 0.15686190499859645}, + {0.9800321283245658, 0.7668350414250283, 0.16635325033390524}, + {0.9788062634501479, 0.7745421938654863, 0.1760361942373471}, + {0.9774970739304246, 0.7822563112740953, 0.18592362086777084}, + {0.976108224906952, 0.7899714619636461, 0.1960175103988243}, + {0.9746380082272822, 0.7976905802513132, 0.20633302377351131}, + {0.9730881744707035, 0.8054067300567858, 0.21687685576253862}, + {0.9714683557085738, 0.8131188812721618, 0.2276566805995705}, + {0.9697831130812914, 0.8208229971469754, 0.23868624376433029}, + {0.968041305354793, 0.8285121501431812, 0.24997101177190928}, + {0.9662430438023951, 0.836189261303023, 0.2615346777715621}, + {0.9643942451078572, 0.8438454171701422, 0.273390375539181}, + {0.9625169727369577, 0.8514745194008927, 0.2855471549893648}, + {0.9606261754860036, 0.8590666816140542, 0.29800977930778266}, + {0.9587199044763673, 0.86662276892152, 0.310821685193729}, + {0.9568341051627561, 0.8741269393072385, 0.3239742355406551}, + {0.9549973084887696, 0.8815661177531517, 0.3374737603502378}, + {0.9532150458875698, 0.8889401848892272, 0.3513697543417886}, + {0.9515462272506953, 0.8962233797142661, 0.36562618964558136}, + {0.950018012245954, 0.9034074125145412, 0.3802723264284489}, + {0.9486831530694507, 0.9104706308186431, 0.3952886725437556}, + {0.9475940275601823, 0.9173976138382822, 0.4106669431858655}, + {0.9468091087983127, 0.9241658620670481, 0.4263732130148635}, + {0.9463921563722028, 0.9307581300310862, 0.4423654634949841}, + {0.9464031311450462, 0.9371570608055302, 0.458592798889426}, + {0.9469030741916794, 0.9433453721925603, 0.4749690020361225}, + {0.9479372327167105, 0.9493162253885609, 0.49142738476056075}, + {0.9495450508917115, 0.9550605846153878, 0.5078595779865485}, + {0.9517404201103928, 0.9605853570748163, 0.5242049355302347}, + {0.9545291096426641, 0.9658937621848641, 0.5403611560472134}, + {0.9578957403425837, 0.971000188760133, 0.5562734123813695}, + {0.9618122666687167, 0.9759219036314865, 0.571925695133198}, + {0.966248777481722, 0.980675368253291, 0.5872050182876477}, + {0.9711624870815522, 0.985280023457573, 0.6021551859229256}, + {0.9765108962599102, 0.9897505184610552, 0.6167595818025277}, + {0.9822577545753769, 0.9941071290312428, 0.6310186261682112}, + {0.9883620799212208, 0.9983616470620554, 0.6449240982803861}, +}}; + +template +static constexpr std::array, 256> black_body_data_ = {{ + {0.0, 0.0, 0.0}, + {0.013038855104993618, 0.0037537033758315535, 0.002103027943341456}, + {0.02607771020998725, 0.007507406751663157, 0.004206055886683011}, + {0.03911656531498074, 0.01126111012749475, 0.006309083830024466}, + {0.05111281846889674, 0.0150148135033264, 0.008412111773366015}, + {0.06145201887409168, 0.018768516879157954, 0.010515139716707521}, + {0.07064326337459148, 0.02252222025498951, 0.012618167660048977}, + {0.07897806577026972, 0.026275923630821117, 0.014721195603390481}, + {0.08664361913059343, 0.03002962700665271, 0.016824223546731985}, + {0.09376835672821318, 0.03378333038248431, 0.018927251490073488}, + {0.10044479589169861, 0.03753703375831587, 0.021030279433414945}, + {0.10674212293169041, 0.041271634201045536, 0.02313330737675645}, + {0.11271363536038692, 0.04482597891806931, 0.025236335320097954}, + {0.11840139369546077, 0.048211428422088996, 0.027339363263439456}, + {0.12383926177477003, 0.051448139039433315, 0.029442391206781018}, + {0.12905496821437284, 0.05455261530914037, 0.03154541915012247}, + {0.13415881215680708, 0.05748457013282512, 0.03365241563251253}, + {0.1394282635051205, 0.06009480851170646, 0.035776007200922486}, + {0.1448680365076732, 0.06239658846641056, 0.03791741526748158}, + {0.15046463427844672, 0.06440943575351296, 0.04007701382092898}, + {0.15620567729622375, 0.06614841603004337, 0.042202264001466754}, + {0.1620642871793741, 0.06766725618508368, 0.04427088573012868}, + {0.1679681168976293, 0.06914956019046758, 0.04626676146380417}, + {0.17390879488805058, 0.07061411563078038, 0.048192562428916404}, + {0.17988507705788212, 0.07206107502164819, 0.05005305250836759}, + {0.18589582390636886, 0.073490579693259, 0.0518524382574397}, + {0.19193998883434982, 0.07490276049381833, 0.053594454613670746}, + {0.19801660795994802, 0.07629773842679596, 0.05528243440605366}, + {0.20412479122741767, 0.0776756252290656, 0.05691936524751085}, + {0.21026371462828286, 0.07903652389614257, 0.05850793649497276}, + {0.2164326133809747, 0.08038052915995664, 0.060050578312412416}, + {0.2226307759380115, 0.08170772792393452, 0.06154949439758999}, + {0.22885753870905418, 0.08301819965959711, 0.0630066895818179}, + {0.23511228140445872, 0.08431201676837646, 0.06442399324878009}, + {0.2413944229177235, 0.08558924491193284, 0.06580307931909093}, + {0.24770341767689402, 0.08684994331387272, 0.06714548339482998}, + {0.25403875240487506, 0.08809416503544282, 0.06845261754062515}, + {0.2603999432369943, 0.089321957227491, 0.06972578308625077}, + {0.26678653315130063, 0.09053336136073056, 0.07096618176381639}, + {0.2731980896731617, 0.09172841343612223, 0.07217492543577086}, + {0.2796342028209079, 0.09290714417700069, 0.07335304462466913}, + {0.2860944832637109, 0.09406957920438949, 0.07450149601935155}, + {0.29257856066667054, 0.09521573919680446, 0.07562116910289712}, + {0.29908608220134825, 0.09634564003570609, 0.07671289202394302}, + {0.3056167112027767, 0.09745929293764075, 0.07777743681356081}, + {0.31217012595638344, 0.0985567045740047, 0.07881552403396175}, + {0.31874601860034424, 0.09963787717926836, 0.0798278269321728}, + {0.32534319363742265, 0.10070307071710113, 0.08082304674985791}, + {0.3319596041219896, 0.1017528114823801, 0.08181815186765931}, + {0.3385951481217959, 0.10278707282194993, 0.08281314988265284}, + {0.34524972170116486, 0.10380582517735878, 0.08380805027785368}, + {0.35192321947598326, 0.10480903601879557, 0.08480286230027789}, + {0.35861553489350906, 0.10579666984465097, 0.08579759496848993}, + {0.36532656048179657, 0.10676868817762619, 0.08679225707984467}, + {0.3720561880720667, 0.10772504955741516, 0.08778685721743867}, + {0.3788043089969579, 0.10866570952997373, 0.08878140375678456}, + {0.38557081426725, 0.10959062063337968, 0.08977590487222206}, + {0.392355594729354, 0.11049973238028288, 0.09077036854307868}, + {0.3991585412055988, 0.1113929912369285, 0.09176480255959146}, + {0.40597954461911684, 0.11227034059873503, 0.09275921452860061}, + {0.41281849610493104, 0.1131317207623947, 0.09375361187902712}, + {0.4196752871086668, 0.11397706889445536, 0.09474800186714263}, + {0.4265498094741573, 0.11480631899633567, 0.0957423915816421}, + {0.4334419555210749, 0.11561940186571482, 0.09673678794852814}, + {0.44035161811359996, 0.11641624505422682, 0.09773119773581507}, + {0.44727869072102816, 0.11719677282138305, 0.09872562755806155}, + {0.45422306747112823, 0.11796090608463114, 0.09972008388073797}, + {0.46118464319697156, 0.11870856236545602, 0.10071457302443804}, + {0.4681633134778857, 0.11943965573140711, 0.1017091011689388}, + {0.47515897467511364, 0.12015409673393382, 0.10270367435711814}, + {0.4821715239627041, 0.1208517923418958, 0.10369829849873419}, + {0.4892008593541031, 0.12153264587059787, 0.1046929793740726}, + {0.49624687972487286, 0.12219655690619557, 0.10568772263746884}, + {0.5033094848319175, 0.12284342122529493, 0.10668253382070847}, + {0.5103885753295632, 0.12347313070955779, 0.10767741833631286}, + {0.5174840527828012, 0.12408557325511224, 0.10867238148071282}, + {0.5245958196779755, 0.12468063267654717, 0.10966742843731633}, + {0.5317237794311703, 0.12525818860524965, 0.11066256427947438}, + {0.5388678363945218, 0.12581811638183757, 0.1116577939733483}, + {0.5460278958606667, 0.12636028694240006, 0.11265312238068345}, + {0.5532038640655134, 0.12688456669826084, 0.11364855426149251}, + {0.5603956481895038, 0.12739081740893254, 0.11464409427665198}, + {0.5676031563575221, 0.12787889604792488, 0.11563974699041571}, + {0.5748262976375883, 0.12834865466103332, 0.11663551687284723}, + {0.5820649820384645, 0.12879994021670815, 0.11763140830217725}, + {0.5893191205062877, 0.1292325944480741, 0.11862742556708483}, + {0.5965886249203336, 0.12964645368613567, 0.11962357286890879}, + {0.6038734080880022, 0.13004134868367784, 0.12061985432379002}, + {0.6111733837391209, 0.13041710442930957, 0.12161627396474861}, + {0.618488466519628, 0.1307735399510897, 0.12261283574369633}, + {0.6258185719847208, 0.13111046810909502, 0.12360954353338896}, + {0.6331636165915261, 0.13142769537626633, 0.12460640112931987}, + {0.6405235176913502, 0.13172502160680363, 0.125603412251556}, + {0.6478981935215649, 0.13200223979132508, 0.12660058054652026}, + {0.6552875631971755, 0.13225913579794255, 0.1275979095887203}, + {0.6626915467021134, 0.13249548809833553, 0.1285954028824274}, + {0.6701100648802979, 0.13271106747782782, 0.12959306386330607}, + {0.6775430394264935, 0.13290563672840347, 0.13059089589999584}, + {0.6849903928770076, 0.133078950323475, 0.13158890229564854}, + {0.6924520486002461, 0.13323075407316545, 0.13258708628942104}, + {0.6990269444289148, 0.13526285713010114, 0.13312878204163103}, + {0.7029385031056067, 0.14276164252353424, 0.13230087174729266}, + {0.706849160518104, 0.15003367886528432, 0.13144472110159658}, + {0.7107589339135043, 0.1571072636984418, 0.13055959687730143}, + {0.7146678402982333, 0.16400574341929422, 0.12964472942353197}, + {0.7185758964424839, 0.17074862440458652, 0.1286993099989257}, + {0.7224831188845541, 0.1773523851612915, 0.12772248784920406}, + {0.7263895239350789, 0.18383108192179715, 0.12671336699848523}, + {0.7302951276811657, 0.19019680820853718, 0.12567100271919956}, + {0.7341999459904341, 0.19646004903982417, 0.12459439764026739}, + {0.7381039945149617, 0.20262995773846548, 0.12348249744706852}, + {0.742007288695138, 0.20871457496055673, 0.12233418611951721}, + {0.7459098437634323, 0.21472100396010463, 0.1211482806460144}, + {0.7498116747480748, 0.22065555226824157, 0.11992352514088764}, + {0.7537127964766552, 0.22652384728976455, 0.11865858428082418}, + {0.7576132235796376, 0.23233093142236372, 0.11735203596128549}, + {0.7615129704938024, 0.2380813409383808, 0.11600236305643169}, + {0.7654120514656042, 0.24377917187260056, 0.11460794414495701}, + {0.7693104805544623, 0.24942813542336495, 0.11316704303859387}, + {0.7732082716359728, 0.25503160482399895, 0.11167779691868823}, + {0.7771054384050546, 0.260592655225706, 0.11013820284777173}, + {0.7810019943790253, 0.266114097815743, 0.1085461023755086}, + {0.784897952900607, 0.27159850915024936, 0.10689916389931109}, + {0.7887933271408747, 0.2770482564911545, 0.10519486236601067}, + {0.792688130102133, 0.28246551978783785, 0.10343045580787474}, + {0.7965823746207359, 0.28785231082677337, 0.1016029580881492}, + {0.8004760733698467, 0.2932104899790604, 0.09970910708026909}, + {0.8043692388621376, 0.2985417809010483, 0.09774532731012447}, + {0.8082618834524321, 0.30384778348310415, 0.09570768583739653}, + {0.8121540193402956, 0.30912998529284585, 0.09359183981917277}, + {0.8160456585725648, 0.31438977171944593, 0.09139297375735872}, + {0.8199368130458352, 0.31962843499310634, 0.08910572383870971}, + {0.8238274945088833, 0.32484718222701414, 0.0867240859712489}, + {0.8277177145650534, 0.33004714260695417, 0.08424130301309385}, + {0.8316074846745842, 0.33522937383533186, 0.08164972514342614}, + {0.8354968161568933, 0.3403948679210186, 0.07894063513317165}, + {0.8393857201928158, 0.3455445563935293, 0.07610402711123557}, + {0.8432742078267932, 0.350679315009233, 0.07312832277504416}, + {0.8471622899690239, 0.35579996800812036, 0.07000000201860399}, + {0.8510499773975676, 0.3609072919719153, 0.06670311423184544}, + {0.8549372807604048, 0.3660020193276998, 0.06321861961083997}, + {0.8588242105774635, 0.37108484153559657, 0.05952348231757188}, + {0.8627107772425975, 0.37615641199422883, 0.05558939105319657}, + {0.8665969910255304, 0.38121734869353224, 0.0513809015925008}, + {0.870482862073761, 0.3862682366409203, 0.046852647240651586}, + {0.8743684004144292, 0.39130963008373454, 0.04194497518373403}, + {0.8782536159561499, 0.39634205454821875, 0.03662194288964867}, + {0.8821385184908072, 0.40136600871296174, 0.03117410153953512}, + {0.8860231176953159, 0.40638196613271077, 0.025643215104659372}, + {0.8899074231333507, 0.4113903768267081, 0.020028781568071516}, + {0.891065382338744, 0.4184635684621956, 0.021466471088552607}, + {0.8919871230973406, 0.4256470552949243, 0.02354603033215587}, + {0.8928908994946323, 0.4327756220188152, 0.02570095483314324}, + {0.8937766259341077, 0.4398522418561916, 0.027932126084511257}, + {0.8946442158848376, 0.4468796753940895, 0.030240425579256377}, + {0.8954935818622007, 0.4538604904909103, 0.032626734810374966}, + {0.8963246354082741, 0.4607970798827202, 0.03509193527086419}, + {0.8971372870718866, 0.4676916768037213, 0.037636908453718976}, + {0.8979314463883195, 0.4745463688860316, 0.04026253585193785}, + {0.8987070218586405, 0.48136311056322806, 0.042883774659142816}, + {0.899463920928664, 0.4881437341684682, 0.045483032991513316}, + {0.9002020499675142, 0.49488995989000545, 0.048065003458762835}, + {0.9009213142457936, 0.5016034047235632, 0.05063130309097131}, + {0.9016216179133228, 0.5082855905414284, 0.053183371551623206}, + {0.9023028639764596, 0.5149379513816515, 0.055722495847998925}, + {0.902964954274961, 0.5215618400467861, 0.05824983088146562}, + {0.9036077894583927, 0.5281585340897971, 0.060766416652818796}, + {0.9042312689620561, 0.5347292412547051, 0.06327319275680962}, + {0.9048352909824239, 0.5412751044309391, 0.06577101066369245}, + {0.9054197524520664, 0.5477972061730271, 0.0682606441818552}, + {0.9059845490140521, 0.5542965728309169, 0.07074279841591524}, + {0.9065295749958051, 0.5607741783307898, 0.07321811747290291}, + {0.9070547233823978, 0.5672309476415033, 0.07568719112093336}, + {0.9075598857892664, 0.5736677599577373, 0.07815056056678477}, + {0.9080449524343264, 0.5800854516273583, 0.08060872348871567}, + {0.9085098121094662, 0.5864848188474415, 0.083062138436825}, + {0.9089543521514049, 0.5928666201506813, 0.08551122869395478}, + {0.9093784584118849, 0.5992315787015761, 0.08795638567456415}, + {0.909782015227184, 0.6055803844196885, 0.09039797192630794}, + {0.9101649053869216, 0.6119136959454732, 0.09283632378872866}, + {0.9105270101021349, 0.6182321424625531, 0.09527175375494526}, + {0.9108682089726016, 0.6245363253889187, 0.09770455257523358}, + {0.9111883799533859, 0.630826819948256, 0.10013499113555632}, + {0.9114873993205763, 0.6371041766315243, 0.10256332213928446}, + {0.9117651416361977, 0.6433689225578914, 0.10498978161628147}, + {0.9120214797122554, 0.649621562743278, 0.10741459028014497}, + {0.912256284573901, 0.6558625812839713, 0.1098379547515301}, + {0.91246942542167, 0.6620924424620748, 0.11226006866305718}, + {0.9126607695927773, 0.6683115917789337, 0.11468111365925662}, + {0.9128301825214254, 0.6745204569221216, 0.11710126030325854}, + {0.9129775276981008, 0.6807194486710708, 0.11952066890043198}, + {0.9131026666278179, 0.6869089617459752, 0.12193949024790668}, + {0.9132054587872768, 0.6930893756041974, 0.12435786631781182}, + {0.9132857615808976, 0.6992610551880414, 0.1267759308811086}, + {0.9133434302956924, 0.7054243516274225, 0.12919381007809072}, + {0.9133783180549305, 0.7115796029006738, 0.13161162294090045}, + {0.9133902757705612, 0.7177271344564569, 0.13402948187280572}, + {0.9133791520943453, 0.7238672597994953, 0.13644749308843845}, + {0.913344793367654, 0.7300002810426419, 0.13886575701873277}, + {0.9132870435698786, 0.7361264894275755, 0.1412843686838794}, + {0.9132057442654163, 0.7422461658162536, 0.1437034180372798}, + {0.913100734549166, 0.7483595811550647, 0.1461229902831289}, + {0.9129718509904932, 0.7544669969134981, 0.14854316617002308}, + {0.9128189275755945, 0.7605686654989812, 0.15096402226269828}, + {0.9126417956482176, 0.7666648306494336, 0.15338563119383095}, + {0.9124402838486693, 0.7727557278049575, 0.1558080618976074}, + {0.9122142180510416, 0.778841584459982, 0.15823137982661514}, + {0.9119634212986102, 0.7849226204970876, 0.16065564715346278}, + {0.9116877137373088, 0.7909990485036371, 0.16308092295837506}, + {0.9113869125472361, 0.797071074072276, 0.16550726340392827}, + {0.9110608318720959, 0.803138896086265, 0.16793472189794498}, + {0.9107092827465118, 0.8092027069905707, 0.1703633492455004}, + {0.9103320730211178, 0.8152626930495434, 0.17279319379088973}, + {0.909929007285357, 0.8213190345919861, 0.17522430155033844}, + {0.9094998867878827, 0.8273719062443313, 0.17765671633615956}, + {0.9090445093544782, 0.8334214771526294, 0.1800904798730111}, + {0.9085626693033965, 0.8394679111939684, 0.18252563190683574}, + {0.9080541573580172, 0.8455113671779366, 0.18496221030703314}, + {0.9075187605567102, 0.8515519990386777, 0.18740025116234627}, + {0.9069562621598014, 0.8575899560180628, 0.18983978887092715}, + {0.9063664415535179, 0.8636253828404642, 0.19228085622498767}, + {0.9057490741507888, 0.8696584198795938, 0.19472348449042068}, + {0.9051039312887829, 0.875689203317828, 0.197167703481744}, + {0.9044307801230321, 0.8817178652984231, 0.19961354163268363}, + {0.9037293835180177, 0.8877445340709991, 0.2020610260626995}, + {0.9029994999340526, 0.8937693341306414, 0.20451018263972115}, + {0.9022408833103207, 0.8997923863509576, 0.2069610360393544}, + {0.9059888943947992, 0.9040221289848984, 0.2345476432758713}, + {0.9121353668077321, 0.9072538390291374, 0.2723959319742808}, + {0.918103004002936, 0.910496798148879, 0.30707485069273716}, + {0.9238889872583352, 0.913751436869596, 0.3395892760133458}, + {0.9294904738341414, 0.9170181766931385, 0.3705416931634215}, + {0.9349045893736176, 0.9202974302069179, 0.4003237614900562}, + {0.9401284204049521, 0.9235896011902338, 0.4292051255044417}, + {0.9451590068972918, 0.9268950847179593, 0.45737955986332374}, + {0.9499933348250024, 0.9302142672617891, 0.4849910259595919}, + {0.9546283286947478, 0.9335475267892457, 0.5121493527958956}, + {0.9590608439900784, 0.936895232860618, 0.5389401619772186}, + {0.9632876594878218, 0.9402577467240134, 0.5654314125128757}, + {0.9673054693997428, 0.9436354214086733, 0.5916778659454154}, + {0.971110875291573, 0.9470286018167143, 0.6177242212867308}, + {0.9747003777296833, 0.9504376248134289, 0.6436073706776709}, + {0.9780703676032384, 0.9538628193162827, 0.6693580571761435}, + {0.9812171170667078, 0.9573045063827349, 0.6950021159198041}, + {0.9841367700439326, 0.9607629992969943, 0.7205614186521087}, + {0.9868253322306101, 0.9642386036558243, 0.7460546029896806}, + {0.9892786605268938, 0.9677316174534963, 0.7714976428174245}, + {0.9914924518257658, 0.9712423311659882, 0.7969042996355301}, + {0.9934622310757725, 0.9747710278345115, 0.8222864834722017}, + {0.9951833385285259, 0.9783179831484546, 0.8476545442427741}, + {0.9966509160718274, 0.9818834655278131, 0.873017509008704}, + {0.9978598925382617, 0.9854677362051741, 0.8983832767211907}, + {0.9988049678662737, 0.9890710493073268, 0.9237587792366369}, + {0.999480595975958, 0.9926936519365445, 0.9491501153416039}, + {0.9998809662045313, 0.9963357842516011, 0.9745626630050933}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> plasma_data_ = {{ + {0.05038205347059877, 0.029801736499741757, 0.5279751010495176}, + {0.06353382706361996, 0.028424851177690835, 0.5331235351456174}, + {0.07535267397875561, 0.027204618108821313, 0.5380072654878371}, + {0.08622056271327161, 0.02612369628606181, 0.5426577546250408}, + {0.09637909234021627, 0.02516351238474626, 0.5471034027913018}, + {0.10597907050045527, 0.02430756301203486, 0.5513679345503644}, + {0.11512442337588075, 0.0235544144422598, 0.5554685209574166}, + {0.12390246837508934, 0.022876443394988937, 0.5594230869193363}, + {0.13237958264924907, 0.022256467283011946, 0.5632496670754658}, + {0.14060280627862978, 0.02168533317299063, 0.5669592160880329}, + {0.14860595337659185, 0.021152345584078584, 0.5705618203562642}, + {0.1564211065006705, 0.020649224182780333, 0.5740653310686394}, + {0.16406928001421978, 0.020169228789859318, 0.5774779563374444}, + {0.17157438178522647, 0.019704113165841947, 0.5808064352016079}, + {0.1789495767422052, 0.019250113119147653, 0.584054078695406}, + {0.18621180115469324, 0.018801112566559006, 0.5872277307558299}, + {0.19337385391747602, 0.018351995878840264, 0.5903301881492813}, + {0.20044409185351197, 0.01789999393180025, 0.593363854926767}, + {0.20743511639383128, 0.01743987460850466, 0.5963332877187512}, + {0.21434936531465415, 0.016970872739093673, 0.5992389686439623}, + {0.22119736746683188, 0.016494748620846298, 0.6020833788659872}, + {0.22798262579984302, 0.01600474729153228, 0.6048670732620841}, + {0.23471390034056855, 0.015499747535836161, 0.6075917748304479}, + {0.24139587735519374, 0.014976616724022502, 0.6102591681981376}, + {0.24803115851643903, 0.01443661887416811, 0.6128678816678474}, + {0.25462712204192733, 0.013879480363965033, 0.6154192540143766}, + {0.26118240815987454, 0.013305484446440807, 0.6179109803957406}, + {0.2677033607536392, 0.012713338432089919, 0.6203463317006325}, + {0.27419065115382085, 0.012106344331753975, 0.6227220708698477}, + {0.2806485945135714, 0.011485191704992936, 0.625038400861471}, + {0.2870758894612177, 0.010852198594472949, 0.6272951521878755}, + {0.29347719408360684, 0.010210206090003579, 0.6294899111444117}, + {0.2998551242452729, 0.009558047948332786, 0.6316242235777169}, + {0.30620943129674466, 0.008899055475505046, 0.6336939963015096}, + {0.3125433553743016, 0.008235893717416108, 0.6357002857590853}, + {0.31885566464941756, 0.007572899889250414, 0.6376400727865161}, + {0.3251505835029789, 0.0069117371894770714, 0.6395123380850828}, + {0.3314258950888549, 0.006257740755607049, 0.6413161393477004}, + {0.3376822144299248, 0.005614742031369818, 0.643048949066938}, + {0.343925123616484, 0.00498757999986155, 0.6447101941536691}, + {0.35014944433050965, 0.004378575729205644, 0.6462980198153693}, + {0.3563593495264177, 0.0037944194657679817, 0.6478102381291251}, + {0.3625526716933222, 0.0032394075990651583, 0.6492450805997739}, + {0.3687335729955321, 0.002720261374452697, 0.6506012705463909}, + {0.3748968968242403, 0.002241239865606646, 0.6518761301685362}, + {0.38104622727684795, 0.001810210773066439, 0.6530679993306958}, + {0.3871831206545137, 0.0014300761021609504, 0.6541771655986202}, + {0.3933034524768182, 0.0011100331980040906, 0.6551990534286212}, + {0.39941134218209506, 0.0008549181444151815, 0.6561331884791302}, + {0.40550267547562835, 0.0006738585958816878, 0.656977095844568}, + {0.4115805613352908, 0.0005727689276359682, 0.6577301981873359}, + {0.4176418962835305, 0.000559689848675834, 0.6583901257368883}, + {0.4236882377452387, 0.0006415963809730485, 0.6589560636788017}, + {0.4297191157868382, 0.0008265327400941048, 0.6594251390708742}, + {0.43573345912178957, 0.0011224144971593696, 0.6597970982982151}, + {0.4417323328094361, 0.0015353882778950684, 0.6600691382766763}, + {0.4477136781734527, 0.002075242343276844, 0.6602401195491348}, + {0.45367754705516167, 0.0027502600296914884, 0.6603101230367315}, + {0.45962289480536683, 0.003569082980411755, 0.6602771266757947}, + {0.4655492492356133, 0.004539882193632057, 0.6601391424818946}, + {0.4714571093971736, 0.005672943386802442, 0.6598971161567793}, + {0.4773434667747343, 0.0069747060416045946, 0.6595491544709485}, + {0.48321032105464906, 0.00845482487303384, 0.6590950901585111}, + {0.4890546814926811, 0.010121547209062692, 0.6585341518234636}, + {0.49487752945710545, 0.011984730267283644, 0.6578650488841956}, + {0.5006778931801235, 0.01404940920364397, 0.6570881342241002}, + {0.5064532641572821, 0.016327053582825775, 0.6562022327592171}, + {0.512206101996081, 0.018827299101003524, 0.6552090987935029}, + {0.517932476985869, 0.021556895188755264, 0.6541092197088938}, + {0.5236333071472989, 0.02452621873336916, 0.6529010471797861}, + {0.5293056865203295, 0.02774076220334348, 0.651586191657666}, + {0.5349525083091329, 0.031211170127490386, 0.6501649809244013}, + {0.5405698921735111, 0.034943657938542025, 0.6486401484123572}, + {0.5461562839529602, 0.03894709993862434, 0.6470103291518646}, + {0.5517150940137298, 0.04312993669146801, 0.6452770884507062}, + {0.5572424908996385, 0.04732473166532047, 0.6434432899905641}, + {0.5627382914453162, 0.05153956982770822, 0.6415090129244055}, + {0.5682006939186361, 0.05577231508140689, 0.639477236154527}, + {0.5736324841026456, 0.06002312768941918, 0.6373489241079173}, + {0.5790288922820648, 0.06429083299444488, 0.635126168256215}, + {0.5843916716197954, 0.06857462612193421, 0.6328118231142932}, + {0.5897190859433459, 0.07287330061804262, 0.6304080857996939}, + {0.5950105087389658, 0.07718497188889406, 0.627917359511397}, + {0.600266274548656, 0.08151172798904885, 0.6253419897153364}, + {0.6054847038259513, 0.08584937397306835, 0.6226862814869409}, + {0.6106674577942587, 0.09020012029057023, 0.6199508828839105}, + {0.6158118936935632, 0.09455974518910823, 0.6171401916106442}, + {0.6209196353232503, 0.09893048328312148, 0.6142567668402714}, + {0.625987078238522, 0.10330809138750463, 0.6113050903371116}, + {0.6310165297116345, 0.10769470016602048, 0.6082874219554474}, + {0.6360082571946242, 0.11208841745759027, 0.6052049784133696}, + {0.6409587158624425, 0.11648801193763364, 0.6020653233567386}, + {0.6458724305886356, 0.120894724408147, 0.5988668588802512}, + {0.6507458962880415, 0.1253053066756304, 0.5956172158180971}, + {0.65558059804725, 0.12972201477991677, 0.59231673323355}, + {0.6603740711643852, 0.13414058702631182, 0.5889711004114799}, + {0.6651285526432004, 0.1385621615837031, 0.5855824728255514}, + {0.669845240296135, 0.1429888560980906, 0.582153977816893}, + {0.6745217289587141, 0.14741542201076516, 0.5786883585907729}, + {0.6791604036855876, 0.15184511348395324, 0.5751888508715063}, + {0.6837578997178535, 0.1562746720253843, 0.5716602384468066}, + {0.6883185616652895, 0.16070636061039098, 0.5681027207214548}, + {0.6928400648216108, 0.16513791277492407, 0.5645221138655818}, + {0.6973235757805955, 0.1695694677210192, 0.5609195098635373}, + {0.7017692243107729, 0.1740021467142358, 0.5572959855617685}, + {0.7061777422578236, 0.17843369623403554, 0.5536573853799269}, + {0.7105493783435904, 0.18286537302055275, 0.5500038553740142}, + {0.7148829033672169, 0.1872959178727836, 0.5463382579948199}, + {0.7191815273421805, 0.19172659246702414, 0.5426627244615733}, + {0.7234440590934259, 0.196155133293472, 0.5389811286444972}, + {0.7276695980921538, 0.20058267652430906, 0.5352935340967259}, + {0.7318622095195731, 0.20501034405621088, 0.5316009984849964}, + {0.7360187549600071, 0.20943588386264006, 0.527908404300108}, + {0.7401433549469377, 0.2138615497973006, 0.5242158683817802}, + {0.7442319068498962, 0.2182850864322064, 0.520524273866664}, + {0.7482894956274093, 0.22270875088361386, 0.516833738969623}, + {0.7523120538611476, 0.2271302847089524, 0.5131491434259574}, + {0.7563036182318114, 0.23155182037018107, 0.509468548147597}, + {0.760264196042346, 0.23597347976619776, 0.505794013908438}, + {0.7641927663268164, 0.24039301314981837, 0.5021264170700042}, + {0.7680903336977949, 0.24481467160443043, 0.49846488562080354}, + {0.7719579098239822, 0.24923420250548467, 0.494813286735782}, + {0.7757964670137317, 0.2536558602885356, 0.49117075886112754}, + {0.7796040489503765, 0.2580753889528994, 0.487539157444613}, + {0.7833826364367662, 0.262496918855311, 0.48391855557538205}, + {0.7871331836672137, 0.2669195732674377, 0.4803070299618413}, + {0.7908547764917832, 0.2713421013551332, 0.4767064258861618}, + {0.7945493142314948, 0.2757677557136531, 0.47311690432863956}, + {0.7982159123706819, 0.2801942814938595, 0.4695382974681735}, + {0.801855440805233, 0.28462393619999926, 0.46597078035645983}, + {0.8054670443253337, 0.28905445984517764, 0.46241517054928255}, + {0.8090525637702202, 0.2934891151740604, 0.4588696581516773}, + {0.8126121722311862, 0.29792563692815727, 0.4553380455774297}, + {0.8161437857429269, 0.3023651595826911, 0.45181643298028346}, + {0.8196512962080388, 0.30680981323456863, 0.44830592266123775}, + {0.8231319147062668, 0.31125833345906073, 0.4448063071891859}, + {0.8265884164961489, 0.31571198854333155, 0.4413158011478088}, + {0.8300180400348914, 0.3201695064581668, 0.43783618296069426}, + {0.8334225331012705, 0.3246331633551905, 0.43436568094830924}, + {0.8368011616192005, 0.3291026789528604, 0.4309050603621552}, + {0.8401547945201179, 0.33357719515430856, 0.42745544005358527}, + {0.8434842793132458, 0.33805985158665625, 0.42401293964429126}, + {0.8467879171814312, 0.3425483651134692, 0.42057931701643003}, + {0.8500663933256695, 0.3470460241716122, 0.41715281999997633}, + {0.853319036312829, 0.35155053489832117, 0.4137341950926385}, + {0.8565475037861691, 0.35606419689875035, 0.4103217013252645}, + {0.8597501517507731, 0.3605857048991911, 0.4069170743064185}, + {0.8629268039532411, 0.36511621303625214, 0.40351944853543975}, + {0.8660782631128492, 0.36965787597771715, 0.4001259551388744}, + {0.8692029205728464, 0.3742093808977564, 0.3967383275867196}, + {0.8723033707464051, 0.37877204764837713, 0.39335483663056486}, + {0.8753760334959819, 0.38334454940566526, 0.38997620732417515}, + {0.8784234745450857, 0.3879302203109463, 0.3865997186779487}, + {0.8814431427224427, 0.3925267186370576, 0.38322908763780417}, + {0.8844358150168464, 0.39713621668929217, 0.3798604589983262}, + {0.8874022475255273, 0.4017598897994324, 0.3764939692996154}, + {0.8903399254603347, 0.40639538423669647, 0.3731303392842935}, + {0.8932503482591801, 0.41104606226907536, 0.3697678512068009}, + {0.8961310320776956, 0.41570955292043654, 0.3664072199362221}, + {0.8989844448210237, 0.42039023641999307, 0.36304673325600695}, + {0.9018071346530614, 0.4250847229961323, 0.35968810073229274}, + {0.9046008288037846, 0.4297942088907302, 0.35632947125103215}, + {0.9073652324299479, 0.4345218955954952, 0.3529699824197478}, + {0.9100979328220618, 0.43926537724749737, 0.3496103521951318}, + {0.9128003257007559, 0.4440270702284773, 0.3462508642176817}, + {0.9154710325568927, 0.4488045475293247, 0.3428902329848131}, + {0.9181094141599885, 0.45360124699433185, 0.3395287458827024}, + {0.9207141279319739, 0.45841471975818476, 0.3361661136226204}, + {0.9232868464124966, 0.463248191094171, 0.3328014851212701}, + {0.9258252179695905, 0.46810089493647095, 0.3294349948733575}, + {0.928328943461609, 0.4729723618415593, 0.32606736582761625}, + {0.9307983028156818, 0.4778650729009944, 0.32269687622031573}, + {0.9332320356689454, 0.48277753475654456, 0.31932524626654357}, + {0.935630382313249, 0.4877102534916354, 0.3159517572279356}, + {0.9379901229720649, 0.4926647102078156, 0.3125751263224191}, + {0.94031286905006, 0.4976391653394365, 0.30919749958566495}, + {0.9425982043994484, 0.5026368889510107, 0.3058160067766645}, + {0.9448439581861301, 0.507655339193432, 0.30243337976158996}, + {0.9470512797767, 0.5126970710073548, 0.2990488875873464}, + {0.9492170420289342, 0.5177605158051324, 0.29566225939396684}, + {0.9513443493064214, 0.5228482560427825, 0.2922747680564989}, + {0.95342812024145, 0.5279576952925963, 0.2888831386174737}, + {0.9554704126542967, 0.5330914441820193, 0.28548964857337034}, + {0.9574691920662094, 0.5382478782970336, 0.2820960181641041}, + {0.9594239777856378, 0.5434283103460965, 0.27870139293719676}, + {0.9613362570153808, 0.5486340651043815, 0.27530489863581714}, + {0.9632030520719662, 0.5538624913974601, 0.2719092715909324}, + {0.9650243153126318, 0.5591162551393607, 0.26851277921609085}, + {0.9667981202444841, 0.5643936755766422, 0.2651181499385089}, + {0.9685263667936735, 0.5696984485228503, 0.26172065963235575}, + {0.9702051814086846, 0.5750258633596333, 0.258325028790098}, + {0.9718350028152128, 0.5803792760776375, 0.25493140399836905}, + {0.973416234677147, 0.5857590553651805, 0.2515399093896209}, + {0.9749470666071361, 0.5911624621207934, 0.24815128177724166}, + {0.9764282806289234, 0.5965932508399702, 0.24476679063210272}, + {0.9778561235005537, 0.6020486514176712, 0.24138715955646184}, + {0.9792333190737449, 0.6075304496592373, 0.23801267291982608}, + {0.980556172868528, 0.6130368443483086, 0.23464603815019064}, + {0.9818260338342485, 0.618569237111758, 0.2312874100772107}, + {0.983041213251059, 0.6241290418881347, 0.2279369200964918}, + {0.984199086129537, 0.6297154282611285, 0.22459528753260782}, + {0.9853012455753073, 0.6353282428938619, 0.22126480373791835}, + {0.9863451305526932, 0.6409666230896872, 0.2179481656192832}, + {0.987332269632511, 0.6466314474784756, 0.21464768988345995}, + {0.988260166889663, 0.6523228213835303, 0.2113640451754461}, + {0.9891280720682684, 0.6580401935630623, 0.20810040712251393}, + {0.989935193134965, 0.6637850245048573, 0.2048589308368297}, + {0.9906811112647872, 0.6695553903969398, 0.20164228467841383}, + {0.9913652104916543, 0.675353231166615, 0.19845282041957812}, + {0.9919851419644327, 0.681176590770927, 0.19529516473738912}, + {0.9925412186450403, 0.6870284413732891, 0.19216971523394297}, + {0.9930321637354537, 0.6929047946873668, 0.18908404856516375}, + {0.9934561180556553, 0.6988071461016482, 0.18604138565745748}, + {0.9938141746253392, 0.7047390032802133, 0.18304294167742508}, + {0.9941031429791255, 0.7106953484789053, 0.18009726563511483}, + {0.9943241754734297, 0.7166792156038955, 0.17720784326567807}, + {0.9944741584952311, 0.7226885545120336, 0.17438115112347216}, + {0.9945531662213939, 0.7287264314705092, 0.17162175513054803}, + {0.994561164165776, 0.7347887640856848, 0.16893804446424532}, + {0.9944951727911301, 0.7408770946176795, 0.16633533149747243}, + {0.9943551582286289, 0.7469929781194636, 0.16382095249343898}, + {0.9941411819033531, 0.7531343027240105, 0.16140421771177754}, + {0.993851140881807, 0.7593021960529095, 0.1590918763664673}, + {0.9934821808433413, 0.7654965143680154, 0.15689111532223957}, + {0.9930331122322037, 0.7717184174350065, 0.15480781781660563}, + {0.9925051688188334, 0.7779647295700995, 0.15285502755098562}, + {0.9918972375664695, 0.7842360395514291, 0.15104222448313137}, + {0.9912091443124736, 0.7905349489016323, 0.1493769620239061}, + {0.9904392291943233, 0.7968562534486284, 0.1478701260432203}, + {0.9895871071514554, 0.8032031721875696, 0.14652892189857109}, + {0.9886482096752364, 0.8095764705517057, 0.1453570476879498}, + {0.9876210577245915, 0.815976398662919, 0.14436290762709728}, + {0.986509178197983, 0.8223986911764639, 0.14355699253114637}, + {0.9853139963633676, 0.8288446279885695, 0.14294492163758302}, + {0.9840311334696324, 0.8353129155540111, 0.14252796680830504}, + {0.9826532853628255, 0.8418092005650518, 0.14230298881977124}, + {0.9811900755223993, 0.8483271434249618, 0.14227897296255487}, + {0.9796442447131871, 0.854863423552606, 0.1424529510156046}, + {0.9779950043835023, 0.8614303744688768, 0.14280800468858543}, + {0.9762651924699953, 0.8680136489692144, 0.14335094248589855}, + {0.9744429204121595, 0.8746206082101065, 0.14406105658536314}, + {0.972530126666216, 0.8812478776950604, 0.14492296106549138}, + {0.9705333468892211, 0.8878931459431306, 0.14591884881454822}, + {0.968443047163475, 0.8945621097233081, 0.14701399877638566}, + {0.9662712851816472, 0.901246373209881, 0.14817986820470014}, + {0.964020955903533, 0.9079483440427187, 0.1493700336843369}, + {0.9616812107840874, 0.9146696029935507, 0.1505199051295305}, + {0.959275857396244, 0.9214055790441742, 0.15156603392174148}, + {0.9568081246010715, 0.9281498350816461, 0.1524089373934798}, + {0.9542874028057909, 0.934905090703852, 0.15292087802256293}, + {0.9517260321586368, 0.9416690683960072, 0.15292489914850274}, + {0.9491513146628231, 0.9484323225943193, 0.1521779775289114}, + {0.9466019493393495, 0.9551882982848324, 0.15032766414862223}, + {0.9441522165792432, 0.9619135560223769, 0.14686103617160504}, + {0.9418959241387963, 0.9685885113553053, 0.14095488309848805}, + {0.9400151278782742, 0.9751557856205376, 0.131325887773911}, +}}; + +template +static constexpr std::array, 256> smooth_cool_warm_data_ = { + {{0.22999950386952345, 0.2989989340493756, 0.754000138575591}, + {0.23451750918602265, 0.30586471825124395, 0.760211287847582}, + {0.23905139222321087, 0.31271835359723077, 0.7663613706951183}, + {0.2436017365913441, 0.3195596165920886, 0.7724494083708939}, + {0.24816908043486074, 0.3263882334026712, 0.7784744332927407}, + {0.25275391815771386, 0.33320388462766504, 0.7844354891865984}, + {0.2573567020073366, 0.34000620954660093, 0.7903316312278389}, + {0.2619778435347082, 0.34679480991553485, 0.7961619261808826}, + {0.26661771494573344, 0.3535692533668808, 0.8019254525370478}, + {0.271276650357161, 0.3603290764626063, 0.8076213006505808}, + {0.27595494696856954, 0.3670737874430388, 0.813248572872804}, + {0.28065286616048707, 0.37380286870769464, 0.8188063836843368}, + {0.28537063452740463, 0.3805157790595848, 0.8242938598253321}, + {0.29010844485334814, 0.3872119557402635, 0.829710140423685}, + {0.29486645703670583, 0.3938908162793105, 0.8350543771211604}, + {0.2996447989701334, 0.4005517601788923, 0.8403257341974003}, + {0.30444356738064665, 0.4071941704514421, 0.8455233886917599}, + {0.3092628286343541, 0.41381741502624314, 0.8506465305229377}, + {0.31410261950970153, 0.42042084803879193, 0.8556943626063482}, + {0.3189629479426216, 0.4270038110151302, 0.8606661009692109}, + {0.32384379374653405, 0.43356563396190284, 0.8655609748633052}, + {0.32874510930975565, 0.4401056363716498, 0.8703782268753609}, + {0.33366682027256384, 0.4466231281517378, 0.8751171130350492}, + {0.33860882618583127, 0.45311741048440196, 0.8797769029205332}, + {0.3435710011529169, 0.45958777662452927, 0.8843568797615591}, + {0.3485531944562718, 0.46603351264108767, 0.8888563405400349}, + {0.3535552311699886, 0.47245389810747423, 0.8932745960880898}, + {0.3585769127594044, 0.47884820674548473, 0.8976109711835649}, + {0.3636180176686533, 0.4852157070271205, 0.9018648046429221}, + {0.3686783018969878, 0.49155566273800605, 0.9060354494115308}, + {0.37375749956453747, 0.49786733350580864, 0.9101222726513168}, + {0.37885532346808715, 0.5041499752967064, 0.9141246558257436}, + {0.38397146562736917, 0.5104028408826495, 0.918041994782103}, + {0.38910559782229387, 0.5166251802818846, 0.9218736998310882}, + {0.39425737212145806, 0.5228162411749818, 0.9256191958236355}, + {0.39942642140225487, 0.5289752692983762, 0.9292779222250065}, + {0.4046123598628117, 0.5351015088172548, 0.9328493331860931}, + {0.4098147835259849, 0.541194202679442, 0.9363328976119261}, + {0.41503327073558766, 0.5472525929517891, 0.9397280992273693}, + {0.4202673826449946, 0.5532759211404236, 0.943034436639982}, + {0.42551666369825586, 0.5592634284961118, 0.9462514234000324}, + {0.43078064210382544, 0.5652143563058468, 0.9493785880576479}, + {0.43605883030099185, 0.5711279461717078, 0.9524154742170866}, + {0.44135072541910086, 0.5770034402779125, 0.9553616405881157}, + {0.4466558097296202, 0.5828400816469308, 0.9582166610344868}, + {0.4519735510911263, 0.5886371143854353, 0.960980124619491}, + {0.457303403387259, 0.5943937839208078, 0.9636516356485881}, + {0.46264480695769356, 0.6001093372288535, 0.9662308137090968}, + {0.4679971890221843, 0.6057830230533238, 0.968717293706932}, + {0.4733599640977317, 0.6114140921177984, 0.9711107259003909}, + {0.4787325344089037, 0.6170017973304325, 0.9734107759309701}, + {0.48411429029138214, 0.6225453939820256, 0.9756171248512094}, + {0.48950461058876166, 0.6280441399378467, 0.9777294691495587}, + {0.49490286304267245, 0.6334972958235978, 0.9797475207722576}, + {0.5003084046762621, 0.6389041252058836, 0.9816710071422271}, + {0.5057205821711058, 0.644263894767512, 0.983499671174965}, + {0.511138732237593, 0.6495758744779339, 0.9852332712914448}, + {0.5165621819788595, 0.654839337759102, 0.9868715814280132}, + {0.5219902492483212, 0.6600535616470082, 0.9884143910432847}, + {0.5274222430008886, 0.6652178269491371, 0.9898615051220324}, + {0.5328574636379119, 0.670331418398056, 0.9912127441760742}, + {0.5382952033459485, 0.6753936248013475, 0.9924679442421503}, + {0.5437347464294153, 0.6804037391880692, 0.9936269568768029}, + {0.5491753696372063, 0.685361058951912, 0.9946896491482432}, + {0.5546163424833603, 0.690264885991224, 0.9956559036252249}, + {0.5600569275618472, 0.695114526846042, 0.9965256183629146}, + {0.5654963808555731, 0.6999092928322662, 0.9972987068857656}, + {0.5709339520396719, 0.7046485001731109, 0.9979750981673984}, + {0.5763688847791901, 0.7093314701279408, 0.9985547366074979}, + {0.5818004170212294, 0.7139575291186055, 0.9990375820057199}, + {0.5872277812816606, 0.7185260088533676, 0.9994236095326229}, + {0.5926502049264796, 0.7230362464485207, 0.9997128096976274}, + {0.5980669104479099, 0.7274875845477786, 0.9999051883140077}, + {0.603477115735333, 0.7318793714395154, 1.0}, + {0.6088800343411463, 0.7362109611719294, 0.9999995804425049}, + {0.6142748757416401, 0.7404817136661965, 0.9999016817439826}, + {0.6196608455929782, 0.7446909948276748, 0.9997071369848932}, + {0.6250371459823868, 0.7488381766552155, 0.9994160278693497}, + {0.6304029756746347, 0.7529226373486367, 0.9990284511333963}, + {0.6357575303538953, 0.7569437614144018, 0.9985445184894549}, + {0.6411000028610946, 0.7609009397695506, 0.9979643565678705}, + {0.6464295834268168, 0.7647935698439208, 0.9972881068555687}, + {0.6517454598998733, 0.7686210556806996, 0.9965159256318358}, + {0.6570468179716188, 0.7723828080353353, 0.9956479839012286}, + {0.6623328413960967, 0.7760782444728409, 0.9946844673236305}, + {0.6676027122061123, 0.7797067894635203, 0.9936255761414589}, + {0.6728556109253114, 0.7832678744771355, 0.9924715251040422}, + {0.6780907167763519, 0.7867609380755451, 0.9912225433891731}, + {0.683307207885253, 0.7901854260038265, 0.9898788745218482}, + {0.6885042614820046, 0.7935407912799094, 0.988440776290216}, + {0.6936810540975126, 0.7968264942827246, 0.9869085206587308}, + {0.6988367617569751, 0.8000420028388932, 0.9852823936785383}, + {0.7039705601697447, 0.8031867923079613, 0.983562695395095}, + {0.7090816249157784, 0.8062603456661956, 0.9817497397530396}, + {0.714169131628733, 0.8092621535889422, 0.9798438544983238}, + {0.7192322561757896, 0.8121917145315617, 0.9778453810776183}, + {0.7242701748342745, 0.8150485348089448, 0.9757546745350029}, + {0.7292820644651583, 0.8178321286736122, 0.9735721034059553}, + {0.7342671026834836, 0.8205420183923986, 0.971298049608644}, + {0.7392244680258144, 0.8231777343217284, 0.9689329083325428}, + {0.7441533401147525, 0.8257388149814784, 0.9664770879243741}, + {0.7490528998206014, 0.8282248071274302, 0.9639310097713906}, + {0.7539223294202332, 0.8306352658223072, 0.9612951081820061}, + {0.7587608127532254, 0.8329697545053927, 0.9585698302637836}, + {0.7635675353753275, 0.8352278450607313, 0.9557556357987903}, + {0.7683416847093205, 0.8374091178838983, 0.9528529971163268}, + {0.7730824501933197, 0.8395131619473374, 0.9498623989630331}, + {0.7777890234265885, 0.8415395748642601, 0.9467843383703861}, + {0.7824605983129111, 0.8434879629510917, 0.9436193245195849}, + {0.7870963712015859, 0.8453579412884608, 0.9403678786038298}, + {0.7916955410260809, 0.8471491337807205, 0.9370305336880028}, + {0.7962573094404225, 0.8488611732139871, 0.933607834565744}, + {0.8007808809533457, 0.8504937013126886, 0.9301003376139276}, + {0.8052654630602748, 0.8520463687946024, 0.9265086106445327}, + {0.8097102663731715, 0.8535188354243787, 0.9228332327539112}, + {0.8141145047483038, 0.854910770065524, 0.9190747941694408}, + {0.8184773954119764, 0.8562218507308311, 0.9152338960935597}, + {0.822798159084272, 0.857451764631246, 0.9113111505451725}, + {0.827076020100851, 0.8586002082231403, 0.9073071801984174}, + {0.8313102065328385, 0.8596668872539794, 0.9032226182187731}, + {0.8354999503048602, 0.8606515168063638, 0.8990581080965018}, + {0.8396444873112505, 0.8615538213404197, 0.8948143034773921}, + {0.8437430575304858, 0.8623735347345196, 0.8904918679907933}, + {0.8477949051378751, 0.8631104003243038, 0.8860914750749006}, + {0.8517992786165454, 0.8637641709399845, 0.8816138077992733}, + {0.8557554308667662, 0.8643346089419015, 0.8770595586845422}, + {0.8596626193136427, 0.8648214862543027, 0.8724294295192715}, + {0.8635201060132168, 0.8652245843973202, 0.8677241311739308}, + {0.8676431881102519, 0.8645140349150363, 0.8626161485985507}, + {0.8719973001889246, 0.8626912788780988, 0.8571344116931553}, + {0.8762551679574422, 0.8607866996599632, 0.8516174449794455}, + {0.8804169678453379, 0.8588005566711197, 0.8460661683343939}, + {0.8844828646854237, 0.8567331182372422, 0.8404815005112565}, + {0.8884530127026752, 0.8545846614985785, 0.834864358985154}, + {0.892327556446231, 0.8523554723065947, 0.829215659800157}, + {0.8961066316684723, 0.8500458451177988, 0.8235363174178995}, + {0.8997903661548088, 0.8476560828846528, 0.8178272445677435}, + {0.9033788805075311, 0.8451864969434798, 0.812089352098517}, + {0.9068722888867912, 0.8426374068992736, 0.8063235488318476}, + {0.910270699711566, 0.8400091405073019, 0.8005307414171138}, + {0.9135742163232042, 0.8373020335514, 0.7947118341880348}, + {0.9167829376139871, 0.8345164297188294, 0.7888677290209213}, + {0.9198969586229171, 0.8316526804715908, 0.7829993251946056}, + {0.9229163711008167, 0.8287111449140491, 0.7771075192520753}, + {0.9258412640466325, 0.8256921896567365, 0.7711932048638259}, + {0.9286717242167226, 0.822596188676188, 0.7652572726929551}, + {0.9314078366087624, 0.8194235231706464, 0.7593006102620192}, + {0.9340496849217929, 0.8161745814114749, 0.7533241018216675}, + {0.9365973519938281, 0.8128497585900935, 0.7473286282210768}, + {0.9390509202183217, 0.8094494566602553, 0.7413150667802011}, + {0.9414104719407324, 0.8059740841754534, 0.7352842911638605}, + {0.9436760898363059, 0.8024240561212462, 0.7292371712576793}, + {0.9458478572701444, 0.7987997937422701, 0.7231745730458999}, + {0.9479258586405416, 0.7951017243636899, 0.717097358491085}, + {0.9499101797065052, 0.7913302812068249, 0.7110063854157246}, + {0.951800907900325, 0.7874859031986702, 0.7049025073857709}, + {0.953598132625986, 0.7835690347750057, 0.6987865735961123}, + {0.9553019455441706, 0.7795801256767763, 0.6926594287580068}, + {0.9569124408445594, 0.7755196307393911, 0.6865219129884912}, + {0.9584297155060683, 0.7713880096745724, 0.6803748617017831}, + {0.9598538695456499, 0.7671857268443542, 0.6742191055026909}, + {0.9611850062562218, 0.7629132510268043, 0.6680554700820523}, + {0.9624232324342575, 0.758571055173009, 0.6618847761142137}, + {0.9635686585975486, 0.7541596161548229, 0.6557078391565709}, + {0.9646213991936067, 0.7496794145028565, 0.6495254695511868}, + {0.9655815727991436, 0.7451309341341271, 0.6433384723285004}, + {0.9664493023110522, 0.7405146620687538, 0.6371476471131512}, + {0.9672247151292687, 0.7358310881350345, 0.6309537880319284}, + {0.9679079433318883, 0.7310807046621858, 0.6247576836238656}, + {0.9684991238428787, 0.7262640061599712, 0.6185601167525033}, + {0.9689983985927076, 0.7213814889843815, 0.612361864520328}, + {0.9694059146721955, 0.7164336509884588, 0.6061636981854146}, + {0.9697218244798756, 0.7114209911572899, 0.5999663830802852}, + {0.9699462858631324, 0.7063440092261024, 0.5937706785330095}, + {0.9700794622533694, 0.7012032052803152, 0.5875773377905578}, + {0.9701215227954475, 0.6959990793362977, 0.5813871079444363}, + {0.9700726424716136, 0.6907321309014792, 0.5752007298586196}, + {0.9699330022201408, 0.6854028585123331, 0.5690189380998024}, + {0.9697027890488664, 0.6800117592486405, 0.5628424608699958}, + {0.9693821961438281, 0.6745593282222776, 0.556672019941486}, + {0.9689714229731695, 0.6690460580386323, 0.5505083305941867}, + {0.968470675386481, 0.663472438228566, 0.5443521015554007}, + {0.9678801657097379, 0.65783895464866, 0.5382040349420275}, + {0.9672001128359847, 0.6521460888472544, 0.5320648262052324}, + {0.9664307423119013, 0.6463943173935754, 0.5259351640776159}, + {0.9655722864203883, 0.6405841111669635, 0.5198157305229032}, + {0.964624984259297, 0.6347159346029446, 0.5137072006881956}, + {0.9635890818164178, 0.6287902448925465, 0.507610242858806}, + {0.9624648320408441, 0.6228074911309212, 0.5015255184157178}, + {0.9612524949108144, 0.6167681134109175, 0.4954536817957061}, + {0.9599523374981328, 0.6106725418568123, 0.4893953804541488}, + {0.9585646340292623, 0.6045211955929051, 0.4833512548305818}, + {0.9570896659431806, 0.5983144816411149, 0.4773219383170267}, + {0.9555277219460815, 0.5920527937410947, 0.47130805722914443}, + {0.9538790980630029, 0.5857365110856726, 0.4653102307802585}, + {0.9521440976864516, 0.5793659969636203, 0.4593290710582975}, + {0.9503230316221086, 0.57294159730086, 0.4533651830057083}, + {0.948416218131665, 0.5664636390902013, 0.4474191644024001}, + {0.9464239829728659, 0.5599324286985411, 0.44149160585177294}, + {0.9443466594368136, 0.5533482500391552, 0.4355830907698924}, + {0.9421845883825966, 0.546711362595224, 0.42969419537788606}, + {0.9399381182692833, 0.5400219992790316, 0.4238254886976179}, + {0.9376076051853501, 0.533280364109342, 0.4179775325507263}, + {0.9351934128755736, 0.5264866296872404, 0.4121508815610997}, + {0.9326959127654463, 0.5196409344481697, 0.40634608316087356}, + {0.9301154839831494, 0.5127433796649743, 0.40056367760003836}, + {0.9274525133791317, 0.5057940261733677, 0.39480419795975347}, + {0.9247073955433249, 0.49879289078734274, 0.38906817016946776}, + {0.9218805328200373, 0.4917399423674949, 0.38335611302795025}, + {0.9189723353205592, 0.4846350974999652, 0.37766853822834884}, + {0.9159832209335118, 0.47747821573754495, 0.37200595038739454}, + {0.9129136153329698, 0.47026909434728564, 0.3663688470788784}, + {0.90976395198439, 0.46300746250050845, 0.36075771887154084}, + {0.9065346721483711, 0.4556929748311352, 0.35517304937151345}, + {0.9032262248822704, 0.44832520427650463, 0.34961531526947287}, + {0.8998390670397057, 0.44090363410085304, 0.34408498639266283}, + {0.896373663267962, 0.43342764898501834, 0.3385825257619646}, + {0.8928304860033279, 0.42589652504602493, 0.33310838965420186}, + {0.8892100154643842, 0.41830941862630455, 0.32766302766986616}, + {0.8855127396432578, 0.4106653536635276, 0.32224688280648867}, + {0.8817391542948727, 0.4029632074170497, 0.31686039153786477}, + {0.8778897629242048, 0.3952016942845104, 0.3115039838993836}, + {0.8739650767715597, 0.3873793473900178, 0.30617808357969667}, + {0.8699656147959004, 0.37949449756134346, 0.30088310801901375}, + {0.8658919036562271, 0.37154524923423027, 0.2956194685142945}, + {0.8617444776910301, 0.3635294527231879, 0.29038757033164536}, + {0.8575238788958367, 0.35544467217440223, 0.2851878128262474}, + {0.8532306568988527, 0.3472881483602095, 0.2800205895701496}, + {0.8488653689347272, 0.33905675527607415, 0.27488628848829755}, + {0.844428579816439, 0.33074694924673165, 0.2697852920031808}, + {0.8399208619053304, 0.3223547089197083, 0.26471797718851403}, + {0.835342795079293, 0.3138754640964424, 0.2596847159323806}, + {0.8306949666991194, 0.30530401078823033, 0.25468587511031116}, + {0.825977971573034, 0.2966344091359757, 0.24972181676877747}, + {0.8211924119194148, 0.28785985982733997, 0.2447928983196327}, + {0.8163388973277163, 0.2789725532777859, 0.23989947274604145}, + {0.8114180447176049, 0.2699634839588782, 0.2350418888204895}, + {0.8064304782963232, 0.2608222196264688, 0.230220491335487}, + {0.8013768295142913, 0.25153661146923556, 0.2254356213476219}, + {0.7962577370189533, 0.24209242581295431, 0.22068761643565016}, + {0.7910738466068946, 0.2324728700992567, 0.21597681097335308}, + {0.785825811174225, 0.22265797397565007, 0.2113035364179236}, + {0.7805142906652605, 0.21262376808227257, 0.20666812161469034}, + {0.7751399520194979, 0.20234117434687338, 0.2020708931190197}, + {0.7697034691169152, 0.19177447487857652, 0.19751217553628297}, + {0.7642055227215985, 0.18087914808905534, 0.19299229188080813}, + {0.7586468004237221, 0.16959872367321424, 0.18851156395477772}, + {0.7530279965798936, 0.15786005774647732, 0.18407031274806854}, + {0.7473498122518853, 0.1455659466237694, 0.17966885886006054}, + {0.7416129551437725, 0.13258300379739485, 0.1753075229444704}, + {0.7358181395374971, 0.11872050682883606, 0.17098662617829208}, + {0.729966086226886, 0.1036904371731237, 0.16670649075593325}, + {0.7240575224501452, 0.08702339888581809, 0.1624674404096517}, + {0.7180931818208612, 0.06786174152286231, 0.15826980095738155}, + {0.712073804257538, 0.04430319728532283, 0.15411390087901955}, + {0.7060001359117047, 0.015991824033980695, 0.15000007192220008}}}; + +template +static constexpr std::array, 256> viridis_data_ = { + {{0.2670039853213788, 0.0048725657145795975, 0.32941506855247793}, + {0.26850981914385313, 0.009602990407952114, 0.33542640725404194}, + {0.2699440291511295, 0.014623657659867702, 0.34137927634304566}, + {0.271304877824855, 0.01994002237673082, 0.3472686291318146}, + {0.27259406260318486, 0.0255617891189931, 0.3530934750332732}, + {0.27380892621369024, 0.03149509118386225, 0.3588528426972369}, + {0.27495208578509805, 0.03775096330071057, 0.36454366367333946}, + {0.27602196419599767, 0.04416532238909473, 0.3701640471152313}, + {0.2770178542655486, 0.050341751402647274, 0.37571443702683854}, + {0.2779409905222335, 0.05632269668695442, 0.381191238867294}, + {0.2787908952957126, 0.06214312525024266, 0.386591645366443}, + {0.27956600607518295, 0.06783500475980075, 0.39191741935399227}, + {0.2802669260610985, 0.07341543578584622, 0.3971628433351474}, + {0.2808940110629919, 0.07890627296909186, 0.402329588370124}, + {0.2814459462121492, 0.08431870698834085, 0.4074140304183279}, + {0.2819238934697361, 0.08966415929405766, 0.4124144814203868}, + {0.2823269547340802, 0.09495395414045926, 0.4173312035070467}, + {0.28265591676374746, 0.10019440706631136, 0.42215967285462885}, + {0.2829099523467409, 0.10539218382981966, 0.42690236327520725}, + {0.2830909293924702, 0.11055163703080462, 0.43155385240026206}, + {0.2831969393871863, 0.11567940038180258, 0.4361155100499537}, + {0.2832289314889045, 0.1207758539544326, 0.4405840195472734}, + {0.2831869362255922, 0.1258463172454443, 0.4449595399107695}, + {0.28307192228564804, 0.13089406218358995, 0.4492411716459423}, + {0.28288394120635924, 0.1359185257084681, 0.45342671165618736}, + {0.2826229022373855, 0.1409252633679265, 0.4575173087262126}, + {0.28228993571972105, 0.14591072658175047, 0.46150987016675354}, + {0.28188687220607433, 0.1508804582163323, 0.46540543189260436}, + {0.2814119198278991, 0.15583292129399035, 0.4692010151483717}, + {0.28086783263625503, 0.16077064757597467, 0.4728995412212838}, + {0.28025489346354565, 0.16569211148611415, 0.47649814467710355}, + {0.2795739667261627, 0.17059758179728512, 0.47999676019204823}, + {0.2788258570423396, 0.1754892977307652, 0.48339725816565043}, + {0.27801194338413965, 0.1803657682817326, 0.4866968956818299}, + {0.27713381181214125, 0.18522747944269774, 0.4898983578428951}, + {0.27619391034977797, 0.19007295088871226, 0.49300101709660177}, + {0.2751907580349635, 0.19490465707076896, 0.49600544367769356}, + {0.2741278682015853, 0.19972012989770083, 0.4989111236465034}, + {0.2730059901819072, 0.20451860824383267, 0.501720814888259}, + {0.2718278175684958, 0.2093023055918103, 0.5044342141093779}, + {0.270594950010942, 0.21406778548878086, 0.5070519265124999}, + {0.269307759397765, 0.21881747729569145, 0.5095772914792083}, + {0.26796790172934454, 0.22354795925559695, 0.5120080244602125}, + {0.26657969502130613, 0.22826164495517987, 0.5143493563955112}, + {0.2651448458327315, 0.23295512949133207, 0.5165991088272563}, + {0.2636630077044143, 0.23762961892442647, 0.518761871180001}, + {0.2621377837546321, 0.2422852962306279, 0.5208371781925083}, + {0.2605709530063988, 0.2469207884353261, 0.5228279594551629}, + {0.2589647163025411, 0.25153645885437026, 0.5247362360674637}, + {0.25732189181335147, 0.2561289544795441, 0.526563035336139}, + {0.2556446444203948, 0.2607026175814763, 0.5283122832934375}, + {0.25393482507335086, 0.26525311670734747, 0.529983099667603}, + {0.2521940157752079, 0.2697816202890161, 0.5315789243388298}, + {0.25042475493562577, 0.27428927505771267, 0.5331031508732055}, + {0.24862894949587117, 0.27877378236392025, 0.5345559912288645}, + {0.2468106816724398, 0.2832364292997213, 0.535941192655048}, + {0.24497187865778625, 0.28767394082010833, 0.5372600476888723}, + {0.24311260591427697, 0.2920915797036902, 0.5385162258554254}, + {0.24123680455606578, 0.29648409536913767, 0.5397090946733651}, + {0.23934601183850307, 0.30085361498147906, 0.5408439702969619}, + {0.23744072960970264, 0.3052012458833173, 0.54192113151443}, + {0.23552593740524197, 0.30952576959302097, 0.5429440191062838}, + {0.23360265375847195, 0.3138273924379346, 0.5439141607822711}, + {0.2316738606254108, 0.31810492063632195, 0.5448340596245334}, + {0.22973857739190007, 0.3223605353157074, 0.545706183707169}, + {0.22780178259701628, 0.3265930678980134, 0.5465320928009385}, + {0.2258629950192772, 0.3308036038834664, 0.547314007363377}, + {0.22392470580707102, 0.33499321123505194, 0.5480531185864527}, + {0.22198891605799553, 0.33915975136273824, 0.5487520417750932}, + {0.22005663012512805, 0.34330635098841344, 0.5494131386548431}, + {0.2181298368119725, 0.34743089526543186, 0.550038069892983}, + {0.21620955549289145, 0.3515344874402382, 0.5506271540883877}, + {0.21429775792403594, 0.3556180358438001, 0.5511840927098516}, + {0.21239496605173308, 0.3596815871313281, 0.5517100354247325}, + {0.21050268170035974, 0.36372617292766, 0.5522061103879761}, + {0.20862288591525807, 0.36775072789850616, 0.5526750588505742}, + {0.20675560837319001, 0.3717573067826811, 0.5531171238472018}, + {0.20490280700807212, 0.3757448655138847, 0.5535330780419422}, + {0.203062536964648, 0.3797154379631177, 0.5539251341179698}, + {0.20123872979412472, 0.3836690001875795, 0.554294093380729}, + {0.1994294675547129, 0.3876065665572156, 0.5546421417067892}, + {0.19763565582691228, 0.39152713200801975, 0.5549691052245624}, + {0.1958598486981541, 0.39543169955970453, 0.5552760714931869}, + {0.19409958576782552, 0.3993222611485653, 0.5555651140662646}, + {0.19235677239756216, 0.40319783169922974, 0.5558360841919235}, + {0.19063051802725675, 0.4070603881536437, 0.5560891205440711}, + {0.18892269821185473, 0.41090896152858886, 0.5563260943031525}, + {0.18723045233808386, 0.4147455132535933, 0.5565471249886993}, + {0.185555627191317, 0.4185690891632772, 0.5567531019269415}, + {0.18389780714307888, 0.42238166634427127, 0.5569440809497231}, + {0.18225556044836397, 0.4261832146898191, 0.5571201071543374}, + {0.1806287343914301, 0.4299737941881375, 0.5572820892587651}, + {0.17901849569766765, 0.43375533862493676, 0.5574301104997077}, + {0.1774226636398102, 0.4375259202510252, 0.55756509546256}, + {0.17584043270381128, 0.4412894613100537, 0.5576851118285253}, + {0.17427359528182015, 0.4450430447202011, 0.557792099701029}, + {0.17271876393003963, 0.4487896287788335, 0.557885089501858}, + {0.1711755310919842, 0.45252916766885326, 0.5579651016381476}, + {0.1696456943850158, 0.4562607533360476, 0.5580300944043132}, + {0.1681254681463012, 0.4599872896301423, 0.5580821016030234}, + {0.1666166265008438, 0.46370687659642523, 0.5581190973303202}, + {0.16511640601237285, 0.46742241082026353, 0.5581410993753088}, + {0.1636245598287687, 0.47113199888460483, 0.5581480982786068}, + {0.1621417205544945, 0.4748365872638394, 0.5581400991890099}, + {0.16066449675721917, 0.4785391201733818, 0.5581150965608792}, + {0.15919365349458042, 0.48223570943504873, 0.5580731010879704}, + {0.15772843426155927, 0.48593124098759627, 0.5580130923782937}, + {0.1562695869579672, 0.4896228308128307, 0.5579361006261909}, + {0.1548143719173188, 0.49331236133238937, 0.5578400853105705}, + {0.1533635209362011, 0.4969989517366848, 0.5577240977120556}, + {0.1519176771981809, 0.5006835421001327, 0.5575871128989297}, + {0.15047545758720676, 0.504368072136516, 0.557430091404037}, + {0.14903861048813108, 0.5080496628380102, 0.5572501110986087}, + {0.1476063950561745, 0.5117321922659829, 0.5570490817856095}, + {0.14617954401090907, 0.5154117832267491, 0.5568231063967104}, + {0.14475833306803976, 0.519092312358787, 0.5565720684276931}, + {0.14334247788386512, 0.522771903366683, 0.5562950984952888}, + {0.141934629618203, 0.5264514940838813, 0.5559911321954153}, + {0.14053541463564725, 0.5301310233517843, 0.5556590862704173}, + {0.13914656229528236, 0.5338106140906136, 0.555298125858835}, + {0.13776935391441048, 0.5374911432800976, 0.5549060695018647}, + {0.13640749570156585, 0.5411717339632349, 0.5544831157469011}, + {0.13506529616957136, 0.544852263189304, 0.554029048083696}, + {0.13374243075510836, 0.5485338538220298, 0.5535411013024801}, + {0.13244357030675505, 0.5522144442800521, 0.553018159322021}, + {0.13117137121614486, 0.5558979736087772, 0.5524590815222541}, + {0.12993250302214393, 0.5595805638443141, 0.5518641468320762}, + {0.12872831884644725, 0.5632640933331003, 0.5512290558865701}, + {0.12756743939839627, 0.5669476835219266, 0.5505561295873137}, + {0.12645227472350737, 0.5706322130377723, 0.5498410244005342}, + {0.12539338154311577, 0.5743168031831126, 0.5490861069146677}, + {0.12439424184336756, 0.5780013325949876, 0.5482869865182912}, + {0.12346233479357416, 0.5816859227477941, 0.5474450777703374}, + {0.122605426766972, 0.5853695126930177, 0.5465571752923358}, + {0.12183030409088419, 0.5890540421334565, 0.5456230413386914}, + {0.1211473750007544, 0.592737632144662, 0.5446411489781364}, + {0.12056429075653713, 0.5964211612480832, 0.5436109978665574}, + {0.12009133699819924, 0.6001027515502533, 0.5425301161500574}, + {0.11973729926029653, 0.6037842799987541, 0.541399947187814}, + {0.11951131929191963, 0.6074628706490315, 0.5402180758379009}, + {0.11942233180714437, 0.6111394611583431, 0.5389822116295199}, + {0.11948233048502255, 0.6148159892453784, 0.537692026866569}, + {0.11969830860262576, 0.6184885802617517, 0.5363471743826108}, + {0.12008036996652452, 0.6221601072840744, 0.5349459699054088}, + {0.12063730989641286, 0.6258266990315783, 0.5334881295553462}, + {0.1213794417235072, 0.6294912247800063, 0.5319729045347256}, + {0.12231134108889466, 0.6331518172152074, 0.5303980764654408}, + {0.1234432274542607, 0.6368074097895444, 0.5287632561537092}, + {0.12477941321977204, 0.6404599344231255, 0.5270680133779303}, + {0.12632525332983902, 0.6441055281645606, 0.5253112061650272}, + {0.1280865204366354, 0.6477480507159987, 0.5234909414076758}, + {0.1300663115014182, 0.6513826457355586, 0.5216081476931036}, + {0.13226766345372454, 0.6550131658699597, 0.5196608602452112}, + {0.1346914034616326, 0.6586347623899736, 0.5176490803131216}, + {0.13733813187439356, 0.6622503590720668, 0.5155713087695435}, + {0.1402095413205375, 0.6658578775169739, 0.5134270017152724}, + {0.14330221816701194, 0.6694574760216492, 0.511215244517751}, + {0.14661571262857995, 0.6730489911445044, 0.5089359136232384}, + {0.15014733747892414, 0.6766295918037593, 0.5065891708280766}, + {0.1538939151679172, 0.6802021032660456, 0.5041718156197705}, + {0.15785048833835377, 0.6837637060778221, 0.5016860876044946}, + {0.162015053737826, 0.6873143096440719, 0.49912936913057365}, + {0.1663826794355118, 0.6908548182506177, 0.49650199274870527}, + {0.17094719748923695, 0.6943824243247052, 0.4938032891165472}, + {0.1757068993715085, 0.6978989283401605, 0.4910328874274477}, + {0.18065236935056878, 0.7014005373289202, 0.4881891991816308}, + {0.18578314370608157, 0.704890036301888, 0.48527277191686385}, + {0.19108956697744361, 0.7083646483099804, 0.48228409897291785}, + {0.19656998786638302, 0.7118252614850998, 0.4792214366155811}, + {0.20221879696964223, 0.7152707565867668, 0.47608398702197946}, + {0.2080291781284243, 0.7186993731402823, 0.47287333975819085}, + {0.21400005157818647, 0.7221128620832928, 0.4695878639271211}, + {0.22012339076765558, 0.7255074824139881, 0.46622623255251056}, + {0.22639732501345455, 0.7288869647642494, 0.46278873032462237}, + {0.2328146240063111, 0.7322455890831692, 0.45927711461163473}, + {0.2393729244291451, 0.7355862151598742, 0.4556885106741981}, + {0.2460698827335157, 0.7389086924367883, 0.452023984943217}, + {0.25289815079190964, 0.742209322598094, 0.44828439600718756}, + {0.2598571632843528, 0.745490792270686, 0.4444668436999196}, + {0.2669403953805219, 0.7487494270612788, 0.44057327076578856}, + {0.27414945925613216, 0.7519868887012355, 0.43660069156818965}, + {0.28147665665716626, 0.755201528324013, 0.43255213457796365}, + {0.2889217691195198, 0.7583929812556258, 0.42842552870164097}, + {0.2964789382360529, 0.7615596257155389, 0.4242229866985808}, + {0.3041471124530943, 0.7647022727239619, 0.41994345744752104}, + {0.31192524014449496, 0.7678207187194435, 0.41558582710182396}, + {0.31980838304287407, 0.7709123713051562, 0.41115231354707876}, + {0.32779655496333804, 0.7739788075712202, 0.40663965647349865}, + {0.33588466791449195, 0.7770164660401522, 0.4020491587042435}, + {0.34407488193371133, 0.7800278920656099, 0.3973804752308849}, + {0.3523599689997323, 0.7830095562872507, 0.3926359923281875}, + {0.36074006346245197, 0.7859622236060678, 0.3878145232212208}, + {0.36921428939455786, 0.7888866412701451, 0.38291381435701694}, + {0.37777835651210034, 0.7917793150973379, 0.37793936040098913}, + {0.3864336209519174, 0.7946427215203885, 0.3728856256306759}, + {0.3951736619954228, 0.797473402038798, 0.3677571865876491}, + {0.4040019632351159, 0.8002737966998706, 0.3625514261814766}, + {0.4129129804482464, 0.8030394840252982, 0.3572690015831872}, + {0.4219070059826357, 0.805772174900056, 0.3519105924567475}, + {0.4309833172715677, 0.8084715598896897, 0.3464758054878499}, + {0.4401363189373519, 0.8111362580724669, 0.34096741055434293}, + {0.44936866381374757, 0.8137666304213753, 0.3353835991203212}, + {0.458673642833963, 0.8163613360822743, 0.32972721765157326}, + {0.46805401938353625, 0.8189196953983692, 0.3239973827222524}, + {0.47750397699915853, 0.8214424087022711, 0.3181950138984179}, + {0.48702494316955264, 0.8239271261653897, 0.31232166294182256}, + {0.49661532811633474, 0.8263744743966721, 0.306376800619062}, + {0.5062702739767431, 0.8287841998369972, 0.3003624619571904}, + {0.5159926874598648, 0.8311565342261135, 0.2942785778807102}, + {0.5257756141542576, 0.8334892678013092, 0.28812725033290043}, + {0.5356220541188685, 0.8357835879688815, 0.28190734645112897}, + {0.5455239631257167, 0.838037329833802, 0.2756260283833135}, + {0.5554828787549823, 0.8402520764412206, 0.2692817313403921}, + {0.5654983251339641, 0.8424283847332169, 0.2628767994071899}, + {0.5755622254006186, 0.8445641394621258, 0.25641551104548627}, + {0.5856786942007215, 0.8466594333420596, 0.24989656346356887}, + {0.5958385796727564, 0.8487151964088427, 0.2433292811877542}, + {0.6060460684908495, 0.8507314758177834, 0.2367113216835447}, + {0.616292940650758, 0.8527072471488548, 0.23005204277336477}, + {0.6265778183939344, 0.8546430238400886, 0.2233537871857682}, + {0.6369023105271391, 0.8565402909227283, 0.2166198017460239}, + {0.6472561782044223, 0.8583980753432965, 0.2098615478515251}, + {0.6576426853779066, 0.8602173283504794, 0.20308155987152815}, + {0.6680535433907611, 0.8619971207604976, 0.19629330158139313}, + {0.6784900623681449, 0.8637403601361504, 0.18950231977185272}, + {0.6889439127328617, 0.86544616002535, 0.18272505128011118}, + {0.6994137684819729, 0.8671149653844072, 0.17597180349415806}, + {0.7098982863987701, 0.868749193048019, 0.1692568079838667}, + {0.7203901380970731, 0.8703480050687866, 0.16260354455700873}, + {0.7308896616716263, 0.8719142204262896, 0.1560285800997179}, + {0.7413875101130836, 0.873447039008859, 0.1495612865358065}, + {0.7518850354669301, 0.8749492431662675, 0.14322737498076443}, + {0.7623728828501631, 0.8764220675983936, 0.13706403823168214}, + {0.7728534061279669, 0.8778662616531304, 0.13110820913488913}, + {0.7833152551224711, 0.8792830913055214, 0.1254048217206159}, + {0.7937591112086629, 0.880675925144139, 0.12000541978485552}, + {0.8041826246822775, 0.8820441108502998, 0.11496466377053949}, + {0.8145754845039437, 0.8833909489919768, 0.11034716773962891}, + {0.8249409891695173, 0.8847181273467387, 0.10621658195896774}, + {0.8352698545299048, 0.8860269688856748, 0.1026459672214125}, + {0.8455623467619914, 0.8873201416511192, 0.09970160643955417}, + {0.8558102197403156, 0.8885989857373076, 0.09745185636949635}, + {0.8660121015321746, 0.8898658327014707, 0.09595302142849352}, + {0.876168577861264, 0.8911230006650279, 0.09524987622820644}, + {0.8862704693847823, 0.8923718488516762, 0.09537386433165168}, + {0.8963209276849421, 0.8936140145545759, 0.09633501924437288}, + {0.9063108305457804, 0.8948528630958348, 0.0981248266153556}, + {0.916243267627844, 0.8960890285051739, 0.10071727474383468}, + {0.9261061834911258, 0.8973278764153646, 0.10407091253184719}, + {0.9359031089867296, 0.8985677257631529, 0.10813047743488122}, + {0.9456365256783655, 0.899812890310841, 0.112838121119233}, + {0.9552994651064829, 0.9010627378634819, 0.11812754907477127}, + {0.9648948576822979, 0.9023209051300205, 0.12394140017411451}, + {0.9744168120052771, 0.9035877501583347, 0.13021471316475502}, + {0.9838691793408701, 0.9048649215326077, 0.13689772464133854}, + {0.9932481489335602, 0.9061547634208059, 0.14393594366968385}}}; + +template +inline std::array +color_map_(Real scalar, std::array, 256> const &table) { + static_assert(std::is_floating_point_v, + "Color tables are only implemented in floating point " + "arithmetic. If you require bytes please submit an issue or " + "pull request"); + + using boost::math::isnan; + + if ((isnan)(scalar)) + { + scalar = static_cast(0); + } + else + { + scalar = std::clamp(scalar, static_cast(0), static_cast(1)); + } + + if (scalar == static_cast(1)) { + return table.back(); + } + + Real s = (table.size() - 1) * scalar; + Real ii = std::floor(s); + Real t = s - ii; + auto i = static_cast(ii); + auto const &rgb0 = table[i]; + auto const &rgb1 = table[i + 1]; + return {(1 - t) * rgb0[0] + t * rgb1[0], (1 - t) * rgb0[1] + t * rgb1[1], + (1 - t) * rgb0[2] + t * rgb1[2]}; +} +} // namespace detail + +template std::array viridis(Real x) { + return detail::color_map_(x, detail::viridis_data_); +} + +template std::array smooth_cool_warm(Real x) { + return detail::color_map_(x, detail::smooth_cool_warm_data_); +} + +template std::array plasma(Real x) { + return detail::color_map_(x, detail::plasma_data_); +} + +template std::array black_body(Real x) { + return detail::color_map_(x, detail::black_body_data_); +} + +template std::array inferno(Real x) { + return detail::color_map_(x, detail::inferno_data_); +} + +template std::array kindlmann(Real x) { + return detail::color_map_(x, detail::kindlmann_data_); +} + +template +std::array extended_kindlmann(Real x) { + return detail::color_map_(x, detail::extended_kindlmann_data_); +} + +template +std::array to_8bit_rgba(const std::array &v) { + using std::sqrt; + std::array pixel {}; + for (auto i = 0; i < 3; ++i) { + // Apply gamma correction here: + Real u = sqrt(v[i]); + pixel[i] = 255 * std::clamp(u, static_cast(0), static_cast(1)); + } + + pixel[3] = 255; + return pixel; +} + +} // Namespace boost::math::tools + +#endif // BOOST_MATH_COLOR_MAPS_HPP diff --git a/third-party/boost-math/include/boost/math/tools/complex.hpp b/third-party/boost-math/include/boost/math/tools/complex.hpp new file mode 100644 index 0000000000000..ec51440116a3d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/complex.hpp @@ -0,0 +1,115 @@ +// Copyright John Maddock 2018. +// 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) + +// +// Tools for operator on complex as well as scalar types. +// + +#ifndef BOOST_MATH_TOOLS_COMPLEX_HPP +#define BOOST_MATH_TOOLS_COMPLEX_HPP + +#include +#include + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include +#include + +namespace boost { +namespace math { + +template +using complex = cuda::std::complex; + +} // namespace math +} // namespace boost + +#else + +#include +#include + +namespace boost { +namespace math { + +template +using complex = std::complex; + +} // namespace math +} // namespace boost + +#endif + +namespace boost { + namespace math { + namespace tools { + + namespace detail { + template + struct is_complex_type_impl + { + static constexpr bool value = false; + }; + + #ifndef BOOST_MATH_ENABLE_CUDA + template + struct is_complex_type_impl().real()), + decltype(std::declval().imag())>> + { + static constexpr bool value = true; + }; + #else + template + struct is_complex_type_impl().real()), + decltype(cuda::std::declval().imag())>> + { + static constexpr bool value = true; + }; + #endif + } // Namespace detail + + template + struct is_complex_type : public detail::is_complex_type_impl {}; + + // + // Use this trait to typecast integer literals to something + // that will interoperate with T: + // + template ::value> + struct integer_scalar_type + { + typedef int type; + }; + template + struct integer_scalar_type + { + typedef typename T::value_type type; + }; + template ::value> + struct unsigned_scalar_type + { + typedef unsigned type; + }; + template + struct unsigned_scalar_type + { + typedef typename T::value_type type; + }; + template ::value> + struct scalar_type + { + typedef T type; + }; + template + struct scalar_type + { + typedef typename T::value_type type; + }; + + +} } } + +#endif // BOOST_MATH_TOOLS_COMPLEX_HPP diff --git a/third-party/boost-math/include/boost/math/tools/concepts.hpp b/third-party/boost-math/include/boost/math/tools/concepts.hpp new file mode 100644 index 0000000000000..db0394b462d43 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/concepts.hpp @@ -0,0 +1,24 @@ +// (C) Copyright Matt Borland 2022. +// 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) +// +// Macros that substitute for STL concepts or typename depending on availability of + +#ifndef BOOST_MATH_TOOLS_CONCEPTS_HPP +#define BOOST_MATH_TOOLS_CONCEPTS_HPP + +// LLVM clang supports concepts but apple's clang does not fully support at version 13 +// See: https://en.cppreference.com/w/cpp/compiler_support/20 +#if (__cplusplus > 202000L || _MSVC_LANG > 202000L) +# if __has_include() && (!defined(__APPLE__) || (defined(__APPLE__) && defined(__clang__) && __clang__ > 13)) +# include +# define BOOST_MATH_FLOATING_POINT_TYPE std::floating_point +# else +# define BOOST_MATH_FLOATING_POINT_TYPE typename +# endif +#else +# define BOOST_MATH_FLOATING_POINT_TYPE typename +#endif + +#endif // BOOST_MATH_TOOLS_CONCEPTS_HPP diff --git a/third-party/boost-math/include/boost/math/tools/condition_numbers.hpp b/third-party/boost-math/include/boost/math/tools/condition_numbers.hpp new file mode 100644 index 0000000000000..c285b479fb10d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/condition_numbers.hpp @@ -0,0 +1,144 @@ +// (C) Copyright Nick Thompson 2019. +// 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) + +#ifndef BOOST_MATH_TOOLS_CONDITION_NUMBERS_HPP +#define BOOST_MATH_TOOLS_CONDITION_NUMBERS_HPP +#include +#include +#include +#include + +namespace boost { namespace math { namespace tools { + +template +class summation_condition_number { +public: + summation_condition_number(Real const x = 0) + { + using std::abs; + m_l1 = abs(x); + m_sum = x; + m_c = 0; + } + + void operator+=(Real const & x) + { + using std::abs; + // No need to Kahan the l1 calc; it's well conditioned: + m_l1 += abs(x); + BOOST_MATH_IF_CONSTEXPR (kahan) + { + Real y = x - m_c; + Real t = m_sum + y; + m_c = (t-m_sum) -y; + m_sum = t; + } + else + { + m_sum += x; + } + } + + inline void operator-=(Real const & x) + { + this->operator+=(-x); + } + + // Is operator*= relevant? Presumably everything gets rescaled, + // (m_sum -> k*m_sum, m_l1->k*m_l1, m_c->k*m_c), + // but is this sensible? More important is it useful? + // In addition, it might change the condition number. + + Real operator()() const + { + using std::abs; + if (m_sum == Real(0) && m_l1 != Real(0)) + { + return std::numeric_limits::infinity(); + } + return m_l1/abs(m_sum); + } + + Real sum() const + { + // Higham, 1993, "The Accuracy of Floating Point Summation": + // "In [17] and [18], Kahan describes a variation of compensated summation in which the final sum is also corrected + // thus s=s+e is appended to the algorithm above)." + return m_sum + m_c; + } + + Real l1_norm() const + { + return m_l1; + } + +private: + Real m_l1; + Real m_sum; + Real m_c; +}; + +template +Real evaluation_condition_number(F const & f, Real const & x) +{ + using std::abs; + using std::isnan; + using std::sqrt; + using boost::math::differentiation::finite_difference_derivative; + + Real fx = f(x); + if (isnan(fx)) + { + return std::numeric_limits::quiet_NaN(); + } + bool caught_exception = false; + Real fp; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try + { +#endif + fp = finite_difference_derivative(f, x); +#ifndef BOOST_MATH_NO_EXCEPTIONS + } + catch(...) + { + caught_exception = true; + } +#endif + if (isnan(fp) || caught_exception) + { + // Check if the right derivative exists: + fp = finite_difference_derivative(f, x); + if (isnan(fp)) + { + // Check if a left derivative exists: + const Real eps = (std::numeric_limits::epsilon)(); + Real h = - 2 * sqrt(eps); + h = boost::math::differentiation::detail::make_xph_representable(x, h); + Real yh = f(x + h); + Real y0 = f(x); + Real diff = yh - y0; + fp = diff / h; + if (isnan(fp)) + { + return std::numeric_limits::quiet_NaN(); + } + } + } + + if (fx == 0) + { + if (x==0 || fp==0) + { + return std::numeric_limits::quiet_NaN(); + } + return std::numeric_limits::infinity(); + } + + return abs(x*fp/fx); +} + +}}} // Namespaces +#endif diff --git a/third-party/boost-math/include/boost/math/tools/config.hpp b/third-party/boost-math/include/boost/math/tools/config.hpp new file mode 100644 index 0000000000000..964a2bf0bbab6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/config.hpp @@ -0,0 +1,856 @@ +// Copyright (c) 2006-7 John Maddock +// Copyright (c) 2021 Matt Borland +// 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) + +#ifndef BOOST_MATH_TOOLS_CONFIG_HPP +#define BOOST_MATH_TOOLS_CONFIG_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#ifndef __CUDACC_RTC__ + +#include + +// Minimum language standard transition +#ifdef _MSVC_LANG +# if _MSVC_LANG < 201402L +# pragma message("Boost.Math requires C++14"); +# endif +# if _MSC_VER == 1900 +# pragma message("MSVC 14.0 has broken C++14 constexpr support. Support for this compiler will be removed in Boost 1.86") +# endif +#else +# if __cplusplus < 201402L +# warning "Boost.Math requires C++14" +# endif +#endif + +#ifndef BOOST_MATH_STANDALONE +#include + + +// The following are all defined as standalone macros as well +// If Boost.Config is available just use those definitions because they are more fine-grained + +// Could be defined in TR1 +#ifndef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION +# define BOOST_MATH_PREVENT_MACRO_SUBSTITUTION BOOST_PREVENT_MACRO_SUBSTITUTION +#endif + +#define BOOST_MATH_CXX14_CONSTEXPR BOOST_CXX14_CONSTEXPR +#ifdef BOOST_NO_CXX14_CONSTEXPR +# define BOOST_MATH_NO_CXX14_CONSTEXPR +#endif + +#define BOOST_MATH_IF_CONSTEXPR BOOST_IF_CONSTEXPR +#ifdef BOOST_NO_CXX17_IF_CONSTEXPR +# define BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#endif + +#ifdef BOOST_NO_CXX17_HDR_EXECUTION +# define BOOST_MATH_NO_CXX17_HDR_EXECUTION +#endif + +#ifdef BOOST_HAS_THREADS +# define BOOST_MATH_HAS_THREADS +#endif +#ifdef BOOST_DISABLE_THREADS +# define BOOST_MATH_DISABLE_THREADS +#endif +#ifdef BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_MATH_NO_CXX11_THREAD_LOCAL +#endif + +#ifdef BOOST_NO_EXCEPTIONS +# define BOOST_MATH_NO_EXCEPTIONS +#endif + +#ifdef BOOST_NO_TYPEID +# define BOOST_MATH_NO_TYPEID +#endif +#ifdef BOOST_NO_RTTI +# define BOOST_MATH_NO_RTTI +#endif + +#define BOOST_MATH_NOINLINE BOOST_NOINLINE +#define BOOST_MATH_FORCEINLINE BOOST_FORCEINLINE + +#define BOOST_MATH_JOIN(X, Y) BOOST_JOIN(X, Y) +#define BOOST_MATH_STRINGIZE(X) BOOST_STRINGIZE(X) + +#else // Things from boost/config that are required, and easy to replicate + +#define BOOST_MATH_PREVENT_MACRO_SUBSTITUTION +#define BOOST_MATH_NO_REAL_CONCEPT_TESTS +#define BOOST_MATH_NO_DISTRIBUTION_CONCEPT_TESTS +#define BOOST_MATH_NO_LEXICAL_CAST + +// Since Boost.Multiprecision is in active development some tests do not fully cooperate yet. +#define BOOST_MATH_NO_MP_TESTS + +#if ((__cplusplus > 201400L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201400L))) +#define BOOST_MATH_CXX14_CONSTEXPR constexpr +#else +#define BOOST_MATH_CXX14_CONSTEXPR +#define BOOST_MATH_NO_CXX14_CONSTEXPR +#endif // BOOST_MATH_CXX14_CONSTEXPR + +#if ((__cplusplus > 201700L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201700L))) +#define BOOST_MATH_IF_CONSTEXPR if constexpr + +// Clang on mac provides the execution header with none of the functionality. TODO: Check back on this +// https://en.cppreference.com/w/cpp/compiler_support "Standardization of Parallelism TS" +# if !__has_include() || (defined(__APPLE__) && defined(__clang__)) +# define BOOST_MATH_NO_CXX17_HDR_EXECUTION +# endif +#else +# define BOOST_MATH_IF_CONSTEXPR if +# define BOOST_MATH_NO_CXX17_IF_CONSTEXPR +# define BOOST_MATH_NO_CXX17_HDR_EXECUTION +#endif + +#if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) +#define BOOST_MATH_HAS_CXX17_NUMERIC +#endif + +#define BOOST_MATH_JOIN(X, Y) BOOST_MATH_DO_JOIN(X, Y) +#define BOOST_MATH_DO_JOIN(X, Y) BOOST_MATH_DO_JOIN2(X,Y) +#define BOOST_MATH_DO_JOIN2(X, Y) X##Y + +#define BOOST_MATH_STRINGIZE(X) BOOST_MATH_DO_STRINGIZE(X) +#define BOOST_MATH_DO_STRINGIZE(X) #X + +#ifdef BOOST_MATH_DISABLE_THREADS // No threads, do nothing +// Detect thread support via STL implementation +#elif defined(__has_include) +# if !__has_include() || !__has_include() || !__has_include() || !__has_include() +# define BOOST_MATH_DISABLE_THREADS +# else +# define BOOST_MATH_HAS_THREADS +# endif +#else +# define BOOST_MATH_HAS_THREADS // The default assumption is that the machine has threads +#endif // Thread Support + +#ifdef BOOST_MATH_DISABLE_THREADS +# define BOOST_MATH_NO_CXX11_THREAD_LOCAL +#endif // BOOST_MATH_DISABLE_THREADS + +#ifdef __GNUC__ +# if !defined(__EXCEPTIONS) && !defined(BOOST_MATH_NO_EXCEPTIONS) +# define BOOST_MATH_NO_EXCEPTIONS +# endif + // + // Make sure we have some std lib headers included so we can detect __GXX_RTTI: + // +# include // for min and max +# include +# ifndef __GXX_RTTI +# ifndef BOOST_MATH_NO_TYPEID +# define BOOST_MATH_NO_TYPEID +# endif +# ifndef BOOST_MATH_NO_RTTI +# define BOOST_MATH_NO_RTTI +# endif +# endif +#endif + +#if !defined(BOOST_MATH_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_MATH_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // nvcc doesn't always parse __noinline__, + // see: https://svn.boost.org/trac/boost/ticket/9392 +# define BOOST_MATH_NOINLINE __attribute__ ((noinline)) +# elif defined(__HIP__) + // See https://github.com/boostorg/config/issues/392 +# define BOOST_MATH_NOINLINE __attribute__ ((noinline)) +# else +# define BOOST_MATH_NOINLINE __attribute__ ((__noinline__)) +# endif +# else +# define BOOST_MATH_NOINLINE +# endif +#endif + +#if !defined(BOOST_MATH_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_MATH_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_MATH_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_MATH_FORCEINLINE inline +# endif +#endif + +#endif // BOOST_MATH_STANDALONE + +// Support compilers with P0024R2 implemented without linking TBB +// https://en.cppreference.com/w/cpp/compiler_support +#if !defined(BOOST_MATH_NO_CXX17_HDR_EXECUTION) && defined(BOOST_MATH_HAS_THREADS) +# define BOOST_MATH_EXEC_COMPATIBLE +#endif + +// C++23 +#if __cplusplus > 202002L || (defined(_MSVC_LANG) &&_MSVC_LANG > 202002L) +# if defined(__GNUC__) && __GNUC__ >= 13 + // libstdc++3 only defines to/from_chars for std::float128_t when one of these defines are set + // otherwise we're right out of luck... +# if defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) || defined(_GLIBCXX_HAVE_FLOAT128_MATH) +# include // std::strlen is used with from_chars +# include +# include +# define BOOST_MATH_USE_CHARCONV_FOR_CONVERSION +# endif +# endif +#endif + +#include // for min and max +#include +#include +#include +#include + +#include + +#if (defined(__NetBSD__)\ + || (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +//# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif + +#if defined(__EMSCRIPTEN__) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif + +#ifdef __IBMCPP__ +// +// For reasons I don't understand, the tests with IMB's compiler all +// pass at long double precision, but fail with real_concept, those tests +// are disabled for now. (JM 2012). +#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS +# define BOOST_MATH_NO_REAL_CONCEPT_TESTS +#endif // BOOST_MATH_NO_REAL_CONCEPT_TESTS +#endif +#ifdef sun +// Any use of __float128 in program startup code causes a segfault (tested JM 2015, Solaris 11). +# define BOOST_MATH_DISABLE_FLOAT128 +#endif +#ifdef __HAIKU__ +// +// Not sure what's up with the math detection on Haiku, but linking fails with +// float128 code enabled, and we don't have an implementation of __expl, so +// disabling long double functions for now as well. +# define BOOST_MATH_DISABLE_FLOAT128 +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +// +// Darwin's rather strange "double double" is rather hard to +// support, it should be possible given enough effort though... +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) && (LDBL_MANT_DIG == 106) && (LDBL_MIN_EXP > DBL_MIN_EXP) +// +// Generic catch all case for gcc's "double-double" long double type. +// We do not support this as it's not even remotely IEEE conforming: +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +// +// Intel compiler prior to version 10 has sporadic problems +// calling the long double overloads of the std lib math functions: +// calling ::powl is OK, but std::pow(long double, long double) +// may segfault depending upon the value of the arguments passed +// and the specific Linux distribution. +// +// We'll be conservative and disable long double support for this compiler. +// +// Comment out this #define and try building the tests to determine whether +// your Intel compiler version has this issue or not. +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if defined(unix) && defined(__INTEL_COMPILER) +// +// Intel compiler has sporadic issues compiling std::fpclassify depending on +// the exact OS version used. Use our own code for this as we know it works +// well on Intel processors: +// +#define BOOST_MATH_DISABLE_STD_FPCLASSIFY +#endif + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) + // Better safe than sorry, our tests don't support hardware exceptions: +# define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) +#endif + +#ifdef __IBMCPP__ +# define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS +#endif + +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) +# define BOOST_MATH_USE_C99 +#endif + +#if (defined(__hpux) && !defined(__hppa)) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(__GNUC__) && defined(_GLIBCXX_USE_C99) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(_LIBCPP_VERSION) && !defined(_MSC_VER) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(__CYGWIN__) || defined(__HP_aCC) || defined(__INTEL_COMPILER) \ + || defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \ + || (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99))\ + || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590) + +namespace boost { namespace math { namespace tools { namespace detail { +template +struct type {}; + +template +struct non_type {}; +}}}} // Namespace boost, math tools, detail + +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) boost::math::tools::detail::type* = 0 +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::math::tools::detail::type* +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::math::tools::detail::non_type* = 0 +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::math::tools::detail::non_type* + +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +#else + +// no workaround needed: expand to nothing + +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + + +#endif // __SUNPRO_CC + +#if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT) +// Sun's compiler emits a hard error if a constant underflows, +// as does aCC on PA-RISC, while gcc issues a large number of warnings: +# define BOOST_MATH_SMALL_CONSTANT(x) 0.0 +#else +# define BOOST_MATH_SMALL_CONSTANT(x) x +#endif + +// +// Tune performance options for specific compilers, +// but check at each step that nothing has been previously defined by the user first +// +#ifdef _MSC_VER +# ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 2 +# endif +#if _MSC_VER <= 1900 +# ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_RATIONAL_METHOD 1 +# endif +#else +# ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 2 +# endif +#endif +#if _MSC_VER > 1900 +# ifndef BOOST_MATH_INT_TABLE_TYPE +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT +# endif +# ifndef BOOST_MATH_INT_VALUE_SUFFIX +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L +# endif +#endif + +#elif defined(__INTEL_COMPILER) +# ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 2 +# endif +# ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 1 +# endif + +#elif defined(__GNUC__) +# ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 3 +# endif +# ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 3 +# endif + +#elif defined(__clang__) + +#if __clang__ > 6 +# ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 3 +# endif +# ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 3 +# endif +# ifndef BOOST_MATH_INT_TABLE_TYPE +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT +# endif +# ifndef BOOST_MATH_INT_VALUE_SUFFIX +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L +# endif +#endif + +#endif + +// +// noexcept support: +// +#include +#define BOOST_MATH_NOEXCEPT(T) noexcept(std::is_floating_point::value) +#define BOOST_MATH_IS_FLOAT(T) (std::is_floating_point::value) + +// +// The maximum order of polynomial that will be evaluated +// via an unrolled specialisation: +// +#ifndef BOOST_MATH_MAX_POLY_ORDER +# define BOOST_MATH_MAX_POLY_ORDER 20 +#endif +// +// Set the method used to evaluate polynomials and rationals: +// +#ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 2 +#endif +#ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 1 +#endif +// +// decide whether to store constants as integers or reals: +// +#ifndef BOOST_MATH_INT_TABLE_TYPE +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT +#endif +#ifndef BOOST_MATH_INT_VALUE_SUFFIX +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF +#endif +// +// And then the actual configuration: +// +#if defined(BOOST_MATH_STANDALONE) && defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && !defined(__STRICT_ANSI__) \ + && !defined(BOOST_MATH_DISABLE_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128) +# define BOOST_MATH_USE_FLOAT128 +#elif defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_MATH_DISABLE_FLOAT128) +# define BOOST_MATH_USE_FLOAT128 +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +// +// Only enable this when the compiler really is GCC as clang and probably +// intel too don't support __float128 yet :-( +// +# if defined(__INTEL_COMPILER) && defined(__GNUC__) +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) +# define BOOST_MATH_FLOAT128_TYPE __float128 +# endif +# elif defined(__GNUC__) +# define BOOST_MATH_FLOAT128_TYPE __float128 +# endif + +# ifndef BOOST_MATH_FLOAT128_TYPE +# define BOOST_MATH_FLOAT128_TYPE _Quad +# endif +#endif +// +// Check for WinCE with no iostream support: +// +#if defined(_WIN32_WCE) && !defined(__SGI_STL_PORT) +# define BOOST_MATH_NO_LEXICAL_CAST +#endif + +// +// Helper macro for controlling the FP behaviour: +// +#ifndef BOOST_MATH_CONTROL_FP +# define BOOST_MATH_CONTROL_FP +#endif +// +// Helper macro for using statements: +// +#define BOOST_MATH_STD_USING_CORE \ + using std::abs;\ + using std::acos;\ + using std::cos;\ + using std::fmod;\ + using std::modf;\ + using std::tan;\ + using std::asin;\ + using std::cosh;\ + using std::frexp;\ + using std::pow;\ + using std::tanh;\ + using std::atan;\ + using std::exp;\ + using std::ldexp;\ + using std::sin;\ + using std::atan2;\ + using std::fabs;\ + using std::log;\ + using std::sinh;\ + using std::ceil;\ + using std::floor;\ + using std::log10;\ + using std::sqrt;\ + using std::log2;\ + using std::ilogb; + +#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE + +namespace boost{ namespace math{ +namespace tools +{ + +template +inline T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c) BOOST_MATH_NOEXCEPT(T) +{ + return (std::max)((std::max)(a, b), c); +} + +template +inline T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d) BOOST_MATH_NOEXCEPT(T) +{ + return (std::max)((std::max)(a, b), (std::max)(c, d)); +} + +} // namespace tools + +template +void suppress_unused_variable_warning(const T&) BOOST_MATH_NOEXCEPT(T) +{ +} + +namespace detail{ + +template +struct is_integer_for_rounding +{ + static constexpr bool value = std::is_integral::value || (std::numeric_limits::is_specialized && std::numeric_limits::is_integer); +}; + +} + +}} // namespace boost namespace math + +#ifdef __GLIBC_PREREQ +# if __GLIBC_PREREQ(2,14) +# define BOOST_MATH_HAVE_FIXED_GLIBC +# endif +#endif + +#if ((defined(__linux__) && !defined(__UCLIBC__) && !defined(BOOST_MATH_HAVE_FIXED_GLIBC)) || defined(__QNX__) || defined(__IBMCPP__)) +// +// This code was introduced in response to this glibc bug: http://sourceware.org/bugzilla/show_bug.cgi?id=2445 +// Basically powl and expl can return garbage when the result is small and certain exception flags are set +// on entrance to these functions. This appears to have been fixed in Glibc 2.14 (May 2011). +// Much more information in this message thread: https://groups.google.com/forum/#!topic/boost-list/ZT99wtIFlb4 +// + +#include + +# ifdef FE_ALL_EXCEPT + +namespace boost{ namespace math{ + namespace detail + { + struct fpu_guard + { + fpu_guard() + { + fegetexceptflag(&m_flags, FE_ALL_EXCEPT); + feclearexcept(FE_ALL_EXCEPT); + } + ~fpu_guard() + { + fesetexceptflag(&m_flags, FE_ALL_EXCEPT); + } + private: + fexcept_t m_flags; + }; + + } // namespace detail + }} // namespaces + +# define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object; +# define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0); + +# else + +# define BOOST_FPU_EXCEPTION_GUARD +# define BOOST_MATH_INSTRUMENT_FPU + +# endif + +#else // All other platforms. +# define BOOST_FPU_EXCEPTION_GUARD +# define BOOST_MATH_INSTRUMENT_FPU +#endif + +#ifdef BOOST_MATH_INSTRUMENT + +# include +# include +# include + +# define BOOST_MATH_INSTRUMENT_CODE(x) \ + std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl; +# define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(#name << " = " << name) + +#else + +# define BOOST_MATH_INSTRUMENT_CODE(x) +# define BOOST_MATH_INSTRUMENT_VARIABLE(name) + +#endif + +// +// Thread local storage: +// +#ifndef BOOST_MATH_DISABLE_THREADS +# define BOOST_MATH_THREAD_LOCAL thread_local +#else +# define BOOST_MATH_THREAD_LOCAL +#endif + +// +// Some mingw flavours have issues with thread_local and types with non-trivial destructors +// See https://sourceforge.net/p/mingw-w64/bugs/527/ +// +// When running windows-2022 or 2025 we see this issue again with GCC 12 and 14 +// +#if (defined(__MINGW32__) && ((__GNUC__ < 9) || (__GNUC__ >= 12)) && !defined(__clang__)) +# define BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES +#endif + + +// +// Can we have constexpr tables? +// +#if (!defined(BOOST_MATH_NO_CXX14_CONSTEXPR)) || (defined(_MSC_VER) && _MSC_VER >= 1910) +#define BOOST_MATH_HAVE_CONSTEXPR_TABLES +#define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION constexpr +#else +#define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION +#endif + +// +// CUDA support: +// + +#ifdef __CUDACC__ + +// We have to get our include order correct otherwise you get compilation failures +#include +#include +#include +#include +#include +#include +#include +#include + +# define BOOST_MATH_CUDA_ENABLED __host__ __device__ +# define BOOST_MATH_HAS_GPU_SUPPORT + +# ifndef BOOST_MATH_ENABLE_CUDA +# define BOOST_MATH_ENABLE_CUDA +# endif + +// Device code can not handle exceptions +# ifndef BOOST_MATH_NO_EXCEPTIONS +# define BOOST_MATH_NO_EXCEPTIONS +# endif + +// We want to use force inline from CUDA instead of the host compiler +# undef BOOST_MATH_FORCEINLINE +# define BOOST_MATH_FORCEINLINE __forceinline__ + +#elif defined(SYCL_LANGUAGE_VERSION) + +# define BOOST_MATH_SYCL_ENABLED SYCL_EXTERNAL +# define BOOST_MATH_HAS_GPU_SUPPORT + +# ifndef BOOST_MATH_ENABLE_SYCL +# define BOOST_MATH_ENABLE_SYCL +# endif + +# ifndef BOOST_MATH_NO_EXCEPTIONS +# define BOOST_MATH_NO_EXCEPTIONS +# endif + +// spir64 does not support long double +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +# define BOOST_MATH_NO_REAL_CONCEPT_TESTS + +# undef BOOST_MATH_FORCEINLINE +# define BOOST_MATH_FORCEINLINE inline + +#endif + +#ifndef BOOST_MATH_CUDA_ENABLED +# define BOOST_MATH_CUDA_ENABLED +#endif + +#ifndef BOOST_MATH_SYCL_ENABLED +# define BOOST_MATH_SYCL_ENABLED +#endif + +// Not all functions that allow CUDA allow SYCL (e.g. Recursion is disallowed by SYCL) +# define BOOST_MATH_GPU_ENABLED BOOST_MATH_CUDA_ENABLED BOOST_MATH_SYCL_ENABLED + +// Additional functions that need replaced/marked up +#ifdef BOOST_MATH_HAS_GPU_SUPPORT +template +BOOST_MATH_GPU_ENABLED constexpr void gpu_safe_swap(T& a, T& b) { T t(a); a = b; b = t; } +template +BOOST_MATH_GPU_ENABLED constexpr T gpu_safe_min(const T& a, const T& b) { return a < b ? a : b; } +template +BOOST_MATH_GPU_ENABLED constexpr T gpu_safe_max(const T& a, const T& b) { return a > b ? a : b; } + +#define BOOST_MATH_GPU_SAFE_SWAP(a, b) gpu_safe_swap(a, b) +#define BOOST_MATH_GPU_SAFE_MIN(a, b) gpu_safe_min(a, b) +#define BOOST_MATH_GPU_SAFE_MAX(a, b) gpu_safe_max(a, b) + +#else + +#define BOOST_MATH_GPU_SAFE_SWAP(a, b) std::swap(a, b) +#define BOOST_MATH_GPU_SAFE_MIN(a, b) (std::min)(a, b) +#define BOOST_MATH_GPU_SAFE_MAX(a, b) (std::max)(a, b) + +#endif + +// Static variables are not allowed with CUDA or C++20 modules +// See if we can inline them instead + +#if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L +# define BOOST_MATH_INLINE_CONSTEXPR inline constexpr +# define BOOST_MATH_STATIC static +# ifndef BOOST_MATH_HAS_GPU_SUPPORT +# define BOOST_MATH_STATIC_LOCAL_VARIABLE static +# else +# define BOOST_MATH_STATIC_LOCAL_VARIABLE +# endif +#else +# ifndef BOOST_MATH_HAS_GPU_SUPPORT +# define BOOST_MATH_INLINE_CONSTEXPR static constexpr +# define BOOST_MATH_STATIC static +# define BOOST_MATH_STATIC_LOCAL_VARIABLE +# else +# define BOOST_MATH_INLINE_CONSTEXPR constexpr +# define BOOST_MATH_STATIC constexpr +# define BOOST_MATH_STATIC_LOCAL_VARIABLE static +# endif +#endif + +#define BOOST_MATH_FP_NAN FP_NAN +#define BOOST_MATH_FP_INFINITE FP_INFINITE +#define BOOST_MATH_FP_ZERO FP_ZERO +#define BOOST_MATH_FP_SUBNORMAL FP_SUBNORMAL +#define BOOST_MATH_FP_NORMAL FP_NORMAL + +#else // Special section for CUDA NVRTC to ensure we consume no STL headers + +#ifndef BOOST_MATH_STANDALONE +# define BOOST_MATH_STANDALONE +#endif + +#define BOOST_MATH_HAS_NVRTC +#define BOOST_MATH_ENABLE_CUDA +#define BOOST_MATH_HAS_GPU_SUPPORT + +#define BOOST_MATH_GPU_ENABLED __host__ __device__ +#define BOOST_MATH_CUDA_ENABLED __host__ __device__ + +#define BOOST_MATH_STATIC static +#define BOOST_MATH_STATIC_LOCAL_VARIABLE + +#define BOOST_MATH_NOEXCEPT(T) noexcept(boost::math::is_floating_point_v) +#define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T) +#define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) +#define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) +#define BOOST_MATH_BIG_CONSTANT(T, N, V) static_cast(V) +#define BOOST_MATH_FORCEINLINE __forceinline__ +#define BOOST_MATH_STD_USING +#define BOOST_MATH_IF_CONSTEXPR if +#define BOOST_MATH_IS_FLOAT(T) (boost::math::is_floating_point::value) +#define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION constexpr +#define BOOST_MATH_NO_EXCEPTIONS +#define BOOST_MATH_PREVENT_MACRO_SUBSTITUTION + +// This should be defined to nothing but since it is not specifically a math macro +// we need to undef before proceeding +#ifdef BOOST_FPU_EXCEPTION_GUARD +# undef BOOST_FPU_EXCEPTION_GUARD +#endif + +#define BOOST_FPU_EXCEPTION_GUARD + +template +BOOST_MATH_GPU_ENABLED constexpr void gpu_safe_swap(T& a, T& b) { T t(a); a = b; b = t; } + +#define BOOST_MATH_GPU_SAFE_SWAP(a, b) gpu_safe_swap(a, b) +#define BOOST_MATH_GPU_SAFE_MIN(a, b) (::min)(a, b) +#define BOOST_MATH_GPU_SAFE_MAX(a, b) (::max)(a, b) + +#define BOOST_MATH_FP_NAN 0 +#define BOOST_MATH_FP_INFINITE 1 +#define BOOST_MATH_FP_ZERO 2 +#define BOOST_MATH_FP_SUBNORMAL 3 +#define BOOST_MATH_FP_NORMAL 4 + +#define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF +#define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT + +#if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L +# define BOOST_MATH_INLINE_CONSTEXPR inline constexpr +#else +# define BOOST_MATH_INLINE_CONSTEXPR constexpr +#endif + +#define BOOST_MATH_INSTRUMENT_VARIABLE(x) +#define BOOST_MATH_INSTRUMENT_CODE(x) + +#endif // NVRTC + +#endif // BOOST_MATH_TOOLS_CONFIG_HPP + + + + diff --git a/third-party/boost-math/include/boost/math/tools/convert_from_string.hpp b/third-party/boost-math/include/boost/math/tools/convert_from_string.hpp new file mode 100644 index 0000000000000..3b7895cdf65c7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/convert_from_string.hpp @@ -0,0 +1,85 @@ +// Copyright John Maddock 2016. +// Copyright Matt Borland 2023. +// 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) + +#ifndef BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED +#define BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#ifndef BOOST_MATH_STANDALONE + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif + +namespace boost{ namespace math{ namespace tools{ + + template + struct convert_from_string_result + { + typedef typename std::conditional::value, const char*, T>::type type; + }; + + template + Real convert_from_string(const char* p, const std::false_type&) + { + #ifdef BOOST_MATH_NO_LEXICAL_CAST + + // This function should not compile, we don't have the necessary functionality to support it: + static_assert(sizeof(Real) == 0, "boost.lexical_cast is not supported in standalone mode."); + (void)p; // Suppresses -Wunused-parameter + return Real(0); + + #elif defined(BOOST_MATH_USE_CHARCONV_FOR_CONVERSION) + + if constexpr (std::is_arithmetic_v) + { + Real v {}; + std::from_chars(p, p + std::strlen(p), v); + + return v; + } + else + { + return boost::lexical_cast(p); + } + + #else + + return boost::lexical_cast(p); + + #endif + } + template + constexpr const char* convert_from_string(const char* p, const std::true_type&) noexcept + { + return p; + } + template + constexpr typename convert_from_string_result::type convert_from_string(const char* p) noexcept((std::is_constructible::value)) + { + return convert_from_string(p, std::is_constructible()); + } + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED + diff --git a/third-party/boost-math/include/boost/math/tools/cstdint.hpp b/third-party/boost-math/include/boost/math/tools/cstdint.hpp new file mode 100644 index 0000000000000..ce2c913b5c597 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/cstdint.hpp @@ -0,0 +1,107 @@ +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_TOOLS_CSTDINT +#define BOOST_MATH_TOOLS_CSTDINT + +#include + + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include + +namespace boost { +namespace math { + +using cuda::std::int8_t; +using cuda::std::int16_t; +using cuda::std::int32_t; +using cuda::std::int64_t; + +using cuda::std::int_fast8_t; +using cuda::std::int_fast16_t; +using cuda::std::int_fast32_t; +using cuda::std::int_fast64_t; + +using cuda::std::int_least8_t; +using cuda::std::int_least16_t; +using cuda::std::int_least32_t; +using cuda::std::int_least64_t; + +using cuda::std::intmax_t; +using cuda::std::intptr_t; + +using cuda::std::uint8_t; +using cuda::std::uint16_t; +using cuda::std::uint32_t; +using cuda::std::uint64_t; + +using cuda::std::uint_fast8_t; +using cuda::std::uint_fast16_t; +using cuda::std::uint_fast32_t; +using cuda::std::uint_fast64_t; + +using cuda::std::uint_least8_t; +using cuda::std::uint_least16_t; +using cuda::std::uint_least32_t; +using cuda::std::uint_least64_t; + +using cuda::std::uintmax_t; +using cuda::std::uintptr_t; + +using size_t = unsigned long; + +#else + +#include + +namespace boost { +namespace math { + +using std::int8_t; +using std::int16_t; +using std::int32_t; +using std::int64_t; + +using std::int_fast8_t; +using std::int_fast16_t; +using std::int_fast32_t; +using std::int_fast64_t; + +using std::int_least8_t; +using std::int_least16_t; +using std::int_least32_t; +using std::int_least64_t; + +using std::intmax_t; +using std::intptr_t; + +using std::uint8_t; +using std::uint16_t; +using std::uint32_t; +using std::uint64_t; + +using std::uint_fast8_t; +using std::uint_fast16_t; +using std::uint_fast32_t; +using std::uint_fast64_t; + +using std::uint_least8_t; +using std::uint_least16_t; +using std::uint_least32_t; +using std::uint_least64_t; + +using std::uintmax_t; +using std::uintptr_t; + +using std::size_t; + +#endif + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_CSTDINT diff --git a/third-party/boost-math/include/boost/math/tools/cubic_roots.hpp b/third-party/boost-math/include/boost/math/tools/cubic_roots.hpp new file mode 100644 index 0000000000000..451c5de813368 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/cubic_roots.hpp @@ -0,0 +1,176 @@ +// (C) Copyright Nick Thompson 2021. +// 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) +#ifndef BOOST_MATH_TOOLS_CUBIC_ROOTS_HPP +#define BOOST_MATH_TOOLS_CUBIC_ROOTS_HPP +#include +#include +#include +#include + +namespace boost::math::tools { + +// Solves ax^3 + bx^2 + cx + d = 0. +// Only returns the real roots, as types get weird for real coefficients and +// complex roots. Follows Numerical Recipes, Chapter 5, section 6. NB: A better +// algorithm apparently exists: Algorithm 954: An Accurate and Efficient Cubic +// and Quartic Equation Solver for Physical Applications However, I don't have +// access to that paper! +template +std::array cubic_roots(Real a, Real b, Real c, Real d) { + using std::abs; + using std::acos; + using std::cbrt; + using std::cos; + using std::fma; + using std::sqrt; + std::array roots = {std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN()}; + if (a == 0) { + // bx^2 + cx + d = 0: + if (b == 0) { + // cx + d = 0: + if (c == 0) { + if (d != 0) { + // No solutions: + return roots; + } + roots[0] = 0; + roots[1] = 0; + roots[2] = 0; + return roots; + } + roots[0] = -d / c; + return roots; + } + auto [x0, x1] = quadratic_roots(b, c, d); + roots[0] = x0; + roots[1] = x1; + return roots; + } + if (d == 0) { + auto [x0, x1] = quadratic_roots(a, b, c); + roots[0] = x0; + roots[1] = x1; + roots[2] = 0; + std::sort(roots.begin(), roots.end()); + return roots; + } + Real p = b / a; + Real q = c / a; + Real r = d / a; + Real Q = (p * p - 3 * q) / 9; + Real R = (2 * p * p * p - 9 * p * q + 27 * r) / 54; + if (R * R < Q * Q * Q) { + Real rtQ = sqrt(Q); + Real theta = acos(R / (Q * rtQ)) / 3; + Real st = sin(theta); + Real ct = cos(theta); + roots[0] = -2 * rtQ * ct - p / 3; + roots[1] = -rtQ * (-ct + sqrt(Real(3)) * st) - p / 3; + roots[2] = rtQ * (ct + sqrt(Real(3)) * st) - p / 3; + } else { + // In Numerical Recipes, Chapter 5, Section 6, it is claimed that we + // only have one real root if R^2 >= Q^3. But this isn't true; we can + // even see this from equation 5.6.18. The condition for having three + // real roots is that A = B. It *is* the case that if we're in this + // branch, and we have 3 real roots, two are a double root. Take + // (x+1)^2(x-2) = x^3 - 3x -2 as an example. This clearly has a double + // root at x = -1, and it gets sent into this branch. + Real arg = R * R - Q * Q * Q; + Real A = (R >= 0 ? -1 : 1) * cbrt(abs(R) + sqrt(arg)); + Real B = 0; + if (A != 0) { + B = Q / A; + } + roots[0] = A + B - p / 3; + // Yes, we're comparing floats for equality: + // Any perturbation pushes the roots into the complex plane; out of the + // bailiwick of this routine. + if (A == B || arg == 0) { + roots[1] = -A - p / 3; + roots[2] = -A - p / 3; + } + } + // Root polishing: + for (auto &r : roots) { + // Horner's method. + // Here I'll take John Gustaffson's opinion that the fma is a *distinct* + // operation from a*x +b: Make sure to compile these fmas into a single + // instruction and not a function call! (I'm looking at you Windows.) + Real f = fma(a, r, b); + f = fma(f, r, c); + f = fma(f, r, d); + Real df = fma(3 * a, r, 2 * b); + df = fma(df, r, c); + if (df != 0) { + Real d2f = fma(6 * a, r, 2 * b); + Real denom = 2 * df * df - f * d2f; + if (denom != 0) { + r -= 2 * f * df / denom; + } else { + r -= f / df; + } + } + } + std::sort(roots.begin(), roots.end()); + return roots; +} + +// Computes the empirical residual p(r) (first element) and expected residual +// eps*|rp'(r)| (second element) for a root. Recall that for a numerically +// computed root r satisfying r = r_0(1+eps) of a function p, |p(r)| <= +// eps|rp'(r)|. +template +std::array cubic_root_residual(Real a, Real b, Real c, Real d, + Real root) { + using std::abs; + using std::fma; + std::array out; + Real residual = fma(a, root, b); + residual = fma(residual, root, c); + residual = fma(residual, root, d); + + out[0] = residual; + + // The expected residual is: + // eps*[4|ar^3| + 3|br^2| + 2|cr| + |d|] + // This can be demonstrated by assuming the coefficients and the root are + // perturbed according to the rounding model of floating point arithmetic, + // and then working through the inequalities. + root = abs(root); + Real expected_residual = fma(4 * abs(a), root, 3 * abs(b)); + expected_residual = fma(expected_residual, root, 2 * abs(c)); + expected_residual = fma(expected_residual, root, abs(d)); + out[1] = expected_residual * std::numeric_limits::epsilon(); + return out; +} + +// Computes the condition number of rootfinding. This is defined in Corless, A +// Graduate Introduction to Numerical Methods, Section 3.2.1. +template +Real cubic_root_condition_number(Real a, Real b, Real c, Real d, Real root) { + using std::abs; + using std::fma; + // There are *absolute* condition numbers that can be defined when r = 0; + // but they basically reduce to the residual computed above. + if (root == static_cast(0)) { + return std::numeric_limits::infinity(); + } + + Real numerator = fma(abs(a), abs(root), abs(b)); + numerator = fma(numerator, abs(root), abs(c)); + numerator = fma(numerator, abs(root), abs(d)); + Real denominator = fma(3 * a, root, 2 * b); + denominator = fma(denominator, root, c); + if (denominator == static_cast(0)) { + return std::numeric_limits::infinity(); + } + denominator *= root; + return numerator / abs(denominator); +} + +} // namespace boost::math::tools +#endif diff --git a/third-party/boost-math/include/boost/math/tools/cxx03_warn.hpp b/third-party/boost-math/include/boost/math/tools/cxx03_warn.hpp new file mode 100644 index 0000000000000..7aafea7553a93 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/cxx03_warn.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2020 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) + +#ifndef BOOST_MATH_TOOLS_CXX03_WARN_HPP +#define BOOST_MATH_TOOLS_CXX03_WARN_HPP + +#include + +#if defined(BOOST_NO_CXX11_NOEXCEPT) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_RVALUE_REFERENCES" +#endif +#if defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_SFINAE_EXPR" +#endif +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_AUTO_DECLARATIONS" +#endif +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_LAMBDAS" +#endif +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX" +#endif +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_TUPLE" +#endif +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_INITIALIZER_LIST" +#endif +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_CHRONO" +#endif +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_CONSTEXPR" +#endif +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NULLPTR" +#endif +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NUMERIC_LIMITS" +#endif +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_DECLTYPE" +#endif +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_ARRAY" +#endif +#if defined(BOOST_NO_CXX11_ALLOCATOR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_ALLOCATOR" +#endif +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS" +#endif + +#ifdef BOOST_MATH_SHOW_CXX03_WARNING +// +// The above list includes everything we use, plus a few we're likely to use soon. +// As from March 2020, C++03 support is deprecated, and as from March 2021 will be removed, +// so mark up as such: +// +// March 2021(mborland): C++03 support has been removed. Replace warning with hard error. +// +#error Support for C++03 has been removed. The minimum requirement for this library is fully compliant C++11. +#endif + +#endif diff --git a/third-party/boost-math/include/boost/math/tools/detail/is_const_iterable.hpp b/third-party/boost-math/include/boost/math/tools/detail/is_const_iterable.hpp new file mode 100644 index 0000000000000..e5efc82c30aee --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/is_const_iterable.hpp @@ -0,0 +1,38 @@ +// (C) Copyright John Maddock 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP +#define BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP + +#include + +#define BOOST_MATH_HAS_IS_CONST_ITERABLE + +#include +#include + +namespace boost { + namespace math { + namespace tools { + namespace detail { + + template + using begin_t = decltype(std::declval().begin()); + template + using end_t = decltype(std::declval().end()); + template + using const_iterator_t = typename T::const_iterator; + + template + struct is_const_iterable + : public std::integral_constant::value + && is_detected::value + && is_detected::value + > {}; + +} } } } + +#endif // BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_10.hpp new file mode 100644 index 0000000000000..04ad90b69b5aa --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_10.hpp @@ -0,0 +1,84 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_11.hpp new file mode 100644 index 0000000000000..f99ab8250786b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_11.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_12.hpp new file mode 100644 index 0000000000000..3006ebe51e4be --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_12.hpp @@ -0,0 +1,96 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_13.hpp new file mode 100644 index 0000000000000..0f11189097f1e --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_13.hpp @@ -0,0 +1,102 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_14.hpp new file mode 100644 index 0000000000000..caba4b97eaf98 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_14.hpp @@ -0,0 +1,108 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_15.hpp new file mode 100644 index 0000000000000..c8f42ac813052 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_15.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_16.hpp new file mode 100644 index 0000000000000..2ed591ccf54b3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_16.hpp @@ -0,0 +1,120 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_17.hpp new file mode 100644 index 0000000000000..5e9fc8cd7c571 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_17.hpp @@ -0,0 +1,126 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_18.hpp new file mode 100644 index 0000000000000..ffb62ff049079 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_18.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_19.hpp new file mode 100644 index 0000000000000..56df108ac8525 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_19.hpp @@ -0,0 +1,138 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_2.hpp new file mode 100644 index 0000000000000..63091ebddd9e6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_2.hpp @@ -0,0 +1,36 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_20.hpp new file mode 100644 index 0000000000000..c16e5143ec307 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_20.hpp @@ -0,0 +1,144 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_3.hpp new file mode 100644 index 0000000000000..0aeccc111528c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_3.hpp @@ -0,0 +1,42 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_4.hpp new file mode 100644 index 0000000000000..61058fce84164 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_5.hpp new file mode 100644 index 0000000000000..47021bc50993a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_5.hpp @@ -0,0 +1,54 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_6.hpp new file mode 100644 index 0000000000000..bfd24371d5e54 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_6.hpp @@ -0,0 +1,60 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_7.hpp new file mode 100644 index 0000000000000..50ddca63ffed0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_7.hpp @@ -0,0 +1,66 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_8.hpp new file mode 100644 index 0000000000000..3be7ba4d16915 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_8.hpp @@ -0,0 +1,72 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_9.hpp new file mode 100644 index 0000000000000..4ec53c48bd294 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner1_9.hpp @@ -0,0 +1,78 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_10.hpp new file mode 100644 index 0000000000000..f242d7464e812 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_10.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_11.hpp new file mode 100644 index 0000000000000..edf7f86c528f2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_11.hpp @@ -0,0 +1,97 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_12.hpp new file mode 100644 index 0000000000000..969c9c4dddc30 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_12.hpp @@ -0,0 +1,104 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_13.hpp new file mode 100644 index 0000000000000..ed4559d11ed5f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_13.hpp @@ -0,0 +1,111 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_14.hpp new file mode 100644 index 0000000000000..4b79eb78a40f8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_14.hpp @@ -0,0 +1,118 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_15.hpp new file mode 100644 index 0000000000000..28b62eee75a09 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_15.hpp @@ -0,0 +1,125 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_16.hpp new file mode 100644 index 0000000000000..6368b405487a3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_16.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_17.hpp new file mode 100644 index 0000000000000..551e6191cfe1b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_17.hpp @@ -0,0 +1,139 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_18.hpp new file mode 100644 index 0000000000000..19cfdc19e1d0f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_18.hpp @@ -0,0 +1,146 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_19.hpp new file mode 100644 index 0000000000000..9ea87fd93b8ab --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_19.hpp @@ -0,0 +1,153 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_2.hpp new file mode 100644 index 0000000000000..1982a81f3f348 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_20.hpp new file mode 100644 index 0000000000000..23afe55e05492 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_20.hpp @@ -0,0 +1,160 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_3.hpp new file mode 100644 index 0000000000000..f9d6953b828dd --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_4.hpp new file mode 100644 index 0000000000000..8f11de5b31de7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_5.hpp new file mode 100644 index 0000000000000..eba9ee9e6df4c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_5.hpp @@ -0,0 +1,55 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_6.hpp new file mode 100644 index 0000000000000..ef77c6255b8f4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_6.hpp @@ -0,0 +1,62 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_7.hpp new file mode 100644 index 0000000000000..fe8d21b95f269 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_7.hpp @@ -0,0 +1,69 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_8.hpp new file mode 100644 index 0000000000000..de1810a9403be --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_8.hpp @@ -0,0 +1,76 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_9.hpp new file mode 100644 index 0000000000000..5c53b73299320 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner2_9.hpp @@ -0,0 +1,83 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_10.hpp new file mode 100644 index 0000000000000..7fb5bb47454f1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_10.hpp @@ -0,0 +1,156 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_11.hpp new file mode 100644 index 0000000000000..9f22820deae2d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_11.hpp @@ -0,0 +1,181 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_12.hpp new file mode 100644 index 0000000000000..b049613766296 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_12.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_13.hpp new file mode 100644 index 0000000000000..f39a33cc902b0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_13.hpp @@ -0,0 +1,237 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_14.hpp new file mode 100644 index 0000000000000..32b9e7db29912 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_14.hpp @@ -0,0 +1,268 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_15.hpp new file mode 100644 index 0000000000000..55325c84b9fdd --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_15.hpp @@ -0,0 +1,301 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_16.hpp new file mode 100644 index 0000000000000..f71d62f50c23c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_16.hpp @@ -0,0 +1,336 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_17.hpp new file mode 100644 index 0000000000000..783a34558caf2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_17.hpp @@ -0,0 +1,373 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_18.hpp new file mode 100644 index 0000000000000..b10b270c41792 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_18.hpp @@ -0,0 +1,412 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_19.hpp new file mode 100644 index 0000000000000..21147591c884b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_19.hpp @@ -0,0 +1,453 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[18] * x2 + a[16]); + t[1] = static_cast(a[17] * x2 + a[15]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_2.hpp new file mode 100644 index 0000000000000..ee3e35e6caa06 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_20.hpp new file mode 100644 index 0000000000000..338aeb7dbc13a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_20.hpp @@ -0,0 +1,496 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[18] * x2 + a[16]); + t[1] = static_cast(a[17] * x2 + a[15]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[19] * x2 + a[17]; + t[1] = a[18] * x2 + a[16]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[15]); + t[1] += static_cast(a[14]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_3.hpp new file mode 100644 index 0000000000000..1eee0cfac0b65 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_4.hpp new file mode 100644 index 0000000000000..efa7fba485c8a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_5.hpp new file mode 100644 index 0000000000000..f150e2a4a474a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_5.hpp @@ -0,0 +1,61 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_6.hpp new file mode 100644 index 0000000000000..fe679e74d2669 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_6.hpp @@ -0,0 +1,76 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_7.hpp new file mode 100644 index 0000000000000..76f080ad9ca50 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_7.hpp @@ -0,0 +1,93 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_8.hpp new file mode 100644 index 0000000000000..75634bdfc648a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_8.hpp @@ -0,0 +1,112 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_9.hpp new file mode 100644 index 0000000000000..63a40580d1233 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/polynomial_horner3_9.hpp @@ -0,0 +1,133 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_10.hpp new file mode 100644 index 0000000000000..e2f6c6d2fba4a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_10.hpp @@ -0,0 +1,138 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_10_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_11.hpp new file mode 100644 index 0000000000000..31d480a65a18d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_11.hpp @@ -0,0 +1,150 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_11_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_12.hpp new file mode 100644 index 0000000000000..c08a85b3a612b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_12.hpp @@ -0,0 +1,162 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_12_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_13.hpp new file mode 100644 index 0000000000000..cc87ec2dc7e61 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_13.hpp @@ -0,0 +1,174 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_13_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_14.hpp new file mode 100644 index 0000000000000..256473710f405 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_14.hpp @@ -0,0 +1,186 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_14_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_15.hpp new file mode 100644 index 0000000000000..2ab24814e7e3c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_15.hpp @@ -0,0 +1,198 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_15_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_16.hpp new file mode 100644 index 0000000000000..dce0b5e9b140e --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_16.hpp @@ -0,0 +1,210 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_16_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_17.hpp new file mode 100644 index 0000000000000..8e875d657663b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_17.hpp @@ -0,0 +1,222 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_17_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_18.hpp new file mode 100644 index 0000000000000..ab67a970b0af7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_18.hpp @@ -0,0 +1,234 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_18_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_19.hpp new file mode 100644 index 0000000000000..dc300343a5fa0 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_19.hpp @@ -0,0 +1,246 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_19_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_2.hpp new file mode 100644 index 0000000000000..c6b1ef9ef987e --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_2.hpp @@ -0,0 +1,42 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_2_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_20.hpp new file mode 100644 index 0000000000000..5b8b170c15b93 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_20.hpp @@ -0,0 +1,258 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_20_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((((b[19] * x + b[18]) * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) * z + a[19]) / (((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18]) * z + b[19])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_3.hpp new file mode 100644 index 0000000000000..6933e22bf16bf --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_3.hpp @@ -0,0 +1,54 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_3_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_4.hpp new file mode 100644 index 0000000000000..49b9835778d87 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_4.hpp @@ -0,0 +1,66 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_4_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_5.hpp new file mode 100644 index 0000000000000..91e97ff445ced --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_5.hpp @@ -0,0 +1,78 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_5_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_6.hpp new file mode 100644 index 0000000000000..876b026cdef88 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_6.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_6_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_7.hpp new file mode 100644 index 0000000000000..bcac18293ca02 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_7.hpp @@ -0,0 +1,102 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_7_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_8.hpp new file mode 100644 index 0000000000000..55e30a53e88e6 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_8.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_8_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_9.hpp new file mode 100644 index 0000000000000..c7087de508023 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner1_9.hpp @@ -0,0 +1,126 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_9_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_10.hpp new file mode 100644 index 0000000000000..4d74a714d5236 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_10.hpp @@ -0,0 +1,144 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_11.hpp new file mode 100644 index 0000000000000..15f1cf25567ff --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_11.hpp @@ -0,0 +1,160 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_12.hpp new file mode 100644 index 0000000000000..24e9d9e7f7a10 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_12.hpp @@ -0,0 +1,176 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_13.hpp new file mode 100644 index 0000000000000..495f88525d078 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_13.hpp @@ -0,0 +1,192 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_14.hpp new file mode 100644 index 0000000000000..273e723b6ca11 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_14.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_15.hpp new file mode 100644 index 0000000000000..c7e24ec7db0f1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_15.hpp @@ -0,0 +1,224 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_16.hpp new file mode 100644 index 0000000000000..2eebd702bc109 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_16.hpp @@ -0,0 +1,240 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_17.hpp new file mode 100644 index 0000000000000..1fee63047fc81 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_17.hpp @@ -0,0 +1,256 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_18.hpp new file mode 100644 index 0000000000000..7aedbf2aad816 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_18.hpp @@ -0,0 +1,272 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_19.hpp new file mode 100644 index 0000000000000..1c36a267cbec3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_19.hpp @@ -0,0 +1,288 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_2.hpp new file mode 100644 index 0000000000000..bb2e2c4dcf49f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_20.hpp new file mode 100644 index 0000000000000..a591b901c9d9f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_20.hpp @@ -0,0 +1,304 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((((b[19] * x2 + b[17]) * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18]) * z + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z2 + a[19]) / ((((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18]) * z + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z2 + b[19])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_3.hpp new file mode 100644 index 0000000000000..0b410d8bbe234 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_4.hpp new file mode 100644 index 0000000000000..07a9a2c5ad1fe --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_5.hpp new file mode 100644 index 0000000000000..0933ddfbc4202 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_5.hpp @@ -0,0 +1,64 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_6.hpp new file mode 100644 index 0000000000000..dee9c6e168d56 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_6.hpp @@ -0,0 +1,80 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_7.hpp new file mode 100644 index 0000000000000..6f9a85838c2dd --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_7.hpp @@ -0,0 +1,96 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_8.hpp new file mode 100644 index 0000000000000..33dda23bba934 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_8.hpp @@ -0,0 +1,112 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_9.hpp new file mode 100644 index 0000000000000..a9025a8900665 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner2_9.hpp @@ -0,0 +1,128 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_10.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_10.hpp new file mode 100644 index 0000000000000..b7cec124e2a10 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_10.hpp @@ -0,0 +1,396 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_11.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_11.hpp new file mode 100644 index 0000000000000..579f0e4868321 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_11.hpp @@ -0,0 +1,482 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_12.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_12.hpp new file mode 100644 index 0000000000000..54300dd08e1f9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_12.hpp @@ -0,0 +1,576 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_13.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_13.hpp new file mode 100644 index 0000000000000..d2fc7b63318bb --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_13.hpp @@ -0,0 +1,678 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_14.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_14.hpp new file mode 100644 index 0000000000000..0b7675f49474c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_14.hpp @@ -0,0 +1,788 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_15.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_15.hpp new file mode 100644 index 0000000000000..8286caed0b33c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_15.hpp @@ -0,0 +1,906 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_16.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_16.hpp new file mode 100644 index 0000000000000..fc823e4162294 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_16.hpp @@ -0,0 +1,1032 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_17.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_17.hpp new file mode 100644 index 0000000000000..cf7f75a706f26 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_17.hpp @@ -0,0 +1,1166 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_18.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_18.hpp new file mode 100644 index 0000000000000..f853ed3e0c2fd --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_18.hpp @@ -0,0 +1,1308 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_19.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_19.hpp new file mode 100644 index 0000000000000..d44e22c90b97e --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_19.hpp @@ -0,0 +1,1458 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[18] * x2 + a[16]; + t[1] = a[17] * x2 + a[15]; + t[2] = b[18] * x2 + b[16]; + t[3] = b[17] * x2 + b[15]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[13]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[18]); + t[2] += static_cast(b[18]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_2.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_2.hpp new file mode 100644 index 0000000000000..bb2e2c4dcf49f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_20.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_20.hpp new file mode 100644 index 0000000000000..967edf08328c3 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_20.hpp @@ -0,0 +1,1616 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[18] * x2 + a[16]; + t[1] = a[17] * x2 + a[15]; + t[2] = b[18] * x2 + b[16]; + t[3] = b[17] * x2 + b[15]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[13]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[18]); + t[2] += static_cast(b[18]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[19] * x2 + a[17]; + t[1] = a[18] * x2 + a[16]; + t[2] = b[19] * x2 + b[17]; + t[3] = b[18] * x2 + b[16]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[15]); + t[1] += static_cast(a[14]); + t[2] += static_cast(b[15]); + t[3] += static_cast(b[14]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[18]); + t[1] += static_cast(a[19]); + t[2] += static_cast(b[18]); + t[3] += static_cast(b[19]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_3.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_3.hpp new file mode 100644 index 0000000000000..0b410d8bbe234 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_4.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_4.hpp new file mode 100644 index 0000000000000..07a9a2c5ad1fe --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_5.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_5.hpp new file mode 100644 index 0000000000000..62c76dd506807 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_5.hpp @@ -0,0 +1,86 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_6.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_6.hpp new file mode 100644 index 0000000000000..f81a068acb85b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_6.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_7.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_7.hpp new file mode 100644 index 0000000000000..fea457ccf8e8d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_7.hpp @@ -0,0 +1,186 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_8.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_8.hpp new file mode 100644 index 0000000000000..306e2a41d9dae --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_8.hpp @@ -0,0 +1,248 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_9.hpp b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_9.hpp new file mode 100644 index 0000000000000..93a3527c18444 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/detail/rational_horner3_9.hpp @@ -0,0 +1,318 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::math::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if((-1 <= x) && (x <= 1)) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/third-party/boost-math/include/boost/math/tools/engel_expansion.hpp b/third-party/boost-math/include/boost/math/tools/engel_expansion.hpp new file mode 100644 index 0000000000000..2d22a84d83d4d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/engel_expansion.hpp @@ -0,0 +1,124 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_ENGEL_EXPANSION_HPP +#define BOOST_MATH_TOOLS_ENGEL_EXPANSION_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math::tools { + +template +class engel_expansion { +public: + engel_expansion(Real x) : x_{x} + { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into an Engel expansion."); + } + + if(x==0) + { + throw std::domain_error("Zero does not have an Engel expansion."); + } + a_.reserve(64); + // Let the error bound grow by 1 ULP/iteration. + // I haven't done the error analysis to show that this is an expected rate of error growth, + // but if you don't do this, you can easily get into an infinite loop. + Real i = 1; + Real computed = 0; + Real term = 1; + Real scale = std::numeric_limits::epsilon()*abs(x_)/2; + Real u = x; + while (abs(x_ - computed) > (i++)*scale) + { + Real recip = 1/u; + Real ak = ceil(recip); + a_.push_back(static_cast(ak)); + u = u*ak - 1; + if (u==0) + { + break; + } + term /= ak; + computed += term; + } + + for (size_t j = 1; j < a_.size(); ++j) + { + // Sanity check: This should only happen when wraparound occurs: + if (a_[j] < a_[j-1]) + { + throw std::domain_error("The digits of an Engel expansion must form a non-decreasing sequence; consider increasing the wide of the integer type."); + } + // Watch out for saturating behavior: + if (a_[j] == (std::numeric_limits::max)()) + { + throw std::domain_error("The integer type Z does not have enough width to hold the terms of the Engel expansion; please widen the type."); + } + } + a_.shrink_to_fit(); + } + + + const std::vector& digits() const + { + return a_; + } + + template + friend std::ostream& operator<<(std::ostream& out, engel_expansion& eng); + +private: + Real x_; + std::vector a_; +}; + + +template +std::ostream& operator<<(std::ostream& out, engel_expansion& engel) +{ + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(engel.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "{"; + for (size_t i = 0; i < engel.a_.size() - 1; ++i) + { + out << engel.a_[i] << ", "; + } + out << engel.a_.back(); + out << "}"; + return out; +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/estrin.hpp b/third-party/boost-math/include/boost/math/tools/estrin.hpp new file mode 100644 index 0000000000000..1955e9398f82f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/estrin.hpp @@ -0,0 +1,72 @@ +/* + * Copyright Thomas Dybdahl Ahle, Nick Thompson, Matt Borland, John Maddock, 2023 + * 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) + */ +#ifndef BOOST_MATH_TOOLS_ESTRIN_HPP +#define BOOST_MATH_TOOLS_ESTRIN_HPP + +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace tools { + +template +inline RealOrComplex evaluate_polynomial_estrin(RandomAccessContainer1 const &coeffs, RandomAccessContainer2 &scratch, RealOrComplex z) { + // Does anyone care about the complex coefficients, real argument case? + // I've never seen it used, and this static assert makes the error messages much better: + static_assert(std::is_same::value, + "The value type of the scratch space must be the same as the abscissa."); + auto n = coeffs.size(); + BOOST_MATH_ASSERT_MSG(scratch.size() >= (n + 1) / 2, "The scratch space must be at least N+1/2"); + + if (n == 0) { + return static_cast(0); + } + for (decltype(n) i = 0; i < n / 2; i++) { + scratch[i] = coeffs[2 * i] + coeffs[2 * i + 1] * z; + } + if (n & 1) { + scratch[n / 2] = coeffs[n - 1]; + } + auto m = (n + 1) / 2; + + while (m != 1) { + z = z * z; + for (decltype(n) i = 0; i < m / 2; i++) { + scratch[i] = scratch[2 * i] + scratch[2 * i + 1] * z; + } + if (m & 1) { + scratch[m / 2] = scratch[m - 1]; + } + m = (m + 1) / 2; + } + return scratch[0]; +} + +// The std::array template specialization doesn't need to allocate: +template +inline RealOrComplex2 evaluate_polynomial_estrin(const std::array &coeffs, RealOrComplex2 z) { + std::array ds; + return evaluate_polynomial_estrin(coeffs, ds, z); +} + +template +inline RealOrComplex evaluate_polynomial_estrin(const RandomAccessContainer &coeffs, RealOrComplex z) { + auto n = coeffs.size(); + // Normally, I'd make `ds` a RandomAccessContainer, but its value type needs to be RealOrComplex, + // and the value_type of the passed RandomAccessContainer can just be Real. + // Allocation of the std::vector is not ideal, but I have no other ideas at the moment: + std::vector ds((n + 1) / 2); + return evaluate_polynomial_estrin(coeffs, ds, z); +} + +} // namespace tools +} // namespace math +} // namespace boost +#endif diff --git a/third-party/boost-math/include/boost/math/tools/fraction.hpp b/third-party/boost-math/include/boost/math/tools/fraction.hpp new file mode 100644 index 0000000000000..f36d024c4061d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/fraction.hpp @@ -0,0 +1,354 @@ +// (C) Copyright John Maddock 2005-2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_TOOLS_FRACTION_INCLUDED +#define BOOST_MATH_TOOLS_FRACTION_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +namespace detail +{ + + template + struct is_pair : public boost::math::false_type{}; + + template + struct is_pair> : public boost::math::true_type{}; + + template + struct fraction_traits_simple + { + using result_type = typename Gen::result_type; + using value_type = typename Gen::result_type; + + BOOST_MATH_GPU_ENABLED static result_type a(const value_type&) BOOST_MATH_NOEXCEPT(value_type) + { + return 1; + } + BOOST_MATH_GPU_ENABLED static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v; + } + }; + + template + struct fraction_traits_pair + { + using value_type = typename Gen::result_type; + using result_type = typename value_type::first_type; + + BOOST_MATH_GPU_ENABLED static result_type a(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v.first; + } + BOOST_MATH_GPU_ENABLED static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v.second; + } + }; + + template + struct fraction_traits + : public boost::math::conditional< + is_pair::value, + fraction_traits_pair, + fraction_traits_simple>::type + { + }; + + template ::value> + struct tiny_value + { + // For float, double, and long double, 1/min_value() is finite. + // But for mpfr_float and cpp_bin_float, 1/min_value() is inf. + // Multiply the min by 16 so that the reciprocal doesn't overflow. + BOOST_MATH_GPU_ENABLED static T get() { + return 16*tools::min_value(); + } + }; + template + struct tiny_value + { + using value_type = typename T::value_type; + BOOST_MATH_GPU_ENABLED static T get() { + return 16*tools::min_value(); + } + }; + +} // namespace detail + +namespace detail { + +// +// continued_fraction_b +// Evaluates: +// +// b0 + a1 +// --------------- +// b1 + a2 +// ---------- +// b2 + a3 +// ----- +// b3 + ... +// +// Note that the first a0 returned by generator Gen is discarded. +// + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_b_impl(Gen& g, const U& factor, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + // SYCL can not handle this condition so we only check float on that platform + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + using value_type = typename traits::value_type; + using integer_type = typename integer_scalar_type::type; + using scalar_type = typename scalar_type::type; + + integer_type const zero(0), one(1); + + result_type tiny = detail::tiny_value::get(); + scalar_type terminator = abs(factor); + + value_type v = g(); + + result_type f, C, D, delta; + f = traits::b(v); + if(f == zero) + f = tiny; + C = f; + D = 0; + + boost::math::uintmax_t counter(max_terms); + do{ + v = g(); + D = traits::b(v) + traits::a(v) * D; + if(D == result_type(0)) + D = tiny; + C = traits::b(v) + traits::a(v) / C; + if(C == zero) + C = tiny; + D = one/D; + delta = C*D; + f = f * delta; + }while((abs(delta - one) > terminator) && --counter); + + max_terms = max_terms - counter; + + return f; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, const U& factor, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + return detail::continued_fraction_b_impl(g, factor, max_terms); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, const U& factor) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + boost::math::uintmax_t max_terms = (boost::math::numeric_limits::max)(); + return detail::continued_fraction_b_impl(g, factor, max_terms); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, int bits) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits); + boost::math::uintmax_t max_terms = (boost::math::numeric_limits::max)(); + return detail::continued_fraction_b_impl(g, factor, max_terms); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, int bits, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits); + return detail::continued_fraction_b_impl(g, factor, max_terms); +} + +namespace detail { + +// +// continued_fraction_a +// Evaluates: +// +// a1 +// --------------- +// b1 + a2 +// ---------- +// b2 + a3 +// ----- +// b3 + ... +// +// Note that the first a1 and b1 returned by generator Gen are both used. +// +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_a_impl(Gen& g, const U& factor, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + using value_type = typename traits::value_type; + using integer_type = typename integer_scalar_type::type; + using scalar_type = typename scalar_type::type; + + integer_type const zero(0), one(1); + + result_type tiny = detail::tiny_value::get(); + scalar_type terminator = abs(factor); + + value_type v = g(); + + result_type f, C, D, delta, a0; + f = traits::b(v); + a0 = traits::a(v); + if(f == zero) + f = tiny; + C = f; + D = 0; + + boost::math::uintmax_t counter(max_terms); + + do{ + v = g(); + D = traits::b(v) + traits::a(v) * D; + if(D == zero) + D = tiny; + C = traits::b(v) + traits::a(v) / C; + if(C == zero) + C = tiny; + D = one/D; + delta = C*D; + f = f * delta; + }while((abs(delta - one) > terminator) && --counter); + + max_terms = max_terms - counter; + + return a0/f; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, const U& factor, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + return detail::continued_fraction_a_impl(g, factor, max_terms); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, const U& factor) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + boost::math::uintmax_t max_iter = (boost::math::numeric_limits::max)(); + return detail::continued_fraction_a_impl(g, factor, max_iter); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, int bits) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + typedef detail::fraction_traits traits; + typedef typename traits::result_type result_type; + + result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits); + boost::math::uintmax_t max_iter = (boost::math::numeric_limits::max)(); + + return detail::continued_fraction_a_impl(g, factor, max_iter); +} + +template +BOOST_MATH_GPU_ENABLED inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, int bits, boost::math::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()()) + #endif + ) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits); + return detail::continued_fraction_a_impl(g, factor, max_terms); +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_FRACTION_INCLUDED diff --git a/third-party/boost-math/include/boost/math/tools/header_deprecated.hpp b/third-party/boost-math/include/boost/math/tools/header_deprecated.hpp new file mode 100644 index 0000000000000..867fcaa217d1f --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/header_deprecated.hpp @@ -0,0 +1,27 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_TOOLS_HEADER_DEPRECATED +#define BOOST_MATH_TOOLS_HEADER_DEPRECATED + +#ifndef BOOST_MATH_STANDALONE + +# include +# define BOOST_MATH_HEADER_DEPRECATED(expr) BOOST_HEADER_DEPRECATED(expr) + +#else + +# ifdef _MSC_VER +// Expands to "This header is deprecated; use expr instead." +# define BOOST_MATH_HEADER_DEPRECATED(expr) __pragma("This header is deprecated; use " expr " instead.") +# else // GNU, Clang, Intel, IBM, etc. +// Expands to "This header is deprecated use expr instead" +# define BOOST_MATH_HEADER_DEPRECATED_MESSAGE(expr) _Pragma(#expr) +# define BOOST_MATH_HEADER_DEPRECATED(expr) BOOST_MATH_HEADER_DEPRECATED_MESSAGE(message "This header is deprecated use " expr " instead") +# endif + +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_TOOLS_HEADER_DEPRECATED diff --git a/third-party/boost-math/include/boost/math/tools/is_constant_evaluated.hpp b/third-party/boost-math/include/boost/math/tools/is_constant_evaluated.hpp new file mode 100644 index 0000000000000..eb903dbd71c35 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/is_constant_evaluated.hpp @@ -0,0 +1,51 @@ +// Copyright John Maddock 2011-2021. +// 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) + +#ifndef BOOST_MATH_TOOLS_IS_CONSTANT_EVALUATED_HPP +#define BOOST_MATH_TOOLS_IS_CONSTANT_EVALUATED_HPP + +#include + +#ifdef __has_include +# if __has_include() +# include +# ifdef __cpp_lib_is_constant_evaluated +# include +# define BOOST_MATH_HAS_IS_CONSTANT_EVALUATED +# endif +# endif +#endif + +#ifdef __has_builtin +# if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_MATH_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +# endif +#endif +// +// MSVC also supports __builtin_is_constant_evaluated if it's recent enough: +// +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif +// +// As does GCC-9: +// +#if !defined(BOOST_MATH_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) && !defined(BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + +#if defined(BOOST_MATH_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_MATH_NO_CXX14_CONSTEXPR) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) std::is_constant_evaluated() +#elif defined(BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) __builtin_is_constant_evaluated() +#elif !defined(BOOST_MATH_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 6) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) __builtin_constant_p(x) +# define BOOST_MATH_USING_BUILTIN_CONSTANT_P +#else +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) false +# define BOOST_MATH_NO_CONSTEXPR_DETECTION +#endif + +#endif // BOOST_MATH_TOOLS_IS_CONSTANT_EVALUATED_HPP diff --git a/third-party/boost-math/include/boost/math/tools/is_detected.hpp b/third-party/boost-math/include/boost/math/tools/is_detected.hpp new file mode 100644 index 0000000000000..93fa96f60b15a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/is_detected.hpp @@ -0,0 +1,56 @@ +// Copyright Matt Borland 2021. +// 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) +// +// https://en.cppreference.com/w/cpp/experimental/is_detected + +#ifndef BOOST_MATH_TOOLS_IS_DETECTED_HPP +#define BOOST_MATH_TOOLS_IS_DETECTED_HPP + +#include + +namespace boost { namespace math { namespace tools { + +template +using void_t = void; + +namespace detail { + +template class Op, typename... Args> +struct detector +{ + using value_t = boost::math::false_type; + using type = Default; +}; + +template class Op, typename... Args> +struct detector>, Op, Args...> +{ + using value_t = boost::math::true_type; + using type = Op; +}; + +} // Namespace detail + +// Special type to indicate detection failure +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(const nonesuch&) = delete; + void operator=(const nonesuch&) = delete; +}; + +template class Op, typename... Args> +using is_detected = typename detail::detector::value_t; + +template class Op, typename... Args> +using detected_t = typename detail::detector::type; + +template class Op, typename... Args> +using detected_or = detail::detector; + +}}} // Namespaces boost math tools + +#endif // BOOST_MATH_TOOLS_IS_DETECTED_HPP diff --git a/third-party/boost-math/include/boost/math/tools/is_standalone.hpp b/third-party/boost-math/include/boost/math/tools/is_standalone.hpp new file mode 100644 index 0000000000000..343bbc20af03b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/is_standalone.hpp @@ -0,0 +1,18 @@ +// Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_TOOLS_IS_STANDALONE_HPP +#define BOOST_MATH_TOOLS_IS_STANDALONE_HPP + +#ifdef __has_include +#if !__has_include() || !__has_include() || !__has_include() || \ + !__has_include() || !__has_include() +# ifndef BOOST_MATH_STANDALONE +# define BOOST_MATH_STANDALONE +# endif +#endif +#endif + +#endif // BOOST_MATH_TOOLS_IS_STANDALONE_HPP diff --git a/third-party/boost-math/include/boost/math/tools/luroth_expansion.hpp b/third-party/boost-math/include/boost/math/tools/luroth_expansion.hpp new file mode 100644 index 0000000000000..583b227d7a775 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/luroth_expansion.hpp @@ -0,0 +1,147 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_LUROTH_EXPANSION_HPP +#define BOOST_MATH_TOOLS_LUROTH_EXPANSION_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +namespace boost::math::tools { + +template +class luroth_expansion { +public: + luroth_expansion(Real x) : x_{x} + { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into a Luroth representation."); + } + d_.reserve(50); + Real dn1 = floor(x); + d_.push_back(static_cast(dn1)); + if (dn1 == x) + { + d_.shrink_to_fit(); + return; + } + // This attempts to follow the notation of: + // "Khinchine's constant for Luroth Representation", by Sophia Kalpazidou. + x = x - dn1; + Real computed = dn1; + Real prod = 1; + // Let the error bound grow by 1 ULP/iteration. + // I haven't done the error analysis to show that this is an expected rate of error growth, + // but if you don't do this, you can easily get into an infinite loop. + Real i = 1; + Real scale = std::numeric_limits::epsilon()*abs(x_)/2; + while (abs(x_ - computed) > (i++)*scale) + { + Real recip = 1/x; + Real dn = floor(recip); + // x = n + 1/k => lur(x) = ((n; k - 1)) + // Note that this is a bit different than Kalpazidou (examine the half-open interval of definition carefully). + // One way to examine this definition is better for rationals (it never happens for irrationals) + // is to consider i + 1/3. If you follow Kalpazidou, then you get ((i, 3, 0)); a zero digit! + // That's bad since it destroys uniqueness and also breaks the computation of the geometric mean. + if (recip == dn) { + d_.push_back(static_cast(dn - 1)); + break; + } + d_.push_back(static_cast(dn)); + Real tmp = 1/(dn+1); + computed += prod*tmp; + prod *= tmp/dn; + x = dn*(dn+1)*(x - tmp); + } + + for (size_t i = 1; i < d_.size(); ++i) + { + // Sanity check: + if (d_[i] <= 0) + { + throw std::domain_error("Found a digit <= 0; this is an error."); + } + } + d_.shrink_to_fit(); + } + + + const std::vector& digits() const { + return d_; + } + + // Under the assumption of 'randomness', this mean converges to 2.2001610580. + // See Finch, Mathematical Constants, section 1.8.1. + Real digit_geometric_mean() const { + if (d_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + Real g = 0; + for (size_t i = 1; i < d_.size(); ++i) { + g += log(static_cast(d_[i])); + } + return exp(g/(d_.size() - 1)); + } + + template + friend std::ostream& operator<<(std::ostream& out, luroth_expansion& scf); + +private: + const Real x_; + std::vector d_; +}; + + +template +std::ostream& operator<<(std::ostream& out, luroth_expansion& luroth) +{ + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(luroth.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "((" << luroth.d_.front(); + if (luroth.d_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < luroth.d_.size() -1; ++i) + { + out << luroth.d_[i] << ", "; + } + out << luroth.d_.back(); + } + out << "))"; + return out; +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/minima.hpp b/third-party/boost-math/include/boost/math/tools/minima.hpp new file mode 100644 index 0000000000000..a6be94cb2be91 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/minima.hpp @@ -0,0 +1,164 @@ +// (C) Copyright John Maddock 2006. +// 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) + + +#ifndef BOOST_MATH_TOOLS_MINIMA_HPP +#define BOOST_MATH_TOOLS_MINIMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +BOOST_MATH_GPU_ENABLED boost::math::pair brent_find_minima(F f, T min, T max, int bits, boost::math::uintmax_t& max_iter) + noexcept(BOOST_MATH_IS_FLOAT(T) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()(std::declval())) + #endif + ) +{ + BOOST_MATH_STD_USING + bits = (boost::math::min)(policies::digits >() / 2, bits); + T tolerance = static_cast(ldexp(1.0, 1-bits)); + T x; // minima so far + T w; // second best point + T v; // previous value of w + T u; // most recent evaluation point + T delta; // The distance moved in the last step + T delta2; // The distance moved in the step before last + T fu, fv, fw, fx; // function evaluations at u, v, w, x + T mid; // midpoint of min and max + T fract1, fract2; // minimal relative movement in x + + static const T golden = 0.3819660f; // golden ratio, don't need too much precision here! + + x = w = v = max; + fw = fv = fx = f(x); + delta2 = delta = 0; + + boost::math::uintmax_t count = max_iter; + + do{ + // get midpoint + mid = (min + max) / 2; + // work out if we're done already: + fract1 = tolerance * fabs(x) + tolerance / 4; + fract2 = 2 * fract1; + if(fabs(x - mid) <= (fract2 - (max - min) / 2)) + break; + + if(fabs(delta2) > fract1) + { + // try and construct a parabolic fit: + T r = (x - w) * (fx - fv); + T q = (x - v) * (fx - fw); + T p = (x - v) * q - (x - w) * r; + q = 2 * (q - r); + if(q > 0) + p = -p; + q = fabs(q); + T td = delta2; + delta2 = delta; + // determine whether a parabolic step is acceptable or not: + if((fabs(p) >= fabs(q * td / 2)) || (p <= q * (min - x)) || (p >= q * (max - x))) + { + // nope, try golden section instead + delta2 = (x >= mid) ? min - x : max - x; + delta = golden * delta2; + } + else + { + // whew, parabolic fit: + delta = p / q; + u = x + delta; + if(((u - min) < fract2) || ((max- u) < fract2)) + delta = (mid - x) < 0 ? (T)-fabs(fract1) : (T)fabs(fract1); + } + } + else + { + // golden section: + delta2 = (x >= mid) ? min - x : max - x; + delta = golden * delta2; + } + // update current position: + u = (fabs(delta) >= fract1) ? T(x + delta) : (delta > 0 ? T(x + fabs(fract1)) : T(x - fabs(fract1))); + fu = f(u); + if(fu <= fx) + { + // good new point is an improvement! + // update brackets: + if(u >= x) + min = x; + else + max = x; + // update control points: + v = w; + w = x; + x = u; + fv = fw; + fw = fx; + fx = fu; + } + else + { + // Oh dear, point u is worse than what we have already, + // even so it *must* be better than one of our endpoints: + if(u < x) + min = u; + else + max = u; + if((fu <= fw) || (w == x)) + { + // however it is at least second best: + v = w; + w = u; + fv = fw; + fw = fu; + } + else if((fu <= fv) || (v == x) || (v == w)) + { + // third best: + v = u; + fv = fu; + } + } + + }while(--count); + + max_iter -= count; + + return boost::math::make_pair(x, fx); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair brent_find_minima(F f, T min, T max, int digits) + noexcept(BOOST_MATH_IS_FLOAT(T) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()(std::declval())) + #endif + ) +{ + boost::math::uintmax_t m = (boost::math::numeric_limits::max)(); + return brent_find_minima(f, min, max, digits, m); +} + +}}} // namespaces + +#endif + + + + diff --git a/third-party/boost-math/include/boost/math/tools/mp.hpp b/third-party/boost-math/include/boost/math/tools/mp.hpp new file mode 100644 index 0000000000000..560ae8b50017a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/mp.hpp @@ -0,0 +1,423 @@ +// Copyright Peter Dimov 2015-2021. +// Copyright Matt Borland 2021. +// 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) +// +// Template metaprogramming classes and functions to replace MPL +// Source: http://www.pdimov.com/cpp2/simple_cxx11_metaprogramming.html +// Source: https://github.com/boostorg/mp11/ + +#ifndef BOOST_MATH_TOOLS_MP +#define BOOST_MATH_TOOLS_MP + +#include +#include +#include + +namespace boost { namespace math { namespace tools { namespace meta_programming { + +// Types: +// Typelist +template +struct mp_list {}; + +// Size_t +template +using mp_size_t = boost::math::integral_constant; + +// Boolean +template +using mp_bool = boost::math::integral_constant; + +// Identity +template +struct mp_identity +{ + using type = T; +}; + +// Turns struct into quoted metafunction +template class F> +struct mp_quote_trait +{ + template + using fn = typename F::type; +}; + +namespace detail { +// Size +template +struct mp_size_impl {}; + +template class L, typename... T> // Template template parameter must use class +struct mp_size_impl> +{ + using type = boost::math::integral_constant; +}; +} + +template +using mp_size = typename detail::mp_size_impl::type; + +namespace detail { +// Front +template +struct mp_front_impl {}; + +template class L, typename T1, typename... T> +struct mp_front_impl> +{ + using type = T1; +}; +} + +template +using mp_front = typename detail::mp_front_impl::type; + +namespace detail { +// At +// TODO - Use tree based lookup for larger typelists +// http://odinthenerd.blogspot.com/2017/04/tree-based-lookup-why-kvasirmpl-is.html +template +struct mp_at_c {}; + +template class L, typename T0, typename... T> +struct mp_at_c, 0> +{ + using type = T0; +}; + +template class L, typename T0, typename T1, typename... T> +struct mp_at_c, 1> +{ + using type = T1; +}; + +template class L, typename T0, typename T1, typename T2, typename... T> +struct mp_at_c, 2> +{ + using type = T2; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename... T> +struct mp_at_c, 3> +{ + using type = T3; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename... T> +struct mp_at_c, 4> +{ + using type = T4; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename... T> +struct mp_at_c, 5> +{ + using type = T5; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename... T> +struct mp_at_c, 6> +{ + using type = T6; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename... T> +struct mp_at_c, 7> +{ + using type = T7; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename... T> +struct mp_at_c, 8> +{ + using type = T8; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename... T> +struct mp_at_c, 9> +{ + using type = T9; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename... T> +struct mp_at_c, 10> +{ + using type = T10; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename T11, typename... T> +struct mp_at_c, 11> +{ + using type = T11; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename... T> +struct mp_at_c, 12> +{ + using type = T12; +}; +} + +template +using mp_at_c = typename detail::mp_at_c::type; + +template +using mp_at = typename detail::mp_at_c::type; + +// Back +template +using mp_back = mp_at_c::value - 1>; + +namespace detail { +// Push back +template +struct mp_push_back_impl {}; + +template class L, typename... U, typename... T> +struct mp_push_back_impl, T...> +{ + using type = L; +}; +} + +template +using mp_push_back = typename detail::mp_push_back_impl::type; + +namespace detail { +// Push front +template +struct mp_push_front_impl {}; + +template class L, typename... U, typename... T> +struct mp_push_front_impl, T...> +{ + using type = L; +}; +} + +template +using mp_push_front = typename detail::mp_push_front_impl::type; + +namespace detail{ +// If +template +struct mp_if_c_impl{}; + +template +struct mp_if_c_impl +{ + using type = T; +}; + +template +struct mp_if_c_impl +{ + using type = E; +}; +} + +template +using mp_if_c = typename detail::mp_if_c_impl::type; + +template +using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; + +namespace detail { +// Find if +template class P> +struct mp_find_if_impl {}; + +template class L, template class P> +struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class P> +struct mp_find_if_impl_2 +{ + using r = typename mp_find_if_impl::type; + using type = mp_size_t<1 + r::value>; +}; + +template class L, typename T1, typename... T, template class P> +struct mp_find_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_if_impl_2, P>>::type; +}; +} + +template class P> +using mp_find_if = typename detail::mp_find_if_impl::type; + +template +using mp_find_if_q = mp_find_if; + +namespace detail { +// Append +template +struct mp_append_impl {}; + +template<> +struct mp_append_impl<> +{ + using type = mp_list<>; +}; + +template class L, typename... T> +struct mp_append_impl> +{ + using type = L; +}; + +template class L1, typename... T1, template class L2, typename... T2> +struct mp_append_impl, L2> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3> +struct mp_append_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3, template class L4, typename... T4> +struct mp_append_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3, template class L4, typename... T4, + template class L5, typename... T5, typename... Lr> +struct mp_append_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename mp_append_impl, Lr...>::type; +}; +} + +template +using mp_append = typename detail::mp_append_impl::type; + +namespace detail { +// Remove if +template class P> +struct mp_remove_if_impl{}; + +template class L, typename... T, template class P> +struct mp_remove_if_impl, P> +{ + template + struct _f + { + using type = mp_if, mp_list<>, mp_list>; + }; + + using type = mp_append, typename _f::type...>; +}; +} + +template class P> +using mp_remove_if = typename detail::mp_remove_if_impl::type; + +template +using mp_remove_if_q = mp_remove_if; + +template +struct integer_sequence {}; + +template +using index_sequence = integer_sequence; + +namespace detail { + +template +struct iseq_if_c_impl {}; + +template +struct iseq_if_c_impl +{ + using type = T; +}; + +template +struct iseq_if_c_impl +{ + using type = F; +}; + +template +using iseq_if_c = typename iseq_if_c_impl::type; + +template +struct iseq_identity +{ + using type = T; +}; + +template +struct append_integer_sequence {}; + +template +struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence; +}; + +template +struct make_integer_sequence_impl; + +template +class make_integer_sequence_impl_ +{ +private: + static_assert(N >= 0, "N must not be negative"); + + static constexpr T M = N / 2; + static constexpr T R = N % 2; + + using seq1 = typename make_integer_sequence_impl::type; + using seq2 = typename append_integer_sequence::type; + using seq3 = typename make_integer_sequence_impl::type; + using seq4 = typename append_integer_sequence::type; + +public: + using type = seq4; +}; + +template +struct make_integer_sequence_impl +{ + using type = typename iseq_if_c>, + iseq_if_c>, + make_integer_sequence_impl_>>::type; +}; + +} // namespace detail + +template +using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +template +using make_index_sequence = make_integer_sequence; + +template +using index_sequence_for = make_integer_sequence; + +}}}} // namespaces + +#endif // BOOST_MATH_TOOLS_MP diff --git a/third-party/boost-math/include/boost/math/tools/norms.hpp b/third-party/boost-math/include/boost/math/tools/norms.hpp new file mode 100644 index 0000000000000..3be45f14c4f4d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/norms.hpp @@ -0,0 +1,638 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_NORMS_HPP +#define BOOST_MATH_TOOLS_NORMS_HPP +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + + +namespace boost::math::tools { + +// Mallat, "A Wavelet Tour of Signal Processing", equation 2.60: +template +auto total_variation(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "At least two samples are required to compute the total variation."); + auto it = first; + if constexpr (std::is_unsigned::value) + { + T tmp = *it; + double tv = 0; + while (++it != last) + { + if (*it > tmp) + { + tv += *it - tmp; + } + else + { + tv += tmp - *it; + } + tmp = *it; + } + return tv; + } + else if constexpr (std::is_integral::value) + { + double tv = 0; + double tmp = *it; + while(++it != last) + { + double tmp2 = *it; + tv += abs(tmp2 - tmp); + tmp = *it; + } + return tv; + } + else + { + T tmp = *it; + T tv = 0; + while (++it != last) + { + tv += abs(*it - tmp); + tmp = *it; + } + return tv; + } +} + +template +inline auto total_variation(Container const & v) +{ + return total_variation(v.cbegin(), v.cend()); +} + + +template +auto sup_norm(ForwardIterator first, ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one value is required to compute the sup norm."); + using T = typename std::iterator_traits::value_type; + using std::abs; + if constexpr (boost::math::tools::is_complex_type::value) + { + auto it = std::max_element(first, last, [](T a, T b) { return abs(b) > abs(a); }); + return abs(*it); + } + else if constexpr (std::is_unsigned::value) + { + return *std::max_element(first, last); + } + else + { + auto pair = std::minmax_element(first, last); + if (abs(*pair.first) > abs(*pair.second)) + { + return abs(*pair.first); + } + else + { + return abs(*pair.second); + } + } +} + +template +inline auto sup_norm(Container const & v) +{ + return sup_norm(v.cbegin(), v.cend()); +} + +template +auto l1_norm(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + if constexpr (std::is_unsigned::value) + { + double l1 = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + } + return l1; + } + else if constexpr (std::is_integral::value) + { + double l1 = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + l1 += abs(tmp); + } + return l1; + } + else + { + decltype(abs(*first)) l1 = 0; + for (auto it = first; it != last; ++it) + { + l1 += abs(*it); + } + return l1; + } + +} + +template +inline auto l1_norm(Container const & v) +{ + return l1_norm(v.cbegin(), v.cend()); +} + + +template +auto l2_norm(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + if constexpr (boost::math::tools::is_complex_type::value) + { + typedef typename T::value_type Real; + Real l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += norm(*it); + } + Real result = sqrt(l2); + if (!isfinite(result)) + { + Real a = sup_norm(first, last); + l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += norm(*it/a); + } + return a*sqrt(l2); + } + return result; + } + else if constexpr (is_floating_point::value || + std::numeric_limits::max_exponent) + { + T l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += (*it)*(*it); + } + T result = sqrt(l2); + // Higham, Accuracy and Stability of Numerical Algorithms, + // Problem 27.5 presents a different algorithm to deal with overflow. + // The algorithm used here takes 3 passes *if* there is overflow. + // Higham's algorithm is 1 pass, but more requires operations than the no overflow case. + // I'm operating under the assumption that overflow is rare since the dynamic range of floating point numbers is huge. + if (!isfinite(result)) + { + T a = sup_norm(first, last); + l2 = 0; + for (auto it = first; it != last; ++it) + { + T tmp = *it/a; + l2 += tmp*tmp; + } + return a*sqrt(l2); + } + return result; + } + else + { + double l2 = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + l2 += tmp*tmp; + } + return sqrt(l2); + } +} + +template +inline auto l2_norm(Container const & v) +{ + return l2_norm(v.cbegin(), v.cend()); +} + +template +size_t l0_pseudo_norm(ForwardIterator first, ForwardIterator last) +{ + using RealOrComplex = typename std::iterator_traits::value_type; + size_t count = 0; + for (auto it = first; it != last; ++it) + { + if (*it != RealOrComplex(0)) + { + ++count; + } + } + return count; +} + +template +inline size_t l0_pseudo_norm(Container const & v) +{ + return l0_pseudo_norm(v.cbegin(), v.cend()); +} + +template +size_t hamming_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + size_t count = 0; + auto it1 = first1; + auto it2 = first2; + while (it1 != last1) + { + if (*it1++ != *it2++) + { + ++count; + } + } + return count; +} + +template +inline size_t hamming_distance(Container const & v, Container const & w) +{ + return hamming_distance(v.cbegin(), v.cend(), w.cbegin()); +} + +template +auto lp_norm(ForwardIterator first, ForwardIterator last, unsigned p) +{ + using std::abs; + using std::pow; + using std::is_floating_point; + using std::isfinite; + using RealOrComplex = typename std::iterator_traits::value_type; + if constexpr (boost::math::tools::is_complex_type::value) + { + using std::norm; + using Real = typename RealOrComplex::value_type; + Real lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it), p); + } + + auto result = pow(lp, Real(1)/Real(p)); + if (!isfinite(result)) + { + auto a = boost::math::tools::sup_norm(first, last); + Real lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it)/a, p); + } + result = a*pow(lp, Real(1)/Real(p)); + } + return result; + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + BOOST_MATH_ASSERT_MSG(p >= 0, "For p < 0, the lp norm is not a norm"); + RealOrComplex lp = 0; + + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it), p); + } + + RealOrComplex result = pow(lp, RealOrComplex(1)/RealOrComplex(p)); + if (!isfinite(result)) + { + RealOrComplex a = boost::math::tools::sup_norm(first, last); + lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it)/a, p); + } + result = a*pow(lp, RealOrComplex(1)/RealOrComplex(p)); + } + return result; + } + else + { + double lp = 0; + + for (auto it = first; it != last; ++it) + { + double tmp = *it; + lp += pow(abs(tmp), p); + } + double result = pow(lp, 1.0/static_cast(p)); + if (!isfinite(result)) + { + double a = boost::math::tools::sup_norm(first, last); + lp = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + lp += pow(abs(tmp)/a, p); + } + result = a*pow(lp, static_cast(1)/static_cast(p)); + } + return result; + } +} + +template +inline auto lp_norm(Container const & v, unsigned p) +{ + return lp_norm(v.cbegin(), v.cend(), p); +} + + +template +auto lp_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, unsigned p) +{ + using std::pow; + using std::abs; + using std::is_floating_point; + using std::isfinite; + using RealOrComplex = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename RealOrComplex::value_type; + using std::norm; + Real dist = 0; + while(it1 != last1) + { + auto tmp = *it1++ - *it2++; + dist += pow(abs(tmp), p); + } + return pow(dist, Real(1)/Real(p)); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + RealOrComplex dist = 0; + while(it1 != last1) + { + auto tmp = *it1++ - *it2++; + dist += pow(abs(tmp), p); + } + return pow(dist, RealOrComplex(1)/RealOrComplex(p)); + } + else + { + double dist = 0; + while(it1 != last1) + { + double tmp1 = *it1++; + double tmp2 = *it2++; + // Naively you'd expect the integer subtraction to be faster, + // but this can overflow or wraparound: + //double tmp = *it1++ - *it2++; + dist += pow(abs(tmp1 - tmp2), p); + } + return pow(dist, 1.0/static_cast(p)); + } +} + +template +inline auto lp_distance(Container const & v, Container const & w, unsigned p) +{ + return lp_distance(v.cbegin(), v.cend(), w.cbegin(), p); +} + + +template +auto l1_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sum = 0; + while (it1 != last1) { + sum += abs(*it1++ - *it2++); + } + return sum; + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sum = 0; + while (it1 != last1) + { + sum += abs(*it1++ - *it2++); + } + return sum; + } + else if constexpr (std::is_unsigned::value) + { + double sum = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + if (x1 > x2) + { + sum += (x1 - x2); + } + else + { + sum += (x2 - x1); + } + } + return sum; + } + else if constexpr (std::is_integral::value) + { + double sum = 0; + while(it1 != last1) + { + double x1 = *it1++; + double x2 = *it2++; + sum += abs(x1-x2); + } + return sum; + } + else + { + BOOST_MATH_ASSERT_MSG(false, "Could not recognize type."); + } + +} + +template +auto l1_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "L1 distance requires both containers to have the same number of elements"); + return l1_distance(v.cbegin(), v.cend(), w.begin()); +} + +template +auto l2_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sum = 0; + while (it1 != last1) { + sum += norm(*it1++ - *it2++); + } + return sqrt(sum); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sum = 0; + while (it1 != last1) + { + T tmp = *it1++ - *it2++; + sum += tmp*tmp; + } + return sqrt(sum); + } + else if constexpr (std::is_unsigned::value) + { + double sum = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + if (x1 > x2) + { + double tmp = x1-x2; + sum += tmp*tmp; + } + else + { + double tmp = x2 - x1; + sum += tmp*tmp; + } + } + return sqrt(sum); + } + else + { + double sum = 0; + while(it1 != last1) + { + double x1 = *it1++; + double x2 = *it2++; + double tmp = x1-x2; + sum += tmp*tmp; + } + return sqrt(sum); + } +} + +template +auto l2_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "L2 distance requires both containers to have the same number of elements"); + return l2_distance(v.cbegin(), v.cend(), w.begin()); +} + +template +auto sup_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sup_sq = 0; + while (it1 != last1) { + Real tmp = norm(*it1++ - *it2++); + if (tmp > sup_sq) { + sup_sq = tmp; + } + } + return sqrt(sup_sq); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sup = 0; + while (it1 != last1) + { + T tmp = *it1++ - *it2++; + if (sup < abs(tmp)) + { + sup = abs(tmp); + } + } + return sup; + } + else // integral values: + { + double sup = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + double tmp; + if (x1 > x2) + { + tmp = x1-x2; + } + else + { + tmp = x2 - x1; + } + if (sup < tmp) { + sup = tmp; + } + } + return sup; + } +} + +template +auto sup_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "sup distance requires both containers to have the same number of elements"); + return sup_distance(v.cbegin(), v.cend(), w.begin()); +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/nothrow.hpp b/third-party/boost-math/include/boost/math/tools/nothrow.hpp new file mode 100644 index 0000000000000..20bb5fa163b0d --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/nothrow.hpp @@ -0,0 +1,27 @@ +// (C) Copyright Antony Polukhin 2022. +// 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) + +#ifndef BOOST_MATH_TOOLS_NOTHROW_HPP +#define BOOST_MATH_TOOLS_NOTHROW_HPP + +#include + +#ifndef BOOST_MATH_STANDALONE + +#include + +#define BOOST_MATH_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW + +#else // Standalone mode - use noexcept or throw() + +#if __cplusplus >= 201103L +#define BOOST_MATH_NOTHROW noexcept +#else +#define BOOST_MATH_NOTHROW throw() +#endif + +#endif + +#endif // BOOST_MATH_TOOLS_NOTHROW_HPP diff --git a/third-party/boost-math/include/boost/math/tools/numeric_limits.hpp b/third-party/boost-math/include/boost/math/tools/numeric_limits.hpp new file mode 100644 index 0000000000000..87a7802363dd8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/numeric_limits.hpp @@ -0,0 +1,888 @@ +// Copyright (c) 2024 Matt Borland +// 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) +// +// Regular use of std::numeric_limits functions can not be used on +// GPU platforms like CUDA since they are missing the __device__ marker +// and libcu++ does not provide something analogous. +// Rather than using giant if else blocks make our own version of numeric limits +// +// On the CUDA NVRTC platform we use a best attempt at emulating the functions +// and values since we do not have any macros to go off of. +// Use the values as found on GCC 11.4 RHEL 9.4 x64 + +#ifndef BOOST_MATH_TOOLS_NUMERIC_LIMITS_HPP +#define BOOST_MATH_TOOLS_NUMERIC_LIMITS_HPP + +#include + +#ifndef BOOST_MATH_HAS_NVRTC + +#include +#include +#include +#include + +#endif + +namespace boost { +namespace math { + +template +struct numeric_limits +#ifndef BOOST_MATH_HAS_NVRTC +: public std::numeric_limits {}; +#else +{}; +#endif + +#if defined(BOOST_MATH_HAS_GPU_SUPPORT) && !defined(BOOST_MATH_HAS_NVRTC) + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float (min) () { return FLT_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float (max) () { return FLT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float lowest () { return -FLT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float epsilon () { return FLT_EPSILON; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float round_error () { return 0.5F; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float infinity () { return static_cast(INFINITY); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float quiet_NaN () { return static_cast(NAN); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float signaling_NaN () + { + #ifdef FLT_SNAN + return FLT_SNAN; + #else + return static_cast(NAN); + #endif + } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float denorm_min () { return FLT_TRUE_MIN; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double (min) () { return DBL_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double (max) () { return DBL_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double lowest () { return -DBL_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double epsilon () { return DBL_EPSILON; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double round_error () { return 0.5; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double infinity () { return static_cast(INFINITY); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double quiet_NaN () { return static_cast(NAN); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double signaling_NaN () + { + #ifdef DBL_SNAN + return DBL_SNAN; + #else + return static_cast(NAN); + #endif + } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double denorm_min () { return DBL_TRUE_MIN; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short (min) () { return SHRT_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short (max) () { return SHRT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short lowest () { return SHRT_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short (max) () { return USHRT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int (min) () { return INT_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int (max) () { return INT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int lowest () { return INT_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int (max) () { return UINT_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long (min) () { return LONG_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long (max) () { return LONG_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long lowest () { return LONG_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long (max) () { return ULONG_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long (min) () { return LLONG_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long (max) () { return LLONG_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long lowest () { return LLONG_MIN; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long (max) () { return ULLONG_MAX; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = std::numeric_limits::is_specialized; + BOOST_MATH_STATIC constexpr bool is_signed = std::numeric_limits::is_signed; + BOOST_MATH_STATIC constexpr bool is_integer = std::numeric_limits::is_integer; + BOOST_MATH_STATIC constexpr bool is_exact = std::numeric_limits::is_exact; + BOOST_MATH_STATIC constexpr bool has_infinity = std::numeric_limits::has_infinity; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = std::numeric_limits::has_quiet_NaN; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = std::numeric_limits::has_signaling_NaN; + + BOOST_MATH_STATIC constexpr std::float_round_style round_style = std::numeric_limits::round_style; + BOOST_MATH_STATIC constexpr bool is_iec559 = std::numeric_limits::is_iec559; + BOOST_MATH_STATIC constexpr bool is_bounded = std::numeric_limits::is_bounded; + BOOST_MATH_STATIC constexpr bool is_modulo = std::numeric_limits::is_modulo; + BOOST_MATH_STATIC constexpr int digits = std::numeric_limits::digits; + BOOST_MATH_STATIC constexpr int digits10 = std::numeric_limits::digits10; + BOOST_MATH_STATIC constexpr int max_digits10 = std::numeric_limits::max_digits10; + BOOST_MATH_STATIC constexpr int radix = std::numeric_limits::radix; + BOOST_MATH_STATIC constexpr int min_exponent = std::numeric_limits::min_exponent; + BOOST_MATH_STATIC constexpr int min_exponent10 = std::numeric_limits::min_exponent10; + BOOST_MATH_STATIC constexpr int max_exponent = std::numeric_limits::max_exponent; + BOOST_MATH_STATIC constexpr int max_exponent10 = std::numeric_limits::max_exponent10; + BOOST_MATH_STATIC constexpr bool traps = std::numeric_limits::traps; + BOOST_MATH_STATIC constexpr bool tinyness_before = std::numeric_limits::tinyness_before; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool (min) () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool (max) () { return true; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool lowest () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool epsilon () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool round_error () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool infinity () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool quiet_NaN () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool signaling_NaN () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool denorm_min () { return false; } +}; + +#elif defined(BOOST_MATH_HAS_NVRTC) // Pure NVRTC support - Removes rounding style and approximates the traits + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = false; + BOOST_MATH_STATIC constexpr bool is_exact = false; + BOOST_MATH_STATIC constexpr bool has_infinity = true; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = true; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = true; + + BOOST_MATH_STATIC constexpr bool is_iec559 = true; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 24; + BOOST_MATH_STATIC constexpr int digits10 = 6; + BOOST_MATH_STATIC constexpr int max_digits10 = 9; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = -125; + BOOST_MATH_STATIC constexpr int min_exponent10 = -37; + BOOST_MATH_STATIC constexpr int max_exponent = 128; + BOOST_MATH_STATIC constexpr int max_exponent10 = 38; + BOOST_MATH_STATIC constexpr bool traps = false; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float (min) () { return 1.17549435e-38F; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float (max) () { return 3.40282347e+38F; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float lowest () { return -3.40282347e+38F; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float epsilon () { return 1.1920929e-07; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float round_error () { return 0.5F; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float infinity () { return __int_as_float(0x7f800000); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float quiet_NaN () { return __int_as_float(0x7fc00000); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float signaling_NaN () { return __int_as_float(0x7fa00000); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr float denorm_min () { return 1.4013e-45F; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = false; + BOOST_MATH_STATIC constexpr bool is_exact = false; + BOOST_MATH_STATIC constexpr bool has_infinity = true; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = true; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = true; + + BOOST_MATH_STATIC constexpr bool is_iec559 = true; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 53; + BOOST_MATH_STATIC constexpr int digits10 = 15; + BOOST_MATH_STATIC constexpr int max_digits10 = 21; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = -1021; + BOOST_MATH_STATIC constexpr int min_exponent10 = -307; + BOOST_MATH_STATIC constexpr int max_exponent = 1024; + BOOST_MATH_STATIC constexpr int max_exponent10 = 308; + BOOST_MATH_STATIC constexpr bool traps = false; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double (min) () { return 2.2250738585072014e-308; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double (max) () { return 1.7976931348623157e+308; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double lowest () { return -1.7976931348623157e+308; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double epsilon () { return 2.2204460492503131e-16; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double round_error () { return 0.5; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double infinity () { return __longlong_as_double(0x7ff0000000000000ULL); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double quiet_NaN () { return __longlong_as_double(0x7ff8000000000000ULL); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double signaling_NaN () { return __longlong_as_double(0x7ff4000000000000ULL); } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr double denorm_min () { return 4.9406564584124654e-324; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 15; + BOOST_MATH_STATIC constexpr int digits10 = 4; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short (min) () { return -32768; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short (max) () { return 32767; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short lowest () { return -32768; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr short denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = false; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = true; + BOOST_MATH_STATIC constexpr int digits = 16; + BOOST_MATH_STATIC constexpr int digits10 = 4; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short (max) () { return 65535U; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned short denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 31; + BOOST_MATH_STATIC constexpr int digits10 = 9; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int (min) () { return -2147483648; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int (max) () { return 2147483647; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int lowest () { return -2147483648; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr int denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = false; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = true; + BOOST_MATH_STATIC constexpr int digits = 32; + BOOST_MATH_STATIC constexpr int digits10 = 9; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int (max) () { return 4294967295U; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned int denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 63; + BOOST_MATH_STATIC constexpr int digits10 = 18; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long (min) () { return -9223372036854775808L; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long (max) () { return 9223372036854775807L; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long lowest () { return -9223372036854775808L; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = false; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = true; + BOOST_MATH_STATIC constexpr int digits = 64; + BOOST_MATH_STATIC constexpr int digits10 = 19; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long (max) () { return 18446744073709551615UL; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = true; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 63; + BOOST_MATH_STATIC constexpr int digits10 = 18; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long (min) () { return -9223372036854775808LL; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long (max) () { return 9223372036854775807LL; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long lowest () { return -9223372036854775808LL; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr long long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = false; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = true; + BOOST_MATH_STATIC constexpr int digits = 64; + BOOST_MATH_STATIC constexpr int digits10 = 19; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = true; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long (min) () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long (max) () { return 18446744073709551615UL; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long lowest () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long epsilon () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long round_error () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long infinity () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long quiet_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long signaling_NaN () { return 0; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr unsigned long long denorm_min () { return 0; } +}; + +template <> +struct numeric_limits +{ + BOOST_MATH_STATIC constexpr bool is_specialized = true; + BOOST_MATH_STATIC constexpr bool is_signed = false; + BOOST_MATH_STATIC constexpr bool is_integer = true; + BOOST_MATH_STATIC constexpr bool is_exact = true; + BOOST_MATH_STATIC constexpr bool has_infinity = false; + BOOST_MATH_STATIC constexpr bool has_quiet_NaN = false; + BOOST_MATH_STATIC constexpr bool has_signaling_NaN = false; + + BOOST_MATH_STATIC constexpr bool is_iec559 = false; + BOOST_MATH_STATIC constexpr bool is_bounded = true; + BOOST_MATH_STATIC constexpr bool is_modulo = false; + BOOST_MATH_STATIC constexpr int digits = 1; + BOOST_MATH_STATIC constexpr int digits10 = 0; + BOOST_MATH_STATIC constexpr int max_digits10 = 0; + BOOST_MATH_STATIC constexpr int radix = 2; + BOOST_MATH_STATIC constexpr int min_exponent = 0; + BOOST_MATH_STATIC constexpr int min_exponent10 = 0; + BOOST_MATH_STATIC constexpr int max_exponent = 0; + BOOST_MATH_STATIC constexpr int max_exponent10 = 0; + BOOST_MATH_STATIC constexpr bool traps = false; + BOOST_MATH_STATIC constexpr bool tinyness_before = false; + + // Member Functions + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool (min) () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool (max) () { return true; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool lowest () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool epsilon () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool round_error () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool infinity () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool quiet_NaN () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool signaling_NaN () { return false; } + BOOST_MATH_GPU_ENABLED BOOST_MATH_STATIC constexpr bool denorm_min () { return false; } +}; + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +} // namespace math +} // namespace boost + +#endif diff --git a/third-party/boost-math/include/boost/math/tools/numerical_differentiation.hpp b/third-party/boost-math/include/boost/math/tools/numerical_differentiation.hpp new file mode 100644 index 0000000000000..2bdda70a6c117 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/numerical_differentiation.hpp @@ -0,0 +1,12 @@ +// (C) Copyright Nick Thompson 2018. +// 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) +#ifndef BOOST_MATH_TOOLS_NUMERICAL_DIFFERENTIATION_HPP +#define BOOST_MATH_TOOLS_NUMERICAL_DIFFERENTIATION_HPP +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +#endif diff --git a/third-party/boost-math/include/boost/math/tools/polynomial.hpp b/third-party/boost-math/include/boost/math/tools/polynomial.hpp new file mode 100644 index 0000000000000..5d395cdbed1a1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/polynomial.hpp @@ -0,0 +1,862 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Jeremy William Murphy 2015. + + +// 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) + +#ifndef BOOST_MATH_TOOLS_POLYNOMIAL_HPP +#define BOOST_MATH_TOOLS_POLYNOMIAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +BOOST_MATH_GPU_ENABLED T chebyshev_coefficient(unsigned n, unsigned m) +{ + BOOST_MATH_STD_USING + if(m > n) + return 0; + if((n & 1) != (m & 1)) + return 0; + if(n == 0) + return 1; + T result = T(n) / 2; + unsigned r = n - m; + r /= 2; + + BOOST_MATH_ASSERT(n - 2 * r == m); + + if(r & 1) + result = -result; + result /= n - r; + result *= boost::math::binomial_coefficient(n - r, r); + result *= ldexp(1.0f, m); + return result; +} + +template +BOOST_MATH_GPU_ENABLED Seq polynomial_to_chebyshev(const Seq& s) +{ + // Converts a Polynomial into Chebyshev form: + typedef typename Seq::value_type value_type; + typedef typename Seq::difference_type difference_type; + Seq result(s); + difference_type order = s.size() - 1; + difference_type even_order = order & 1 ? order - 1 : order; + difference_type odd_order = order & 1 ? order : order - 1; + + for(difference_type i = even_order; i >= 0; i -= 2) + { + value_type val = s[i]; + for(difference_type k = even_order; k > i; k -= 2) + { + val -= result[k] * chebyshev_coefficient(static_cast(k), static_cast(i)); + } + val /= chebyshev_coefficient(static_cast(i), static_cast(i)); + result[i] = val; + } + result[0] *= 2; + + for(difference_type i = odd_order; i >= 0; i -= 2) + { + value_type val = s[i]; + for(difference_type k = odd_order; k > i; k -= 2) + { + val -= result[k] * chebyshev_coefficient(static_cast(k), static_cast(i)); + } + val /= chebyshev_coefficient(static_cast(i), static_cast(i)); + result[i] = val; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED T evaluate_chebyshev(const Seq& a, const T& x) +{ + // Clenshaw's formula: + typedef typename Seq::difference_type difference_type; + T yk2 = 0; + T yk1 = 0; + T yk = 0; + for(difference_type i = a.size() - 1; i >= 1; --i) + { + yk2 = yk1; + yk1 = yk; + yk = 2 * x * yk1 - yk2 + a[i]; + } + return a[0] / 2 + yk * x - yk1; +} + + +template +class polynomial; + +namespace detail { + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Chapter 4.6.1, Algorithm D: Division of polynomials over a field. +* +* @tparam T Coefficient type, must be not be an integer. +* +* Template-parameter T actually must be a field but we don't currently have that +* subtlety of distinction. +*/ +template +BOOST_MATH_GPU_ENABLED typename std::enable_if::is_integer, void >::type +division_impl(polynomial &q, polynomial &u, const polynomial& v, N n, N k) +{ + q[k] = u[n + k] / v[n]; + for (N j = n + k; j > k;) + { + j--; + u[j] -= q[k] * v[j - k]; + } +} + +template +BOOST_MATH_GPU_ENABLED T integer_power(T t, N n) +{ + switch(n) + { + case 0: + return static_cast(1u); + case 1: + return t; + case 2: + return t * t; + case 3: + return t * t * t; + } + T result = integer_power(t, n / 2); + result *= result; + if(n & 1) + result *= t; + return result; +} + + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Chapter 4.6.1, Algorithm R: Pseudo-division of polynomials. +* +* @tparam T Coefficient type, must be an integer. +* +* Template-parameter T actually must be a unique factorization domain but we +* don't currently have that subtlety of distinction. +*/ +template +BOOST_MATH_GPU_ENABLED typename std::enable_if::is_integer, void >::type +division_impl(polynomial &q, polynomial &u, const polynomial& v, N n, N k) +{ + q[k] = u[n + k] * integer_power(v[n], k); + for (N j = n + k; j > 0;) + { + j--; + u[j] = v[n] * u[j] - (j < k ? T(0) : u[n + k] * v[j - k]); + } +} + + +/** + * Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 + * Chapter 4.6.1, Algorithm D and R: Main loop. + * + * @param u Dividend. + * @param v Divisor. + */ +template +BOOST_MATH_GPU_ENABLED std::pair< polynomial, polynomial > +division(polynomial u, const polynomial& v) +{ + BOOST_MATH_ASSERT(v.size() <= u.size()); + BOOST_MATH_ASSERT(v); + BOOST_MATH_ASSERT(u); + + typedef typename polynomial::size_type N; + + N const m = u.size() - 1, n = v.size() - 1; + N k = m - n; + polynomial q; + q.data().resize(m - n + 1); + + do + { + division_impl(q, u, v, n, k); + } + while (k-- != 0); + u.data().resize(n); + u.normalize(); // Occasionally, the remainder is zeroes. + return std::make_pair(q, u); +} + +// +// These structures are the same as the void specializations of the functors of the same name +// in the std lib from C++14 onwards: +// +struct negate +{ + template + BOOST_MATH_GPU_ENABLED T operator()(T const &x) const + { + return -x; + } +}; + +struct plus +{ + template + BOOST_MATH_GPU_ENABLED T operator()(T const &x, U const& y) const + { + return x + y; + } +}; + +struct minus +{ + template + BOOST_MATH_GPU_ENABLED T operator()(T const &x, U const& y) const + { + return x - y; + } +}; + +} // namespace detail + +/** + * Returns the zero element for multiplication of polynomials. + */ +template +BOOST_MATH_GPU_ENABLED polynomial zero_element(std::multiplies< polynomial >) +{ + return polynomial(); +} + +template +BOOST_MATH_GPU_ENABLED polynomial identity_element(std::multiplies< polynomial >) +{ + return polynomial(T(1)); +} + +/* Calculates a / b and a % b, returning the pair (quotient, remainder) together + * because the same amount of computation yields both. + * This function is not defined for division by zero: user beware. + */ +template +BOOST_MATH_GPU_ENABLED std::pair< polynomial, polynomial > +quotient_remainder(const polynomial& dividend, const polynomial& divisor) +{ + BOOST_MATH_ASSERT(divisor); + if (dividend.size() < divisor.size()) + return std::make_pair(polynomial(), dividend); + return detail::division(dividend, divisor); +} + + +template +class polynomial +{ +public: + // typedefs: + typedef typename std::vector::value_type value_type; + typedef typename std::vector::size_type size_type; + + // construct: + BOOST_MATH_GPU_ENABLED polynomial()= default; + + template + BOOST_MATH_GPU_ENABLED polynomial(const U* data, unsigned order) + : m_data(data, data + order + 1) + { + normalize(); + } + + template + BOOST_MATH_GPU_ENABLED polynomial(Iterator first, Iterator last) + : m_data(first, last) + { + normalize(); + } + + template + BOOST_MATH_GPU_ENABLED polynomial(Iterator first, unsigned length) + : m_data(first, std::next(first, length + 1)) + { + normalize(); + } + + BOOST_MATH_GPU_ENABLED polynomial(std::vector&& p) : m_data(std::move(p)) + { + normalize(); + } + + template ::value, bool>::type = true> + BOOST_MATH_GPU_ENABLED explicit polynomial(const U& point) + { + if (point != U(0)) + m_data.push_back(point); + } + + // move: + BOOST_MATH_GPU_ENABLED polynomial(polynomial&& p) noexcept + : m_data(std::move(p.m_data)) { } + + // copy: + BOOST_MATH_GPU_ENABLED polynomial(const polynomial& p) + : m_data(p.m_data) { } + + template + BOOST_MATH_GPU_ENABLED polynomial(const polynomial& p) + { + m_data.resize(p.size()); + for(unsigned i = 0; i < p.size(); ++i) + { + m_data[i] = boost::math::tools::real_cast(p[i]); + } + } +#ifdef BOOST_MATH_HAS_IS_CONST_ITERABLE + template ::value, bool>::type = true> + BOOST_MATH_GPU_ENABLED explicit polynomial(const Range& r) + : polynomial(r.begin(), r.end()) + { + } +#endif + BOOST_MATH_GPU_ENABLED polynomial(std::initializer_list l) : polynomial(std::begin(l), std::end(l)) + { + } + + polynomial& + BOOST_MATH_GPU_ENABLED operator=(std::initializer_list l) + { + m_data.assign(std::begin(l), std::end(l)); + normalize(); + return *this; + } + + + // access: + BOOST_MATH_GPU_ENABLED size_type size() const { return m_data.size(); } + BOOST_MATH_GPU_ENABLED size_type degree() const + { + if (size() == 0) + BOOST_MATH_THROW_EXCEPTION(std::logic_error("degree() is undefined for the zero polynomial.")); + return m_data.size() - 1; + } + BOOST_MATH_GPU_ENABLED value_type& operator[](size_type i) + { + return m_data[i]; + } + BOOST_MATH_GPU_ENABLED const value_type& operator[](size_type i) const + { + return m_data[i]; + } + + BOOST_MATH_GPU_ENABLED T evaluate(T z) const + { + return this->operator()(z); + } + + BOOST_MATH_GPU_ENABLED T operator()(T z) const + { + return m_data.size() > 0 ? boost::math::tools::evaluate_polynomial((m_data).data(), z, m_data.size()) : T(0); + } + BOOST_MATH_GPU_ENABLED std::vector chebyshev() const + { + return polynomial_to_chebyshev(m_data); + } + + BOOST_MATH_GPU_ENABLED std::vector const& data() const + { + return m_data; + } + + BOOST_MATH_GPU_ENABLED std::vector & data() + { + return m_data; + } + + BOOST_MATH_GPU_ENABLED polynomial prime() const + { +#ifdef _MSC_VER + // Disable int->float conversion warning: +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if (m_data.size() == 0) + { + return polynomial({}); + } + + std::vector p_data(m_data.size() - 1); + for (size_t i = 0; i < p_data.size(); ++i) { + p_data[i] = m_data[i+1]*static_cast(i+1); + } + return polynomial(std::move(p_data)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } + + BOOST_MATH_GPU_ENABLED polynomial integrate() const + { + std::vector i_data(m_data.size() + 1); + // Choose integration constant such that P(0) = 0. + i_data[0] = T(0); + for (size_t i = 1; i < i_data.size(); ++i) + { + i_data[i] = m_data[i-1]/static_cast(i); + } + return polynomial(std::move(i_data)); + } + + // operators: + BOOST_MATH_GPU_ENABLED polynomial& operator =(polynomial&& p) noexcept + { + m_data = std::move(p.m_data); + return *this; + } + + BOOST_MATH_GPU_ENABLED polynomial& operator =(const polynomial& p) + { + m_data = p.m_data; + return *this; + } + + template + BOOST_MATH_GPU_ENABLED typename std::enable_if::value, polynomial&>::type operator +=(const U& value) + { + addition(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED typename std::enable_if::value, polynomial&>::type operator -=(const U& value) + { + subtraction(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED typename std::enable_if::value, polynomial&>::type operator *=(const U& value) + { + multiplication(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED typename std::enable_if::value, polynomial&>::type operator /=(const U& value) + { + division(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED typename std::enable_if::value, polynomial&>::type operator %=(const U& /*value*/) + { + // We can always divide by a scalar, so there is no remainder: + this->set_zero(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator +=(const polynomial& value) + { + addition(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator -=(const polynomial& value) + { + subtraction(value); + normalize(); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED void multiply(const polynomial& a, const polynomial& b) { + if (!a || !b) + { + this->set_zero(); + return; + } + std::vector prod(a.size() + b.size() - 1, T(0)); + for (unsigned i = 0; i < a.size(); ++i) + for (unsigned j = 0; j < b.size(); ++j) + prod[i+j] += a.m_data[i] * b.m_data[j]; + m_data.swap(prod); + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator *=(const polynomial& value) + { + this->multiply(*this, value); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator /=(const polynomial& value) + { + *this = quotient_remainder(*this, value).first; + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator %=(const polynomial& value) + { + *this = quotient_remainder(*this, value).second; + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator >>=(U const &n) + { + BOOST_MATH_ASSERT(n <= m_data.size()); + m_data.erase(m_data.begin(), m_data.begin() + n); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& operator <<=(U const &n) + { + m_data.insert(m_data.begin(), n, static_cast(0)); + normalize(); + return *this; + } + + // Convenient and efficient query for zero. + BOOST_MATH_GPU_ENABLED bool is_zero() const + { + return m_data.empty(); + } + + // Conversion to bool. + BOOST_MATH_GPU_ENABLED inline explicit operator bool() const + { + return !m_data.empty(); + } + + // Fast way to set a polynomial to zero. + BOOST_MATH_GPU_ENABLED void set_zero() + { + m_data.clear(); + } + + /** Remove zero coefficients 'from the top', that is for which there are no + * non-zero coefficients of higher degree. */ + BOOST_MATH_GPU_ENABLED void normalize() + { + m_data.erase(std::find_if(m_data.rbegin(), m_data.rend(), [](const T& x)->bool { return x != T(0); }).base(), m_data.end()); + } + +private: + template + BOOST_MATH_GPU_ENABLED polynomial& addition(const U& value, R op) + { + if(m_data.size() == 0) + m_data.resize(1, 0); + m_data[0] = op(m_data[0], value); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& addition(const U& value) + { + return addition(value, detail::plus()); + } + + template + BOOST_MATH_GPU_ENABLED polynomial& subtraction(const U& value) + { + return addition(value, detail::minus()); + } + + template + BOOST_MATH_GPU_ENABLED polynomial& addition(const polynomial& value, R op) + { + if (m_data.size() < value.size()) + m_data.resize(value.size(), 0); + for(size_type i = 0; i < value.size(); ++i) + m_data[i] = op(m_data[i], value[i]); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& addition(const polynomial& value) + { + return addition(value, detail::plus()); + } + + template + BOOST_MATH_GPU_ENABLED polynomial& subtraction(const polynomial& value) + { + return addition(value, detail::minus()); + } + + template + BOOST_MATH_GPU_ENABLED polynomial& multiplication(const U& value) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x * value; }); + return *this; + } + + template + BOOST_MATH_GPU_ENABLED polynomial& division(const U& value) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x / value; }); + return *this; + } + + std::vector m_data; +}; + + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator + (const polynomial& a, const polynomial& b) +{ + polynomial result(a); + result += b; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator + (polynomial&& a, const polynomial& b) +{ + a += b; + return std::move(a); +} +template +BOOST_MATH_GPU_ENABLED inline polynomial operator + (const polynomial& a, polynomial&& b) +{ + b += a; + return b; +} +template +BOOST_MATH_GPU_ENABLED inline polynomial operator + (polynomial&& a, polynomial&& b) +{ + a += b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator - (const polynomial& a, const polynomial& b) +{ + polynomial result(a); + result -= b; + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator - (polynomial&& a, const polynomial& b) +{ + a -= b; + return a; +} +template +BOOST_MATH_GPU_ENABLED inline polynomial operator - (const polynomial& a, polynomial&& b) +{ + b -= a; + return -b; +} +template +BOOST_MATH_GPU_ENABLED inline polynomial operator - (polynomial&& a, polynomial&& b) +{ + a -= b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator * (const polynomial& a, const polynomial& b) +{ + polynomial result; + result.multiply(a, b); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator / (const polynomial& a, const polynomial& b) +{ + return quotient_remainder(a, b).first; +} + +template +BOOST_MATH_GPU_ENABLED inline polynomial operator % (const polynomial& a, const polynomial& b) +{ + return quotient_remainder(a, b).second; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator + (polynomial a, const U& b) +{ + a += b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator - (polynomial a, const U& b) +{ + a -= b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator * (polynomial a, const U& b) +{ + a *= b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator / (polynomial a, const U& b) +{ + a /= b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator % (const polynomial&, const U&) +{ + // Since we can always divide by a scalar, result is always an empty polynomial: + return polynomial(); +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator + (const U& a, polynomial b) +{ + b += a; + return b; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator - (const U& a, polynomial b) +{ + b -= a; + return -b; +} + +template +BOOST_MATH_GPU_ENABLED inline typename std::enable_if::value, polynomial >::type operator * (const U& a, polynomial b) +{ + b *= a; + return b; +} + +template +BOOST_MATH_GPU_ENABLED bool operator == (const polynomial &a, const polynomial &b) +{ + return a.data() == b.data(); +} + +template +BOOST_MATH_GPU_ENABLED bool operator != (const polynomial &a, const polynomial &b) +{ + return a.data() != b.data(); +} + +template +BOOST_MATH_GPU_ENABLED polynomial operator >> (polynomial a, const U& b) +{ + a >>= b; + return a; +} + +template +BOOST_MATH_GPU_ENABLED polynomial operator << (polynomial a, const U& b) +{ + a <<= b; + return a; +} + +// Unary minus (negate). +template +BOOST_MATH_GPU_ENABLED polynomial operator - (polynomial a) +{ + std::transform(a.data().begin(), a.data().end(), a.data().begin(), detail::negate()); + return a; +} + +template +BOOST_MATH_GPU_ENABLED bool odd(polynomial const &a) +{ + return a.size() > 0 && a[0] != static_cast(0); +} + +template +BOOST_MATH_GPU_ENABLED bool even(polynomial const &a) +{ + return !odd(a); +} + +template +BOOST_MATH_GPU_ENABLED polynomial pow(polynomial base, int exp) +{ + if (exp < 0) + return policies::raise_domain_error( + "boost::math::tools::pow<%1%>", + "Negative powers are not supported for polynomials.", + base, policies::policy<>()); + // if the policy is ignore_error or errno_on_error, raise_domain_error + // will return std::numeric_limits>::quiet_NaN(), which + // defaults to polynomial(), which is the zero polynomial + polynomial result(T(1)); + if (exp & 1) + result = base; + /* "Exponentiation by squaring" */ + while (exp >>= 1) + { + base *= base; + if (exp & 1) + result *= base; + } + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline std::basic_ostream& operator << (std::basic_ostream& os, const polynomial& poly) +{ + os << "{ "; + for(unsigned i = 0; i < poly.size(); ++i) + { + if(i) os << ", "; + os << poly[i]; + } + os << " }"; + return os; +} + +} // namespace tools +} // namespace math +} // namespace boost + +// +// Polynomial specific overload of gcd algorithm: +// +#include + +#endif // BOOST_MATH_TOOLS_POLYNOMIAL_HPP diff --git a/third-party/boost-math/include/boost/math/tools/polynomial_gcd.hpp b/third-party/boost-math/include/boost/math/tools/polynomial_gcd.hpp new file mode 100644 index 0000000000000..4a213e127a1e1 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/polynomial_gcd.hpp @@ -0,0 +1,268 @@ +// (C) Copyright Jeremy William Murphy 2016. +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_TOOLS_POLYNOMIAL_GCD_HPP +#define BOOST_MATH_TOOLS_POLYNOMIAL_GCD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include + +#else +#include +#include +#include +#include +#include + +namespace boost { namespace integer { + +namespace gcd_detail { + +template +inline EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) noexcept(std::is_arithmetic::value) +{ + using std::swap; + while (b != EuclideanDomain(0)) + { + a %= b; + swap(a, b); + } + return a; +} + +enum method_type +{ + method_euclid = 0, + method_binary = 1, + method_mixed = 2 +}; + +} // gcd_detail + +template ::value_type> +std::pair gcd_range(Iter first, Iter last) noexcept(std::is_arithmetic::value) +{ + BOOST_MATH_ASSERT(first != last); + + T d = *first; + ++first; + while (d != T(1) && first != last) + { + #ifdef BOOST_MATH_HAS_CXX17_NUMERIC + d = std::gcd(d, *first); + #else + d = gcd_detail::Euclid_gcd(d, *first); + #endif + ++first; + } + return std::make_pair(d, first); +} + +}} // namespace boost::integer +#endif + +namespace boost{ + + namespace integer { + + namespace gcd_detail { + + template + struct gcd_traits; + + template + struct gcd_traits > + { + inline static const boost::math::tools::polynomial& abs(const boost::math::tools::polynomial& val) { return val; } + + static const method_type method = method_euclid; + }; + + } +} + +namespace math{ namespace tools{ + +/* From Knuth, 4.6.1: +* +* We may write any nonzero polynomial u(x) from R[x] where R is a UFD as +* +* u(x) = cont(u) . pp(u(x)) +* +* where cont(u), the content of u, is an element of S, and pp(u(x)), the primitive +* part of u(x), is a primitive polynomial over S. +* When u(x) = 0, it is convenient to define cont(u) = pp(u(x)) = O. +*/ + +template +T content(polynomial const &x) +{ + return x ? boost::integer::gcd_range(x.data().begin(), x.data().end()).first : T(0); +} + +// Knuth, 4.6.1 +template +polynomial primitive_part(polynomial const &x, T const &cont) +{ + return x ? x / cont : polynomial(); +} + + +template +polynomial primitive_part(polynomial const &x) +{ + return primitive_part(x, content(x)); +} + + +// Trivial but useful convenience function referred to simply as l() in Knuth. +template +T leading_coefficient(polynomial const &x) +{ + return x ? x.data().back() : T(0); +} + + +namespace detail +{ + /* Reduce u and v to their primitive parts and return the gcd of their + * contents. Used in a couple of gcd algorithms. + */ + template + T reduce_to_primitive(polynomial &u, polynomial &v) + { + T const u_cont = content(u), v_cont = content(v); + u /= u_cont; + v /= v_cont; + + #ifdef BOOST_MATH_HAS_CXX17_NUMERIC + return std::gcd(u_cont, v_cont); + #else + return boost::integer::gcd_detail::Euclid_gcd(u_cont, v_cont); + #endif + } +} + + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Algorithm 4.6.1C: Greatest common divisor over a unique factorization domain. +* +* The subresultant algorithm by George E. Collins [JACM 14 (1967), 128-142], +* later improved by W. S. Brown and J. F. Traub [JACM 18 (1971), 505-514]. +* +* Although step C3 keeps the coefficients to a "reasonable" size, they are +* still potentially several binary orders of magnitude larger than the inputs. +* Thus, this algorithm should only be used where T is a multi-precision type. +* +* @tparam T Polynomial coefficient type. +* @param u First polynomial. +* @param v Second polynomial. +* @return Greatest common divisor of polynomials u and v. +*/ +template +typename std::enable_if< std::numeric_limits::is_integer, polynomial >::type +subresultant_gcd(polynomial u, polynomial v) +{ + using std::swap; + BOOST_MATH_ASSERT(u || v); + + if (!u) + return v; + if (!v) + return u; + + typedef typename polynomial::size_type N; + + if (u.degree() < v.degree()) + swap(u, v); + + T const d = detail::reduce_to_primitive(u, v); + T g = 1, h = 1; + polynomial r; + while (true) + { + BOOST_MATH_ASSERT(u.degree() >= v.degree()); + // Pseudo-division. + r = u % v; + if (!r) + return d * primitive_part(v); // Attach the content. + if (r.degree() == 0) + return d * polynomial(T(1)); // The content is the result. + N const delta = u.degree() - v.degree(); + // Adjust remainder. + u = v; + v = r / (g * detail::integer_power(h, delta)); + g = leading_coefficient(u); + T const tmp = detail::integer_power(g, delta); + if (delta <= N(1)) + h = tmp * detail::integer_power(h, N(1) - delta); + else + h = tmp / detail::integer_power(h, delta - N(1)); + } +} + + +/** + * @brief GCD for polynomials with unbounded multi-precision integral coefficients. + * + * The multi-precision constraint is enforced via numeric_limits. + * + * Note that intermediate terms in the evaluation can grow arbitrarily large, hence the need for + * unbounded integers, otherwise numeric overflow would break the algorithm. + * + * @tparam T A multi-precision integral type. + */ +template +typename std::enable_if::is_integer && !std::numeric_limits::is_bounded, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + return subresultant_gcd(u, v); +} +// GCD over bounded integers is not currently allowed: +template +typename std::enable_if::is_integer && std::numeric_limits::is_bounded, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + static_assert(sizeof(v) == 0, "GCD on polynomials of bounded integers is disallowed due to the excessive growth in the size of intermediate terms."); + return subresultant_gcd(u, v); +} +// GCD over polynomials of floats can go via the Euclid algorithm: +template +typename std::enable_if::is_integer && (std::numeric_limits::min_exponent != std::numeric_limits::max_exponent) && !std::numeric_limits::is_exact, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + return boost::integer::gcd_detail::Euclid_gcd(u, v); +} + +} +// +// Using declaration so we overload the default implementation in this namespace: +// +using boost::math::tools::gcd; + +} + +namespace integer +{ + // + // Using declaration so we overload the default implementation in this namespace: + // + using boost::math::tools::gcd; +} + +} // namespace boost::math::tools + +#endif diff --git a/third-party/boost-math/include/boost/math/tools/precision.hpp b/third-party/boost-math/include/boost/math/tools/precision.hpp new file mode 100644 index 0000000000000..6e863401d943b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/precision.hpp @@ -0,0 +1,418 @@ +// Copyright John Maddock 2005-2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_PRECISION_INCLUDED +#define BOOST_MATH_TOOLS_PRECISION_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#include +#include +#include +#include +#include // LDBL_MANT_DIG +#endif + +namespace boost{ namespace math +{ +namespace tools +{ +// If T is not specialized, the functions digits, max_value and min_value, +// all get synthesised automatically from std::numeric_limits. +// However, if numeric_limits is not specialised for type RealType, +// for example with NTL::RR type, then you will get a compiler error +// when code tries to use these functions, unless you explicitly specialise them. + +// For example if the precision of RealType varies at runtime, +// then numeric_limits support may not be appropriate, +// see boost/math/tools/ntl.hpp for examples like +// template <> NTL::RR max_value ... +// See Conceptual Requirements for Real Number Types. + +template +BOOST_MATH_GPU_ENABLED inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept +{ + static_assert( ::boost::math::numeric_limits::is_specialized, "Type T must be specialized"); + static_assert( ::boost::math::numeric_limits::radix == 2 || ::boost::math::numeric_limits::radix == 10, "Type T must have a radix of 2 or 10"); + + return boost::math::numeric_limits::radix == 2 + ? boost::math::numeric_limits::digits + : ((boost::math::numeric_limits::digits + 1) * 1000L) / 301L; +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + static_assert( ::boost::math::numeric_limits::is_specialized, "Type T must be specialized"); + return (boost::math::numeric_limits::max)(); +} // Also used as a finite 'infinite' value for - and +infinity, for example: +// -max_value = -1.79769e+308, max_value = 1.79769e+308. + +template +BOOST_MATH_GPU_ENABLED inline constexpr T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + static_assert( ::boost::math::numeric_limits::is_specialized, "Type T must be specialized"); + + return (boost::math::numeric_limits::min)(); +} + +namespace detail{ +// +// Logarithmic limits come next, note that although +// we can compute these from the log of the max value +// that is not in general thread safe (if we cache the value) +// so it's better to specialise these: +// +// For type float first: +// +template +BOOST_MATH_GPU_ENABLED constexpr T log_max_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return 88.0f; +} + +template +BOOST_MATH_GPU_ENABLED constexpr T log_min_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return -87.0f; +} +// +// Now double: +// +template +BOOST_MATH_GPU_ENABLED constexpr T log_max_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return 709.0; +} + +template +BOOST_MATH_GPU_ENABLED constexpr T log_min_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return -708.0; +} +// +// 80 and 128-bit long doubles: +// +template +BOOST_MATH_GPU_ENABLED inline constexpr T log_max_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return 11356.0L; +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T log_min_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return -11355.0L; +} + +template +BOOST_MATH_GPU_ENABLED inline T log_max_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + static const T m = boost::math::tools::max_value(); + static const T val = log(m); +#else + static const T val = log(boost::math::tools::max_value()); +#endif + return val; +} + +template +BOOST_MATH_GPU_ENABLED inline T log_min_value(const boost::math::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + static const T m = boost::math::tools::min_value(); + static const T val = log(m); +#else + static const T val = log(boost::math::tools::min_value()); +#endif + return val; +} + +template +BOOST_MATH_GPU_ENABLED constexpr T epsilon(const boost::math::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(boost::math::is_floating_point::value) +{ + return boost::math::numeric_limits::epsilon(); +} + +#if defined(__GNUC__) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) +template <> +BOOST_MATH_GPU_ENABLED inline constexpr long double epsilon(const boost::math::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double)) noexcept(boost::math::is_floating_point::value) +{ + // numeric_limits on Darwin (and elsewhere) tells lies here: + // the issue is that long double on a few platforms is + // really a "double double" which has a non-contiguous + // mantissa: 53 bits followed by an unspecified number of + // zero bits, followed by 53 more bits. Thus the apparent + // precision of the type varies depending where it's been. + // Set epsilon to the value that a 106 bit fixed mantissa + // type would have, as that will give us sensible behaviour everywhere. + // + // This static assert fails for some unknown reason, so + // disabled for now... + // static_assert(std::numeric_limits::digits == 106); + return 2.4651903288156618919116517665087e-32L; +} +#endif + +template +BOOST_MATH_GPU_ENABLED inline T epsilon(const boost::math::false_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + // Note: don't cache result as precision may vary at runtime: + BOOST_MATH_STD_USING // for ADL of std names + return ldexp(static_cast(1), 1-policies::digits >()); +} + +template +struct log_limit_traits +{ + typedef typename boost::math::conditional< + (boost::math::numeric_limits::radix == 2) && + ( + ( boost::math::numeric_limits::max_exponent == 128 + || boost::math::numeric_limits::max_exponent == 1024 + || boost::math::numeric_limits::max_exponent == 16384 + ) + && (-boost::math::numeric_limits::min_exponent10 + 1 == boost::math::numeric_limits::max_exponent10) + ), + boost::math::integral_constant::max_exponent > (boost::math::numeric_limits::max)() ? (boost::math::numeric_limits::max)() : static_cast(boost::math::numeric_limits::max_exponent))>, + boost::math::integral_constant + >::type tag_type; + static constexpr bool value = (tag_type::value != 0); + static_assert(::boost::math::numeric_limits::is_specialized || !value, "Type T must be specialized or equal to 0"); +}; + +template struct log_limit_noexcept_traits_imp : public log_limit_traits {}; +template struct log_limit_noexcept_traits_imp : public boost::math::integral_constant {}; + +template +struct log_limit_noexcept_traits : public log_limit_noexcept_traits_imp::value> {}; + +} // namespace detail + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4309) +#endif + +template +BOOST_MATH_GPU_ENABLED inline T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits::value) +{ +#ifndef BOOST_MATH_HAS_NVRTC + #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::log_max_value(typename detail::log_limit_traits::tag_type()); + #else + BOOST_MATH_ASSERT(::boost::math::numeric_limits::is_specialized); + BOOST_MATH_STD_USING + static const T val = log((boost::math::numeric_limits::max)()); + return val; + #endif +#else + return log((boost::math::numeric_limits::max)()); +#endif +} + +template +BOOST_MATH_GPU_ENABLED inline T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits::value) +{ +#ifndef BOOST_MATH_HAS_NVRTC + #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::log_min_value(typename detail::log_limit_traits::tag_type()); + #else + BOOST_MATH_ASSERT(::boost::math::numeric_limits::is_specialized); + BOOST_MATH_STD_USING + static const T val = log((boost::math::numeric_limits::min)()); + return val; + #endif +#else + return log((boost::math::numeric_limits::min)()); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +BOOST_MATH_GPU_ENABLED constexpr T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept(boost::math::is_floating_point::value) +{ + // NVRTC does not like this dispatching method so we just skip to where we want to go +#ifndef BOOST_MATH_HAS_NVRTC + #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::epsilon(boost::math::integral_constant::is_specialized>()); + #else + return ::boost::math::numeric_limits::is_specialized ? + detail::epsilon(boost::math::true_type()) : + detail::epsilon(boost::math::false_type()); + #endif +#else + return boost::math::numeric_limits::epsilon(); +#endif +} + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED inline constexpr T root_epsilon_imp(const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.00034526698300124390839884978618400831996329879769945L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.1490116119384765625e-7L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.32927225399135962333569506281281311031656150598474e-9L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.1387778780781445675529539585113525390625e-16L); +} + +template +BOOST_MATH_GPU_ENABLED inline T root_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING + BOOST_MATH_STATIC_LOCAL_VARIABLE const T r_eps = sqrt(tools::epsilon()); + return r_eps; +} + +template +BOOST_MATH_GPU_ENABLED inline T root_epsilon_imp(const T*, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + return sqrt(tools::epsilon()); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T cbrt_epsilon_imp(const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.0049215666011518482998719164346805794944150447839903L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T cbrt_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(6.05545445239333906078989272793696693569753008995e-6L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T cbrt_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(4.76837158203125e-7L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T cbrt_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(5.7749313854154005630396773604745549542403508090496e-12L); +} + +template +BOOST_MATH_GPU_ENABLED inline T cbrt_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING; + static const T cbrt_eps = pow(tools::epsilon(), T(1) / 3); + return cbrt_eps; +} + +template +BOOST_MATH_GPU_ENABLED inline T cbrt_epsilon_imp(const T*, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING; + return pow(tools::epsilon(), T(1) / 3); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T forth_root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.018581361171917516667460937040007436176452688944747L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T forth_root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.0001220703125L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T forth_root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.18145860519450699870567321328132261891067079047605e-4L); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T forth_root_epsilon_imp(const T*, const boost::math::integral_constant&) noexcept(boost::math::is_floating_point::value) +{ + return static_cast(0.37252902984619140625e-8L); +} + +template +BOOST_MATH_GPU_ENABLED inline T forth_root_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING + static const T r_eps = sqrt(sqrt(tools::epsilon())); + return r_eps; +} + +template +BOOST_MATH_GPU_ENABLED inline T forth_root_epsilon_imp(const T*, const boost::math::integral_constant&) +{ + BOOST_MATH_STD_USING + return sqrt(sqrt(tools::epsilon())); +} + +template +struct root_epsilon_traits +{ + typedef boost::math::integral_constant::radix == 2) && (::boost::math::numeric_limits::digits != (boost::math::numeric_limits::max)()) ? boost::math::numeric_limits::digits : 0> tag_type; + static constexpr bool has_noexcept = (tag_type::value == 113) || (tag_type::value == 64) || (tag_type::value == 53) || (tag_type::value == 24); +}; + +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T root_epsilon() noexcept(boost::math::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::root_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T cbrt_epsilon() noexcept(boost::math::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::cbrt_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +template +BOOST_MATH_GPU_ENABLED inline constexpr T forth_root_epsilon() noexcept(boost::math::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::forth_root_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_PRECISION_INCLUDED + diff --git a/third-party/boost-math/include/boost/math/tools/promotion.hpp b/third-party/boost-math/include/boost/math/tools/promotion.hpp new file mode 100644 index 0000000000000..a65f3703f44f4 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/promotion.hpp @@ -0,0 +1,135 @@ +// boost\math\tools\promotion.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2006. +// Copyright Matt Borland 2023. +// Copyright Ryan Elandt 2023. + +// 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) + +// Promote arguments functions to allow math functions to have arguments +// provided as integer OR real (floating-point, built-in or UDT) +// (called ArithmeticType in functions that use promotion) +// that help to reduce the risk of creating multiple instantiations. +// Allows creation of an inline wrapper that forwards to a foo(RT, RT) function, +// so you never get to instantiate any mixed foo(RT, IT) functions. + +#ifndef BOOST_MATH_PROMOTION_HPP +#define BOOST_MATH_PROMOTION_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost +{ + namespace math + { + namespace tools + { + ///// This promotion system works as follows: + // + // Rule (one argument promotion rule): + // - Promotes `T` to `double` if `T` is an integer type as identified by + // `std::is_integral`, otherwise is `T` + // + // Rule (two or more argument promotion rule): + // - 1. Calculates type using applying Rule. + // - 2. Calculates type using applying Rule + // - If the type calculated in 1 and 2 are both floating point types, as + // identified by `std::is_floating_point`, then return the type + // determined by `std::common_type`. Otherwise return the type using + // an asymmetric convertibility rule. + // + ///// Discussion: + // + // If either T1 or T2 is an integer type, + // pretend it was a double (for the purposes of further analysis). + // Then pick the wider of the two floating-point types + // as the actual signature to forward to. + // For example: + // foo(int, short) -> double foo(double, double); // ***NOT*** float foo(float, float) + // foo(int, float) -> double foo(double, double); // ***NOT*** float foo(float, float) + // foo(int, double) -> foo(double, double); + // foo(double, float) -> double foo(double, double); + // foo(double, float) -> double foo(double, double); + // foo(any-int-or-float-type, long double) -> foo(long double, long double); + // ONLY float foo(float, float) is unchanged, so the only way to get an + // entirely float version is to call foo(1.F, 2.F). But since most (all?) the + // math functions convert to double internally, probably there would not be the + // hoped-for gain by using float here. + // + // This follows the C-compatible conversion rules of pow, etc + // where pow(int, float) is converted to pow(double, double). + + + // Promotes a single argument to double if it is an integer type + template + struct promote_arg { + using type = typename boost::math::conditional::value, double, T>::type; + }; + + + // Promotes two arguments, neither of which is an integer type using an asymmetric + // convertibility rule. + template ::value && boost::math::is_floating_point::value)> + struct pa2_integral_already_removed { + using type = typename boost::math::conditional< + !boost::math::is_floating_point::value && boost::math::is_convertible::value, + T2, T1>::type; + }; + // For two floating point types, promotes using `std::common_type` functionality + template + struct pa2_integral_already_removed { + using type = boost::math::common_type_t; + }; + + + // Template definition for promote_args_permissive + template + struct promote_args_permissive; + // Specialization for one argument + template + struct promote_args_permissive { + using type = typename promote_arg::type>::type; + }; + // Specialization for two or more arguments + template + struct promote_args_permissive { + using type = typename pa2_integral_already_removed< + typename promote_args_permissive::type, + typename promote_args_permissive::type + >::type; + }; + + template + using promote_args_permissive_t = typename promote_args_permissive::type; + + + // Same as `promote_args_permissive` but with a static assertion that the promoted type + // is not `long double` if `BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS` is defined + template + struct promote_args { + using type = typename promote_args_permissive::type; +#if defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) + // + // Guard against use of long double if it's not supported: + // + static_assert((0 == boost::math::is_same::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented."); +#endif + }; + + template + using promote_args_t = typename promote_args::type; + + } // namespace tools + } // namespace math +} // namespace boost + +#endif // BOOST_MATH_PROMOTION_HPP diff --git a/third-party/boost-math/include/boost/math/tools/quartic_roots.hpp b/third-party/boost-math/include/boost/math/tools/quartic_roots.hpp new file mode 100644 index 0000000000000..88a4f72531aac --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/quartic_roots.hpp @@ -0,0 +1,157 @@ +// (C) Copyright Nick Thompson 2021. +// 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) +#ifndef BOOST_MATH_TOOLS_QUARTIC_ROOTS_HPP +#define BOOST_MATH_TOOLS_QUARTIC_ROOTS_HPP +#include +#include +#include + +namespace boost::math::tools { + +namespace detail { + +// Make sure the nans are always at the back of the array: +template +bool comparator(Real r1, Real r2) { + using std::isnan; + if (isnan(r1)) { return false; } + if (isnan(r2)) { return true; } + return r1 < r2; +} + +template +std::array polish_and_sort(Real a, Real b, Real c, Real d, Real e, std::array& roots) { + // Polish the roots with a Halley iterate. + using std::fma; + using std::abs; + for (auto &r : roots) { + Real df = fma(4*a, r, 3*b); + df = fma(df, r, 2*c); + df = fma(df, r, d); + Real d2f = fma(12*a, r, 6*b); + d2f = fma(d2f, r, 2*c); + Real f = fma(a, r, b); + f = fma(f,r,c); + f = fma(f,r,d); + f = fma(f,r,e); + Real denom = 2*df*df - f*d2f; + if (abs(denom) > (std::numeric_limits::min)()) + { + r -= 2*f*df/denom; + } + } + std::sort(roots.begin(), roots.end(), detail::comparator); + return roots; +} + +} +// Solves ax^4 + bx^3 + cx^2 + dx + e = 0. +// Only returns the real roots, as these are the only roots of interest in ray intersection problems. +// Follows Graphics Gems V: https://github.com/erich666/GraphicsGems/blob/master/gems/Roots3And4.c +template +std::array quartic_roots(Real a, Real b, Real c, Real d, Real e) { + using std::abs; + using std::sqrt; + auto nan = std::numeric_limits::quiet_NaN(); + std::array roots{nan, nan, nan, nan}; + if (abs(a) <= (std::numeric_limits::min)()) { + auto cbrts = cubic_roots(b, c, d, e); + roots[0] = cbrts[0]; + roots[1] = cbrts[1]; + roots[2] = cbrts[2]; + if (b == 0 && c == 0 && d == 0 && e == 0) { + roots[3] = 0; + } + return detail::polish_and_sort(a, b, c, d, e, roots); + } + if (abs(e) <= (std::numeric_limits::min)()) { + auto v = cubic_roots(a, b, c, d); + roots[0] = v[0]; + roots[1] = v[1]; + roots[2] = v[2]; + roots[3] = 0; + return detail::polish_and_sort(a, b, c, d, e, roots); + } + // Now solve x^4 + Ax^3 + Bx^2 + Cx + D = 0. + Real A = b/a; + Real B = c/a; + Real C = d/a; + Real D = e/a; + Real Asq = A*A; + // Let x = y - A/4: + // Mathematica: Expand[(y - A/4)^4 + A*(y - A/4)^3 + B*(y - A/4)^2 + C*(y - A/4) + D] + // We now solve the depressed quartic y^4 + py^2 + qy + r = 0. + Real p = B - 3*Asq/8; + Real q = C - A*B/2 + Asq*A/8; + Real r = D - A*C/4 + Asq*B/16 - 3*Asq*Asq/256; + if (abs(r) <= (std::numeric_limits::min)()) { + auto [r1, r2, r3] = cubic_roots(Real(1), Real(0), p, q); + r1 -= A/4; + r2 -= A/4; + r3 -= A/4; + roots[0] = r1; + roots[1] = r2; + roots[2] = r3; + roots[3] = -A/4; + return detail::polish_and_sort(a, b, c, d, e, roots); + } + // Biquadratic case: + if (abs(q) <= (std::numeric_limits::min)()) { + auto [r1, r2] = quadratic_roots(Real(1), p, r); + if (r1 >= 0) { + Real rtr = sqrt(r1); + roots[0] = rtr - A/4; + roots[1] = -rtr - A/4; + } + if (r2 >= 0) { + Real rtr = sqrt(r2); + roots[2] = rtr - A/4; + roots[3] = -rtr - A/4; + } + return detail::polish_and_sort(a, b, c, d, e, roots); + } + + // Now split the depressed quartic into two quadratics: + // y^4 + py^2 + qy + r = (y^2 + sy + u)(y^2 - sy + v) = y^4 + (v+u-s^2)y^2 + s(v - u)y + uv + // So p = v+u-s^2, q = s(v - u), r = uv. + // Then (v+u)^2 - (v-u)^2 = 4uv = 4r = (p+s^2)^2 - q^2/s^2. + // Multiply through by s^2 to get s^2(p+s^2)^2 - q^2 - 4rs^2 = 0, which is a cubic in s^2. + // Then we let z = s^2, to get + // z^3 + 2pz^2 + (p^2 - 4r)z - q^2 = 0. + auto z_roots = cubic_roots(Real(1), 2*p, p*p - 4*r, -q*q); + // z = s^2, so s = sqrt(z). + // Hence we require a root > 0, and for the sake of sanity we should take the largest one: + Real largest_root = std::numeric_limits::lowest(); + for (auto z : z_roots) { + if (z > largest_root) { + largest_root = z; + } + } + // No real roots: + if (largest_root <= 0) { + return roots; + } + Real s = sqrt(largest_root); + // s is nonzero, because we took care of the biquadratic case. + Real v = (p + largest_root + q/s)/2; + Real u = v - q/s; + // Now solve y^2 + sy + u = 0: + auto [root0, root1] = quadratic_roots(Real(1), s, u); + + // Now solve y^2 - sy + v = 0: + auto [root2, root3] = quadratic_roots(Real(1), -s, v); + roots[0] = root0; + roots[1] = root1; + roots[2] = root2; + roots[3] = root3; + + for (auto& r : roots) { + r -= A/4; + } + return detail::polish_and_sort(a, b, c, d, e, roots); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/random_vector.hpp b/third-party/boost-math/include/boost/math/tools/random_vector.hpp new file mode 100644 index 0000000000000..79c0af40305c8 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/random_vector.hpp @@ -0,0 +1,101 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2021. +// 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) + +#include +#include +#include +#include + +namespace boost { namespace math { + +// To stress test, set global_seed = 0, global_size = huge. +static constexpr std::size_t global_seed = 0; +static constexpr std::size_t global_size = 128; + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937_64 gen(seed); + + std::normal_distribution dis(0, 1); + for (auto& x : v) + { + x = dis(gen); + } + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_uniform_vector(std::size_t size, std::size_t seed, T lower_bound = T(0), T upper_bound = T(1)) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + std::uniform_real_distribution dis(lower_bound, upper_bound); + + for (auto& x : v) + { + x = dis(gen); + } + + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed, T mean, T stddev) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + std::normal_distribution dis(mean, stddev); + for (auto& x : v) + { + x = dis(gen); + } + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937_64 gen(seed); + + // Rescaling by larger than 2 is UB! + std::uniform_int_distribution dis(std::numeric_limits::lowest()/2, (std::numeric_limits::max)()/2); + for (auto& x : v) + { + x = dis(gen); + } + return v; +} + +}} // Namespaces diff --git a/third-party/boost-math/include/boost/math/tools/rational.hpp b/third-party/boost-math/include/boost/math/tools/rational.hpp new file mode 100644 index 0000000000000..1079463d08c10 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/rational.hpp @@ -0,0 +1,346 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_RATIONAL_HPP +#define BOOST_MATH_TOOLS_RATIONAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_NVRTC +#include +#endif + +#if BOOST_MATH_POLY_METHOD == 1 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_POLY_METHOD == 2 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_POLY_METHOD == 3 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#endif +#if BOOST_MATH_RATIONAL_METHOD == 1 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_RATIONAL_METHOD == 2 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_RATIONAL_METHOD == 3 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#endif + +#if 0 +// +// This just allows dependency trackers to find the headers +// used in the above PP-magic. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace boost{ namespace math{ namespace tools{ + +// +// Forward declaration to keep two phase lookup happy: +// +template +BOOST_MATH_GPU_ENABLED U evaluate_polynomial(const T* poly, U const& z, boost::math::size_t count) BOOST_MATH_NOEXCEPT(U); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial_c_imp(const T* a, const V& val, const Tag*) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, val, Tag::value); +} + +} // namespace detail + +// +// Polynomial evaluation with runtime size. +// This requires a for-loop which may be more expensive than +// the loop expanded versions above: +// +template +BOOST_MATH_GPU_ENABLED inline U evaluate_polynomial(const T* poly, U const& z, boost::math::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + BOOST_MATH_ASSERT(count > 0); + U sum = static_cast(poly[count - 1]); + for(int i = static_cast(count) - 2; i >= 0; --i) + { + sum *= z; + sum += static_cast(poly[i]); + } + return sum; +} +// +// Compile time sized polynomials, just inline forwarders to the +// implementations above: +// +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial(const T(&a)[N], const V& val) BOOST_MATH_NOEXCEPT(V) +{ + typedef boost::math::integral_constant(N)> tag_type; + return detail::evaluate_polynomial_c_imp(static_cast(a), val, static_cast(nullptr)); +} + +#ifndef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_polynomial(const std::array& a, const V& val) BOOST_MATH_NOEXCEPT(V) +{ + typedef boost::math::integral_constant(N)> tag_type; + return detail::evaluate_polynomial_c_imp(static_cast(a.data()), val, static_cast(nullptr)); +} +#endif +// +// Even polynomials are trivial: just square the argument! +// +template +BOOST_MATH_GPU_ENABLED inline U evaluate_even_polynomial(const T* poly, U z, boost::math::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + return evaluate_polynomial(poly, U(z*z), count); +} + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_even_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, V(z*z)); +} + +#ifndef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_even_polynomial(const std::array& a, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, V(z*z)); +} +#endif +// +// Odd polynomials come next: +// +template +BOOST_MATH_GPU_ENABLED inline U evaluate_odd_polynomial(const T* poly, U z, boost::math::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + return poly[0] + z * evaluate_polynomial(poly+1, U(z*z), count-1); +} + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_odd_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + typedef boost::math::integral_constant(N-1)> tag_type; + return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast(a) + 1, V(z*z), static_cast(nullptr)); +} + +#ifndef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_odd_polynomial(const std::array& a, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + typedef boost::math::integral_constant(N-1)> tag_type; + return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast(a.data()) + 1, V(z*z), static_cast(nullptr)); +} +#endif + +template +BOOST_MATH_GPU_ENABLED V evaluate_rational(const T* num, const U* denom, const V& z_, boost::math::size_t count) BOOST_MATH_NOEXCEPT(V); + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_rational_c_imp(const T* num, const U* denom, const V& z, const Tag*) BOOST_MATH_NOEXCEPT(V) +{ + return boost::math::tools::evaluate_rational(num, denom, z, Tag::value); +} + +} +// +// Rational functions: numerator and denominator must be +// equal in size. These always have a for-loop and so may be less +// efficient than evaluating a pair of polynomials. However, there +// are some tricks we can use to prevent overflow that might otherwise +// occur in polynomial evaluation, if z is large. This is important +// in our Lanczos code for example. +// +template +BOOST_MATH_GPU_ENABLED V evaluate_rational(const T* num, const U* denom, const V& z_, boost::math::size_t count) BOOST_MATH_NOEXCEPT(V) +{ + V z(z_); + V s1, s2; + if(z <= 1) + { + s1 = static_cast(num[count-1]); + s2 = static_cast(denom[count-1]); + for(int i = (int)count - 2; i >= 0; --i) + { + s1 *= z; + s2 *= z; + s1 += num[i]; + s2 += denom[i]; + } + } + else + { + z = 1 / z; + s1 = static_cast(num[0]); + s2 = static_cast(denom[0]); + for(unsigned i = 1; i < count; ++i) + { + s1 *= z; + s2 *= z; + s1 += num[i]; + s2 += denom[i]; + } + } + return s1 / s2; +} + +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_rational(const T(&a)[N], const U(&b)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return detail::evaluate_rational_c_imp(a, b, z, static_cast(N)>*>(nullptr)); +} + +#ifndef BOOST_MATH_HAS_NVRTC +template +BOOST_MATH_GPU_ENABLED BOOST_MATH_GPU_ENABLED inline V evaluate_rational(const std::array& a, const std::array& b, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return detail::evaluate_rational_c_imp(a.data(), b.data(), z, static_cast(N)>*>(nullptr)); +} +#endif + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_RATIONAL_HPP + + + + diff --git a/third-party/boost-math/include/boost/math/tools/real_cast.hpp b/third-party/boost-math/include/boost/math/tools/real_cast.hpp new file mode 100644 index 0000000000000..a68738b347584 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/real_cast.hpp @@ -0,0 +1,31 @@ +// Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_REAL_CAST_HPP +#define BOOST_MATH_TOOLS_REAL_CAST_HPP + +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math +{ + namespace tools + { + template + inline constexpr To real_cast(T t) noexcept(BOOST_MATH_IS_FLOAT(T) && BOOST_MATH_IS_FLOAT(To)) + { + return static_cast(t); + } + } // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_REAL_CAST_HPP + + + diff --git a/third-party/boost-math/include/boost/math/tools/recurrence.hpp b/third-party/boost-math/include/boost/math/tools/recurrence.hpp new file mode 100644 index 0000000000000..b08988d4bf318 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/recurrence.hpp @@ -0,0 +1,330 @@ +// (C) Copyright Anton Bikineev 2014 +// 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) + +#ifndef BOOST_MATH_TOOLS_RECURRENCE_HPP_ +#define BOOST_MATH_TOOLS_RECURRENCE_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace math { + namespace tools { + namespace detail{ + + // + // Function ratios directly from recurrence relations: + // H. Shintan, Note on Miller's recurrence algorithm, J. Sci. Hiroshima Univ. Ser. A-I + // Math., 29 (1965), pp. 121 - 133. + // and: + // COMPUTATIONAL ASPECTS OF THREE-TERM RECURRENCE RELATIONS + // WALTER GAUTSCHI + // SIAM REVIEW Vol. 9, No. 1, January, 1967 + // + template + struct function_ratio_from_backwards_recurrence_fraction + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + typedef std::pair result_type; + function_ratio_from_backwards_recurrence_fraction(const Recurrence& r) : r(r), k(0) {} + + result_type operator()() + { + value_type a, b, c; + std::tie(a, b, c) = r(k); + ++k; + // an and bn defined as per Gauchi 1.16, not the same + // as the usual continued fraction a' and b's. + value_type bn = a / c; + value_type an = b / c; + return result_type(-bn, an); + } + + private: + function_ratio_from_backwards_recurrence_fraction operator=(const function_ratio_from_backwards_recurrence_fraction&) = delete; + + Recurrence r; + int k; + }; + + template + struct recurrence_reverser + { + recurrence_reverser(const R& r) : r(r) {} + std::tuple operator()(int i) + { + using std::swap; + std::tuple t = r(-i); + swap(std::get<0>(t), std::get<2>(t)); + return t; + } + R r; + }; + + template + struct recurrence_offsetter + { + typedef decltype(std::declval()(0)) result_type; + recurrence_offsetter(Recurrence const& rr, int offset) : r(rr), k(offset) {} + result_type operator()(int i) + { + return r(i + k); + } + private: + Recurrence r; + int k; + }; + + + + } // namespace detail + + // + // Given a stable backwards recurrence relation: + // a f_n-1 + b f_n + c f_n+1 = 0 + // returns the ratio f_n / f_n-1 + // + // Recurrence: a functor that returns a tuple of the factors (a,b,c). + // factor: Convergence criteria, should be no less than machine epsilon. + // max_iter: Maximum iterations to use solving the continued fraction. + // + template + T function_ratio_from_backwards_recurrence(const Recurrence& r, const T& factor, std::uintmax_t& max_iter) + { + detail::function_ratio_from_backwards_recurrence_fraction f(r); + return boost::math::tools::continued_fraction_a(f, factor, max_iter); + } + + // + // Given a stable forwards recurrence relation: + // a f_n-1 + b f_n + c f_n+1 = 0 + // returns the ratio f_n / f_n+1 + // + // Note that in most situations where this would be used, we're relying on + // pseudo-convergence, as in most cases f_n will not be minimal as N -> -INF + // as long as we reach convergence on the continued-fraction before f_n + // switches behaviour, we should be fine. + // + // Recurrence: a functor that returns a tuple of the factors (a,b,c). + // factor: Convergence criteria, should be no less than machine epsilon. + // max_iter: Maximum iterations to use solving the continued fraction. + // + template + T function_ratio_from_forwards_recurrence(const Recurrence& r, const T& factor, std::uintmax_t& max_iter) + { + boost::math::tools::detail::function_ratio_from_backwards_recurrence_fraction > f(r); + return boost::math::tools::continued_fraction_a(f, factor, max_iter); + } + + + + // solves usual recurrence relation for homogeneous + // difference equation in stable forward direction + // a(n)w(n-1) + b(n)w(n) + c(n)w(n+1) = 0 + // + // Params: + // get_coefs: functor returning a tuple, where + // get<0>() is a(n); get<1>() is b(n); get<2>() is c(n); + // last_index: index N to be found; + // first: w(-1); + // second: w(0); + // + template + inline T apply_recurrence_relation_forward(const NextCoefs& get_coefs, unsigned number_of_steps, T first, T second, long long* log_scaling = nullptr, T* previous = nullptr) + { + BOOST_MATH_STD_USING + using std::tuple; + using std::get; + using std::swap; + + T third; + T a, b, c; + + for (unsigned k = 0; k < number_of_steps; ++k) + { + tie(a, b, c) = get_coefs(k); + + if ((log_scaling) && + ((fabs(tools::max_value() * (c / (a * 2048))) < fabs(first)) + || (fabs(tools::max_value() * (c / (b * 2048))) < fabs(second)) + || (fabs(tools::min_value() * (c * 2048 / a)) > fabs(first)) + || (fabs(tools::min_value() * (c * 2048 / b)) > fabs(second)) + )) + + { + // Rescale everything: + long long log_scale = lltrunc(log(fabs(second))); + T scale = exp(T(-log_scale)); + second *= scale; + first *= scale; + *log_scaling += log_scale; + } + // scale each part separately to avoid spurious overflow: + third = (a / -c) * first + (b / -c) * second; + BOOST_MATH_ASSERT((boost::math::isfinite)(third)); + + + swap(first, second); + swap(second, third); + } + + if (previous) + *previous = first; + + return second; + } + + // solves usual recurrence relation for homogeneous + // difference equation in stable backward direction + // a(n)w(n-1) + b(n)w(n) + c(n)w(n+1) = 0 + // + // Params: + // get_coefs: functor returning a tuple, where + // get<0>() is a(n); get<1>() is b(n); get<2>() is c(n); + // number_of_steps: index N to be found; + // first: w(1); + // second: w(0); + // + template + inline T apply_recurrence_relation_backward(const NextCoefs& get_coefs, unsigned number_of_steps, T first, T second, long long* log_scaling = nullptr, T* previous = nullptr) + { + BOOST_MATH_STD_USING + using std::tuple; + using std::get; + using std::swap; + + T next; + T a, b, c; + + for (unsigned k = 0; k < number_of_steps; ++k) + { + tie(a, b, c) = get_coefs(-static_cast(k)); + + if ((log_scaling) && (second != 0) && + ( (fabs(tools::max_value() * (a / b) / 2048) < fabs(second)) + || (fabs(tools::max_value() * (a / c) / 2048) < fabs(first)) + || (fabs(tools::min_value() * (a / b) * 2048) > fabs(second)) + || (fabs(tools::min_value() * (a / c) * 2048) > fabs(first)) + )) + { + // Rescale everything: + int log_scale = itrunc(log(fabs(second))); + T scale = exp(T(-log_scale)); + second *= scale; + first *= scale; + *log_scaling += log_scale; + } + // scale each part separately to avoid spurious overflow: + next = (b / -a) * second + (c / -a) * first; + BOOST_MATH_ASSERT((boost::math::isfinite)(next)); + + swap(first, second); + swap(second, next); + } + + if (previous) + *previous = first; + + return second; + } + + template + struct forward_recurrence_iterator + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + + forward_recurrence_iterator(const Recurrence& r, value_type f_n_minus_1, value_type f_n) + : f_n_minus_1(f_n_minus_1), f_n(f_n), coef(r), k(0) {} + + forward_recurrence_iterator(const Recurrence& r, value_type f_n) + : f_n(f_n), coef(r), k(0) + { + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations >(); + f_n_minus_1 = f_n * boost::math::tools::function_ratio_from_forwards_recurrence(detail::recurrence_offsetter(r, -1), value_type(boost::math::tools::epsilon() * 2), max_iter); + boost::math::policies::check_series_iterations("forward_recurrence_iterator<>::forward_recurrence_iterator", max_iter, boost::math::policies::policy<>()); + } + + forward_recurrence_iterator& operator++() + { + using std::swap; + value_type a, b, c; + std::tie(a, b, c) = coef(k); + value_type f_n_plus_1 = a * f_n_minus_1 / -c + b * f_n / -c; + swap(f_n_minus_1, f_n); + swap(f_n, f_n_plus_1); + ++k; + return *this; + } + + forward_recurrence_iterator operator++(int) + { + forward_recurrence_iterator t(*this); + ++(*this); + return t; + } + + value_type operator*() { return f_n; } + + value_type f_n_minus_1, f_n; + Recurrence coef; + int k; + }; + + template + struct backward_recurrence_iterator + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + + backward_recurrence_iterator(const Recurrence& r, value_type f_n_plus_1, value_type f_n) + : f_n_plus_1(f_n_plus_1), f_n(f_n), coef(r), k(0) {} + + backward_recurrence_iterator(const Recurrence& r, value_type f_n) + : f_n(f_n), coef(r), k(0) + { + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations >(); + f_n_plus_1 = f_n * boost::math::tools::function_ratio_from_backwards_recurrence(detail::recurrence_offsetter(r, 1), value_type(boost::math::tools::epsilon() * 2), max_iter); + boost::math::policies::check_series_iterations("backward_recurrence_iterator<>::backward_recurrence_iterator", max_iter, boost::math::policies::policy<>()); + } + + backward_recurrence_iterator& operator++() + { + using std::swap; + value_type a, b, c; + std::tie(a, b, c) = coef(k); + value_type f_n_minus_1 = c * f_n_plus_1 / -a + b * f_n / -a; + swap(f_n_plus_1, f_n); + swap(f_n, f_n_minus_1); + --k; + return *this; + } + + backward_recurrence_iterator operator++(int) + { + backward_recurrence_iterator t(*this); + ++(*this); + return t; + } + + value_type operator*() { return f_n; } + + value_type f_n_plus_1, f_n; + Recurrence coef; + int k; + }; + + } + } +} // namespaces + +#endif // BOOST_MATH_TOOLS_RECURRENCE_HPP_ diff --git a/third-party/boost-math/include/boost/math/tools/roots.hpp b/third-party/boost-math/include/boost/math/tools/roots.hpp new file mode 100644 index 0000000000000..b0b0fc246cfc9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/roots.hpp @@ -0,0 +1,1062 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP +#define BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include // test for multiprecision types in complex Newton +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +#include +#include +#endif + +namespace boost { +namespace math { +namespace tools { + +namespace detail { + +namespace dummy { + + template + BOOST_MATH_GPU_ENABLED typename T::value_type get(const T&) BOOST_MATH_NOEXCEPT(T); +} + +template +BOOST_MATH_GPU_ENABLED void unpack_tuple(const Tuple& t, T& a, T& b) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Use ADL to find the right overload for get: + a = get<0>(t); + b = get<1>(t); +} +template +BOOST_MATH_GPU_ENABLED void unpack_tuple(const Tuple& t, T& a, T& b, T& c) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Use ADL to find the right overload for get: + a = get<0>(t); + b = get<1>(t); + c = get<2>(t); +} + +template +BOOST_MATH_GPU_ENABLED inline void unpack_0(const Tuple& t, T& val) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Rely on ADL to find the correct overload of get: + val = get<0>(t); +} + +template +BOOST_MATH_GPU_ENABLED inline void unpack_tuple(const boost::math::pair& p, V& a, V& b) BOOST_MATH_NOEXCEPT(T) +{ + a = p.first; + b = p.second; +} +template +BOOST_MATH_GPU_ENABLED inline void unpack_0(const boost::math::pair& p, V& a) BOOST_MATH_NOEXCEPT(T) +{ + a = p.first; +} + +template +BOOST_MATH_GPU_ENABLED void handle_zero_derivative(F f, + T& last_f0, + const T& f0, + T& delta, + T& result, + T& guess, + const T& min, + const T& max) noexcept(BOOST_MATH_IS_FLOAT(T) + #ifndef BOOST_MATH_HAS_GPU_SUPPORT + && noexcept(std::declval()(std::declval())) + #endif + ) +{ + if (last_f0 == 0) + { + // this must be the first iteration, pretend that we had a + // previous one at either min or max: + if (result == min) + { + guess = max; + } + else + { + guess = min; + } + unpack_0(f(guess), last_f0); + delta = guess - result; + } + if (sign(last_f0) * sign(f0) < 0) + { + // we've crossed over so move in opposite direction to last step: + if (delta < 0) + { + delta = (result - min) / 2; + } + else + { + delta = (result - max) / 2; + } + } + else + { + // move in same direction as last step: + if (delta < 0) + { + delta = (result - max) / 2; + } + else + { + delta = (result - min) / 2; + } + } +} + +} // namespace + +template +BOOST_MATH_GPU_ENABLED boost::math::pair bisect(F f, T min, T max, Tol tol, boost::math::uintmax_t& max_iter, const Policy& pol) noexcept(policies::is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()(std::declval())) +#endif +) +{ + T fmin = f(min); + T fmax = f(max); + if (fmin == 0) + { + max_iter = 2; + return boost::math::make_pair(min, min); + } + if (fmax == 0) + { + max_iter = 2; + return boost::math::make_pair(max, max); + } + + // + // Error checking: + // + constexpr auto function = "boost::math::tools::bisect<%1%>"; + if (min >= max) + { + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, + "Arguments in wrong order in boost::math::tools::bisect (first arg=%1%)", min, pol)); + } + if (fmin * fmax >= 0) + { + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, + "No change of sign in boost::math::tools::bisect, either there is no root to find, or there are multiple roots in the interval (f(min) = %1%).", fmin, pol)); + } + + // + // Three function invocations so far: + // + std::uintmax_t count = max_iter; + if (count < 3) + count = 0; + else + count -= 3; + + while (count && (0 == tol(min, max))) + { + T mid = (min + max) / 2; + T fmid = f(mid); + if ((mid == max) || (mid == min)) + break; + if (fmid == 0) + { + min = max = mid; + break; + } + else if (sign(fmid) * sign(fmin) < 0) + { + max = mid; + } + else + { + min = mid; + fmin = fmid; + } + --count; + } + + max_iter -= count; + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Bisection required " << max_iter << " iterations.\n"; +#endif + + return boost::math::make_pair(min, max); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair bisect(F f, T min, T max, Tol tol, boost::math::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value && BOOST_MATH_IS_FLOAT(T) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()(std::declval())) +#endif +) +{ + return bisect(f, min, max, tol, max_iter, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair bisect(F f, T min, T max, Tol tol) noexcept(policies::is_noexcept_error_policy >::value && BOOST_MATH_IS_FLOAT(T) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()(std::declval())) +#endif +) +{ + boost::math::uintmax_t m = (boost::math::numeric_limits::max)(); + return bisect(f, min, max, tol, m, policies::policy<>()); +} + + +template +BOOST_MATH_GPU_ENABLED T newton_raphson_iterate(F f, T guess, T min, T max, int digits, boost::math::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value && BOOST_MATH_IS_FLOAT(T) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()(std::declval())) +#endif +) +{ + BOOST_MATH_STD_USING + + constexpr auto function = "boost::math::tools::newton_raphson_iterate<%1%>"; + if (min > max) + { + return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::newton_raphson_iterate(first arg=%1%)", min, boost::math::policies::policy<>()); + } + + T f0(0), f1, last_f0(0); + T result = guess; + + T factor = static_cast(ldexp(1.0, 1 - digits)); + T delta = tools::max_value(); + T delta1 = tools::max_value(); + T delta2 = tools::max_value(); + + // + // We use these to sanity check that we do actually bracket a root, + // we update these to the function value when we update the endpoints + // of the range. Then, provided at some point we update both endpoints + // checking that max_range_f * min_range_f <= 0 verifies there is a root + // to be found somewhere. Note that if there is no root, and we approach + // a local minima, then the derivative will go to zero, and hence the next + // step will jump out of bounds (or at least past the minima), so this + // check *should* happen in pathological cases. + // + T max_range_f = 0; + T min_range_f = 0; + + boost::math::uintmax_t count(max_iter); + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton_raphson_iterate, guess = " << guess << ", min = " << min << ", max = " << max + << ", digits = " << digits << ", max_iter = " << max_iter << "\n"; +#endif + + do { + last_f0 = f0; + delta2 = delta1; + delta1 = delta; + detail::unpack_tuple(f(result), f0, f1); + --count; + if (0 == f0) + break; + if (f1 == 0) + { + // Oops zero derivative!!! + detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max); + } + else + { + delta = f0 / f1; + } +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton iteration " << max_iter - count << ", delta = " << delta << ", residual = " << f0 << "\n"; +#endif + if (fabs(delta * 2) > fabs(delta2)) + { + // Last two steps haven't converged. + T shift = (delta > 0) ? (result - min) / 2 : (result - max) / 2; + if ((result != 0) && (fabs(shift) > fabs(result))) + { + delta = sign(delta) * fabs(result); // protect against huge jumps! + } + else + delta = shift; + // reset delta1/2 so we don't take this branch next time round: + delta1 = 3 * delta; + delta2 = 3 * delta; + } + guess = result; + result -= delta; + if (result <= min) + { + delta = 0.5F * (guess - min); + result = guess - delta; + if ((result == min) || (result == max)) + break; + } + else if (result >= max) + { + delta = 0.5F * (guess - max); + result = guess - delta; + if ((result == min) || (result == max)) + break; + } + // Update brackets: + if (delta > 0) + { + max = guess; + max_range_f = f0; + } + else + { + min = guess; + min_range_f = f0; + } + // + // Sanity check that we bracket the root: + // + if (max_range_f * min_range_f > 0) + { + return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>()); + } + }while(count && (fabs(result * factor) < fabs(delta))); + + max_iter -= count; + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton Raphson required " << max_iter << " iterations\n"; +#endif + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline T newton_raphson_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value && BOOST_MATH_IS_FLOAT(T) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()(std::declval())) +#endif +) +{ + boost::math::uintmax_t m = (boost::math::numeric_limits::max)(); + return newton_raphson_iterate(f, guess, min, max, digits, m); +} + +// TODO(mborland): Disabled for now +// Recursion needs to be removed, but there is no demand at this time +#ifdef BOOST_MATH_HAS_NVRTC +}}} // Namespaces +#else + +namespace detail { + + struct halley_step + { + template + static T step(const T& /*x*/, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T)) + { + using std::fabs; + T denom = 2 * f0; + T num = 2 * f1 - f0 * (f2 / f1); + T delta; + + BOOST_MATH_INSTRUMENT_VARIABLE(denom); + BOOST_MATH_INSTRUMENT_VARIABLE(num); + + if ((fabs(num) < 1) && (fabs(denom) >= fabs(num) * tools::max_value())) + { + // possible overflow, use Newton step: + delta = f0 / f1; + } + else + delta = denom / num; + return delta; + } + }; + + template + T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))); + + template + T bracket_root_towards_max(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + using std::fabs; + using std::ldexp; + using std::abs; + using std::frexp; + if(count < 2) + return guess - (max + min) / 2; // Not enough counts left to do anything!! + // + // Move guess towards max until we bracket the root, updating min and max as we go: + // + int e; + frexp(max / guess, &e); + e = abs(e); + T guess0 = guess; + T multiplier = e < 64 ? static_cast(2) : static_cast(ldexp(T(1), e / 32)); + T f_current = f0; + if (fabs(min) < fabs(max)) + { + while (--count && ((f_current < 0) == (f0 < 0))) + { + min = guess; + guess *= multiplier; + if (guess > max) + { + guess = max; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= e > 1024 ? 8 : 2; + unpack_0(f(guess), f_current); + } + } + else + { + // + // If min and max are negative we have to divide to head towards max: + // + while (--count && ((f_current < 0) == (f0 < 0))) + { + min = guess; + guess /= multiplier; + if (guess > max) + { + guess = max; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= e > 1024 ? 8 : 2; + unpack_0(f(guess), f_current); + } + } + + if (count) + { + max = guess; + if (multiplier > 16) + return (guess0 - guess) + bracket_root_towards_min(f, guess, f_current, min, max, count); + } + return guess0 - (max + min) / 2; + } + + template + T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + using std::fabs; + using std::ldexp; + using std::abs; + using std::frexp; + if (count < 2) + return guess - (max + min) / 2; // Not enough counts left to do anything!! + // + // Move guess towards min until we bracket the root, updating min and max as we go: + // + int e; + frexp(guess / min, &e); + e = abs(e); + T guess0 = guess; + T multiplier = e < 64 ? static_cast(2) : static_cast(ldexp(T(1), e / 32)); + T f_current = f0; + + if (fabs(min) < fabs(max)) + { + while (--count && ((f_current < 0) == (f0 < 0))) + { + max = guess; + guess /= multiplier; + if (guess < min) + { + guess = min; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= e > 1024 ? 8 : 2; + unpack_0(f(guess), f_current); + } + } + else + { + // + // If min and max are negative we have to multiply to head towards min: + // + while (--count && ((f_current < 0) == (f0 < 0))) + { + max = guess; + guess *= multiplier; + if (guess < min) + { + guess = min; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= e > 1024 ? 8 : 2; + unpack_0(f(guess), f_current); + } + } + + if (count) + { + min = guess; + if (multiplier > 16) + return (guess0 - guess) + bracket_root_towards_max(f, guess, f_current, min, max, count); + } + return guess0 - (max + min) / 2; + } + + template + T second_order_root_finder(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + BOOST_MATH_STD_USING + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, guess = " << guess << ", min = " << min << ", max = " << max + << ", digits = " << digits << ", max_iter = " << max_iter << "\n"; +#endif + static const char* function = "boost::math::tools::halley_iterate<%1%>"; + if (min >= max) + { + return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::halley_iterate(first arg=%1%)", min, boost::math::policies::policy<>()); + } + + T f0(0), f1, f2; + T result = guess; + + T factor = ldexp(static_cast(1.0), 1 - digits); + T delta = (std::max)(T(10000000 * guess), T(10000000)); // arbitrarily large delta + T last_f0 = 0; + T delta1 = delta; + T delta2 = delta; + bool out_of_bounds_sentry = false; + + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, limit = " << factor << "\n"; + #endif + + // + // We use these to sanity check that we do actually bracket a root, + // we update these to the function value when we update the endpoints + // of the range. Then, provided at some point we update both endpoints + // checking that max_range_f * min_range_f <= 0 verifies there is a root + // to be found somewhere. Note that if there is no root, and we approach + // a local minima, then the derivative will go to zero, and hence the next + // step will jump out of bounds (or at least past the minima), so this + // check *should* happen in pathological cases. + // + T max_range_f = 0; + T min_range_f = 0; + + std::uintmax_t count(max_iter); + + do { + last_f0 = f0; + delta2 = delta1; + delta1 = delta; +#ifndef BOOST_MATH_NO_EXCEPTIONS + try +#endif + { + detail::unpack_tuple(f(result), f0, f1, f2); + } +#ifndef BOOST_MATH_NO_EXCEPTIONS + catch (const std::overflow_error&) + { + f0 = max > 0 ? tools::max_value() : -tools::min_value(); + f1 = f2 = 0; + } +#endif + --count; + + BOOST_MATH_INSTRUMENT_VARIABLE(f0); + BOOST_MATH_INSTRUMENT_VARIABLE(f1); + BOOST_MATH_INSTRUMENT_VARIABLE(f2); + + if (0 == f0) + break; + if (f1 == 0) + { + // Oops zero derivative!!! + detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max); + } + else + { + if (f2 != 0) + { + delta = Stepper::step(result, f0, f1, f2); + if (delta * f1 / f0 < 0) + { + // Oh dear, we have a problem as Newton and Halley steps + // disagree about which way we should move. Probably + // there is cancelation error in the calculation of the + // Halley step, or else the derivatives are so small + // that their values are basically trash. We will move + // in the direction indicated by a Newton step, but + // by no more than twice the current guess value, otherwise + // we can jump way out of bounds if we're not careful. + // See https://svn.boost.org/trac/boost/ticket/8314. + delta = f0 / f1; + if (fabs(delta) > 2 * fabs(result)) + delta = (delta < 0 ? -1 : 1) * 2 * fabs(result); + } + } + else + delta = f0 / f1; + } + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, delta = " << delta << ", residual = " << f0 << "\n"; + #endif + // We need to avoid delta/delta2 overflowing here: + T convergence = (fabs(delta2) > 1) || (fabs(tools::max_value() * delta2) > fabs(delta)) ? fabs(delta / delta2) : tools::max_value(); + if ((convergence > 0.8) && (convergence < 2)) + { + // last two steps haven't converged. + if (fabs(min) < 1 ? fabs(1000 * min) < fabs(max) : fabs(max / min) > 1000) + { + if(delta > 0) + delta = bracket_root_towards_min(f, result, f0, min, max, count); + else + delta = bracket_root_towards_max(f, result, f0, min, max, count); + } + else + { + delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2; + if ((result != 0) && (fabs(delta) > result)) + delta = sign(delta) * fabs(result) * 0.9f; // protect against huge jumps! + } + // reset delta2 so that this branch will *not* be taken on the + // next iteration: + delta2 = delta * 3; + delta1 = delta * 3; + BOOST_MATH_INSTRUMENT_VARIABLE(delta); + } + guess = result; + result -= delta; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + + // check for out of bounds step: + if (result < min) + { + T diff = ((fabs(min) < 1) && (fabs(result) > 1) && (tools::max_value() / fabs(result) < fabs(min))) + ? T(1000) + : (fabs(min) < 1) && (fabs(tools::max_value() * min) < fabs(result)) + ? ((min < 0) != (result < 0)) ? -tools::max_value() : tools::max_value() : T(result / min); + if (fabs(diff) < 1) + diff = 1 / diff; + if (!out_of_bounds_sentry && (diff > 0) && (diff < 3)) + { + // Only a small out of bounds step, lets assume that the result + // is probably approximately at min: + delta = 0.99f * (guess - min); + result = guess - delta; + out_of_bounds_sentry = true; // only take this branch once! + } + else + { + if (fabs(float_distance(min, max)) < 2) + { + result = guess = (min + max) / 2; + break; + } + delta = bracket_root_towards_min(f, guess, f0, min, max, count); + result = guess - delta; + if (result <= min) + result = float_next(min); + if (result >= max) + result = float_prior(max); + guess = min; + continue; + } + } + else if (result > max) + { + T diff = ((fabs(max) < 1) && (fabs(result) > 1) && (tools::max_value() / fabs(result) < fabs(max))) ? T(1000) : T(result / max); + if (fabs(diff) < 1) + diff = 1 / diff; + if (!out_of_bounds_sentry && (diff > 0) && (diff < 3)) + { + // Only a small out of bounds step, lets assume that the result + // is probably approximately at min: + delta = 0.99f * (guess - max); + result = guess - delta; + out_of_bounds_sentry = true; // only take this branch once! + } + else + { + if (fabs(float_distance(min, max)) < 2) + { + result = guess = (min + max) / 2; + break; + } + delta = bracket_root_towards_max(f, guess, f0, min, max, count); + result = guess - delta; + if (result >= max) + result = float_prior(max); + if (result <= min) + result = float_next(min); + guess = min; + continue; + } + } + // update brackets: + if (delta > 0) + { + max = guess; + max_range_f = f0; + } + else + { + min = guess; + min_range_f = f0; + } + // + // Sanity check that we bracket the root: + // + if (max_range_f * min_range_f > 0) + { + return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>()); + } + } while(count && (fabs(result * factor) < fabs(delta))); + + max_iter -= count; + + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root finder required " << max_iter << " iterations.\n"; + #endif + + return result; + } +} // T second_order_root_finder + +template +T halley_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T halley_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return halley_iterate(f, guess, min, max, digits, m); +} + +namespace detail { + + struct schroder_stepper + { + template + static T step(const T& x, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T)) + { + using std::fabs; + T ratio = f0 / f1; + T delta; + if ((x != 0) && (fabs(ratio / x) < 0.1)) + { + delta = ratio + (f2 / (2 * f1)) * ratio * ratio; + // check second derivative doesn't over compensate: + if (delta * ratio < 0) + delta = ratio; + } + else + delta = ratio; // fall back to Newton iteration. + return delta; + } + }; + +} + +template +T schroder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T schroder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return schroder_iterate(f, guess, min, max, digits, m); +} +// +// These two are the old spelling of this function, retained for backwards compatibility just in case: +// +template +T schroeder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T schroeder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return schroder_iterate(f, guess, min, max, digits, m); +} + +#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS +/* + * Why do we set the default maximum number of iterations to the number of digits in the type? + * Because for double roots, the number of digits increases linearly with the number of iterations, + * so this default should recover full precision even in this somewhat pathological case. + * For isolated roots, the problem is so rapidly convergent that this doesn't matter at all. + */ +template +ComplexType complex_newton(F g, ComplexType guess, int max_iterations = std::numeric_limits::digits) +{ + typedef typename ComplexType::value_type Real; + using std::norm; + using std::abs; + using std::max; + // z0, z1, and z2 cannot be the same, in case we immediately need to resort to Muller's Method: + ComplexType z0 = guess + ComplexType(1, 0); + ComplexType z1 = guess + ComplexType(0, 1); + ComplexType z2 = guess; + + do { + auto pair = g(z2); + if (norm(pair.second) == 0) + { + // Muller's method. Notation follows Numerical Recipes, 9.5.2: + ComplexType q = (z2 - z1) / (z1 - z0); + auto P0 = g(z0); + auto P1 = g(z1); + ComplexType qp1 = static_cast(1) + q; + ComplexType A = q * (pair.first - qp1 * P1.first + q * P0.first); + + ComplexType B = (static_cast(2) * q + static_cast(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first; + ComplexType C = qp1 * pair.first; + ComplexType rad = sqrt(B * B - static_cast(4) * A * C); + ComplexType denom1 = B + rad; + ComplexType denom2 = B - rad; + ComplexType correction = (z1 - z2) * static_cast(2) * C; + if (norm(denom1) > norm(denom2)) + { + correction /= denom1; + } + else + { + correction /= denom2; + } + + z0 = z1; + z1 = z2; + z2 = z2 + correction; + } + else + { + z0 = z1; + z1 = z2; + z2 = z2 - (pair.first / pair.second); + } + + // See: https://math.stackexchange.com/questions/3017766/constructing-newton-iteration-converging-to-non-root + // If f' is continuous, then convergence of x_n -> x* implies f(x*) = 0. + // This condition approximates this convergence condition by requiring three consecutive iterates to be clustered. + Real tol = (max)(abs(z2) * std::numeric_limits::epsilon(), std::numeric_limits::epsilon()); + bool real_close = abs(z0.real() - z1.real()) < tol && abs(z0.real() - z2.real()) < tol && abs(z1.real() - z2.real()) < tol; + bool imag_close = abs(z0.imag() - z1.imag()) < tol && abs(z0.imag() - z2.imag()) < tol && abs(z1.imag() - z2.imag()) < tol; + if (real_close && imag_close) + { + return z2; + } + + } while (max_iterations--); + + // The idea is that if we can get abs(f) < eps, we should, but if we go through all these iterations + // and abs(f) < sqrt(eps), then roundoff error simply does not allow that we can evaluate f to < eps + // This is somewhat awkward as it isn't scale invariant, but using the Daubechies coefficient example code, + // I found this condition generates correct roots, whereas the scale invariant condition discussed here: + // https://scicomp.stackexchange.com/questions/30597/defining-a-condition-number-and-termination-criteria-for-newtons-method + // allows nonroots to be passed off as roots. + auto pair = g(z2); + if (abs(pair.first) < sqrt(std::numeric_limits::epsilon())) + { + return z2; + } + + return { std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() }; +} +#endif + + +#if !defined(BOOST_MATH_NO_CXX17_IF_CONSTEXPR) +// https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711 +namespace detail +{ +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) +inline float fma_workaround(float x, float y, float z) { return ::fmaf(x, y, z); } +inline double fma_workaround(double x, double y, double z) { return ::fma(x, y, z); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline long double fma_workaround(long double x, long double y, long double z) { return ::fmal(x, y, z); } +#endif +#endif +template +inline T discriminant(T const& a, T const& b, T const& c) +{ + T w = 4 * a * c; +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) + T e = fma_workaround(-c, 4 * a, w); + T f = fma_workaround(b, b, -w); +#else + T e = std::fma(-c, 4 * a, w); + T f = std::fma(b, b, -w); +#endif + return f + e; +} + +template +std::pair quadratic_roots_imp(T const& a, T const& b, T const& c) +{ +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) + using boost::math::copysign; +#else + using std::copysign; +#endif + using std::sqrt; + if constexpr (std::is_floating_point::value) + { + T nan = std::numeric_limits::quiet_NaN(); + if (a == 0) + { + if (b == 0 && c != 0) + { + return std::pair(nan, nan); + } + else if (b == 0 && c == 0) + { + return std::pair(0, 0); + } + return std::pair(-c / b, -c / b); + } + if (b == 0) + { + T x0_sq = -c / a; + if (x0_sq < 0) { + return std::pair(nan, nan); + } + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + T discriminant = detail::discriminant(a, b, c); + // Is there a sane way to flush very small negative values to zero? + // If there is I don't know of it. + if (discriminant < 0) + { + return std::pair(nan, nan); + } + T q = -(b + copysign(sqrt(discriminant), b)) / T(2); + T x0 = q / a; + T x1 = c / q; + if (x0 < x1) + { + return std::pair(x0, x1); + } + return std::pair(x1, x0); + } + else if constexpr (boost::math::tools::is_complex_type::value) + { + typename T::value_type nan = std::numeric_limits::quiet_NaN(); + if (a.real() == 0 && a.imag() == 0) + { + using std::norm; + if (b.real() == 0 && b.imag() && norm(c) != 0) + { + return std::pair({ nan, nan }, { nan, nan }); + } + else if (b.real() == 0 && b.imag() && c.real() == 0 && c.imag() == 0) + { + return std::pair({ 0,0 }, { 0,0 }); + } + return std::pair(-c / b, -c / b); + } + if (b.real() == 0 && b.imag() == 0) + { + T x0_sq = -c / a; + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + // There's no fma for complex types: + T discriminant = b * b - T(4) * a * c; + T q = -(b + sqrt(discriminant)) / T(2); + return std::pair(q / a, c / q); + } + else // Most likely the type is a boost.multiprecision. + { //There is no fma for multiprecision, and in addition it doesn't seem to be useful, so revert to the naive computation. + T nan = std::numeric_limits::quiet_NaN(); + if (a == 0) + { + if (b == 0 && c != 0) + { + return std::pair(nan, nan); + } + else if (b == 0 && c == 0) + { + return std::pair(0, 0); + } + return std::pair(-c / b, -c / b); + } + if (b == 0) + { + T x0_sq = -c / a; + if (x0_sq < 0) { + return std::pair(nan, nan); + } + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + T discriminant = b * b - 4 * a * c; + if (discriminant < 0) + { + return std::pair(nan, nan); + } + T q = -(b + copysign(sqrt(discriminant), b)) / T(2); + T x0 = q / a; + T x1 = c / q; + if (x0 < x1) + { + return std::pair(x0, x1); + } + return std::pair(x1, x0); + } +} +} // namespace detail + +template +inline std::pair::type, typename tools::promote_args::type> quadratic_roots(T1 const& a, T2 const& b, T3 const& c) +{ + typedef typename tools::promote_args::type value_type; + return detail::quadratic_roots_imp(static_cast(a), static_cast(b), static_cast(c)); +} + +#endif + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_NVRTC + +#endif // BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP diff --git a/third-party/boost-math/include/boost/math/tools/series.hpp b/third-party/boost-math/include/boost/math/tools/series.hpp new file mode 100644 index 0000000000000..4617ea3df7d97 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/series.hpp @@ -0,0 +1,221 @@ +// (C) Copyright John Maddock 2005-2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_SERIES_INCLUDED +#define BOOST_MATH_TOOLS_SERIES_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +// +// Simple series summation come first: +// +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms, const V& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + boost::math::uintmax_t counter = max_terms; + + result_type result = init_value; + result_type next_term; + do{ + next_term = func(); + result += next_term; + } + while((abs(factor * result) < abs(next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + typename Functor::result_type init_value = 0; + return sum_series(func, factor, max_terms, init_value); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + result_type factor = ldexp(result_type(1), 1 - bits); + return sum_series(func, factor, max_terms, init_value); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + boost::math::uintmax_t iters = (boost::math::numeric_limits::max)(); + result_type init_val = 0; + return sum_series(func, bits, iters, init_val); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + result_type init_val = 0; + return sum_series(func, bits, max_terms, init_val); +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type sum_series(Functor& func, int bits, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + boost::math::uintmax_t iters = (boost::math::numeric_limits::max)(); + return sum_series(func, bits, iters, init_value); +} +// +// Checked summation: +// +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type checked_sum_series(Functor& func, const U& factor, boost::math::uintmax_t& max_terms, const V& init_value, V& norm) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + boost::math::uintmax_t counter = max_terms; + + result_type result = init_value; + result_type next_term; + do { + next_term = func(); + result += next_term; + norm += fabs(next_term); + } while ((abs(factor * result) < abs(next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + + +// +// Algorithm kahan_sum_series invokes Functor func until the N'th +// term is too small to have any effect on the total, the terms +// are added using the Kahan summation method. +// +// CAUTION: Optimizing compilers combined with extended-precision +// machine registers conspire to render this algorithm partly broken: +// double rounding of intermediate terms (first to a long double machine +// register, and then to a double result) cause the rounding error computed +// by the algorithm to be off by up to 1ulp. However this occurs rarely, and +// in any case the result is still much better than a naive summation. +// +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + result_type factor = pow(result_type(2), result_type(bits)); + result_type result = func(); + result_type next_term, y, t; + result_type carry = 0; + do{ + next_term = func(); + y = next_term - carry; + t = result + y; + carry = t - result; + carry -= y; + result = t; + } + while(fabs(result) < fabs(factor * next_term)); + return result; +} + +template +BOOST_MATH_GPU_ENABLED inline typename Functor::result_type kahan_sum_series(Functor& func, int bits, boost::math::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) +#ifndef BOOST_MATH_HAS_GPU_SUPPORT +&& noexcept(std::declval()()) +#endif +) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + boost::math::uintmax_t counter = max_terms; + + result_type factor = ldexp(result_type(1), bits); + result_type result = func(); + result_type next_term, y, t; + result_type carry = 0; + do{ + next_term = func(); + y = next_term - carry; + t = result + y; + carry = t - result; + carry -= y; + result = t; + } + while((fabs(result) < fabs(factor * next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_SERIES_INCLUDED + diff --git a/third-party/boost-math/include/boost/math/tools/signal_statistics.hpp b/third-party/boost-math/include/boost/math/tools/signal_statistics.hpp new file mode 100644 index 0000000000000..419e55f60aa61 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/signal_statistics.hpp @@ -0,0 +1,353 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP +#define BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost::math::tools { + +template +auto absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + using std::abs; + using RealOrComplex = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last, [](RealOrComplex a, RealOrComplex b) { return abs(b) > abs(a); }); + + + decltype(abs(*first)) i = 1; + decltype(abs(*first)) num = 0; + decltype(abs(*first)) denom = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + num += tmp*i; + denom += tmp; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + decltype(abs(*first)) zero = 0; + return zero; + } + return ((2*num)/denom - i)/(i-1); +} + +template +inline auto absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::tools::absolute_gini_coefficient(v.begin(), v.end()); +} + +template +auto sample_absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + return n*boost::math::tools::absolute_gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::tools::sample_absolute_gini_coefficient(v.begin(), v.end()); +} + + +// The Hoyer sparsity measure is defined in: +// https://arxiv.org/pdf/0811.4706.pdf +template +auto hoyer_sparsity(const ForwardIterator first, const ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Hoyer sparsity requires at least two samples."); + + if constexpr (std::is_unsigned::value) + { + T l1 = 0; + T l2 = 0; + size_t n = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + l2 += (*it)*(*it); + n += 1; + } + + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else { + decltype(abs(*first)) l1 = 0; + decltype(abs(*first)) l2 = 0; + // We wouldn't need to count the elements if it was a random access iterator, + // but our only constraint is that it's a forward iterator. + size_t n = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + l1 += tmp; + l2 += tmp*tmp; + n += 1; + } + if constexpr (std::is_integral::value) + { + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else + { + decltype(abs(*first)) rootn = sqrt(static_cast(n)); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + } +} + +template +inline auto hoyer_sparsity(Container const & v) +{ + return boost::math::tools::hoyer_sparsity(v.cbegin(), v.cend()); +} + + +template +auto oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), + "Signal and noisy_signal must be have the same number of elements."); + if constexpr (std::is_integral::value) + { + double numerator = 0; + double denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (noisy_signal[i] - signal[i])*(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + return numerator/denominator; + } + else if constexpr (boost::math::tools::is_complex_type::value) + + { + using std::norm; + typename Real::value_type numerator = 0; + typename Real::value_type denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += norm(signal[i]); + denominator += norm(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } + else + { + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } +} + +template +auto mean_invariant_oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), "Signal and noisy signal must be have the same number of elements."); + + Real mu = boost::math::tools::mean(signal); + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + Real tmp = signal[i] - mu; + numerator += tmp*tmp; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + +} + +template +auto mean_invariant_oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::tools::mean_invariant_oracle_snr(signal, noisy_signal)); +} + + +// Follows the definition of SNR given in Mallat, A Wavelet Tour of Signal Processing, equation 11.16. +template +auto oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::tools::oracle_snr(signal, noisy_signal)); +} + +// A good reference on the M2M4 estimator: +// D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR estimation techniques for the AWGN channel," IEEE Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. +// A nice python implementation: +// https://github.com/gnuradio/gnuradio/blob/master/gr-digital/examples/snr_estimators.py +template +auto m2m4_snr_estimator(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + BOOST_MATH_ASSERT_MSG(estimated_signal_kurtosis > 0, "The estimated signal kurtosis must be positive"); + BOOST_MATH_ASSERT_MSG(estimated_noise_kurtosis > 0, "The estimated noise kurtosis must be positive."); + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + if constexpr (std::is_floating_point::value || std::numeric_limits::max_exponent) + { + // If we first eliminate N, we obtain the quadratic equation: + // (ka+kw-6)S^2 + 2M2(3-kw)S + kw*M2^2 - M4 = 0 =: a*S^2 + bs*N + cs = 0 + // If we first eliminate S, we obtain the quadratic equation: + // (ka+kw-6)N^2 + 2M2(3-ka)N + ka*M2^2 - M4 = 0 =: a*N^2 + bn*N + cn = 0 + // I believe these equations are totally independent quadratics; + // if one has a complex solution it is not necessarily the case that the other must also. + // However, I can't prove that, so there is a chance that this does unnecessary work. + // Future improvements: There are algorithms which can solve quadratics much more effectively than the naive implementation found here. + // See: https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711#50065711 + auto [M1, M2, M3, M4] = boost::math::tools::first_four_moments(first, last); + if (M4 == 0) + { + // The signal is constant. There is no noise: + return std::numeric_limits::infinity(); + } + // Change to notation in Pauluzzi, equation 41: + auto kw = estimated_noise_kurtosis; + auto ka = estimated_signal_kurtosis; + // A common case, since it's the default: + Real a = (ka+kw-6); + Real bs = 2*M2*(3-kw); + Real cs = kw*M2*M2 - M4; + Real bn = 2*M2*(3-ka); + Real cn = ka*M2*M2 - M4; + auto [S0, S1] = boost::math::tools::quadratic_roots(a, bs, cs); + if (S1 > 0) + { + auto N = M2 - S1; + if (N > 0) + { + return S1/N; + } + if (S0 > 0) + { + N = M2 - S0; + if (N > 0) + { + return S0/N; + } + } + } + auto [N0, N1] = boost::math::tools::quadratic_roots(a, bn, cn); + if (N1 > 0) + { + auto S = M2 - N1; + if (S > 0) + { + return S/N1; + } + if (N0 > 0) + { + S = M2 - N0; + if (S > 0) + { + return S/N0; + } + } + } + // This happens distressingly often. It's a limitation of the method. + return std::numeric_limits::quiet_NaN(); + } + else + { + BOOST_MATH_ASSERT_MSG(false, "The M2M4 estimator has not been implemented for this type."); + return std::numeric_limits::quiet_NaN(); + } +} + +template +inline auto m2m4_snr_estimator(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + return m2m4_snr_estimator(noisy_signal.cbegin(), noisy_signal.cend(), estimated_signal_kurtosis, estimated_noise_kurtosis); +} + +template +inline auto m2m4_snr_estimator_db(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(first, last, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + + +template +inline auto m2m4_snr_estimator_db(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(noisy_signal, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/simple_continued_fraction.hpp b/third-party/boost-math/include/boost/math/tools/simple_continued_fraction.hpp new file mode 100644 index 0000000000000..daf2c3c657fc2 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/simple_continued_fraction.hpp @@ -0,0 +1,177 @@ +// (C) Copyright Nick Thompson 2020. +// 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) + +#ifndef BOOST_MATH_TOOLS_SIMPLE_CONTINUED_FRACTION_HPP +#define BOOST_MATH_TOOLS_SIMPLE_CONTINUED_FRACTION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace boost::math::tools { + +template +class simple_continued_fraction { +public: + simple_continued_fraction(Real x) : x_{x} { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) { + throw std::domain_error("Cannot convert non-finites into continued fractions."); + } + b_.reserve(50); + Real bj = floor(x); + b_.push_back(static_cast(bj)); + if (bj == x) { + b_.shrink_to_fit(); + return; + } + x = 1/(x-bj); + Real f = bj; + if (bj == 0) { + f = 16*(std::numeric_limits::min)(); + } + Real C = f; + Real D = 0; + int i = 0; + // the "1 + i++" lets the error bound grow slowly with the number of convergents. + // I have not worked out the error propagation of the Modified Lentz's method to see if it does indeed grow at this rate. + // Numerical Recipes claims that no one has worked out the error analysis of the modified Lentz's method. + while (abs(f - x_) >= (1 + i++)*std::numeric_limits::epsilon()*abs(x_)) + { + bj = floor(x); + b_.push_back(static_cast(bj)); + x = 1/(x-bj); + D += bj; + if (D == 0) { + D = 16*(std::numeric_limits::min)(); + } + C = bj + 1/C; + if (C==0) { + C = 16*(std::numeric_limits::min)(); + } + D = 1/D; + f *= (C*D); + } + // Deal with non-uniqueness of continued fractions: [a0; a1, ..., an, 1] = a0; a1, ..., an + 1]. + // The shorter representation is considered the canonical representation, + // so if we compute a non-canonical representation, change it to canonical: + if (b_.size() > 2 && b_.back() == 1) { + b_[b_.size() - 2] += 1; + b_.resize(b_.size() - 1); + } + b_.shrink_to_fit(); + + for (size_t i = 1; i < b_.size(); ++i) { + if (b_[i] <= 0) { + std::ostringstream oss; + oss << "Found a negative partial denominator: b[" << i << "] = " << b_[i] << "." + #ifndef BOOST_MATH_STANDALONE + << " This means the integer type '" << boost::core::demangle(typeid(Z).name()) + #else + << " This means the integer type '" << typeid(Z).name() + #endif + << "' has overflowed and you need to use a wider type," + << " or there is a bug."; + throw std::overflow_error(oss.str()); + } + } + } + + Real khinchin_geometric_mean() const { + if (b_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + // Precompute the most probable logarithms. See the Gauss-Kuzmin distribution for details. + // Example: b_i = 1 has probability -log_2(3/4) ~ .415: + // A random partial denominator has ~80% chance of being in this table: + const std::array logs{std::numeric_limits::quiet_NaN(), Real(0), log(static_cast(2)), log(static_cast(3)), log(static_cast(4)), log(static_cast(5)), log(static_cast(6))}; + Real log_prod = 0; + for (size_t i = 1; i < b_.size(); ++i) { + if (b_[i] < static_cast(logs.size())) { + log_prod += logs[b_[i]]; + } + else + { + log_prod += log(static_cast(b_[i])); + } + } + log_prod /= (b_.size()-1); + return exp(log_prod); + } + + Real khinchin_harmonic_mean() const { + if (b_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + Real n = b_.size() - 1; + Real denom = 0; + for (size_t i = 1; i < b_.size(); ++i) { + denom += 1/static_cast(b_[i]); + } + return n/denom; + } + + const std::vector& partial_denominators() const { + return b_; + } + + template + friend std::ostream& operator<<(std::ostream& out, simple_continued_fraction& scf); + +private: + const Real x_; + std::vector b_; +}; + + +template +std::ostream& operator<<(std::ostream& out, simple_continued_fraction& scf) { + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) { + out << std::setprecision(scf.x_.backend().precision()); + } else { + out << std::setprecision(p); + } + + out << "[" << scf.b_.front(); + if (scf.b_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < scf.b_.size() -1; ++i) + { + out << scf.b_[i] << ", "; + } + out << scf.b_.back(); + } + out << "]"; + return out; +} + + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/stats.hpp b/third-party/boost-math/include/boost/math/tools/stats.hpp new file mode 100644 index 0000000000000..b57cc7951d01a --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/stats.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2005-2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_STATS_INCLUDED +#define BOOST_MATH_TOOLS_STATS_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +class stats +{ +public: + stats() + : m_min(tools::max_value()), + m_max(-tools::max_value()), + m_total(0), + m_squared_total(0) + {} + void add(const T& val) + { + if(val < m_min) + m_min = val; + if(val > m_max) + m_max = val; + m_total += val; + ++m_count; + m_squared_total += val*val; + } + T min BOOST_MATH_PREVENT_MACRO_SUBSTITUTION()const{ return m_min; } + T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION()const{ return m_max; } + T total()const{ return m_total; } + T mean()const{ return m_total / static_cast(m_count); } + std::uintmax_t count()const{ return m_count; } + T variance()const + { + BOOST_MATH_STD_USING + + T t = m_squared_total - m_total * m_total / m_count; + t /= m_count; + return t; + } + T variance1()const + { + BOOST_MATH_STD_USING + + T t = m_squared_total - m_total * m_total / m_count; + t /= (m_count-1); + return t; + } + T rms()const + { + BOOST_MATH_STD_USING + + return sqrt(m_squared_total / static_cast(m_count)); + } + stats& operator+=(const stats& s) + { + if(s.m_min < m_min) + m_min = s.m_min; + if(s.m_max > m_max) + m_max = s.m_max; + m_total += s.m_total; + m_squared_total += s.m_squared_total; + m_count += s.m_count; + return *this; + } +private: + T m_min, m_max, m_total, m_squared_total; + std::uintmax_t m_count{0}; +}; + +} // namespace tools +} // namespace math +} // namespace boost + +#endif + diff --git a/third-party/boost-math/include/boost/math/tools/test_value.hpp b/third-party/boost-math/include/boost/math/tools/test_value.hpp new file mode 100644 index 0000000000000..c44fe052894fe --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/test_value.hpp @@ -0,0 +1,143 @@ +// Copyright Paul A. Bristow 2017. +// Copyright John Maddock 2017. + +// 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) + +// test_value.hpp + +#ifndef TEST_VALUE_HPP +#define TEST_VALUE_HPP + +// BOOST_MATH_TEST_VALUE is used to create a test value of suitable type from a decimal digit string. +// Two parameters, both a floating-point literal double like 1.23 (not long double so no suffix L) +// and a decimal digit string const char* like "1.23" must be provided. +// The decimal value represented must be the same of course, with at least enough precision for long double. +// Note there are two gotchas to this approach: +// * You need all values to be real floating-point values +// * and *MUST* include a decimal point (to avoid confusion with an integer literal). +// * It's slow to compile compared to a simple literal. + +// Speed is not an issue for a few test values, +// but it's not generally usable in large tables +// where you really need everything to be statically initialized. + +// Macro BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE provides a global diagnostic value for create_type. + +#include // For float_64_t, float128_t. Must be first include! +#ifndef BOOST_MATH_STANDALONE +#include +#endif +#include +#include + +#ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE +// global int create_type(0); must be defined before including this file. +#endif + +#ifdef BOOST_HAS_FLOAT128 +typedef __float128 largest_float; +#define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##Q +#define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS 113 +#else +typedef long double largest_float; +#define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##L +#define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS std::numeric_limits::digits +#endif + +template +inline T create_test_value(largest_float val, const char*, const std::true_type&, const T2&) +{ // Construct from long double or quad parameter val (ignoring string/const char* str). + // (This is case for MPL parameters = true_ and T2 == false_, + // and MPL parameters = true_ and T2 == true_ cpp_bin_float) + // All built-in/fundamental floating-point types, + // and other User-Defined Types that can be constructed without loss of precision + // from long double suffix L (or quad suffix Q), + // + // Choose this method, even if can be constructed from a string, + // because it will be faster, and more likely to be the closest representation. + // (This is case for MPL parameters = true_type and T2 == true_type). + #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 1; + #endif + return static_cast(val); +} + +template +inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::true_type&) +{ // Construct from decimal digit string const char* @c str (ignoring long double parameter). + // For example, extended precision or other User-Defined types which ARE constructible from a string + // (but not from double, or long double without loss of precision). + // (This is case for MPL parameters = false_type and T2 == true_type). + #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 2; + #endif + return T(str); +} + +template +inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::false_type&) +{ // Create test value using from lexical cast of decimal digit string const char* str. + // For example, extended precision or other User-Defined types which are NOT constructible from a string + // (NOR constructible from a long double). + // (This is case T1 = false_type and T2 == false_type). +#ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 3; +#endif +#if defined(BOOST_MATH_STANDALONE) + static_assert(sizeof(T) == 0, "Can not create a test value using lexical cast of string in standalone mode"); + return T(); +#else + return boost::lexical_cast(str); +#endif +} + +// T real type, x a decimal digits representation of a floating-point, for example: 12.34. +// It must include a decimal point (or it would be interpreted as an integer). + +// x is converted to a long double by appending the letter L (to suit long double fundamental type), 12.34L. +// x is also passed as a const char* or string representation "12.34" +// (to suit most other types that cannot be constructed from long double without possible loss). + +// BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) makes a long double or quad version, with +// suffix a letter L (or Q) to suit long double (or quad) fundamental type, 12.34L or 12.34Q. +// #x makes a decimal digit string version to suit multiprecision and fixed_point constructors, "12.34". +// (Constructing from double or long double (or quad) could lose precision for multiprecision or fixed-point). + +// The matching create_test_value function above is chosen depending on the T1 and T2 mpl bool truths. +// The string version from #x is used if the precision of T is greater than long double. + +// Example: long double test_value = BOOST_MATH_TEST_VALUE(double, 1.23456789); + +#define BOOST_MATH_TEST_VALUE(T, x) create_test_value(\ + BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x),\ + #x,\ + std::integral_constant::is_specialized &&\ + (std::numeric_limits::radix == 2)\ + && (std::numeric_limits::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ + && (std::is_convertible::value || std::is_floating_point::value)>(),\ + std::integral_constant::value>()\ +) + +#if LDBL_MAX_10_EXP > DBL_MAX_10_EXP +#define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) +#else +#define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) 0.0 +#endif + +#define BOOST_MATH_HUGE_TEST_VALUE(T, x) create_test_value(\ + BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x),\ + #x,\ + std::integral_constant::is_specialized &&\ + (std::numeric_limits::radix == 2)\ + && (std::numeric_limits::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ + && std::is_convertible::value>(),\ + std::integral_constant::value>()\ +) +#endif // TEST_VALUE_HPP diff --git a/third-party/boost-math/include/boost/math/tools/throw_exception.hpp b/third-party/boost-math/include/boost/math/tools/throw_exception.hpp new file mode 100644 index 0000000000000..3a918db9432e7 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/throw_exception.hpp @@ -0,0 +1,43 @@ +// (C) Copyright Matt Borland 2021. +// 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) + +#ifndef BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP +#define BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP + +#include + +#ifndef BOOST_MATH_STANDALONE + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +#include +#define BOOST_MATH_THROW_EXCEPTION(expr) boost::throw_exception(expr); + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#else // Standalone mode - use standard library facilities + +#ifdef _MSC_VER +# ifdef _CPPUNWIND +# define BOOST_MATH_THROW_EXCEPTION(expr) throw expr; +# else +# define BOOST_MATH_THROW_EXCEPTION(expr) +# endif +#else +# ifdef __EXCEPTIONS +# define BOOST_MATH_THROW_EXCEPTION(expr) throw expr; +# else +# define BOOST_MATH_THROW_EXCEPTION(expr) +# endif +#endif + +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP diff --git a/third-party/boost-math/include/boost/math/tools/toms748_solve.hpp b/third-party/boost-math/include/boost/math/tools/toms748_solve.hpp new file mode 100644 index 0000000000000..ed2d09444a6cf --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/toms748_solve.hpp @@ -0,0 +1,636 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_TOOLS_SOLVE_ROOT_HPP +#define BOOST_MATH_TOOLS_SOLVE_ROOT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_LOG_ROOT_ITERATIONS +# define BOOST_MATH_LOGGER_INCLUDE +# include BOOST_MATH_LOGGER_INCLUDE +# undef BOOST_MATH_LOGGER_INCLUDE +#else +# define BOOST_MATH_LOG_COUNT(count) +#endif + +namespace boost{ namespace math{ namespace tools{ + +template +class eps_tolerance +{ +public: + BOOST_MATH_GPU_ENABLED eps_tolerance() : eps(4 * tools::epsilon()) + { + + } + BOOST_MATH_GPU_ENABLED eps_tolerance(unsigned bits) + { + BOOST_MATH_STD_USING + eps = BOOST_MATH_GPU_SAFE_MAX(T(ldexp(1.0F, 1-bits)), T(4 * tools::epsilon())); + } + BOOST_MATH_GPU_ENABLED bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return fabs(a - b) <= (eps * BOOST_MATH_GPU_SAFE_MIN(fabs(a), fabs(b))); + } +private: + T eps; +}; + +// CUDA warns about __host__ __device__ marker on defaulted constructor +// but the warning is benign +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_suppress 20012 +#endif + +struct equal_floor +{ + BOOST_MATH_GPU_ENABLED equal_floor() = default; + + template + BOOST_MATH_GPU_ENABLED bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return (floor(a) == floor(b)) || (fabs((b-a)/b) < boost::math::tools::epsilon() * 2); + } +}; + +struct equal_ceil +{ + BOOST_MATH_GPU_ENABLED equal_ceil() = default; + + template + BOOST_MATH_GPU_ENABLED bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return (ceil(a) == ceil(b)) || (fabs((b - a) / b) < boost::math::tools::epsilon() * 2); + } +}; + +struct equal_nearest_integer +{ + BOOST_MATH_GPU_ENABLED equal_nearest_integer() = default; + + template + BOOST_MATH_GPU_ENABLED bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return (floor(a + 0.5f) == floor(b + 0.5f)) || (fabs((b - a) / b) < boost::math::tools::epsilon() * 2); + } +}; + +#ifdef BOOST_MATH_ENABLE_CUDA +# pragma nv_diag_default 20012 +#endif + +namespace detail{ + +template +BOOST_MATH_GPU_ENABLED void bracket(F f, T& a, T& b, T c, T& fa, T& fb, T& d, T& fd) +{ + // + // Given a point c inside the existing enclosing interval + // [a, b] sets a = c if f(c) == 0, otherwise finds the new + // enclosing interval: either [a, c] or [c, b] and sets + // d and fd to the point that has just been removed from + // the interval. In other words d is the third best guess + // to the root. + // + BOOST_MATH_STD_USING // For ADL of std math functions + T tol = tools::epsilon() * 2; + // + // If the interval [a,b] is very small, or if c is too close + // to one end of the interval then we need to adjust the + // location of c accordingly: + // + if((b - a) < 2 * tol * a) + { + c = a + (b - a) / 2; + } + else if(c <= a + fabs(a) * tol) + { + c = a + fabs(a) * tol; + } + else if(c >= b - fabs(b) * tol) + { + c = b - fabs(b) * tol; + } + // + // OK, lets invoke f(c): + // + T fc = f(c); + // + // if we have a zero then we have an exact solution to the root: + // + if(fc == 0) + { + a = c; + fa = 0; + d = 0; + fd = 0; + return; + } + // + // Non-zero fc, update the interval: + // + if(boost::math::sign(fa) * boost::math::sign(fc) < 0) + { + d = b; + fd = fb; + b = c; + fb = fc; + } + else + { + d = a; + fd = fa; + a = c; + fa= fc; + } +} + +template +BOOST_MATH_GPU_ENABLED inline T safe_div(T num, T denom, T r) +{ + // + // return num / denom without overflow, + // return r if overflow would occur. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + if(fabs(denom) < 1) + { + if(fabs(denom * tools::max_value()) <= fabs(num)) + return r; + } + return num / denom; +} + +template +BOOST_MATH_GPU_ENABLED inline T secant_interpolate(const T& a, const T& b, const T& fa, const T& fb) +{ + // + // Performs standard secant interpolation of [a,b] given + // function evaluations f(a) and f(b). Performs a bisection + // if secant interpolation would leave us very close to either + // a or b. Rationale: we only call this function when at least + // one other form of interpolation has already failed, so we know + // that the function is unlikely to be smooth with a root very + // close to a or b. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + T tol = tools::epsilon() * 5; + T c = a - (fa / (fb - fa)) * (b - a); + if((c <= a + fabs(a) * tol) || (c >= b - fabs(b) * tol)) + return (a + b) / 2; + return c; +} + +template +BOOST_MATH_GPU_ENABLED T quadratic_interpolate(const T& a, const T& b, T const& d, + const T& fa, const T& fb, T const& fd, + unsigned count) +{ + // + // Performs quadratic interpolation to determine the next point, + // takes count Newton steps to find the location of the + // quadratic polynomial. + // + // Point d must lie outside of the interval [a,b], it is the third + // best approximation to the root, after a and b. + // + // Note: this does not guarantee to find a root + // inside [a, b], so we fall back to a secant step should + // the result be out of range. + // + // Start by obtaining the coefficients of the quadratic polynomial: + // + T B = safe_div(T(fb - fa), T(b - a), tools::max_value()); + T A = safe_div(T(fd - fb), T(d - b), tools::max_value()); + A = safe_div(T(A - B), T(d - a), T(0)); + + if(A == 0) + { + // failure to determine coefficients, try a secant step: + return secant_interpolate(a, b, fa, fb); + } + // + // Determine the starting point of the Newton steps: + // + T c; + if(boost::math::sign(A) * boost::math::sign(fa) > 0) + { + c = a; + } + else + { + c = b; + } + // + // Take the Newton steps: + // + for(unsigned i = 1; i <= count; ++i) + { + //c -= safe_div(B * c, (B + A * (2 * c - a - b)), 1 + c - a); + c -= safe_div(T(fa+(B+A*(c-b))*(c-a)), T(B + A * (2 * c - a - b)), T(1 + c - a)); + } + if((c <= a) || (c >= b)) + { + // Oops, failure, try a secant step: + c = secant_interpolate(a, b, fa, fb); + } + return c; +} + +template +BOOST_MATH_GPU_ENABLED T cubic_interpolate(const T& a, const T& b, const T& d, + const T& e, const T& fa, const T& fb, + const T& fd, const T& fe) +{ + // + // Uses inverse cubic interpolation of f(x) at points + // [a,b,d,e] to obtain an approximate root of f(x). + // Points d and e lie outside the interval [a,b] + // and are the third and forth best approximations + // to the root that we have found so far. + // + // Note: this does not guarantee to find a root + // inside [a, b], so we fall back to quadratic + // interpolation in case of an erroneous result. + // + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b + << " d = " << d << " e = " << e << " fa = " << fa << " fb = " << fb + << " fd = " << fd << " fe = " << fe); + T q11 = (d - e) * fd / (fe - fd); + T q21 = (b - d) * fb / (fd - fb); + T q31 = (a - b) * fa / (fb - fa); + T d21 = (b - d) * fd / (fd - fb); + T d31 = (a - b) * fb / (fb - fa); + BOOST_MATH_INSTRUMENT_CODE( + "q11 = " << q11 << " q21 = " << q21 << " q31 = " << q31 + << " d21 = " << d21 << " d31 = " << d31); + T q22 = (d21 - q11) * fb / (fe - fb); + T q32 = (d31 - q21) * fa / (fd - fa); + T d32 = (d31 - q21) * fd / (fd - fa); + T q33 = (d32 - q22) * fa / (fe - fa); + T c = q31 + q32 + q33 + a; + BOOST_MATH_INSTRUMENT_CODE( + "q22 = " << q22 << " q32 = " << q32 << " d32 = " << d32 + << " q33 = " << q33 << " c = " << c); + + if((c <= a) || (c >= b)) + { + // Out of bounds step, fall back to quadratic interpolation: + c = quadratic_interpolate(a, b, d, fa, fb, fd, 3); + BOOST_MATH_INSTRUMENT_CODE( + "Out of bounds interpolation, falling back to quadratic interpolation. c = " << c); + } + + return c; +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED boost::math::pair toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::math::uintmax_t& max_iter, const Policy& pol) +{ + // + // Main entry point and logic for Toms Algorithm 748 + // root finder. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + constexpr auto function = "boost::math::tools::toms748_solve<%1%>"; + + // + // Sanity check - are we allowed to iterate at all? + // + if (max_iter == 0) + return boost::math::make_pair(ax, bx); + + boost::math::uintmax_t count = max_iter; + T a, b, fa, fb, c, u, fu, a0, b0, d, fd, e, fe; + static const T mu = 0.5f; + + // initialise a, b and fa, fb: + a = ax; + b = bx; + if(a >= b) + return boost::math::detail::pair_from_single(policies::raise_domain_error( + function, + "Parameters a and b out of order: a=%1%", a, pol)); + fa = fax; + fb = fbx; + + if(tol(a, b) || (fa == 0) || (fb == 0)) + { + max_iter = 0; + if(fa == 0) + b = a; + else if(fb == 0) + a = b; + return boost::math::make_pair(a, b); + } + + if(boost::math::sign(fa) * boost::math::sign(fb) > 0) + return boost::math::detail::pair_from_single(policies::raise_domain_error( + function, + "Parameters a and b do not bracket the root: a=%1%", a, pol)); + // dummy value for fd, e and fe: + fe = e = fd = 1e5F; + + if(fa != 0) + { + // + // On the first step we take a secant step: + // + c = detail::secant_interpolate(a, b, fa, fb); + detail::bracket(f, a, b, c, fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + + if(count && (fa != 0) && !tol(a, b)) + { + // + // On the second step we take a quadratic interpolation: + // + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2); + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + } + } + + while(count && (fa != 0) && !tol(a, b)) + { + // save our brackets: + a0 = a; + b0 = b; + // + // Starting with the third step taken + // we can use either quadratic or cubic interpolation. + // Cubic interpolation requires that all four function values + // fa, fb, fd, and fe are distinct, should that not be the case + // then variable prof will get set to true, and we'll end up + // taking a quadratic step instead. + // + T min_diff = tools::min_value() * 32; + bool prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff); + if(prof) + { + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2); + BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!"); + } + else + { + c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe); + } + // + // re-bracket, and check for termination: + // + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + // + // Now another interpolated step: + // + prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff); + if(prof) + { + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 3); + BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!"); + } + else + { + c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe); + } + // + // Bracket again, and check termination condition, update e: + // + detail::bracket(f, a, b, c, fa, fb, d, fd); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + // + // Now we take a double-length secant step: + // + if(fabs(fa) < fabs(fb)) + { + u = a; + fu = fa; + } + else + { + u = b; + fu = fb; + } + c = u - 2 * (fu / (fb - fa)) * (b - a); + if(fabs(c - u) > (b - a) / 2) + { + c = a + (b - a) / 2; + } + // + // Bracket again, and check termination condition: + // + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + BOOST_MATH_INSTRUMENT_CODE(" tol = " << T((fabs(a) - fabs(b)) / fabs(a))); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + // + // And finally... check to see if an additional bisection step is + // to be taken, we do this if we're not converging fast enough: + // + if((b - a) < mu * (b0 - a0)) + continue; + // + // bracket again on a bisection: + // + e = d; + fe = fd; + detail::bracket(f, a, b, T(a + (b - a) / 2), fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE("Not converging: Taking a bisection!!!!"); + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + } // while loop + + max_iter -= count; + if(fa == 0) + { + b = a; + } + else if(fb == 0) + { + a = b; + } + BOOST_MATH_LOG_COUNT(max_iter) + return boost::math::make_pair(a, b); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::math::uintmax_t& max_iter) +{ + return toms748_solve(f, ax, bx, fax, fbx, tol, max_iter, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair toms748_solve(F f, const T& ax, const T& bx, Tol tol, boost::math::uintmax_t& max_iter, const Policy& pol) +{ + if (max_iter <= 2) + return boost::math::make_pair(ax, bx); + max_iter -= 2; + boost::math::pair r = toms748_solve(f, ax, bx, f(ax), f(bx), tol, max_iter, pol); + max_iter += 2; + return r; +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair toms748_solve(F f, const T& ax, const T& bx, Tol tol, boost::math::uintmax_t& max_iter) +{ + return toms748_solve(f, ax, bx, tol, max_iter, policies::policy<>()); +} + +template +BOOST_MATH_GPU_ENABLED boost::math::pair bracket_and_solve_root(F f, const T& guess, T factor, bool rising, Tol tol, boost::math::uintmax_t& max_iter, const Policy& pol) +{ + BOOST_MATH_STD_USING + constexpr auto function = "boost::math::tools::bracket_and_solve_root<%1%>"; + // + // Set up initial brackets: + // + T a = guess; + T b = a; + T fa = f(a); + T fb = fa; + // + // Set up invocation count: + // + boost::math::uintmax_t count = max_iter - 1; + + int step = 32; + + if((fa < 0) == (guess < 0 ? !rising : rising)) + { + // + // Zero is to the right of b, so walk upwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(count == 0) + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol)); + // + // Heuristic: normally it's best not to increase the step sizes as we'll just end up + // with a really wide range to search for the root. However, if the initial guess was *really* + // bad then we need to speed up the search otherwise we'll take forever if we're orders of + // magnitude out. This happens most often if the guess is a small value (say 1) and the result + // we're looking for is close to std::numeric_limits::min(). + // + if((max_iter - count) % static_cast(step) == 0u) + { + factor *= 2; + if(step > 1) step /= 2; + } + // + // Now go ahead and move our guess by "factor": + // + a = b; + fa = fb; + b *= factor; + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return a > 0 ? boost::math::make_pair(T(0), T(a)) : boost::math::make_pair(T(a), T(0)); + } + if(count == 0) + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol)); + // + // Heuristic: normally it's best not to increase the step sizes as we'll just end up + // with a really wide range to search for the root. However, if the initial guess was *really* + // bad then we need to speed up the search otherwise we'll take forever if we're orders of + // magnitude out. This happens most often if the guess is a small value (say 1) and the result + // we're looking for is close to std::numeric_limits::min(). + // + if((max_iter - count) % static_cast(step) == 0u) + { + factor *= 2; + if(step > 1) step /= 2; + } + // + // Now go ahead and move are guess by "factor": + // + b = a; + fb = fa; + a /= factor; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + max_iter -= count; + max_iter += 1; + boost::math::pair r = toms748_solve( + f, + (a < 0 ? b : a), + (a < 0 ? a : b), + (a < 0 ? fb : fa), + (a < 0 ? fa : fb), + tol, + count, + pol); + max_iter += count; + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + BOOST_MATH_LOG_COUNT(max_iter) + return r; +} + +template +BOOST_MATH_GPU_ENABLED inline boost::math::pair bracket_and_solve_root(F f, const T& guess, const T& factor, bool rising, Tol tol, boost::math::uintmax_t& max_iter) +{ + return bracket_and_solve_root(f, guess, factor, rising, tol, max_iter, policies::policy<>()); +} + +} // namespace tools +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_TOOLS_SOLVE_ROOT_HPP + diff --git a/third-party/boost-math/include/boost/math/tools/traits.hpp b/third-party/boost-math/include/boost/math/tools/traits.hpp new file mode 100644 index 0000000000000..e909881e611b9 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/traits.hpp @@ -0,0 +1,140 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2021. +// 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) + +/* +This header defines two traits classes, both in namespace boost::math::tools. + +is_distribution::value is true iff D has overloaded "cdf" and +"quantile" functions, plus member typedefs value_type and policy_type. +It's not much of a definitive test frankly, +but if it looks like a distribution and quacks like a distribution +then it must be a distribution. + +is_scaled_distribution::value is true iff D is a distribution +as defined above, and has member functions "scale" and "location". + +*/ + +#ifndef BOOST_STATS_IS_DISTRIBUTION_HPP +#define BOOST_STATS_IS_DISTRIBUTION_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +namespace boost{ namespace math{ namespace tools{ + +namespace detail{ + +#define BOOST_MATH_HAS_NAMED_TRAIT(trait, name) \ +template \ +class trait \ +{ \ +private: \ + using yes = char; \ + struct no { char x[2]; }; \ + \ + template \ + static yes test(typename U::name* = nullptr); \ + \ + template \ + static no test(...); \ + \ +public: \ + static constexpr bool value = (sizeof(test(0)) == sizeof(char)); \ +}; + +BOOST_MATH_HAS_NAMED_TRAIT(has_value_type, value_type) +BOOST_MATH_HAS_NAMED_TRAIT(has_policy_type, policy_type) +BOOST_MATH_HAS_NAMED_TRAIT(has_backend_type, backend_type) + +// C++17-esque helpers +#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304L +template +constexpr bool has_value_type_v = has_value_type::value; + +template +constexpr bool has_policy_type_v = has_policy_type::value; + +template +constexpr bool has_backend_type_v = has_backend_type::value; +#endif + +template +char cdf(const D&, ...); +template +char quantile(const D&, ...); + +template +struct has_cdf +{ + static D d; + static constexpr bool value = sizeof(cdf(d, 0.0f)) != 1; +}; + +template +struct has_quantile +{ + static D d; + static constexpr bool value = sizeof(quantile(d, 0.0f)) != 1; +}; + +template +struct is_distribution_imp +{ + static constexpr bool value = + has_quantile::value + && has_cdf::value + && has_value_type::value + && has_policy_type::value; +}; + +template +struct result_tag{}; + +template +double test_has_location(const volatile result_tag*); +template +char test_has_location(...); + +template +double test_has_scale(const volatile result_tag*); +template +char test_has_scale(...); + +template +struct is_scaled_distribution_helper +{ + static constexpr bool value = false; +}; + +template +struct is_scaled_distribution_helper +{ + static constexpr bool value = + (sizeof(test_has_location(0)) != 1) + && + (sizeof(test_has_scale(0)) != 1); +}; + +template +struct is_scaled_distribution_imp +{ + static constexpr bool value = (::boost::math::tools::detail::is_scaled_distribution_helper::value>::value); +}; + +} // namespace detail + +template struct is_distribution : public std::integral_constant::value> {}; +template struct is_scaled_distribution : public std::integral_constant::value> {}; + +}}} + +#endif + + diff --git a/third-party/boost-math/include/boost/math/tools/tuple.hpp b/third-party/boost-math/include/boost/math/tools/tuple.hpp new file mode 100644 index 0000000000000..dcc763e37a66b --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/tuple.hpp @@ -0,0 +1,88 @@ +// (C) Copyright John Maddock 2010. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_TUPLE_HPP_INCLUDED +#define BOOST_MATH_TUPLE_HPP_INCLUDED + +#include + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include +#include +#include + +namespace boost { +namespace math { + +using cuda::std::pair; +using cuda::std::tuple; + +using cuda::std::make_pair; + +using cuda::std::tie; +using cuda::std::get; + +using cuda::std::tuple_size; +using cuda::std::tuple_element; + +namespace detail { + +template +BOOST_MATH_GPU_ENABLED T&& forward(boost::math::remove_reference_t& arg) noexcept +{ + return static_cast(arg); +} + +template +BOOST_MATH_GPU_ENABLED T&& forward(boost::math::remove_reference_t&& arg) noexcept +{ + static_assert(!boost::math::is_lvalue_reference::value, "Cannot forward an rvalue as an lvalue."); + return static_cast(arg); +} + +} // namespace detail + +template +BOOST_MATH_GPU_ENABLED auto make_tuple(T&& t, Ts&&... ts) +{ + return cuda::std::tuple, boost::math::decay_t...>( + boost::math::detail::forward(t), boost::math::detail::forward(ts)... + ); +} + +} // namespace math +} // namespace boost + +#else + +#include + +namespace boost { +namespace math { + +using ::std::tuple; +using ::std::pair; + +// [6.1.3.2] Tuple creation functions +using ::std::ignore; +using ::std::make_tuple; +using ::std::tie; +using ::std::get; + +// [6.1.3.3] Tuple helper classes +using ::std::tuple_size; +using ::std::tuple_element; + +// Pair helpers +using ::std::make_pair; + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_ENABLE_CUDA + +#endif diff --git a/third-party/boost-math/include/boost/math/tools/type_traits.hpp b/third-party/boost-math/include/boost/math/tools/type_traits.hpp new file mode 100644 index 0000000000000..a13332797bfda --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/type_traits.hpp @@ -0,0 +1,494 @@ +// Copyright (c) 2024 Matt Borland +// 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) +// +// Regular use of is not compatible with CUDA +// Adds aliases to unify the support +// Also adds convience overloads like is_same_v so we don't have to wait for C++17 + +#ifndef BOOST_MATH_TOOLS_TYPE_TRAITS +#define BOOST_MATH_TOOLS_TYPE_TRAITS + +#include + +#ifdef BOOST_MATH_ENABLE_CUDA + +#include + +namespace boost { +namespace math { + +// Helper classes +using cuda::std::integral_constant; +using cuda::std::true_type; +using cuda::std::false_type; + +// Primary type categories +using cuda::std::is_void; +using cuda::std::is_null_pointer; +using cuda::std::is_integral; +using cuda::std::is_floating_point; +using cuda::std::is_array; +using cuda::std::is_enum; +using cuda::std::is_union; +using cuda::std::is_class; +using cuda::std::is_function; +using cuda::std::is_pointer; +using cuda::std::is_lvalue_reference; +using cuda::std::is_rvalue_reference; +using cuda::std::is_member_object_pointer; +using cuda::std::is_member_function_pointer; + +// Composite Type Categories +using cuda::std::is_fundamental; +using cuda::std::is_arithmetic; +using cuda::std::is_scalar; +using cuda::std::is_object; +using cuda::std::is_compound; +using cuda::std::is_reference; +using cuda::std::is_member_pointer; + +// Type properties +using cuda::std::is_const; +using cuda::std::is_volatile; +using cuda::std::is_trivial; +using cuda::std::is_trivially_copyable; +using cuda::std::is_standard_layout; +using cuda::std::is_empty; +using cuda::std::is_polymorphic; +using cuda::std::is_abstract; +using cuda::std::is_final; +using cuda::std::is_signed; +using cuda::std::is_unsigned; + +// Supported Operations +using cuda::std::is_constructible; +using cuda::std::is_trivially_constructible; +using cuda::std::is_nothrow_constructible; + +using cuda::std::is_default_constructible; +using cuda::std::is_trivially_default_constructible; +using cuda::std::is_nothrow_default_constructible; + +using cuda::std::is_copy_constructible; +using cuda::std::is_trivially_copy_constructible; +using cuda::std::is_nothrow_copy_constructible; + +using cuda::std::is_move_constructible; +using cuda::std::is_trivially_move_constructible; +using cuda::std::is_nothrow_move_constructible; + +using cuda::std::is_assignable; +using cuda::std::is_trivially_assignable; +using cuda::std::is_nothrow_assignable; + +using cuda::std::is_copy_assignable; +using cuda::std::is_trivially_copy_assignable; +using cuda::std::is_nothrow_copy_assignable; + +using cuda::std::is_move_assignable; +using cuda::std::is_trivially_move_assignable; +using cuda::std::is_nothrow_move_assignable; + +using cuda::std::is_destructible; +using cuda::std::is_trivially_destructible; +using cuda::std::is_nothrow_destructible; + +using cuda::std::has_virtual_destructor; + +// Property Queries +using cuda::std::alignment_of; +using cuda::std::rank; +using cuda::std::extent; + +// Type Relationships +using cuda::std::is_same; +using cuda::std::is_base_of; +using cuda::std::is_convertible; + +// Const-volatility specifiers +using cuda::std::remove_cv; +using cuda::std::remove_cv_t; +using cuda::std::remove_const; +using cuda::std::remove_const_t; +using cuda::std::remove_volatile; +using cuda::std::remove_volatile_t; +using cuda::std::add_cv; +using cuda::std::add_cv_t; +using cuda::std::add_const; +using cuda::std::add_const_t; +using cuda::std::add_volatile; +using cuda::std::add_volatile_t; + +// References +using cuda::std::remove_reference; +using cuda::std::remove_reference_t; +using cuda::std::add_lvalue_reference; +using cuda::std::add_lvalue_reference_t; +using cuda::std::add_rvalue_reference; +using cuda::std::add_rvalue_reference_t; + +// Pointers +using cuda::std::remove_pointer; +using cuda::std::remove_pointer_t; +using cuda::std::add_pointer; +using cuda::std::add_pointer_t; + +// Sign Modifiers +using cuda::std::make_signed; +using cuda::std::make_signed_t; +using cuda::std::make_unsigned; +using cuda::std::make_unsigned_t; + +// Arrays +using cuda::std::remove_extent; +using cuda::std::remove_extent_t; +using cuda::std::remove_all_extents; +using cuda::std::remove_all_extents_t; + +// Misc transformations +using cuda::std::decay; +using cuda::std::decay_t; +using cuda::std::enable_if; +using cuda::std::enable_if_t; +using cuda::std::conditional; +using cuda::std::conditional_t; +using cuda::std::common_type; +using cuda::std::common_type_t; +using cuda::std::underlying_type; +using cuda::std::underlying_type_t; + +#else // STD versions + +#include + +namespace boost { +namespace math { + +// Helper classes +using std::integral_constant; +using std::true_type; +using std::false_type; + +// Primary type categories +using std::is_void; +using std::is_null_pointer; +using std::is_integral; +using std::is_floating_point; +using std::is_array; +using std::is_enum; +using std::is_union; +using std::is_class; +using std::is_function; +using std::is_pointer; +using std::is_lvalue_reference; +using std::is_rvalue_reference; +using std::is_member_object_pointer; +using std::is_member_function_pointer; + +// Composite Type Categories +using std::is_fundamental; +using std::is_arithmetic; +using std::is_scalar; +using std::is_object; +using std::is_compound; +using std::is_reference; +using std::is_member_pointer; + +// Type properties +using std::is_const; +using std::is_volatile; +using std::is_trivial; +using std::is_trivially_copyable; +using std::is_standard_layout; +using std::is_empty; +using std::is_polymorphic; +using std::is_abstract; +using std::is_final; +using std::is_signed; +using std::is_unsigned; + +// Supported Operations +using std::is_constructible; +using std::is_trivially_constructible; +using std::is_nothrow_constructible; + +using std::is_default_constructible; +using std::is_trivially_default_constructible; +using std::is_nothrow_default_constructible; + +using std::is_copy_constructible; +using std::is_trivially_copy_constructible; +using std::is_nothrow_copy_constructible; + +using std::is_move_constructible; +using std::is_trivially_move_constructible; +using std::is_nothrow_move_constructible; + +using std::is_assignable; +using std::is_trivially_assignable; +using std::is_nothrow_assignable; + +using std::is_copy_assignable; +using std::is_trivially_copy_assignable; +using std::is_nothrow_copy_assignable; + +using std::is_move_assignable; +using std::is_trivially_move_assignable; +using std::is_nothrow_move_assignable; + +using std::is_destructible; +using std::is_trivially_destructible; +using std::is_nothrow_destructible; + +using std::has_virtual_destructor; + +// Property Queries +using std::alignment_of; +using std::rank; +using std::extent; + +// Type Relationships +using std::is_same; +using std::is_base_of; +using std::is_convertible; + +// Const-volatility specifiers +using std::remove_cv; +using std::remove_cv_t; +using std::remove_const; +using std::remove_const_t; +using std::remove_volatile; +using std::remove_volatile_t; +using std::add_cv; +using std::add_cv_t; +using std::add_const; +using std::add_const_t; +using std::add_volatile; +using std::add_volatile_t; + +// References +using std::remove_reference; +using std::remove_reference_t; +using std::add_lvalue_reference; +using std::add_lvalue_reference_t; +using std::add_rvalue_reference; +using std::add_rvalue_reference_t; + +// Pointers +using std::remove_pointer; +using std::remove_pointer_t; +using std::add_pointer; +using std::add_pointer_t; + +// Sign Modifiers +using std::make_signed; +using std::make_signed_t; +using std::make_unsigned; +using std::make_unsigned_t; + +// Arrays +using std::remove_extent; +using std::remove_extent_t; +using std::remove_all_extents; +using std::remove_all_extents_t; + +// Misc transformations +using std::decay; +using std::decay_t; +using std::enable_if; +using std::enable_if_t; +using std::conditional; +using std::conditional_t; +using std::common_type; +using std::common_type_t; +using std::underlying_type; +using std::underlying_type_t; + +#endif + +template +using bool_constant = boost::math::integral_constant; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_void_v = boost::math::is_void::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_null_pointer_v = boost::math::is_null_pointer::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_integral_v = boost::math::is_integral::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_floating_point_v = boost::math::is_floating_point::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_array_v = boost::math::is_array::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_enum_v = boost::math::is_enum::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_union_v = boost::math::is_union::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_class_v = boost::math::is_class::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_function_v = boost::math::is_function::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_pointer_v = boost::math::is_pointer::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_lvalue_reference_v = boost::math::is_lvalue_reference::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_rvalue_reference_v = boost::math::is_rvalue_reference::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_member_object_pointer_v = boost::math::is_member_object_pointer::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_member_function_pointer_v = boost::math::is_member_function_pointer::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_fundamental_v = boost::math::is_fundamental::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_arithmetic_v = boost::math::is_arithmetic::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_scalar_v = boost::math::is_scalar::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_object_v = boost::math::is_object::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_compound_v = boost::math::is_compound::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_reference_v = boost::math::is_reference::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_member_pointer_v = boost::math::is_member_pointer::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_const_v = boost::math::is_const::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_volatile_v = boost::math::is_volatile::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivial_v = boost::math::is_trivial::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_copyable_v = boost::math::is_trivially_copyable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_standard_layout_v = boost::math::is_standard_layout::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_empty_v = boost::math::is_empty::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_polymorphic_v = boost::math::is_polymorphic::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_abstract_v = boost::math::is_abstract::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_final_v = boost::math::is_final::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_signed_v = boost::math::is_signed::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_unsigned_v = boost::math::is_unsigned::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_constructible_v = boost::math::is_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_constructible_v = boost::math::is_trivially_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_constructible_v = boost::math::is_nothrow_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_default_constructible_v = boost::math::is_default_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_default_constructible_v = boost::math::is_trivially_default_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_default_constructible_v = boost::math::is_nothrow_default_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_copy_constructible_v = boost::math::is_copy_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_copy_constructible_v = boost::math::is_trivially_copy_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_copy_constructible_v = boost::math::is_nothrow_copy_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_move_constructible_v = boost::math::is_move_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_move_constructible_v = boost::math::is_trivially_move_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_move_constructible_v = boost::math::is_nothrow_move_constructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_assignable_v = boost::math::is_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_assignable_v = boost::math::is_trivially_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_assignable_v = boost::math::is_nothrow_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_copy_assignable_v = boost::math::is_copy_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_copy_assignable_v = boost::math::is_trivially_copy_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_copy_assignable_v = boost::math::is_nothrow_copy_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_move_assignable_v = boost::math::is_move_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_move_assignable_v = boost::math::is_trivially_move_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_move_assignable_v = boost::math::is_nothrow_move_assignable::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_destructible_v = boost::math::is_destructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_trivially_destructible_v = boost::math::is_trivially_destructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_nothrow_destructible_v = boost::math::is_nothrow_destructible::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool has_virtual_destructor_v = boost::math::has_virtual_destructor::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_same_v = boost::math::is_same::value; + +template +BOOST_MATH_INLINE_CONSTEXPR bool is_base_of_v = boost::math::is_base_of::value; + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_TYPE_TRAITS diff --git a/third-party/boost-math/include/boost/math/tools/ulps_plot.hpp b/third-party/boost-math/include/boost/math/tools/ulps_plot.hpp new file mode 100644 index 0000000000000..8e3995673bd9e --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/ulps_plot.hpp @@ -0,0 +1,598 @@ +// (C) Copyright Nick Thompson 2020. +// 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) +#ifndef BOOST_MATH_TOOLS_ULP_PLOT_HPP +#define BOOST_MATH_TOOLS_ULP_PLOT_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +// Design of this function comes from: +// https://blogs.mathworks.com/cleve/2017/01/23/ulps-plots-reveal-math-function-accurary/ + +// The envelope is the maximum of 1/2 and half the condition number of function evaluation. + +namespace boost::math::tools { + +namespace detail { +template +void write_gridlines(std::ostream& fs, int horizontal_lines, int vertical_lines, + F1 x_scale, F2 y_scale, CoarseReal min_x, CoarseReal max_x, PreciseReal min_y, PreciseReal max_y, + int graph_width, int graph_height, int margin_left, std::string const & font_color) +{ + // Make a grid: + for (int i = 1; i <= horizontal_lines; ++i) { + PreciseReal y_cord_dataspace = min_y + ((max_y - min_y)*i)/horizontal_lines; + auto y = y_scale(y_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << y_cord_dataspace << "\n"; + } + + for (int i = 1; i <= vertical_lines; ++i) { + CoarseReal x_cord_dataspace = min_x + ((max_x - min_x)*i)/vertical_lines; + CoarseReal x = x_scale(x_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << x_cord_dataspace << "\n"; + } +} +} + +template +class ulps_plot { +public: + ulps_plot(F hi_acc_impl, CoarseReal a, CoarseReal b, + size_t samples = 1000, bool perturb_abscissas = false, int random_seed = -1); + + ulps_plot& clip(PreciseReal clip); + + ulps_plot& width(int width); + + ulps_plot& envelope_color(std::string const & color); + + ulps_plot& title(std::string const & title); + + ulps_plot& background_color(std::string const & background_color); + + ulps_plot& font_color(std::string const & font_color); + + ulps_plot& crop_color(std::string const & color); + + ulps_plot& nan_color(std::string const & color); + + ulps_plot& ulp_envelope(bool write_ulp); + + template + ulps_plot& add_fn(G g, std::string const & color = "steelblue"); + + ulps_plot& horizontal_lines(int horizontal_lines); + + ulps_plot& vertical_lines(int vertical_lines); + + void write(std::string const & filename) const; + + friend std::ostream& operator<<(std::ostream& fs, ulps_plot const & plot) + { + using std::abs; + using std::floor; + using std::isnan; + if (plot.ulp_list_.size() == 0) + { + throw std::domain_error("No functions added for comparison."); + } + if (plot.width_ <= 1) + { + throw std::domain_error("Width = " + std::to_string(plot.width_) + ", which is too small."); + } + + PreciseReal worst_ulp_distance = 0; + PreciseReal min_y = (std::numeric_limits::max)(); + PreciseReal max_y = std::numeric_limits::lowest(); + for (auto const & ulp_vec : plot.ulp_list_) + { + for (auto const & ulp : ulp_vec) + { + if (static_cast(abs(ulp)) > worst_ulp_distance) + { + worst_ulp_distance = static_cast(abs(ulp)); + } + if (static_cast(ulp) < min_y) + { + min_y = static_cast(ulp); + } + if (static_cast(ulp) > max_y) + { + max_y = static_cast(ulp); + } + } + } + + // half-ulp accuracy is the best that can be expected; sometimes we can get less, but barely less. + // then the axes don't show up; painful! + if (max_y < 0.5) { + max_y = 0.5; + } + if (min_y > -0.5) { + min_y = -0.5; + } + + if (plot.clip_ > 0) + { + if (max_y > plot.clip_) + { + max_y = plot.clip_; + } + if (min_y < -plot.clip_) + { + min_y = -plot.clip_; + } + } + + int height = static_cast(floor(static_cast(plot.width_)/1.61803)); + int margin_top = 40; + int margin_left = 25; + if (plot.title_.size() == 0) + { + margin_top = 10; + margin_left = 15; + } + int margin_bottom = 20; + int margin_right = 20; + int graph_height = height - margin_bottom - margin_top; + int graph_width = plot.width_ - margin_left - margin_right; + + // Maps [a,b] to [0, graph_width] + auto x_scale = [&](CoarseReal x)->CoarseReal + { + return ((x-plot.a_)/(plot.b_ - plot.a_))*static_cast(graph_width); + }; + + auto y_scale = [&](PreciseReal y)->PreciseReal + { + return ((max_y - y)/(max_y - min_y) )*static_cast(graph_height); + }; + + fs << "\n" + << "\n" + << "\n"; + if (plot.title_.size() > 0) + { + fs << "" + << plot.title_ + << "\n"; + } + + // Construct SVG group to simplify the calculations slightly: + fs << "\n"; + // y-axis: + fs << "\n"; + PreciseReal x_axis_loc = y_scale(static_cast(0)); + fs << "\n"; + + if (worst_ulp_distance > 3) + { + detail::write_gridlines(fs, plot.horizontal_lines_, plot.vertical_lines_, x_scale, y_scale, plot.a_, plot.b_, + min_y, max_y, graph_width, graph_height, margin_left, plot.font_color_); + } + else + { + std::vector ys{-3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0}; + for (double & i : ys) + { + if (min_y <= i && i <= max_y) + { + PreciseReal y_cord_dataspace = i; + PreciseReal y = y_scale(y_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << y_cord_dataspace << "\n"; + } + } + for (int i = 1; i <= plot.vertical_lines_; ++i) + { + CoarseReal x_cord_dataspace = plot.a_ + ((plot.b_ - plot.a_)*i)/plot.vertical_lines_; + CoarseReal x = x_scale(x_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << x_cord_dataspace << "\n"; + } + } + + int color_idx = 0; + for (auto const & ulp : plot.ulp_list_) + { + std::string color = plot.colors_[color_idx++]; + for (size_t j = 0; j < ulp.size(); ++j) + { + if (isnan(ulp[j])) + { + if(plot.nan_color_ == "") + continue; + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(plot.clip_)); + fs << "\n"; + y = y_scale(static_cast(-plot.clip_)); + fs << "\n"; + } + if (plot.clip_ > 0 && static_cast(abs(ulp[j])) > plot.clip_) + { + if (plot.crop_color_ == "") + continue; + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(ulp[j] < 0 ? -plot.clip_ : plot.clip_)); + fs << "\n"; + } + else + { + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(ulp[j])); + fs << "\n"; + } + } + } + + if (plot.ulp_envelope_) + { + std::string close_path = "' stroke='" + plot.envelope_color_ + "' stroke-width='1' fill='none'>\n"; + size_t jstart = 0; + while (plot.cond_[jstart] > max_y) + { + ++jstart; + if (jstart >= plot.cond_.size()) + { + goto done; + } + } + + size_t jmin = jstart; + new_top_path: + if (jmin >= plot.cond_.size()) + { + goto start_bottom_paths; + } + fs << "\n" + << "\n"; + return fs; + } + +private: + std::vector precise_abscissas_; + std::vector coarse_abscissas_; + std::vector precise_ordinates_; + std::vector cond_; + std::list> ulp_list_; + std::vector colors_; + CoarseReal a_; + CoarseReal b_; + PreciseReal clip_; + int width_; + std::string envelope_color_; + bool ulp_envelope_; + int horizontal_lines_; + int vertical_lines_; + std::string title_; + std::string background_color_; + std::string font_color_; + std::string crop_color_; + std::string nan_color_; +}; + +template +ulps_plot& ulps_plot::envelope_color(std::string const & color) +{ + envelope_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::clip(PreciseReal clip) +{ + clip_ = clip; + return *this; +} + +template +ulps_plot& ulps_plot::width(int width) +{ + width_ = width; + return *this; +} + +template +ulps_plot& ulps_plot::horizontal_lines(int horizontal_lines) +{ + horizontal_lines_ = horizontal_lines; + return *this; +} + +template +ulps_plot& ulps_plot::vertical_lines(int vertical_lines) +{ + vertical_lines_ = vertical_lines; + return *this; +} + +template +ulps_plot& ulps_plot::title(std::string const & title) +{ + title_ = title; + return *this; +} + +template +ulps_plot& ulps_plot::background_color(std::string const & background_color) +{ + background_color_ = background_color; + return *this; +} + +template +ulps_plot& ulps_plot::font_color(std::string const & font_color) +{ + font_color_ = font_color; + return *this; +} + +template +ulps_plot& ulps_plot::crop_color(std::string const & color) +{ + crop_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::nan_color(std::string const & color) +{ + nan_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::ulp_envelope(bool write_ulp_envelope) +{ + ulp_envelope_ = write_ulp_envelope; + return *this; +} + +namespace detail{ +bool ends_with(std::string const& filename, std::string const& suffix) +{ + if(filename.size() < suffix.size()) + { + return false; + } + + return std::equal(std::begin(suffix), std::end(suffix), std::end(filename) - suffix.size()); +} +} + +template +void ulps_plot::write(std::string const & filename) const +{ + if(!boost::math::tools::detail::ends_with(filename, ".svg")) + { + throw std::logic_error("Only svg files are supported at this time."); + } + std::ofstream fs(filename); + fs << *this; + fs.close(); +} + + +template +ulps_plot::ulps_plot(F hi_acc_impl, CoarseReal a, CoarseReal b, + size_t samples, bool perturb_abscissas, int random_seed) : crop_color_("red") +{ + // Use digits10 for this comparison in case the two types have differeing radixes: + static_assert(std::numeric_limits::digits10 >= std::numeric_limits::digits10, "PreciseReal must have higher precision that CoarseReal"); + if (samples < 10) + { + throw std::domain_error("Must have at least 10 samples, samples = " + std::to_string(samples)); + } + if (b <= a) + { + throw std::domain_error("On interval [a,b], b > a is required."); + } + a_ = a; + b_ = b; + + std::mt19937_64 gen; + if (random_seed == -1) + { + std::random_device rd; + gen.seed(rd()); + } + + // Boost's uniform_real_distribution can generate quad and multiprecision random numbers; std's cannot: + #ifndef BOOST_MATH_STANDALONE + boost::random::uniform_real_distribution dis(static_cast(a), static_cast(b)); + #else + // Use std::random in standalone mode if it is a type that the standard library can support (float, double, or long double) + static_assert(std::numeric_limits::digits10 <= std::numeric_limits::digits10, "Standalone mode does not support types with precision that exceeds long double"); + std::uniform_real_distribution dis(static_cast(a), static_cast(b)); + #endif + + precise_abscissas_.resize(samples); + coarse_abscissas_.resize(samples); + + if (perturb_abscissas) + { + for(size_t i = 0; i < samples; ++i) + { + precise_abscissas_[i] = dis(gen); + } + std::sort(precise_abscissas_.begin(), precise_abscissas_.end()); + for (size_t i = 0; i < samples; ++i) + { + coarse_abscissas_[i] = static_cast(precise_abscissas_[i]); + } + } + else + { + for(size_t i = 0; i < samples; ++i) + { + coarse_abscissas_[i] = static_cast(dis(gen)); + } + std::sort(coarse_abscissas_.begin(), coarse_abscissas_.end()); + for (size_t i = 0; i < samples; ++i) + { + precise_abscissas_[i] = static_cast(coarse_abscissas_[i]); + } + } + + precise_ordinates_.resize(samples); + for (size_t i = 0; i < samples; ++i) + { + precise_ordinates_[i] = hi_acc_impl(precise_abscissas_[i]); + } + + cond_.resize(samples, std::numeric_limits::quiet_NaN()); + for (size_t i = 0 ; i < samples; ++i) + { + PreciseReal y = precise_ordinates_[i]; + if (y != 0) + { + // Maybe cond_ is badly names; should it be half_cond_? + cond_[i] = boost::math::tools::evaluation_condition_number(hi_acc_impl, precise_abscissas_[i])/2; + // Half-ULP accuracy is the correctly rounded result, so make sure the envelop doesn't go below this: + if (cond_[i] < 0.5) + { + cond_[i] = 0.5; + } + } + // else leave it as nan. + } + clip_ = -1; + width_ = 1100; + envelope_color_ = "chartreuse"; + ulp_envelope_ = true; + horizontal_lines_ = 8; + vertical_lines_ = 10; + title_ = ""; + background_color_ = "black"; + font_color_ = "white"; +} + +template +template +ulps_plot& ulps_plot::add_fn(G g, std::string const & color) +{ + using std::abs; + size_t samples = precise_abscissas_.size(); + std::vector ulps(samples); + for (size_t i = 0; i < samples; ++i) + { + PreciseReal y_hi_acc = precise_ordinates_[i]; + PreciseReal y_lo_acc = static_cast(g(coarse_abscissas_[i])); + PreciseReal absy = abs(y_hi_acc); + PreciseReal dist = static_cast(nextafter(static_cast(absy), (std::numeric_limits::max)()) - static_cast(absy)); + ulps[i] = static_cast((y_lo_acc - y_hi_acc)/dist); + } + ulp_list_.emplace_back(ulps); + colors_.emplace_back(color); + return *this; +} + + + + +} // namespace boost::math::tools +#endif diff --git a/third-party/boost-math/include/boost/math/tools/univariate_statistics.hpp b/third-party/boost-math/include/boost/math/tools/univariate_statistics.hpp new file mode 100644 index 0000000000000..98a97abac281c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/univariate_statistics.hpp @@ -0,0 +1,437 @@ +// (C) Copyright Nick Thompson 2018. +// 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) + +#ifndef BOOST_MATH_TOOLS_UNIVARIATE_STATISTICS_HPP +#define BOOST_MATH_TOOLS_UNIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR +#error "The header can only be used in C++17 and later." +#endif +#endif + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost::math::tools { + +template +auto mean(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + if constexpr (std::is_integral::value) + { + double mu = 0; + double i = 1; + for(auto it = first; it != last; ++it) { + mu = mu + (*it - mu)/i; + i += 1; + } + return mu; + } + else if constexpr (std::is_same_v::iterator_category, std::random_access_iterator_tag>) + { + size_t elements = std::distance(first, last); + Real mu0 = 0; + Real mu1 = 0; + Real mu2 = 0; + Real mu3 = 0; + Real i = 1; + auto end = last - (elements % 4); + for(auto it = first; it != end; it += 4) { + Real inv = Real(1)/i; + Real tmp0 = (*it - mu0); + Real tmp1 = (*(it+1) - mu1); + Real tmp2 = (*(it+2) - mu2); + Real tmp3 = (*(it+3) - mu3); + // please generate a vectorized fma here + mu0 += tmp0*inv; + mu1 += tmp1*inv; + mu2 += tmp2*inv; + mu3 += tmp3*inv; + i += 1; + } + Real num1 = Real(elements - (elements %4))/Real(4); + Real num2 = num1 + Real(elements % 4); + + for (auto it = end; it != last; ++it) + { + mu3 += (*it-mu3)/i; + i += 1; + } + + return (num1*(mu0+mu1+mu2) + num2*mu3)/Real(elements); + } + else + { + auto it = first; + Real mu = *it; + Real i = 2; + while(++it != last) + { + mu += (*it - mu)/i; + i += 1; + } + return mu; + } +} + +template +inline auto mean(Container const & v) +{ + return mean(v.cbegin(), v.cend()); +} + +template +auto variance(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute mean and variance."); + // Higham, Accuracy and Stability, equation 1.6a and 1.6b: + if constexpr (std::is_integral::value) + { + double M = *first; + double Q = 0; + double k = 2; + for (auto it = std::next(first); it != last; ++it) + { + double tmp = *it - M; + Q = Q + ((k-1)*tmp*tmp)/k; + M = M + tmp/k; + k += 1; + } + return Q/(k-1); + } + else + { + Real M = *first; + Real Q = 0; + Real k = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real tmp = (*it - M)/k; + Q += k*(k-1)*tmp*tmp; + M += tmp; + k += 1; + } + return Q/(k-1); + } +} + +template +inline auto variance(Container const & v) +{ + return variance(v.cbegin(), v.cend()); +} + +template +auto sample_variance(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template +inline auto sample_variance(Container const & v) +{ + return sample_variance(v.cbegin(), v.cend()); +} + + +// Follows equation 1.5 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto skewness(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute skewness."); + if constexpr (std::is_integral::value) + { + double M1 = *first; + double M2 = 0; + double M3 = 0; + double n = 2; + for (auto it = std::next(first); it != last; ++it) + { + double delta21 = *it - M1; + double tmp = delta21/n; + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + double var = M2/(n-1); + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return static_cast(0); + } + double skew = M3/(M2*sqrt(var)); + return skew; + } + else + { + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M3 += tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 += tmp*(n-1)*delta21; + M1 += tmp; + n += 1; + } + + Real var = M2/(n-1); + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return Real(0); + } + Real skew = M3/(M2*sqrt(var)); + return skew; + } +} + +template +inline auto skewness(Container const & v) +{ + return skewness(v.cbegin(), v.cend()); +} + +// Follows equation 1.5/1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto first_four_moments(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the first four moments."); + if constexpr (std::is_integral::value) + { + double M1 = *first; + double M2 = 0; + double M3 = 0; + double M4 = 0; + double n = 2; + for (auto it = std::next(first); it != last; ++it) + { + double delta21 = *it - M1; + double tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2/(n-1), M3/(n-1), M4/(n-1)); + } + else + { + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real M4 = 0; + Real n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2/(n-1), M3/(n-1), M4/(n-1)); + } +} + +template +inline auto first_four_moments(Container const & v) +{ + return first_four_moments(v.cbegin(), v.cend()); +} + + +// Follows equation 1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto kurtosis(ForwardIterator first, ForwardIterator last) +{ + auto [M1, M2, M3, M4] = first_four_moments(first, last); + if (M2 == 0) + { + return M2; + } + return M4/(M2*M2); +} + +template +inline auto kurtosis(Container const & v) +{ + return kurtosis(v.cbegin(), v.cend()); +} + +template +auto excess_kurtosis(ForwardIterator first, ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template +inline auto excess_kurtosis(Container const & v) +{ + return excess_kurtosis(v.cbegin(), v.cend()); +} + + +template +auto median(RandomAccessIterator first, RandomAccessIterator last) +{ + size_t num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last); + std::nth_element(middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + + +template +inline auto median(RandomAccessContainer & v) +{ + return median(v.begin(), v.end()); +} + +template +auto gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last); + if constexpr (std::is_integral::value) + { + double i = 1; + double num = 0; + double denom = 0; + for (auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + return static_cast(0); + } + + return ((2*num)/denom - i)/(i-1); + } + else + { + Real i = 1; + Real num = 0; + Real denom = 0; + for (auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + return Real(0); + } + + return ((2*num)/denom - i)/(i-1); + } +} + +template +inline auto gini_coefficient(RandomAccessContainer & v) +{ + return gini_coefficient(v.begin(), v.end()); +} + +template +inline auto sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + size_t n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_gini_coefficient(RandomAccessContainer & v) +{ + return sample_gini_coefficient(v.begin(), v.end()); +} + +template +auto median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using Real = typename std::iterator_traits::value_type; + using std::isnan; + if (isnan(center)) + { + center = boost::math::tools::median(first, last); + } + size_t num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last, comparator); + return abs(*middle); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last, comparator); + std::nth_element(middle, middle+1, last, comparator); + return (abs(*middle) + abs(*(middle+1)))/abs(static_cast(2)); + } +} + +template +inline auto median_absolute_deviation(RandomAccessContainer & v, typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(v.begin(), v.end(), center); +} + +} +#endif diff --git a/third-party/boost-math/include/boost/math/tools/user.hpp b/third-party/boost-math/include/boost/math/tools/user.hpp new file mode 100644 index 0000000000000..6d3df000c0055 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/user.hpp @@ -0,0 +1,105 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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) + +#ifndef BOOST_MATH_TOOLS_USER_HPP +#define BOOST_MATH_TOOLS_USER_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +// This file can be modified by the user to change the default policies. +// See "Changing the Policy Defaults" in documentation. + +// define this if the platform has no long double functions, +// or if the long double versions have only double precision: +// +// #define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +// +// Performance tuning options: +// +// #define BOOST_MATH_POLY_METHOD 3 +// #define BOOST_MATH_RATIONAL_METHOD 3 +// +// The maximum order of polynomial that will be evaluated +// via an unrolled specialisation: +// +// #define BOOST_MATH_MAX_POLY_ORDER 17 +// +// decide whether to store constants as integers or reals: +// +// #define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT + +// +// Default policies follow: +// +// Domain errors: +// +// #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error +// +// Pole errors: +// +// #define BOOST_MATH_POLE_ERROR_POLICY throw_on_error +// +// Overflow Errors: +// +// #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error +// +// Internal Evaluation Errors: +// +// #define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error +// +// Underflow: +// +// #define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error +// +// Denorms: +// +// #define BOOST_MATH_DENORM_ERROR_POLICY ignore_error +// +// Max digits to use for internal calculations: +// +// #define BOOST_MATH_DIGITS10_POLICY 0 +// +// Promote floats to doubles internally? +// +// #define BOOST_MATH_PROMOTE_FLOAT_POLICY true +// +// Promote doubles to long double internally: +// +// #define BOOST_MATH_PROMOTE_DOUBLE_POLICY true +// +// What do discrete quantiles return? +// +// #define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards +// +// If a function is mathematically undefined +// (for example the Cauchy distribution has no mean), +// then do we stop the code from compiling? +// +// #define BOOST_MATH_ASSERT_UNDEFINED_POLICY true +// +// Maximum series iterations permitted: +// +// #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000 +// +// Maximum root finding steps permitted: +// +// define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200 +// +// Enable use of __float128 in numeric constants: +// +// #define BOOST_MATH_USE_FLOAT128 +// +// Disable use of __float128 in numeric_constants even if the compiler looks to support it: +// +// #define BOOST_MATH_DISABLE_FLOAT128 + +#endif // BOOST_MATH_TOOLS_USER_HPP + + diff --git a/third-party/boost-math/include/boost/math/tools/utility.hpp b/third-party/boost-math/include/boost/math/tools/utility.hpp new file mode 100644 index 0000000000000..3e22865780f6c --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/utility.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2024 Matt Borland +// 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) + +#ifndef BOOST_MATH_TOOLS_UTILITY +#define BOOST_MATH_TOOLS_UTILITY + +#include + +#ifndef BOOST_MATH_HAS_GPU_SUPPORT + +#include + +namespace boost { +namespace math { + +template +constexpr T min BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (const T& a, const T& b) +{ + return (std::min)(a, b); +} + +template +constexpr T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (const T& a, const T& b) +{ + return (std::max)(a, b); +} + +template +void swap BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (T& a, T& b) +{ + return (std::swap)(a, b); +} + +} // namespace math +} // namespace boost + +#else + +namespace boost { +namespace math { + +template +BOOST_MATH_GPU_ENABLED constexpr T min BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (const T& a, const T& b) +{ + return a < b ? a : b; +} + +template +BOOST_MATH_GPU_ENABLED constexpr T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (const T& a, const T& b) +{ + return a > b ? a : b; +} + +template +BOOST_MATH_GPU_ENABLED constexpr void swap BOOST_MATH_PREVENT_MACRO_SUBSTITUTION (T& a, T& b) +{ + T t(a); + a = b; + b = t; +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HAS_GPU_SUPPORT + +#endif // BOOST_MATH_TOOLS_UTILITY diff --git a/third-party/boost-math/include/boost/math/tools/workaround.hpp b/third-party/boost-math/include/boost/math/tools/workaround.hpp new file mode 100644 index 0000000000000..7edd1c12aaedd --- /dev/null +++ b/third-party/boost-math/include/boost/math/tools/workaround.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006-7 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) + +#ifndef BOOST_MATH_TOOLS_WORHAROUND_HPP +#define BOOST_MATH_TOOLS_WORHAROUND_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +# include +#endif + +#include + +namespace boost{ namespace math{ namespace tools{ +// +// We call this short forwarding function so that we can work around a bug +// on Darwin that causes std::fmod to return a NaN. The test case is: +// std::fmod(1185.0L, 1.5L); +// +template +BOOST_MATH_GPU_ENABLED inline T fmod_workaround(T a, T b) BOOST_MATH_NOEXCEPT(T) +{ + BOOST_MATH_STD_USING + return fmod(a, b); +} +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) +template <> +inline long double fmod_workaround(long double a, long double b) noexcept +{ + return ::fmodl(a, b); +} +#endif + +}}} // namespaces + +#endif // BOOST_MATH_TOOLS_WORHAROUND_HPP + diff --git a/third-party/boost-math/include/boost/math/tr1.hpp b/third-party/boost-math/include/boost/math/tr1.hpp new file mode 100644 index 0000000000000..0ec947b6110ad --- /dev/null +++ b/third-party/boost-math/include/boost/math/tr1.hpp @@ -0,0 +1,1121 @@ +// Copyright John Maddock 2008. +// 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) + +#ifndef BOOST_MATH_TR1_HPP +#define BOOST_MATH_TR1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include // So we can check which std C lib we're using + +#ifdef __cplusplus + +#include +#include + +namespace boost{ namespace math{ namespace tr1{ extern "C"{ + +#endif // __cplusplus + +#ifndef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION +#define BOOST_MATH_PREVENT_MACRO_SUBSTITUTION /**/ +#endif + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_MATH_TR1_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_MATH_TR1_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_MATH_TR1_SOURCE +# define BOOST_MATH_TR1_DECL BOOST_SYMBOL_EXPORT +#else +# define BOOST_MATH_TR1_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_MATH_TR1_SOURCE +#else +# define BOOST_MATH_TR1_DECL +#endif // DYN_LINK +// +// Set any throw specifications on the C99 extern "C" functions - these have to be +// the same as used in the std lib if any. +// +#if defined(__GLIBC__) && defined(__THROW) +# define BOOST_MATH_C99_THROW_SPEC __THROW +#else +# define BOOST_MATH_C99_THROW_SPEC +#endif + +// +// Now set up the libraries to link against: +// Not compatible with standalone mode +// +#ifndef BOOST_MATH_STANDALONE +#include +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_c99 +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_c99f +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_LIB_NAME boost_math_c99l +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_tr1 +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_tr1f +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_LIB_NAME boost_math_tr1l +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#else // Standalone mode +# if defined(_MSC_VER) && !defined(BOOST_ALL_NO_LIB) +# pragma message("Auto linking of TR1 is not supported in standalone mode") +# endif +#endif // BOOST_MATH_STANDALONE + +#if !(defined(__INTEL_COMPILER) && defined(__APPLE__)) && !(defined(__FLT_EVAL_METHOD__) && !defined(__cplusplus)) +#if !defined(FLT_EVAL_METHOD) +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == -1 +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == 0 +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == 1 +typedef double float_t; +typedef double double_t; +#else +typedef long double float_t; +typedef long double double_t; +#endif +#endif + +// C99 Functions: +double BOOST_MATH_TR1_DECL boost_acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_acoshf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_acoshl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_asinhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_asinhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_atanhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_atanhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cbrtf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cbrtl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_copysignf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_copysignl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_erff BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_erfl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_erfcf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_erfcl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_exp2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_exp2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_exp2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_expm1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_expm1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_fdim BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fdimf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fdiml BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_fma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y, double z) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fmaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y, float z) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fmal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, long double z) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fmaxf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fmaxl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fminf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fminl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_hypotf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_hypotl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +#if 0 +int BOOST_MATH_TR1_DECL boost_ilogb BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +int BOOST_MATH_TR1_DECL boost_ilogbf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +int BOOST_MATH_TR1_DECL boost_ilogbl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_lgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_lgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +long long BOOST_MATH_TR1_DECL boost_llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long long BOOST_MATH_TR1_DECL boost_llroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long long BOOST_MATH_TR1_DECL boost_llroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_log1pf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_log1pl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL log2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL log2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL log2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL logb BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL logbf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL logbl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +long BOOST_MATH_TR1_DECL boost_lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL boost_lroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL boost_lroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL nan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL nanf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL nanl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL nearbyint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL nearbyintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL nearbyintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_nextafterf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_nextafterl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, long double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_nexttowardf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, long double y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_nexttowardl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_remainder BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_remainderf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_remainderl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_remquo BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_remquof BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_remquol BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_rint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_rintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_rintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_roundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_roundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_scalbln BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, long ex) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_scalblnf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, long ex) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_scalblnl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long ex) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_scalbn BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, int ex) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_scalbnf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, int ex) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_scalbnl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, int ex) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_tgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_tgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_truncf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_truncl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.1] associated Laguerre polynomials: +double BOOST_MATH_TR1_DECL boost_assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_assoc_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_assoc_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.2] associated Legendre functions: +double BOOST_MATH_TR1_DECL boost_assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_assoc_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_assoc_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.3] beta function: +double BOOST_MATH_TR1_DECL boost_beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_betaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_betal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.4] (complete) elliptic integral of the first kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.5] (complete) elliptic integral of the second kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.6] (complete) elliptic integral of the third kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double nu) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_3f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float nu) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_3l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu) BOOST_MATH_C99_THROW_SPEC; +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +double BOOST_MATH_TR1_DECL conf_hyperg BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double a, double c, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL conf_hypergf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float a, float c, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL conf_hypergl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double a, long double c, long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +// [5.2.1.8] regular modified cylindrical Bessel functions: +double BOOST_MATH_TR1_DECL boost_cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_if BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_il BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +double BOOST_MATH_TR1_DECL boost_cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_jf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_jl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +double BOOST_MATH_TR1_DECL boost_cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_kf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_kl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.11] cylindrical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// cylindrical Bessel functions (of the second kind): +double BOOST_MATH_TR1_DECL boost_cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +double BOOST_MATH_TR1_DECL boost_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +double BOOST_MATH_TR1_DECL boost_ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +double BOOST_MATH_TR1_DECL boost_ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double nu, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_3f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_3l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.15] exponential integral: +double BOOST_MATH_TR1_DECL boost_expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_expintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_expintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.16] Hermite polynomials: +double BOOST_MATH_TR1_DECL boost_hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_hermitef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_hermitel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +#if 0 +// [5.2.1.17] hypergeometric functions: +double BOOST_MATH_TR1_DECL hyperg BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double a, double b, double c, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL hypergf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float a, float b, float c, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL hypergl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double a, long double b, long double c, +long double x) BOOST_MATH_C99_THROW_SPEC; +#endif + +// [5.2.1.18] Laguerre polynomials: +double BOOST_MATH_TR1_DECL boost_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.19] Legendre polynomials: +double BOOST_MATH_TR1_DECL boost_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.20] Riemann zeta function: +double BOOST_MATH_TR1_DECL boost_riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_riemann_zetaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_riemann_zetal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.21] spherical Bessel functions (of the first kind): +double BOOST_MATH_TR1_DECL boost_sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_besself BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_bessell BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.22] spherical associated Legendre functions: +double BOOST_MATH_TR1_DECL boost_sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double theta) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.23] spherical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// spherical Bessel functions (of the second kind): +double BOOST_MATH_TR1_DECL boost_sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +#ifdef __cplusplus + +}}}} // namespaces + +#include + +namespace boost{ namespace math{ namespace tr1{ +// +// Declare overload of the functions which forward to the +// C interfaces: +// +// C99 Functions: +inline double acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float acoshf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_acoshf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double acoshl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_acoshl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::acoshf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::acoshl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::acosh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float asinhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_asinhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double asinhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_asinhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::asinhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::asinhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::asinh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float atanhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_atanhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double atanhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_atanhl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::atanhf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::atanhl(x); } +template +inline typename tools::promote_args::type atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::atanh BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float cbrtf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_cbrtf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double cbrtl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_cbrtl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::cbrtf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::cbrtl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::cbrt BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float copysignf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_copysignf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double copysignl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_copysignl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::copysignf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::copysignl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::copysign BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline double erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erff BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_erff BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_erfl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::erff BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::erfl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::erf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erfcf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_erfcf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfcl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_erfcl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::erfcf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::erfcl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::erfc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#if 0 +double exp2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +float exp2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long double exp2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline float expm1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_expm1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expm1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_expm1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::expm1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::expm1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::expm1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#if 0 +double fdim BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y); +float fdimf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y); +long double fdiml BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y); +double fma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y, double z); +float fmaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y, float z); +long double fmal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, long double z); +#endif +inline double fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmaxf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_fmaxf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmaxl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_fmaxl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::fmaxf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::fmaxl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::fmax BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline double fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fminf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_fminf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fminl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_fminl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::fminf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::fminl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::fmin BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline float hypotf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_hypotf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double hypotl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_hypotl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::hypotf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::hypotl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::hypot BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +#if 0 +int ilogb BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +int ilogbf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +int ilogbl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline float lgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_lgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double lgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_lgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::lgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::lgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::lgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#ifdef BOOST_HAS_LONG_LONG +#if 0 +long long llrint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +long long llrintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long long llrintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline long long llroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_llroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_llroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::llroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::llroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline long long llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return llround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast(x)); } +#endif + +inline float log1pf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_log1pf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double log1pl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_log1pl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::log1pf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::log1pl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::log1p BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } +#if 0 +double log2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +float log2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long double log2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); + +double logb BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +float logbf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long double logbl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +long lrint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +long lrintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long lrintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline long lroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_lroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_lroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::lroundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::lroundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +long lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::lround BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast(x)); } +#if 0 +double nan BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str); +float nanf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str); +long double nanl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(const char *str); +double nearbyint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +float nearbyintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long double nearbyintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline float nextafterf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_nextafterf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nextafterl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_nextafterl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::nextafterf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::nextafterl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::nextafter BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline float nexttowardf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_nexttowardf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nexttowardl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_nexttowardl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::nexttowardf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::nexttowardl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return static_cast::type>(boost::math::tr1::nexttoward BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast(y))); } +#if 0 +double remainder BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y); +float remainderf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y); +long double remainderl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y); +double remquo BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y, int *pquo); +float remquof BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y, int *pquo); +long double remquol BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, int *pquo); +double rint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x); +float rintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x); +long double rintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline float roundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_roundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double roundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_roundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::roundf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::roundl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::round BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } +#if 0 +double scalbln BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, long ex); +float scalblnf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, long ex); +long double scalblnl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long ex); +double scalbn BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, int ex); +float scalbnf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, int ex); +long double scalbnl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, int ex); +#endif +inline float tgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_tgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double tgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_tgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::tgammaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::tgammal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::tgamma BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline float truncf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_truncf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double truncl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_truncl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::truncf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::truncl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::trunc BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +# define NO_MACRO_EXPAND /**/ +// C99 macros defined as C++ templates +template bool signbit NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(long double x); + +template int fpclassify NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(float x); +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(double x); +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(long double x); + +template bool isfinite NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(long double x); + +template bool isinf NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(long double x); + +template bool isnan NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(long double x); + +template bool isnormal NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(long double x); + +#undef NO_MACRO_EXPAND + +// [5.2.1.1] associated Laguerre polynomials: +inline float assoc_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) +{ return boost::math::tr1::boost_assoc_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline double assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, double x) +{ return boost::math::tr1::boost_assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline long double assoc_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) +{ return boost::math::tr1::boost_assoc_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline float assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) +{ return boost::math::tr1::assoc_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline long double assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) +{ return boost::math::tr1::assoc_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +template +inline typename tools::promote_args::type assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, T x) +{ return boost::math::tr1::assoc_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, m, static_cast::type>(x)); } + +// [5.2.1.2] associated Legendre functions: +inline float assoc_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) +{ return boost::math::tr1::boost_assoc_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline double assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double x) +{ return boost::math::tr1::boost_assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline long double assoc_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) +{ return boost::math::tr1::boost_assoc_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline float assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) +{ return boost::math::tr1::assoc_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline long double assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) +{ return boost::math::tr1::assoc_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +template +inline typename tools::promote_args::type assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, T x) +{ return boost::math::tr1::assoc_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, static_cast::type>(x)); } + +// [5.2.1.3] beta function: +inline float betaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_betaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double betal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_betal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::betaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::betal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T2 x, T1 y) +{ return boost::math::tr1::beta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +// [5.2.1.4] (complete) elliptic integral of the first kind: +inline float comp_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k) +{ return boost::math::tr1::boost_comp_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k); } +inline double comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k) +{ return boost::math::tr1::boost_comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k); } +inline long double comp_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k) +{ return boost::math::tr1::boost_comp_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k); } +inline float comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k) +{ return boost::math::tr1::comp_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k); } +inline long double comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k) +{ return boost::math::tr1::comp_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k); } +template +inline typename tools::promote_args::type comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T k) +{ return boost::math::tr1::comp_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k)); } + +// [5.2.1.5] (complete) elliptic integral of the second kind: +inline float comp_ellint_2f(float k) +{ return boost::math::tr1::boost_comp_ellint_2f(k); } +inline double comp_ellint_2(double k) +{ return boost::math::tr1::boost_comp_ellint_2(k); } +inline long double comp_ellint_2l(long double k) +{ return boost::math::tr1::boost_comp_ellint_2l(k); } +inline float comp_ellint_2(float k) +{ return boost::math::tr1::comp_ellint_2f(k); } +inline long double comp_ellint_2(long double k) +{ return boost::math::tr1::comp_ellint_2l(k); } +template +inline typename tools::promote_args::type comp_ellint_2(T k) +{ return boost::math::tr1::comp_ellint_2(static_cast::type> BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k)); } + +// [5.2.1.6] (complete) elliptic integral of the third kind: +inline float comp_ellint_3f(float k, float nu) +{ return boost::math::tr1::boost_comp_ellint_3f(k, nu); } +inline double comp_ellint_3(double k, double nu) +{ return boost::math::tr1::boost_comp_ellint_3(k, nu); } +inline long double comp_ellint_3l(long double k, long double nu) +{ return boost::math::tr1::boost_comp_ellint_3l(k, nu); } +inline float comp_ellint_3(float k, float nu) +{ return boost::math::tr1::comp_ellint_3f(k, nu); } +inline long double comp_ellint_3(long double k, long double nu) +{ return boost::math::tr1::comp_ellint_3l(k, nu); } +template +inline typename tools::promote_args::type comp_ellint_3(T1 k, T2 nu) +{ return boost::math::tr1::comp_ellint_3(static_cast::type> BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k), static_cast::type> BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu)); } + +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +double conf_hyperg BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double a, double c, double x); +float conf_hypergf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float a, float c, float x); +long double conf_hypergl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double a, long double c, long double x); +#endif + +// [5.2.1.8] regular modified cylindrical Bessel functions: +inline float cyl_bessel_if BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_if BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_il BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_il BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_if BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_il BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_i BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +inline float cyl_bessel_jf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_jf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_jl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_jl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_jf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_jl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_j BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +inline float cyl_bessel_kf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_kf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_kl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_kl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_kf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_kl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_k BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type> BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu), static_cast::type>(x)); } + +// [5.2.1.11] cylindrical Neumann functions; +// cylindrical Bessel functions (of the second kind): +inline float cyl_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +inline float ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::boost_ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline double ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double phi) +{ return boost::math::tr1::boost_ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::boost_ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline float ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::ellint_1f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::ellint_1l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +template +inline typename tools::promote_args::type ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 phi) +{ return boost::math::tr1::ellint_1 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(phi)); } + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +inline float ellint_2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::boost_ellint_2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline double ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double phi) +{ return boost::math::tr1::boost_ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::boost_ellint_2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline float ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::ellint_2f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::ellint_2l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, phi); } +template +inline typename tools::promote_args::type ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 phi) +{ return boost::math::tr1::ellint_2 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(phi)); } + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +inline float ellint_3f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) +{ return boost::math::tr1::boost_ellint_3f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline double ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double k, double nu, double phi) +{ return boost::math::tr1::boost_ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline long double ellint_3l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) +{ return boost::math::tr1::boost_ellint_3l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline float ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) +{ return boost::math::tr1::ellint_3f BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline long double ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) +{ return boost::math::tr1::ellint_3l BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +template +inline typename tools::promote_args::type ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 nu, T3 phi) +{ return boost::math::tr1::ellint_3 BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(nu), static_cast::type>(phi)); } + +// [5.2.1.15] exponential integral: +inline float expintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_expintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline double expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_expintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline float expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::expintf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::expintl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::expint BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +// [5.2.1.16] Hermite polynomials: +inline float hermitef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_hermitef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double hermitel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_hermitel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::hermitef BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::hermitel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::hermite BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +#if 0 +// [5.2.1.17] hypergeometric functions: +double hyperg BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double a, double b, double c, double x); +float hypergf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float a, float b, float c, float x); +long double hypergl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double a, long double b, long double c, +long double x); +#endif + +// [5.2.1.18] Laguerre polynomials: +inline float laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::laguerref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::laguerrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::laguerre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +// [5.2.1.19] Legendre polynomials: +inline float legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) +{ return boost::math::tr1::boost_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline double legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, double x) +{ return boost::math::tr1::boost_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline long double legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) +{ return boost::math::tr1::boost_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline float legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) +{ return boost::math::tr1::legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline long double legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) +{ return boost::math::tr1::legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, x); } +template +inline typename tools::promote_args::type legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, T x) +{ return boost::math::tr1::legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, static_cast::type>(x)); } + +// [5.2.1.20] Riemann zeta function: +inline float riemann_zetaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float z) +{ return boost::math::tr1::boost_riemann_zetaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(z); } +inline double riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(double z) +{ return boost::math::tr1::boost_riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(z); } +inline long double riemann_zetal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double z) +{ return boost::math::tr1::boost_riemann_zetal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(z); } +inline float riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(float z) +{ return boost::math::tr1::riemann_zetaf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(z); } +inline long double riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(long double z) +{ return boost::math::tr1::riemann_zetal BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(z); } +template +inline typename tools::promote_args::type riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T z) +{ return boost::math::tr1::riemann_zeta BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(z)); } + +// [5.2.1.21] spherical Bessel functions (of the first kind): +inline float sph_besself BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_sph_besself BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_bessell BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_sph_bessell BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::sph_besself BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::sph_bessell BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::sph_bessel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +// [5.2.1.22] spherical associated Legendre functions: +inline float sph_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) +{ return boost::math::tr1::boost_sph_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline double sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double theta) +{ return boost::math::tr1::boost_sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline long double sph_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) +{ return boost::math::tr1::boost_sph_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline float sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) +{ return boost::math::tr1::sph_legendref BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline long double sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) +{ return boost::math::tr1::sph_legendrel BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +template +inline typename tools::promote_args::type sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, T theta) +{ return boost::math::tr1::sph_legendre BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(l, m, static_cast::type>(theta)); } + +// [5.2.1.23] spherical Neumann functions; +// spherical Bessel functions (of the second kind): +inline float sph_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_sph_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_sph_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::sph_neumannf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::sph_neumannl BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::sph_neumann BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +}}} // namespaces + +#else // __cplusplus + +#include + +#endif // __cplusplus + +#endif // BOOST_MATH_TR1_HPP + diff --git a/third-party/boost-math/include/boost/math/tr1_c_macros.ipp b/third-party/boost-math/include/boost/math/tr1_c_macros.ipp new file mode 100644 index 0000000000000..ec8e7da3eff46 --- /dev/null +++ b/third-party/boost-math/include/boost/math/tr1_c_macros.ipp @@ -0,0 +1,810 @@ +// Copyright John Maddock 2008-11. +// 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) + +#ifndef BOOST_MATH_C_MACROS_IPP +#define BOOST_MATH_C_MACROS_IPP + +// C99 Functions: +#ifdef acosh +#undef acosh +#endif +#define acosh boost_acosh +#ifdef acoshf +#undef acoshf +#endif +#define acoshf boost_acoshf +#ifdef acoshl +#undef acoshl +#endif +#define acoshl boost_acoshl + +#ifdef asinh +#undef asinh +#endif +#define asinh boost_asinh +#ifdef asinhf +#undef asinhf +#endif +#define asinhf boost_asinhf +#ifdef asinhl +#undef asinhl +#endif +#define asinhl boost_asinhl + +#ifdef atanh +#undef atanh +#endif +#define atanh boost_atanh +#ifdef atanhf +#undef atanhf +#endif +#define atanhf boost_atanhf +#ifdef atanhl +#undef atanhl +#endif +#define atanhl boost_atanhl + +#ifdef cbrt +#undef cbrt +#endif +#define cbrt boost_cbrt +#ifdef cbrtf +#undef cbrtf +#endif +#define cbrtf boost_cbrtf +#ifdef cbrtl +#undef cbrtl +#endif +#define cbrtl boost_cbrtl + +#ifdef copysign +#undef copysign +#endif +#define copysign boost_copysign +#ifdef copysignf +#undef copysignf +#endif +#define copysignf boost_copysignf +#ifdef copysignl +#undef copysignl +#endif +#define copysignl boost_copysignl + +#ifdef erf +#undef erf +#endif +#define erf boost_erf +#ifdef erff +#undef erff +#endif +#define erff boost_erff +#ifdef erfl +#undef erfl +#endif +#define erfl boost_erfl + +#ifdef erfc +#undef erfc +#endif +#define erfc boost_erfc +#ifdef erfcf +#undef erfcf +#endif +#define erfcf boost_erfcf +#ifdef erfcl +#undef erfcl +#endif +#define erfcl boost_erfcl + +#if 0 +#ifdef exp2 +#undef exp2 +#endif +#define exp2 boost_exp2 +#ifdef exp2f +#undef exp2f +#endif +#define exp2f boost_exp2f +#ifdef exp2l +#undef exp2l +#endif +#define exp2l boost_exp2l +#endif + +#ifdef expm1 +#undef expm1 +#endif +#define expm1 boost_expm1 +#ifdef expm1f +#undef expm1f +#endif +#define expm1f boost_expm1f +#ifdef expm1l +#undef expm1l +#endif +#define expm1l boost_expm1l + +#if 0 +#ifdef fdim +#undef fdim +#endif +#define fdim boost_fdim +#ifdef fdimf +#undef fdimf +#endif +#define fdimf boost_fdimf +#ifdef fdiml +#undef fdiml +#endif +#define fdiml boost_fdiml +#ifdef acosh +#undef acosh +#endif +#define fma boost_fma +#ifdef fmaf +#undef fmaf +#endif +#define fmaf boost_fmaf +#ifdef fmal +#undef fmal +#endif +#define fmal boost_fmal +#endif + +#ifdef fmax +#undef fmax +#endif +#define fmax boost_fmax +#ifdef fmaxf +#undef fmaxf +#endif +#define fmaxf boost_fmaxf +#ifdef fmaxl +#undef fmaxl +#endif +#define fmaxl boost_fmaxl + +#ifdef fmin +#undef fmin +#endif +#define fmin boost_fmin +#ifdef fminf +#undef fminf +#endif +#define fminf boost_fminf +#ifdef fminl +#undef fminl +#endif +#define fminl boost_fminl + +#ifdef hypot +#undef hypot +#endif +#define hypot boost_hypot +#ifdef hypotf +#undef hypotf +#endif +#define hypotf boost_hypotf +#ifdef hypotl +#undef hypotl +#endif +#define hypotl boost_hypotl + +#if 0 +#ifdef ilogb +#undef ilogb +#endif +#define ilogb boost_ilogb +#ifdef ilogbf +#undef ilogbf +#endif +#define ilogbf boost_ilogbf +#ifdef ilogbl +#undef ilogbl +#endif +#define ilogbl boost_ilogbl +#endif + +#ifdef lgamma +#undef lgamma +#endif +#define lgamma boost_lgamma +#ifdef lgammaf +#undef lgammaf +#endif +#define lgammaf boost_lgammaf +#ifdef lgammal +#undef lgammal +#endif +#define lgammal boost_lgammal + +#ifdef BOOST_HAS_LONG_LONG +#if 0 +#ifdef llrint +#undef llrint +#endif +#define llrint boost_llrint +#ifdef llrintf +#undef llrintf +#endif +#define llrintf boost_llrintf +#ifdef llrintl +#undef llrintl +#endif +#define llrintl boost_llrintl +#endif +#ifdef llround +#undef llround +#endif +#define llround boost_llround +#ifdef llroundf +#undef llroundf +#endif +#define llroundf boost_llroundf +#ifdef llroundl +#undef llroundl +#endif +#define llroundl boost_llroundl +#endif + +#ifdef log1p +#undef log1p +#endif +#define log1p boost_log1p +#ifdef log1pf +#undef log1pf +#endif +#define log1pf boost_log1pf +#ifdef log1pl +#undef log1pl +#endif +#define log1pl boost_log1pl + +#if 0 +#ifdef log2 +#undef log2 +#endif +#define log2 boost_log2 +#ifdef log2f +#undef log2f +#endif +#define log2f boost_log2f +#ifdef log2l +#undef log2l +#endif +#define log2l boost_log2l + +#ifdef logb +#undef logb +#endif +#define logb boost_logb +#ifdef logbf +#undef logbf +#endif +#define logbf boost_logbf +#ifdef logbl +#undef logbl +#endif +#define logbl boost_logbl + +#ifdef lrint +#undef lrint +#endif +#define lrint boost_lrint +#ifdef lrintf +#undef lrintf +#endif +#define lrintf boost_lrintf +#ifdef lrintl +#undef lrintl +#endif +#define lrintl boost_lrintl +#endif + +#ifdef lround +#undef lround +#endif +#define lround boost_lround +#ifdef lroundf +#undef lroundf +#endif +#define lroundf boost_lroundf +#ifdef lroundl +#undef lroundl +#endif +#define lroundl boost_lroundl + +#if 0 +#ifdef nan +#undef nan +#endif +#define nan boost_nan +#ifdef nanf +#undef nanf +#endif +#define nanf boost_nanf +#ifdef nanl +#undef nanl +#endif +#define nanl boost_nanl + +#ifdef nearbyint +#undef nearbyint +#endif +#define nearbyint boost_nearbyint +#ifdef nearbyintf +#undef nearbyintf +#endif +#define nearbyintf boost_nearbyintf +#ifdef nearbyintl +#undef nearbyintl +#endif +#define nearbyintl boost_nearbyintl +#endif + +#ifdef nextafter +#undef nextafter +#endif +#define nextafter boost_nextafter +#ifdef nextafterf +#undef nextafterf +#endif +#define nextafterf boost_nextafterf +#ifdef nextafterl +#undef nextafterl +#endif +#define nextafterl boost_nextafterl + +#ifdef nexttoward +#undef nexttoward +#endif +#define nexttoward boost_nexttoward +#ifdef nexttowardf +#undef nexttowardf +#endif +#define nexttowardf boost_nexttowardf +#ifdef nexttowardl +#undef nexttowardl +#endif +#define nexttowardl boost_nexttowardl + +#if 0 +#ifdef remainder +#undef remainder +#endif +#define remainder boost_remainder +#ifdef remainderf +#undef remainderf +#endif +#define remainderf boost_remainderf +#ifdef remainderl +#undef remainderl +#endif +#define remainderl boost_remainderl + +#ifdef remquo +#undef remquo +#endif +#define remquo boost_remquo +#ifdef remquof +#undef remquof +#endif +#define remquof boost_remquof +#ifdef remquol +#undef remquol +#endif +#define remquol boost_remquol + +#ifdef rint +#undef rint +#endif +#define rint boost_rint +#ifdef rintf +#undef rintf +#endif +#define rintf boost_rintf +#ifdef rintl +#undef rintl +#endif +#define rintl boost_rintl +#endif + +#ifdef round +#undef round +#endif +#define round boost_round +#ifdef roundf +#undef roundf +#endif +#define roundf boost_roundf +#ifdef roundl +#undef roundl +#endif +#define roundl boost_roundl + +#if 0 +#ifdef scalbln +#undef scalbln +#endif +#define scalbln boost_scalbln +#ifdef scalblnf +#undef scalblnf +#endif +#define scalblnf boost_scalblnf +#ifdef scalblnl +#undef scalblnl +#endif +#define scalblnl boost_scalblnl + +#ifdef scalbn +#undef scalbn +#endif +#define scalbn boost_scalbn +#ifdef scalbnf +#undef scalbnf +#endif +#define scalbnf boost_scalbnf +#ifdef scalbnl +#undef scalbnl +#endif +#define scalbnl boost_scalbnl +#endif + +#ifdef tgamma +#undef tgamma +#endif +#define tgamma boost_tgamma +#ifdef tgammaf +#undef tgammaf +#endif +#define tgammaf boost_tgammaf +#ifdef tgammal +#undef tgammal +#endif +#define tgammal boost_tgammal + +#ifdef trunc +#undef trunc +#endif +#define trunc boost_trunc +#ifdef truncf +#undef truncf +#endif +#define truncf boost_truncf +#ifdef truncl +#undef truncl +#endif +#define truncl boost_truncl + +// [5.2.1.1] associated Laguerre polynomials: +#ifdef assoc_laguerre +#undef assoc_laguerre +#endif +#define assoc_laguerre boost_assoc_laguerre +#ifdef assoc_laguerref +#undef assoc_laguerref +#endif +#define assoc_laguerref boost_assoc_laguerref +#ifdef assoc_laguerrel +#undef assoc_laguerrel +#endif +#define assoc_laguerrel boost_assoc_laguerrel + +// [5.2.1.2] associated Legendre functions: +#ifdef assoc_legendre +#undef assoc_legendre +#endif +#define assoc_legendre boost_assoc_legendre +#ifdef assoc_legendref +#undef assoc_legendref +#endif +#define assoc_legendref boost_assoc_legendref +#ifdef assoc_legendrel +#undef assoc_legendrel +#endif +#define assoc_legendrel boost_assoc_legendrel + +// [5.2.1.3] beta function: +#ifdef beta +#undef beta +#endif +#define beta boost_beta +#ifdef betaf +#undef betaf +#endif +#define betaf boost_betaf +#ifdef betal +#undef betal +#endif +#define betal boost_betal + +// [5.2.1.4] (complete) elliptic integral of the first kind: +#ifdef comp_ellint_1 +#undef comp_ellint_1 +#endif +#define comp_ellint_1 boost_comp_ellint_1 +#ifdef comp_ellint_1f +#undef comp_ellint_1f +#endif +#define comp_ellint_1f boost_comp_ellint_1f +#ifdef comp_ellint_1l +#undef comp_ellint_1l +#endif +#define comp_ellint_1l boost_comp_ellint_1l + +// [5.2.1.5] (complete) elliptic integral of the second kind: +#ifdef comp_ellint_2 +#undef comp_ellint_2 +#endif +#define comp_ellint_2 boost_comp_ellint_2 +#ifdef comp_ellint_2f +#undef comp_ellint_2f +#endif +#define comp_ellint_2f boost_comp_ellint_2f +#ifdef comp_ellint_2l +#undef comp_ellint_2l +#endif +#define comp_ellint_2l boost_comp_ellint_2l + +// [5.2.1.6] (complete) elliptic integral of the third kind: +#ifdef comp_ellint_3 +#undef comp_ellint_3 +#endif +#define comp_ellint_3 boost_comp_ellint_3 +#ifdef comp_ellint_3f +#undef comp_ellint_3f +#endif +#define comp_ellint_3f boost_comp_ellint_3f +#ifdef comp_ellint_3l +#undef comp_ellint_3l +#endif +#define comp_ellint_3l boost_comp_ellint_3l + +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +#ifdef conf_hyper +#undef conf_hyper +#endif +#define conf_hyper boost_conf_hyper +#ifdef conf_hyperf +#undef conf_hyperf +#endif +#define conf_hyperf boost_conf_hyperf +#ifdef conf_hyperl +#undef conf_hyperl +#endif +#define conf_hyperl boost_conf_hyperl +#endif + +// [5.2.1.8] regular modified cylindrical Bessel functions: +#ifdef cyl_bessel_i +#undef cyl_bessel_i +#endif +#define cyl_bessel_i boost_cyl_bessel_i +#ifdef cyl_bessel_if +#undef cyl_bessel_if +#endif +#define cyl_bessel_if boost_cyl_bessel_if +#ifdef cyl_bessel_il +#undef cyl_bessel_il +#endif +#define cyl_bessel_il boost_cyl_bessel_il + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +#ifdef cyl_bessel_j +#undef cyl_bessel_j +#endif +#define cyl_bessel_j boost_cyl_bessel_j +#ifdef cyl_bessel_jf +#undef cyl_bessel_jf +#endif +#define cyl_bessel_jf boost_cyl_bessel_jf +#ifdef cyl_bessel_jl +#undef cyl_bessel_jl +#endif +#define cyl_bessel_jl boost_cyl_bessel_jl + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +#ifdef cyl_bessel_k +#undef cyl_bessel_k +#endif +#define cyl_bessel_k boost_cyl_bessel_k +#ifdef cyl_bessel_kf +#undef cyl_bessel_kf +#endif +#define cyl_bessel_kf boost_cyl_bessel_kf +#ifdef cyl_bessel_kl +#undef cyl_bessel_kl +#endif +#define cyl_bessel_kl boost_cyl_bessel_kl + +// [5.2.1.11] cylindrical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// cylindrical Bessel functions (of the second kind): +#ifdef cyl_neumann +#undef cyl_neumann +#endif +#define cyl_neumann boost_cyl_neumann +#ifdef cyl_neumannf +#undef cyl_neumannf +#endif +#define cyl_neumannf boost_cyl_neumannf +#ifdef cyl_neumannl +#undef cyl_neumannl +#endif +#define cyl_neumannl boost_cyl_neumannl + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +#ifdef ellint_1 +#undef ellint_1 +#endif +#define ellint_1 boost_ellint_1 +#ifdef ellint_1f +#undef ellint_1f +#endif +#define ellint_1f boost_ellint_1f +#ifdef ellint_1l +#undef ellint_1l +#endif +#define ellint_1l boost_ellint_1l + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +#ifdef ellint_2 +#undef ellint_2 +#endif +#define ellint_2 boost_ellint_2 +#ifdef ellint_2f +#undef ellint_2f +#endif +#define ellint_2f boost_ellint_2f +#ifdef ellint_2l +#undef ellint_2l +#endif +#define ellint_2l boost_ellint_2l + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +#ifdef ellint_3 +#undef ellint_3 +#endif +#define ellint_3 boost_ellint_3 +#ifdef ellint_3f +#undef ellint_3f +#endif +#define ellint_3f boost_ellint_3f +#ifdef ellint_3l +#undef ellint_3l +#endif +#define ellint_3l boost_ellint_3l + +// [5.2.1.15] exponential integral: +#ifdef expint +#undef expint +#endif +#define expint boost_expint +#ifdef expintf +#undef expintf +#endif +#define expintf boost_expintf +#ifdef expintl +#undef expintl +#endif +#define expintl boost_expintl + +// [5.2.1.16] Hermite polynomials: +#ifdef hermite +#undef hermite +#endif +#define hermite boost_hermite +#ifdef hermitef +#undef hermitef +#endif +#define hermitef boost_hermitef +#ifdef hermitel +#undef hermitel +#endif +#define hermitel boost_hermitel + +#if 0 +// [5.2.1.17] hypergeometric functions: +#ifdef hyperg +#undef hyperg +#endif +#define hyperg boost_hyperg +#ifdef hypergf +#undef hypergf +#endif +#define hypergf boost_hypergf +#ifdef hypergl +#undef hypergl +#endif +#define hypergl boost_hypergl +#endif + +// [5.2.1.18] Laguerre polynomials: +#ifdef laguerre +#undef laguerre +#endif +#define laguerre boost_laguerre +#ifdef laguerref +#undef laguerref +#endif +#define laguerref boost_laguerref +#ifdef laguerrel +#undef laguerrel +#endif +#define laguerrel boost_laguerrel + +// [5.2.1.19] Legendre polynomials: +#ifdef legendre +#undef legendre +#endif +#define legendre boost_legendre +#ifdef legendref +#undef legendref +#endif +#define legendref boost_legendref +#ifdef legendrel +#undef legendrel +#endif +#define legendrel boost_legendrel + +// [5.2.1.20] Riemann zeta function: +#ifdef riemann_zeta +#undef riemann_zeta +#endif +#define riemann_zeta boost_riemann_zeta +#ifdef riemann_zetaf +#undef riemann_zetaf +#endif +#define riemann_zetaf boost_riemann_zetaf +#ifdef riemann_zetal +#undef riemann_zetal +#endif +#define riemann_zetal boost_riemann_zetal + +// [5.2.1.21] spherical Bessel functions (of the first kind): +#ifdef sph_bessel +#undef sph_bessel +#endif +#define sph_bessel boost_sph_bessel +#ifdef sph_besself +#undef sph_besself +#endif +#define sph_besself boost_sph_besself +#ifdef sph_bessell +#undef sph_bessell +#endif +#define sph_bessell boost_sph_bessell + +// [5.2.1.22] spherical associated Legendre functions: +#ifdef sph_legendre +#undef sph_legendre +#endif +#define sph_legendre boost_sph_legendre +#ifdef sph_legendref +#undef sph_legendref +#endif +#define sph_legendref boost_sph_legendref +#ifdef sph_legendrel +#undef sph_legendrel +#endif +#define sph_legendrel boost_sph_legendrel + +// [5.2.1.23] spherical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// spherical Bessel functions (of the second kind): +#ifdef sph_neumann +#undef sph_neumann +#endif +#define sph_neumann boost_sph_neumann +#ifdef sph_neumannf +#undef sph_neumannf +#endif +#define sph_neumannf boost_sph_neumannf +#ifdef sph_neumannl +#undef sph_neumannl +#endif +#define sph_neumannl boost_sph_neumannl + +#endif // BOOST_MATH_C_MACROS_IPP diff --git a/third-party/boost-math/include/boost/math_fwd.hpp b/third-party/boost-math/include/boost/math_fwd.hpp new file mode 100644 index 0000000000000..cb044718d991a --- /dev/null +++ b/third-party/boost-math/include/boost/math_fwd.hpp @@ -0,0 +1,42 @@ +// Boost math_fwd.hpp header file ------------------------------------------// + +// (C) Copyright Hubert Holin and Daryle Walker 2001-2002. 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) + +// See http://www.boost.org/libs/math for documentation. + +#ifndef BOOST_MATH_FWD_HPP +#define BOOST_MATH_FWD_HPP + +namespace boost +{ +namespace math +{ + + +// From ----------------------------------------// + +template < typename T > + class quaternion; + +// Also has many function templates (including operators) + + +// From ------------------------------------------// + +template < typename T > + class octonion; + +template < > + class octonion< float >; +template < > + class octonion< double >; +template < > + class octonion< long double >; + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_FWD_HPP diff --git a/third-party/boost-math/include_private/boost/math/constants/generate.hpp b/third-party/boost-math/include_private/boost/math/constants/generate.hpp new file mode 100644 index 0000000000000..028434e98b535 --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/constants/generate.hpp @@ -0,0 +1,76 @@ +// Copyright John Maddock 2010. +// 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) + +#ifndef BOOST_MATH_CONSTANTS_GENERATE_INCLUDED +#define BOOST_MATH_CONSTANTS_GENERATE_INCLUDED + +#include +#include +#include +#include +#include + +#ifdef USE_MPFR +#include +#elif defined(USE_MPREAL) +#include +#elif defined(USE_CPP_FLOAT) +#include +#else +#include +#endif + +namespace boost{ namespace math{ namespace constants{ + +#ifdef USE_MPFR +typedef mpfr_class generator_type; +#elif defined(USE_MPREAL) +typedef mpfr::mpreal generator_type; +#elif defined(USE_CPP_FLOAT) +typedef boost::multiprecision::number > generator_type; +#else +typedef ntl::RR generator_type; +#endif + +inline void print_constant(const char* name, generator_type(*f)(const std::integral_constant&)) +{ +#ifdef USE_MPFR + mpfr_class::set_dprec(((200 + 1) * 1000L) / 301L); +#elif defined(USE_MPREAL) + mpfr::mpreal::set_default_prec(((200 + 1) * 1000L) / 301L); +#elif defined(USE_CPP_FLOAT) + // Nothing to do, precision is already set. +#else + ntl::RR::SetPrecision(((200 + 1) * 1000L) / 301L); + ntl::RR::SetOutputPrecision(102); +#endif + generator_type value = f(std::integral_constant()); + std::stringstream os; + os << std::setprecision(110) << std::scientific; + os << value; + std::string s = os.str(); + static const regex e("([+-]?\\d+(?:\\.\\d{0,36})?)(\\d*)(?:e([+-]?\\d+))?"); + smatch what; + if(regex_match(s, what, e)) + { + std::cout << + "BOOST_DEFINE_MATH_CONSTANT(" << name << ", " + << what[1] << "e" << (what[3].length() ? what[3].str() : std::string("0")) << ", " + << "\"" << what[1] << what[2] << "e" << (what[3].length() ? what[3].str() : std::string("0")) + << "\");" << std::endl; + } + else + { + std::cout << "Format of numeric constant was not recognised!!" << std::endl; + } +} + +#define BOOST_CONSTANTS_GENERATE(name) \ + boost::math::constants::print_constant(#name, \ + & boost::math::constants::detail::BOOST_JOIN(constant_, name)::get) + +}}} // namespaces + +#endif // BOOST_MATH_CONSTANTS_GENERATE_INCLUDED diff --git a/third-party/boost-math/include_private/boost/math/tools/iteration_logger.hpp b/third-party/boost-math/include_private/boost/math/tools/iteration_logger.hpp new file mode 100644 index 0000000000000..c272a17d70bba --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/tools/iteration_logger.hpp @@ -0,0 +1,77 @@ +// Copyright John Maddock 2014. +// 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) + +#ifndef BOOST_MATH_TOOLS_ITERATION_LOGGER +#define BOOST_MATH_TOOLS_ITERATION_LOGGER + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +struct logger +{ + std::map, unsigned long long> data; + + ~logger() + { + for(std::map, unsigned long long>::const_iterator i = data.begin(); i != data.end(); ++i) + { + std::cout << "Logging iteration data:\n file: " << i->first.first + << "\n function: " << i->first.second + << "\n count: " << i->second << std::endl; + // + // Read in existing data: + // + std::map file_data; + std::string filename = i->first.first + ".logfile"; + std::ifstream is(filename.c_str()); + while(is.good()) + { + std::string f; + unsigned long long c; + is >> std::ws; + std::getline(is, f); + is >> c; + if(f.size()) + file_data[f] = c; + } + is.close(); + if(file_data.find(i->first.second) != file_data.end()) + file_data[i->first.second] += i->second; + else + file_data[i->first.second] = i->second; + // + // Write it out again: + // + std::ofstream os(filename.c_str()); + for(std::map::const_iterator j = file_data.begin(); j != file_data.end(); ++j) + os << j->first << "\n " << j->second << std::endl; + os.close(); + } + } +}; + +inline void log_iterations(const char* file, const char* function, unsigned long long count) +{ + static logger l; + std::pair key(file, function); + if(l.data.find(key) == l.data.end()) + l.data[key] = 0; + l.data[key] += count; +} + +#define BOOST_MATH_LOG_COUNT(count) boost::math::detail::log_iterations(__FILE__, BOOST_CURRENT_FUNCTION, count); + + +}}} // namespaces + +#endif // BOOST_MATH_TOOLS_ITERATION_LOGGER + diff --git a/third-party/boost-math/include_private/boost/math/tools/remez.hpp b/third-party/boost-math/include_private/boost/math/tools/remez.hpp new file mode 100644 index 0000000000000..3fdd473969174 --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/tools/remez.hpp @@ -0,0 +1,667 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_REMEZ_HPP +#define BOOST_MATH_TOOLS_REMEZ_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include "solve.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +namespace detail{ + +// +// The error function: the difference between F(x) and +// the current approximation. This is the function +// for which we must find the extrema. +// +template +struct remez_error_function +{ + typedef boost::function1 function_type; +public: + remez_error_function( + function_type f_, + const polynomial& n, + const polynomial& d, + bool rel_err) + : f(f_), numerator(n), denominator(d), rel_error(rel_err) {} + + T operator()(const T& z)const + { + T y = f(z); + T abs = y - (numerator.evaluate(z) / denominator.evaluate(z)); + T err; + if(rel_error) + { + if(y != 0) + err = abs / fabs(y); + else if(0 == abs) + { + // we must be at a root, or it's not recoverable: + BOOST_MATH_ASSERT(0 == abs); + err = 0; + } + else + { + // We have a divide by zero! + // Lets assume that f(x) is zero as a result of + // internal cancellation error that occurs as a result + // of shifting a root at point z to the origin so that + // the approximation can be "pinned" to pass through + // the origin: in that case it really + // won't matter what our approximation calculates here + // as long as it's a small number, return the absolute error: + err = abs; + } + } + else + err = abs; + return err; + } +private: + function_type f; + polynomial numerator; + polynomial denominator; + bool rel_error; +}; +// +// This function adapts the error function so that it's minima +// are the extrema of the error function. We can find the minima +// with standard techniques. +// +template +struct remez_max_error_function +{ + remez_max_error_function(const remez_error_function& f) + : func(f) {} + + T operator()(const T& x) + { + BOOST_MATH_STD_USING + return -fabs(func(x)); + } +private: + remez_error_function func; +}; + +} // detail + +template +class remez_minimax +{ +public: + typedef boost::function1 function_type; + typedef boost::numeric::ublas::vector vector_type; + typedef boost::numeric::ublas::matrix matrix_type; + + remez_minimax(function_type f, unsigned oN, unsigned oD, T a, T b, bool pin = true, bool rel_err = false, int sk = 0, int bits = 0); + remez_minimax(function_type f, unsigned oN, unsigned oD, T a, T b, bool pin, bool rel_err, int sk, int bits, const vector_type& points); + + void reset(unsigned oN, unsigned oD, T a, T b, bool pin = true, bool rel_err = false, int sk = 0, int bits = 0); + void reset(unsigned oN, unsigned oD, T a, T b, bool pin, bool rel_err, int sk, int bits, const vector_type& points); + + void set_brake(int b) + { + BOOST_MATH_ASSERT(b < 100); + BOOST_MATH_ASSERT(b >= 0); + m_brake = b; + } + + T iterate(); + + polynomial denominator()const; + polynomial numerator()const; + + vector_type const& chebyshev_points()const + { + return control_points; + } + + vector_type const& zero_points()const + { + return zeros; + } + + T error_term()const + { + return solution[solution.size() - 1]; + } + T max_error()const + { + return m_max_error; + } + T max_change()const + { + return m_max_change; + } + void rotate() + { + --orderN; + ++orderD; + } + void rescale(T a, T b) + { + T scale = (b - a) / (max - min); + for(unsigned i = 0; i < control_points.size(); ++i) + { + control_points[i] = (control_points[i] - min) * scale + a; + } + min = a; + max = b; + } +private: + + void init_chebyshev(); + + function_type func; // The function to approximate. + vector_type control_points; // Current control points to be used for the next iteration. + vector_type solution; // Solution from the last iteration contains all unknowns including the error term. + vector_type zeros; // Location of points of zero error from last iteration, plus the two end points. + vector_type maxima; // Location of maxima of the error function, actually contains the control points used for the last iteration. + T m_max_error; // Maximum error found in last approximation. + T m_max_change; // Maximum change in location of control points after last iteration. + unsigned orderN; // Order of the numerator polynomial. + unsigned orderD; // Order of the denominator polynomial. + T min, max; // End points of the range to optimise over. + bool rel_error; // If true optimise for relative not absolute error. + bool pinned; // If true the approximation is "pinned" to go through the origin. + unsigned unknowns; // Total number of unknowns. + int m_precision; // Number of bits precision to which the zeros and maxima are found. + T m_max_change_history[2]; // Past history of changes to control points. + int m_brake; // amount to break by in percentage points. + int m_skew; // amount to skew starting points by in percentage points: -100-100 +}; + +#ifndef BRAKE +#define BRAKE 0 +#endif +#ifndef SKEW +#define SKEW 0 +#endif + +template +void remez_minimax::init_chebyshev() +{ + BOOST_MATH_STD_USING + // + // Fill in the zeros: + // + unsigned terms = pinned ? orderD + orderN : orderD + orderN + 1; + + for(unsigned i = 0; i < terms; ++i) + { + T cheb = cos((2 * terms - 1 - 2 * i) * constants::pi() / (2 * terms)); + cheb += 1; + cheb /= 2; + if(m_skew != 0) + { + T p = static_cast(200 + m_skew) / 200; + cheb = pow(cheb, p); + } + cheb *= (max - min); + cheb += min; + zeros[i+1] = cheb; + } + zeros[0] = min; + zeros[unknowns] = max; + // perform a regular interpolation fit: + matrix_type A(terms, terms); + vector_type b(terms); + // fill in the y values: + for(unsigned i = 0; i < b.size(); ++i) + { + b[i] = func(zeros[i+1]); + } + // fill in powers of x evaluated at each of the control points: + unsigned offsetN = pinned ? 0 : 1; + unsigned offsetD = offsetN + orderN; + unsigned maxorder = (std::max)(orderN, orderD); + for(unsigned i = 0; i < b.size(); ++i) + { + T x0 = zeros[i+1]; + T x = x0; + if(!pinned) + A(i, 0) = 1; + for(unsigned j = 0; j < maxorder; ++j) + { + if(j < orderN) + A(i, j + offsetN) = x; + if(j < orderD) + { + A(i, j + offsetD) = -x * b[i]; + } + x *= x0; + } + } + // + // Now go ahead and solve the expression to get our solution: + // + vector_type l_solution = boost::math::tools::solve(A, b); + // need to add a "fake" error term: + l_solution.resize(unknowns); + l_solution[unknowns-1] = 0; + solution = l_solution; + // + // Now find all the extrema of the error function: + // + detail::remez_error_function Err(func, this->numerator(), this->denominator(), rel_error); + detail::remez_max_error_function Ex(Err); + m_max_error = 0; + //int max_err_location = 0; + for(unsigned i = 0; i < unknowns; ++i) + { + std::pair r = brent_find_minima(Ex, zeros[i], zeros[i+1], m_precision); + maxima[i] = r.first; + T rel_err = fabs(r.second); + if(rel_err > m_max_error) + { + m_max_error = fabs(r.second); + //max_err_location = i; + } + } + control_points = maxima; +} + +template +void remez_minimax::reset( + unsigned oN, + unsigned oD, + T a, + T b, + bool pin, + bool rel_err, + int sk, + int bits) +{ + control_points = vector_type(oN + oD + (pin ? 1 : 2)); + solution = control_points; + zeros = vector_type(oN + oD + (pin ? 2 : 3)); + maxima = control_points; + orderN = oN; + orderD = oD; + rel_error = rel_err; + pinned = pin; + m_skew = sk; + min = a; + max = b; + m_max_error = 0; + unknowns = orderN + orderD + (pinned ? 1 : 2); + // guess our initial control points: + control_points[0] = min; + control_points[unknowns - 1] = max; + T interval = (max - min) / (unknowns - 1); + T spot = min + interval; + for(unsigned i = 1; i < control_points.size(); ++i) + { + control_points[i] = spot; + spot += interval; + } + solution[unknowns - 1] = 0; + m_max_error = 0; + if(bits == 0) + { + // don't bother about more than float precision: + m_precision = (std::min)(24, (boost::math::policies::digits >() / 2) - 2); + } + else + { + // can't be more accurate than half the bits of T: + m_precision = (std::min)(bits, (boost::math::policies::digits >() / 2) - 2); + } + m_max_change_history[0] = m_max_change_history[1] = 1; + init_chebyshev(); + // do one iteration whatever: + //iterate(); +} + +template +inline remez_minimax::remez_minimax( + typename remez_minimax::function_type f, + unsigned oN, + unsigned oD, + T a, + T b, + bool pin, + bool rel_err, + int sk, + int bits) + : func(f) +{ + m_brake = 0; + reset(oN, oD, a, b, pin, rel_err, sk, bits); +} + +template +void remez_minimax::reset( + unsigned oN, + unsigned oD, + T a, + T b, + bool pin, + bool rel_err, + int sk, + int bits, + const vector_type& points) +{ + control_points = vector_type(oN + oD + (pin ? 1 : 2)); + solution = control_points; + zeros = vector_type(oN + oD + (pin ? 2 : 3)); + maxima = control_points; + orderN = oN; + orderD = oD; + rel_error = rel_err; + pinned = pin; + m_skew = sk; + min = a; + max = b; + m_max_error = 0; + unknowns = orderN + orderD + (pinned ? 1 : 2); + control_points = points; + solution[unknowns - 1] = 0; + m_max_error = 0; + if(bits == 0) + { + // don't bother about more than float precision: + m_precision = (std::min)(24, (boost::math::policies::digits >() / 2) - 2); + } + else + { + // can't be more accurate than half the bits of T: + m_precision = (std::min)(bits, (boost::math::policies::digits >() / 2) - 2); + } + m_max_change_history[0] = m_max_change_history[1] = 1; + // do one iteration whatever: + //iterate(); +} + +template +inline remez_minimax::remez_minimax( + typename remez_minimax::function_type f, + unsigned oN, + unsigned oD, + T a, + T b, + bool pin, + bool rel_err, + int sk, + int bits, + const vector_type& points) + : func(f) +{ + m_brake = 0; + reset(oN, oD, a, b, pin, rel_err, sk, bits, points); +} + +template +T remez_minimax::iterate() +{ + BOOST_MATH_STD_USING + matrix_type A(unknowns, unknowns); + vector_type b(unknowns); + + // fill in evaluation of f(x) at each of the control points: + for(unsigned i = 0; i < b.size(); ++i) + { + // take care that none of our control points are at the origin: + if(pinned && (control_points[i] == 0)) + { + if(i) + control_points[i] = control_points[i-1] / 3; + else + control_points[i] = control_points[i+1] / 3; + } + b[i] = func(control_points[i]); + } + + T err_err; + unsigned convergence_count = 0; + do{ + // fill in powers of x evaluated at each of the control points: + int sign = 1; + unsigned offsetN = pinned ? 0 : 1; + unsigned offsetD = offsetN + orderN; + unsigned maxorder = (std::max)(orderN, orderD); + T Elast = solution[unknowns - 1]; + + for(unsigned i = 0; i < b.size(); ++i) + { + T x0 = control_points[i]; + T x = x0; + if(!pinned) + A(i, 0) = 1; + for(unsigned j = 0; j < maxorder; ++j) + { + if(j < orderN) + A(i, j + offsetN) = x; + if(j < orderD) + { + T mult = rel_error ? T(b[i] - sign * fabs(b[i]) * Elast): T(b[i] - sign * Elast); + A(i, j + offsetD) = -x * mult; + } + x *= x0; + } + // The last variable to be solved for is the error term, + // sign changes with each control point: + T E = rel_error ? T(sign * fabs(b[i])) : T(sign); + A(i, unknowns - 1) = E; + sign = -sign; + } + + #ifdef BOOST_MATH_INSTRUMENT + for(unsigned i = 0; i < b.size(); ++i) + std::cout << b[i] << " "; + std::cout << "\n\n"; + for(unsigned i = 0; i < b.size(); ++i) + { + for(unsigned j = 0; j < b.size(); ++ j) + std::cout << A(i, j) << " "; + std::cout << "\n"; + } + std::cout << std::endl; + #endif + // + // Now go ahead and solve the expression to get our solution: + // + solution = boost::math::tools::solve(A, b); + + err_err = (Elast != 0) ? T(fabs((fabs(solution[unknowns-1]) - fabs(Elast)) / fabs(Elast))) : T(1); + }while(orderD && (convergence_count++ < 80) && (err_err > 0.001)); + + // + // Perform a sanity check to verify that the solution to the equations + // is not so much in error as to be useless. The matrix inversion can + // be very close to singular, so this can be a real problem. + // + vector_type sanity = prod(A, solution); + for(unsigned i = 0; i < b.size(); ++i) + { + T err = fabs((b[i] - sanity[i]) / fabs(b[i])); + if(err > sqrt(epsilon())) + { + std::cerr << "Sanity check failed: more than half the digits in the found solution are in error." << std::endl; + } + } + + // + // Next comes another sanity check, we want to verify that all the control + // points do actually alternate in sign, in practice we may have + // additional roots in the error function that cause this to fail. + // Failure here is always fatal: even though this code attempts to correct + // the problem it usually only postpones the inevitable. + // + polynomial num, denom; + num = this->numerator(); + denom = this->denominator(); + T e1 = b[0] - num.evaluate(control_points[0]) / denom.evaluate(control_points[0]); +#ifdef BOOST_MATH_INSTRUMENT + std::cout << e1; +#endif + for(unsigned i = 1; i < b.size(); ++i) + { + T e2 = b[i] - num.evaluate(control_points[i]) / denom.evaluate(control_points[i]); +#ifdef BOOST_MATH_INSTRUMENT + std::cout << " " << e2; +#endif + if(e2 * e1 > 0) + { + std::cerr << std::flush << "Basic sanity check failed: Error term does not alternate in sign, non-recoverable error may follow..." << std::endl; + T perturbation = 0.05; + do{ + T point = control_points[i] * (1 - perturbation) + control_points[i-1] * perturbation; + e2 = func(point) - num.evaluate(point) / denom.evaluate(point); + if(e2 * e1 < 0) + { + control_points[i] = point; + break; + } + perturbation += 0.05; + }while(perturbation < 0.8); + + if((e2 * e1 > 0) && (i + 1 < b.size())) + { + perturbation = 0.05; + do{ + T point = control_points[i] * (1 - perturbation) + control_points[i+1] * perturbation; + e2 = func(point) - num.evaluate(point) / denom.evaluate(point); + if(e2 * e1 < 0) + { + control_points[i] = point; + break; + } + perturbation += 0.05; + }while(perturbation < 0.8); + } + + } + e1 = e2; + } + +#ifdef BOOST_MATH_INSTRUMENT + for(unsigned i = 0; i < solution.size(); ++i) + std::cout << solution[i] << " "; + std::cout << std::endl << this->numerator() << std::endl; + std::cout << this->denominator() << std::endl; + std::cout << std::endl; +#endif + + // + // The next step is to find all the intervals in which our maxima + // lie: + // + detail::remez_error_function Err(func, this->numerator(), this->denominator(), rel_error); + zeros[0] = min; + zeros[unknowns] = max; + for(unsigned i = 1; i < control_points.size(); ++i) + { + eps_tolerance tol(m_precision); + std::uintmax_t max_iter = 1000; + std::pair p = toms748_solve( + Err, + control_points[i-1], + control_points[i], + tol, + max_iter); + zeros[i] = (p.first + p.second) / 2; + //zeros[i] = bisect(Err, control_points[i-1], control_points[i], m_precision); + } + // + // Now find all the extrema of the error function: + // + detail::remez_max_error_function Ex(Err); + m_max_error = 0; + //int max_err_location = 0; + for(unsigned i = 0; i < unknowns; ++i) + { + std::pair r = brent_find_minima(Ex, zeros[i], zeros[i+1], m_precision); + maxima[i] = r.first; + T rel_err = fabs(r.second); + if(rel_err > m_max_error) + { + m_max_error = fabs(r.second); + //max_err_location = i; + } + } + // + // Almost done now! we just need to set our control points + // to the extrema, and calculate how much each point has changed + // (this will be our termination condition): + // + swap(control_points, maxima); + m_max_change = 0; + //int max_change_location = 0; + for(unsigned i = 0; i < unknowns; ++i) + { + control_points[i] = (control_points[i] * (100 - m_brake) + maxima[i] * m_brake) / 100; + T change = fabs((control_points[i] - maxima[i]) / control_points[i]); +#if 0 + if(change > m_max_change_history[1]) + { + // divergence!!! try capping the change: + std::cerr << "Possible divergent step, change will be capped!!" << std::endl; + change = m_max_change_history[1]; + if(control_points[i] < maxima[i]) + control_points[i] = maxima[i] - change * maxima[i]; + else + control_points[i] = maxima[i] + change * maxima[i]; + } +#endif + if(change > m_max_change) + { + m_max_change = change; + //max_change_location = i; + } + } + // + // store max change information: + // + m_max_change_history[0] = m_max_change_history[1]; + m_max_change_history[1] = fabs(m_max_change); + + return m_max_change; +} + +template +polynomial remez_minimax::numerator()const +{ + boost::scoped_array a(new T[orderN + 1]); + if(pinned) + a[0] = 0; + unsigned terms = pinned ? orderN : orderN + 1; + for(unsigned i = 0; i < terms; ++i) + a[pinned ? i+1 : i] = solution[i]; + return boost::math::tools::polynomial(&a[0], orderN); +} + +template +polynomial remez_minimax::denominator()const +{ + unsigned terms = orderD + 1; + unsigned offsetD = pinned ? orderN : (orderN + 1); + boost::scoped_array a(new T[terms]); + a[0] = 1; + for(unsigned i = 0; i < orderD; ++i) + a[i+1] = solution[i + offsetD]; + return boost::math::tools::polynomial(&a[0], orderD); +} + + +}}} // namespaces + +#endif // BOOST_MATH_TOOLS_REMEZ_HPP + + + diff --git a/third-party/boost-math/include_private/boost/math/tools/solve.hpp b/third-party/boost-math/include_private/boost/math/tools/solve.hpp new file mode 100644 index 0000000000000..c0e6c0b25bf59 --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/tools/solve.hpp @@ -0,0 +1,80 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_SOLVE_HPP +#define BOOST_MATH_TOOLS_SOLVE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996 4267 4244) +#endif + +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +namespace boost{ namespace math{ namespace tools{ + +// +// Find x such that Ax = b +// +// Caution: this uses undocumented, and untested ublas code, +// however short of writing our own LU-decomposition code +// it's the only game in town. +// +template +boost::numeric::ublas::vector solve( + const boost::numeric::ublas::matrix& A_, + const boost::numeric::ublas::vector& b_) +{ + //BOOST_MATH_ASSERT(A_.size() == b_.size()); + + boost::numeric::ublas::matrix A(A_); + boost::numeric::ublas::vector b(b_); + boost::numeric::ublas::permutation_matrix<> piv(b.size()); + lu_factorize(A, piv); + lu_substitute(A, piv, b); + // + // iterate to reduce error: + // + boost::numeric::ublas::vector delta(b.size()); + for(unsigned k = 0; k < 1; ++k) + { + noalias(delta) = prod(A_, b); + delta -= b_; + lu_substitute(A, piv, delta); + b -= delta; + + T max_error = 0; + + for(unsigned i = 0; i < delta.size(); ++i) + { + using std::abs; + T err = abs(delta[i] / b[i]); + if(err > max_error) + max_error = err; + } + //std::cout << "Max change in LU error correction: " << max_error << std::endl; + } + + return b; +} + +}}} // namespaces + +#endif // BOOST_MATH_TOOLS_SOLVE_HPP + + diff --git a/third-party/boost-math/include_private/boost/math/tools/test.hpp b/third-party/boost-math/include_private/boost/math/tools/test.hpp new file mode 100644 index 0000000000000..db7b31616e424 --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/tools/test.hpp @@ -0,0 +1,319 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Matt Borland 2024. +// 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) + +#ifndef BOOST_MATH_TOOLS_TEST_HPP +#define BOOST_MATH_TOOLS_TEST_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +struct test_result +{ +private: + boost::math::tools::stats stat; // Statistics for the test. + unsigned worst_case; // Index of the worst case test. +public: + test_result() { worst_case = 0; } + void set_worst(int i){ worst_case = i; } + void add(const T& point){ stat.add(point); } + // accessors: + unsigned worst()const{ return worst_case; } + T min BOOST_MATH_PREVENT_MACRO_SUBSTITUTION()const{ return (stat.min)(); } + T max BOOST_MATH_PREVENT_MACRO_SUBSTITUTION()const{ return (stat.max)(); } + T total()const{ return stat.total(); } + T mean()const{ return stat.mean(); } + std::uintmax_t count()const{ return stat.count(); } + T variance()const{ return stat.variance(); } + T variance1()const{ return stat.variance1(); } + T rms()const{ return stat.rms(); } + + test_result& operator+=(const test_result& t) + { + if((t.stat.max)() > (stat.max)()) + worst_case = t.worst_case; + stat += t.stat; + return *this; + } +}; + +template +struct calculate_result_type +{ + typedef typename T::value_type row_type; + typedef typename row_type::value_type value_type; +}; + +template +T relative_error(T a, T b) +{ + return boost::math::relative_difference(a, b); +} + + +template +void set_output_precision(T, std::ostream& os) +{ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + if(std::numeric_limits::digits10) + { + os << std::setprecision(std::numeric_limits::digits10 + 2); + } + else + os << std::setprecision(22); // and hope for the best! + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +template +void print_row(const Seq& row, std::ostream& os = std::cout) +{ + try { + set_output_precision(row[0], os); + for (unsigned i = 0; i < row.size(); ++i) + { + if (i) + os << ", "; + os << row[i]; + } + os << std::endl; + } + catch (const std::exception&) {} +} + +// +// Function test accepts an matrix of input values (probably a 2D std::array) +// and calls two functors for each row in the array - one calculates a value +// to test, and one extracts the expected value from the array (or possibly +// calculates it at high precision). The two functors are usually simple lambda +// expressions. +// +template +test_result::value_type> test(const A& a, F1 test_func, F2 expect_func) +{ + typedef typename A::value_type row_type; + typedef typename row_type::value_type value_type; + + test_result result; + + for(unsigned i = 0; i < a.size(); ++i) + { + const row_type& row = a[i]; + value_type point; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + point = test_func(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::underflow_error&) + { + point = 0; + } + catch(const std::overflow_error&) + { + point = std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() + : tools::max_value(); + } + catch(const std::exception& e) + { + std::cerr << e.what() << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Unexpected exception."); + // so we don't get further errors: + point = expect_func(row); + } +#endif + value_type expected = expect_func(row); + value_type err = relative_error(point, expected); +#ifdef BOOST_INSTRUMENT + if(err != 0) + { + std::cout << row[0] << " " << err; + if(std::numeric_limits::is_specialized) + { + std::cout << " (" << err / std::numeric_limits::epsilon() << "eps)"; + } + std::cout << std::endl; + } +#endif + if(!(boost::math::isfinite)(point) && (boost::math::isfinite)(expected)) + { + std::cerr << "CAUTION: Found non-finite result, when a finite value was expected at entry " << i << "\n"; + std::cerr << "Found: " << point << " Expected " << expected << " Error: " << err << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Unexpected non-finite result"); + } + if(err > 0.5f) + { + std::cerr << "CAUTION: Gross error found at entry " << i << ".\n"; + std::cerr << "Found: " << point << " Expected " << expected << " Error: " << err << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Gross error"); + } + result.add(err); + if((result.max)() == err) + result.set_worst(i); + } + return result; +} + +template +test_result test_hetero(const A& a, F1 test_func, F2 expect_func) +{ + typedef typename A::value_type row_type; + typedef Real value_type; + + test_result result; + + for(unsigned i = 0; i < a.size(); ++i) + { + const row_type& row = a[i]; + value_type point; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + point = test_func(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::underflow_error&) + { + point = 0; + } + catch(const std::overflow_error&) + { + point = std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() + : tools::max_value(); + } + catch(const std::exception& e) + { + std::cerr << "Unexpected exception at entry: " << i << "\n"; + std::cerr << e.what() << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Unexpected exception."); + // so we don't get further errors: + point = expect_func(row); + } +#endif + value_type expected = expect_func(row); + value_type err = relative_error(point, expected); +#ifdef BOOST_INSTRUMENT + if(err != 0) + { + std::cout << row[0] << " " << err; + if(std::numeric_limits::is_specialized) + { + std::cout << " (" << err / std::numeric_limits::epsilon() << "eps)"; + } + std::cout << std::endl; + } +#endif + if(!(boost::math::isfinite)(point) && (boost::math::isfinite)(expected)) + { + std::cerr << "CAUTION: Found non-finite result, when a finite value was expected at entry " << i << "\n"; + std::cerr << "Found: " << point << " Expected " << expected << " Error: " << err << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Unexpected non-finite result"); + } + if(err > 0.5f) + { + std::cerr << "CAUTION: Gross error found at entry " << i << ".\n"; + std::cerr << "Found: " << point << " Expected " << expected << " Error: " << err << std::endl; + print_row(row, std::cerr); + BOOST_ERROR("Gross error"); + } + result.add(err); + if((result.max)() == err) + result.set_worst(i); + } + return result; +} + +#ifndef BOOST_MATH_NO_EXCEPTIONS +template +void test_check_throw(Val, Exception) +{ + BOOST_CHECK(errno); + errno = 0; +} + +template +void test_check_throw(Val val, std::domain_error const*) +{ + BOOST_CHECK(errno == EDOM); + errno = 0; + if(std::numeric_limits::has_quiet_NaN) + { + BOOST_CHECK((boost::math::isnan)(val)); + } +} + +template +void test_check_throw(Val v, std::overflow_error const*) +{ + BOOST_CHECK(errno == ERANGE); + errno = 0; + BOOST_CHECK((v >= boost::math::tools::max_value()) || (v <= -boost::math::tools::max_value())); +} + +template +void test_check_throw(Val v, boost::math::rounding_error const*) +{ + BOOST_CHECK(errno == ERANGE); + errno = 0; + if(std::numeric_limits::is_specialized && std::numeric_limits::is_integer) + { + BOOST_CHECK((v == (std::numeric_limits::max)()) || (v == (std::numeric_limits::min)())); + } + else + { + BOOST_CHECK((v == boost::math::tools::max_value()) || (v == -boost::math::tools::max_value())); + } +} +#endif + +} // namespace tools +} // namespace math +} // namespace boost + + + // + // exception-free testing support, ideally we'd only define this in our tests, + // but to keep things simple we really need it somewhere that's always included: + // +#if defined(BOOST_MATH_NO_EXCEPTIONS) && defined(BOOST_MATH_HAS_GPU_SUPPORT) +# define BOOST_MATH_CHECK_THROW(x, y) +#elif defined(BOOST_MATH_NO_EXCEPTIONS) +# define BOOST_MATH_CHECK_THROW(x, ExceptionType) boost::math::tools::test_check_throw(x, static_cast(nullptr)); +#else +# define BOOST_MATH_CHECK_THROW(x, y) BOOST_CHECK_THROW(x, y) +#endif + +#endif + + diff --git a/third-party/boost-math/include_private/boost/math/tools/test_data.hpp b/third-party/boost-math/include_private/boost/math/tools/test_data.hpp new file mode 100644 index 0000000000000..5e5faa2d634f1 --- /dev/null +++ b/third-party/boost-math/include_private/boost/math/tools/test_data.hpp @@ -0,0 +1,967 @@ +// (C) Copyright John Maddock 2006. +// 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) + +#ifndef BOOST_MATH_TOOLS_TEST_DATA_HPP +#define BOOST_MATH_TOOLS_TEST_DATA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127 4701 4512) +# pragma warning(disable: 4130) // '==' : logical operation on address of string constant. +#endif +#include +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include +#include +#ifndef BOOST_NO_CXX11_HDR_RANDOM +#include +namespace random_ns = std; +#else +#include +namespace random_ns = boost::random; +#endif +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4130) // '==' : logical operation on address of string constant. +// Used as a warning with BOOST_MATH_ASSERT +#endif + +namespace boost{ namespace math{ namespace tools{ + +enum parameter_type +{ + random_in_range = 0, + periodic_in_range = 1, + power_series = 2, + single_value = 3, + plus_minus_value = 4, + dummy_param = 0x80 +}; + +parameter_type operator | (parameter_type a, parameter_type b) +{ + return static_cast((int)a|(int)b); +} +parameter_type& operator |= (parameter_type& a, parameter_type b) +{ + a = static_cast(a|b); + return a; +} + +// +// If type == random_in_range then +// z1 and r2 are the endpoints of the half open range and n1 is the number of points. +// +// If type == periodic_in_range then +// z1 and r2 are the endpoints of the half open range and n1 is the number of points. +// +// If type == power_series then +// n1 and n2 are the endpoints of the exponents (closed range) and z1 is the basis. +// +// If type == single_value then z1 contains the single value to add. +// +// If type == plus_minus_value then test at +-z1 +// +// If type & dummy_param then this data is ignored and not stored in the output, it +// is passed to the generator function however which can do with it as it sees fit. +// +template +struct parameter_info +{ + parameter_type type; + T z1, z2; + int n1, n2; +}; + +template +inline parameter_info make_random_param(T start_range, T end_range, int n_points) +{ + parameter_info result = { random_in_range, start_range, end_range, n_points, 0 }; + return result; +} + +template +inline parameter_info make_periodic_param(T start_range, T end_range, int n_points) +{ + parameter_info result = { periodic_in_range, start_range, end_range, n_points, 0 }; + return result; +} + +template +inline parameter_info make_power_param(T basis, int start_exponent, int end_exponent) +{ + parameter_info result = { power_series, basis, 0, start_exponent, end_exponent }; + return result; +} + +template +inline parameter_info make_single_param(T val) +{ + parameter_info result = { single_value, val }; + return result; +} + +template +inline parameter_info make_plus_minus_param(T val) +{ + parameter_info result = { plus_minus_value, val }; + return result; +} + +namespace detail{ + +template +inline void unpack_and_append_tuple(Seq&, + const Item&, + const std::integral_constant&, + const std::false_type&) +{ + // termination condition nothing to do here +} + +template +inline void unpack_and_append_tuple(Seq& s, + const Item& data, + const std::integral_constant&, + const std::true_type&) +{ + // extract the N'th element, append, and recurse: + typedef typename Seq::value_type value_type; + value_type val = boost::math::get(data); + s.push_back(val); + + typedef std::integral_constant next_value; + typedef std::integral_constant::value > N+1)> terminate; + + unpack_and_append_tuple(s, data, next_value(), terminate()); +} + +template +inline void unpack_and_append(Seq& s, const Item& data, const std::true_type&) +{ + s.push_back(data); +} + +template +inline void unpack_and_append(Seq& s, const Item& data, const std::false_type&) +{ + // Item had better be a tuple-like type or we've had it!!!! + typedef std::integral_constant next_value; + typedef std::integral_constant::value > 0)> terminate; + + unpack_and_append_tuple(s, data, next_value(), terminate()); +} + +template +inline void unpack_and_append(Seq& s, const Item& data) +{ + typedef typename Seq::value_type value_type; + unpack_and_append(s, data, ::std::is_convertible()); +} + +} // detail + +template +class test_data +{ +public: + typedef std::vector row_type; + typedef row_type value_type; +private: + typedef std::set container_type; +public: + typedef typename container_type::reference reference; + typedef typename container_type::const_reference const_reference; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + typedef typename container_type::difference_type difference_type; + typedef typename container_type::size_type size_type; + + // creation: + test_data(){} + template + test_data(F func, const parameter_info& arg1) + { + insert(func, arg1); + } + + // insertion: + template + test_data& insert(F func, const parameter_info& arg1) + { + // generate data for single argument functor F + + typedef typename std::set::const_iterator it_type; + + std::set points; + create_test_points(points, arg1); + it_type a = points.begin(); + it_type b = points.end(); + row_type row; + while(a != b) + { + if((arg1.type & dummy_param) == 0) + row.push_back(*a); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + // domain_error exceptions from func are swallowed + // and this data point is ignored: + boost::math::tools::detail::unpack_and_append(row, func(*a)); + m_data.insert(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::domain_error&){} +#endif + row.clear(); + ++a; + } + return *this; + } + + template + test_data& insert(F func, const parameter_info& arg1, const parameter_info& arg2) + { + // generate data for 2-argument functor F + + typedef typename std::set::const_iterator it_type; + + std::set points1, points2; + create_test_points(points1, arg1); + create_test_points(points2, arg2); + it_type a = points1.begin(); + it_type b = points1.end(); + row_type row; + while(a != b) + { + it_type c = points2.begin(); + it_type d = points2.end(); + while(c != d) + { + if((arg1.type & dummy_param) == 0) + row.push_back(*a); + if((arg2.type & dummy_param) == 0) + row.push_back(*c); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + // domain_error exceptions from func are swallowed + // and this data point is ignored: + detail::unpack_and_append(row, func(*a, *c)); + m_data.insert(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::domain_error&){} +#endif + row.clear(); + ++c; + } + ++a; + } + return *this; + } + + template + test_data& insert(F func, const parameter_info& arg1, const parameter_info& arg2, const parameter_info& arg3) + { + // generate data for 3-argument functor F + + typedef typename std::set::const_iterator it_type; + + std::set points1, points2, points3; + create_test_points(points1, arg1); + create_test_points(points2, arg2); + create_test_points(points3, arg3); + it_type a = points1.begin(); + it_type b = points1.end(); + row_type row; + while(a != b) + { + it_type c = points2.begin(); + it_type d = points2.end(); + while(c != d) + { + it_type e = points3.begin(); + it_type f = points3.end(); + while(e != f) + { + if((arg1.type & dummy_param) == 0) + row.push_back(*a); + if((arg2.type & dummy_param) == 0) + row.push_back(*c); + if((arg3.type & dummy_param) == 0) + row.push_back(*e); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + // domain_error exceptions from func are swallowed + // and this data point is ignored: + detail::unpack_and_append(row, func(*a, *c, *e)); + m_data.insert(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::domain_error&){} +#endif + row.clear(); + ++e; + } + ++c; + } + ++a; + } + return *this; + } + + template + test_data& insert(F func, const parameter_info& arg1, const parameter_info& arg2, const parameter_info& arg3, const parameter_info& arg4) + { + // generate data for 4-argument functor F + + typedef typename std::set::const_iterator it_type; + + std::set points1, points2, points3, points4; + create_test_points(points1, arg1); + create_test_points(points2, arg2); + create_test_points(points3, arg3); + create_test_points(points4, arg4); + it_type a = points1.begin(); + it_type b = points1.end(); + row_type row; + while(a != b) + { + it_type c = points2.begin(); + it_type d = points2.end(); + while(c != d) + { + it_type e = points3.begin(); + it_type f = points3.end(); + while(e != f) + { + it_type g = points4.begin(); + it_type h = points4.end(); + while (g != h) + { + if ((arg1.type & dummy_param) == 0) + row.push_back(*a); + if ((arg2.type & dummy_param) == 0) + row.push_back(*c); + if ((arg3.type & dummy_param) == 0) + row.push_back(*e); + if ((arg4.type & dummy_param) == 0) + row.push_back(*g); +#ifndef BOOST_NO_EXCEPTIONS + try { +#endif + // domain_error exceptions from func are swallowed + // and this data point is ignored: + detail::unpack_and_append(row, func(*a, *c, *e, *g)); + m_data.insert(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch (const std::domain_error&) {} +#endif + row.clear(); + ++g; + } + ++e; + } + ++c; + } + ++a; + } + return *this; + } + + template + test_data& insert(F func, const parameter_info& arg1, const parameter_info& arg2, const parameter_info& arg3, const parameter_info& arg4, const parameter_info& arg5) + { + // generate data for 5-argument functor F + + typedef typename std::set::const_iterator it_type; + + std::set points1, points2, points3, points4, points5; + create_test_points(points1, arg1); + create_test_points(points2, arg2); + create_test_points(points3, arg3); + create_test_points(points4, arg4); + create_test_points(points5, arg5); + it_type a = points1.begin(); + it_type b = points1.end(); + row_type row; + while(a != b) + { + it_type c = points2.begin(); + it_type d = points2.end(); + while(c != d) + { + it_type e = points3.begin(); + it_type f = points3.end(); + while(e != f) + { + it_type g = points4.begin(); + it_type h = points4.end(); + while (g != h) + { + it_type i = points5.begin(); + it_type j = points5.end(); + while (i != j) + { + if ((arg1.type & dummy_param) == 0) + row.push_back(*a); + if ((arg2.type & dummy_param) == 0) + row.push_back(*c); + if ((arg3.type & dummy_param) == 0) + row.push_back(*e); + if ((arg4.type & dummy_param) == 0) + row.push_back(*g); + if ((arg5.type & dummy_param) == 0) + row.push_back(*i); +#ifndef BOOST_NO_EXCEPTIONS + try { +#endif + // domain_error exceptions from func are swallowed + // and this data point is ignored: + detail::unpack_and_append(row, func(*a, *c, *e, *g, *i)); + m_data.insert(row); +#ifndef BOOST_NO_EXCEPTIONS + } + catch (const std::domain_error&) {} +#endif + row.clear(); + ++i; + } + ++g; + } + ++e; + } + ++c; + } + ++a; + } + return *this; + } + + void clear(){ m_data.clear(); } + + // access: + iterator begin() { return m_data.begin(); } + iterator end() { return m_data.end(); } + const_iterator begin()const { return m_data.begin(); } + const_iterator end()const { return m_data.end(); } + bool operator==(const test_data& d)const{ return m_data == d.m_data; } + bool operator!=(const test_data& d)const{ return m_data != d.m_data; } + void swap(test_data& other){ m_data.swap(other.m_data); } + size_type size()const{ return m_data.size(); } + size_type max_size()const{ return m_data.max_size(); } + bool empty()const{ return m_data.empty(); } + + bool operator < (const test_data& dat)const{ return m_data < dat.m_data; } + bool operator <= (const test_data& dat)const{ return m_data <= dat.m_data; } + bool operator > (const test_data& dat)const{ return m_data > dat.m_data; } + bool operator >= (const test_data& dat)const{ return m_data >= dat.m_data; } + +private: + void create_test_points(std::set& points, const parameter_info& arg1); + std::set m_data; + + static float extern_val; + static float truncate_to_float(float const * pf); + static float truncate_to_float(float c){ return truncate_to_float(&c); } +}; + +// +// This code exists to bemuse the compiler's optimizer and force a +// truncation to float-precision only: +// +template +inline float test_data::truncate_to_float(float const * pf) +{ + BOOST_MATH_STD_USING + int expon; + float f = floor(ldexp(frexp(*pf, &expon), 22)); + f = ldexp(f, expon - 22); + return f; + + //extern_val = *pf; + //return *pf; +} + +template +float test_data::extern_val = 0; + +template +void test_data::create_test_points(std::set& points, const parameter_info& arg1) +{ + BOOST_MATH_STD_USING + // + // Generate a set of test points as requested, try and generate points + // at only float precision: otherwise when testing float versions of functions + // there will be a rounding error in our input values which throws off the results + // (Garbage in garbage out etc). + // + switch(arg1.type & 0x7F) + { + case random_in_range: + { + BOOST_MATH_ASSERT(arg1.z1 < arg1.z2); + BOOST_MATH_ASSERT(arg1.n1 > 0); + typedef float random_type; + + random_ns::mt19937 rnd; + random_ns::uniform_real_distribution ur_a(real_cast(arg1.z1), real_cast(arg1.z2)); + + for(int i = 0; i < arg1.n1; ++i) + { + random_type r = ur_a(rnd); + points.insert(truncate_to_float(r)); + } + } + break; + case periodic_in_range: + { + BOOST_MATH_ASSERT(arg1.z1 < arg1.z2); + BOOST_MATH_ASSERT(arg1.n1 > 0); + float interval = real_cast((arg1.z2 - arg1.z1) / arg1.n1); + T val = arg1.z1; + while(val < arg1.z2) + { + points.insert(truncate_to_float(real_cast(val))); + val += interval; + } + } + break; + case power_series: + { + BOOST_MATH_ASSERT(arg1.n1 < arg1.n2); + + typedef float random_type; + typedef typename boost::mpl::if_< + ::boost::is_floating_point, + T, long double>::type power_type; + + random_ns::mt19937 rnd; + random_ns::uniform_real_distribution ur_a(1.0, 2.0); + + for(int power = arg1.n1; power <= arg1.n2; ++power) + { + random_type r = ur_a(rnd); + power_type p = ldexp(static_cast(r), power); + points.insert(truncate_to_float(real_cast(arg1.z1 + p))); + } + } + break; + case single_value: + { + points.insert(truncate_to_float(real_cast(arg1.z1))); + break; + } + case plus_minus_value: + { + points.insert(truncate_to_float(real_cast(arg1.z1))); + points.insert(truncate_to_float(-real_cast(arg1.z1))); + break; + } + default: + BOOST_MATH_ASSERT(0 == "Invalid parameter_info object"); + // Assert will fail if get here. + // Triggers warning 4130) // '==' : logical operation on address of string constant. + } +} + +// +// Prompt a user for information on a parameter range: +// +template +bool get_user_parameter_info(parameter_info& info, const char* param_name) +{ +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) +#endif + std::string line; + do{ + std::cout << "What kind of distribution do you require for parameter " << param_name << "?\n" + "Choices are:\n" + " r Random values in a half open range\n" + " p Evenly spaced periodic values in a half open range\n" + " e Exponential power series at a particular point: a + 2^b for some range of b\n" + "[Default=r]"; + + std::getline(std::cin, line); + boost::algorithm::trim(line); + + if(line == "r") + { + info.type = random_in_range; + break; + } + else if(line == "p") + { + info.type = periodic_in_range; + break; + } + else if(line == "e") + { + info.type = power_series; + break; + } + else if(line == "") + { + info.type = random_in_range; + break; + } + // + // Ooops, not a valid input.... + // + std::cout << "Sorry don't recognise \"" << line << "\" as a valid input\n" + "do you want to try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "n") + return false; + else if(line == "y") + continue; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + }while(true); + + switch(info.type & ~dummy_param) + { + case random_in_range: + case periodic_in_range: + // get start and end points of range: + do{ + std::cout << "Data will be in the half open range a <= x < b,\n" + "enter value for the start point fo the range [default=0]:"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "") + { + info.z1 = 0; + break; + } +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + info.z1 = boost::lexical_cast(line); + break; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + }while(true); + do{ + std::cout << "Enter value for the end point fo the range [default=1]:"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "") + { + info.z2 = 1; + } + else + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + info.z2 = boost::lexical_cast(line); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + } + if(info.z1 >= info.z2) + { + std::cout << "The end point of the range was <= the start point\n" + "try a different value for the endpoint [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } + break; + }while(true); + do{ + // get the number of points: + std::cout << "How many data points do you want?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + info.n1 = boost::lexical_cast(line); + info.n2 = 0; + if(info.n1 <= 0) + { + std::cout << "The number of points should be > 0\n" + "try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } + break; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + }while(true); + break; + case power_series: + // get start and end points of range: + info.z2 = 0; + do{ + std::cout << "Data will be in the form a + r*2^b\n" + "for random value r,\n" + "enter value for the point a [default=0]:"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "") + { + info.z1 = 0; + break; + } +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + info.z1 = boost::lexical_cast(line); + break; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + }while(true); + + do{ + std::cout << "Data will be in the form a + r*2^b\n" + "for random value r,\n" + "enter value for the starting exponent b:"; + std::getline(std::cin, line); + boost::algorithm::trim(line); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + info.n1 = boost::lexical_cast(line); + break; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + }while(true); + + do{ + std::cout << "Data will be in the form a + r*2^b\n" + "for random value r,\n" + "enter value for the ending exponent b:"; + std::getline(std::cin, line); + boost::algorithm::trim(line); +#ifndef BOOST_NO_EXCEPTIONS + try{ +#endif + info.n2 = boost::lexical_cast(line); + break; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::bad_lexical_cast&) + { + std::cout << "Sorry, that was not valid input, try again [y/n]?"; + std::getline(std::cin, line); + boost::algorithm::trim(line); + if(line == "y") + continue; + if(line == "n") + return false; + std::cout << "Sorry don't recognise that either, giving up...\n\n"; + return false; + } +#endif + }while(true); + + break; + default: + BOOST_MATH_ASSERT(0); // should never get here!! + } + + return true; +#ifdef _MSC_VER +# pragma warning(pop) +#endif +} + +template +inline std::basic_ostream& write_csv(std::basic_ostream& os, + const test_data& data) +{ + const charT defarg[] = { ',', ' ', '\0' }; + return write_csv(os, data, defarg); +} + +template +std::basic_ostream& write_csv(std::basic_ostream& os, + const test_data& data, + const charT* separator) +{ + typedef typename test_data::const_iterator it_type; + typedef typename test_data::value_type value_type; + typedef typename value_type::const_iterator value_type_iterator; + it_type a, b; + a = data.begin(); + b = data.end(); + while(a != b) + { + value_type_iterator x, y; + bool sep = false; + x = a->begin(); + y = a->end(); + while(x != y) + { + if(sep) + os << separator; + os << *x; + sep = true; + ++x; + } + os << std::endl; + ++a; + } + return os; +} + +template +std::ostream& write_code(std::ostream& os, + const test_data& data, + const char* name) +{ + typedef typename test_data::const_iterator it_type; + typedef typename test_data::value_type value_type; + typedef typename value_type::const_iterator value_type_iterator; + + BOOST_MATH_ASSERT(os.good()); + + it_type a, b; + a = data.begin(); + b = data.end(); + if(a == b) + return os; + + os << "#ifndef SC_\n# define SC_(x) static_cast(BOOST_JOIN(x, L))\n#endif\n" + " static const std::arraysize() << ">, " << data.size() << "> " << name << " = {{\n"; + + while(a != b) + { + if(a != data.begin()) + os << ", \n"; + + value_type_iterator x, y; + x = a->begin(); + y = a->end(); + os << " { "; + while(x != y) + { + if(x != a->begin()) + os << ", "; + os << "SC_(" << *x << ")"; + ++x; + } + os << " }"; + ++a; + } + os << "\n }};\n//#undef SC_\n\n"; + return os; +} + +} // namespace tools +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + +#endif // BOOST_MATH_TOOLS_TEST_DATA_HPP + + diff --git a/third-party/boost-math/index.html b/third-party/boost-math/index.html new file mode 100644 index 0000000000000..bc4416553e427 --- /dev/null +++ b/third-party/boost-math/index.html @@ -0,0 +1,14 @@ + + + + + +Automatic redirection failed, please go to +doc/html/index.html. +

Copyright Daryle Walker, Hubert Holin and John Maddock 2006

+

Distributed under the Boost Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt).

+ + + + diff --git a/third-party/update_boost_math.sh b/third-party/update_boost_math.sh new file mode 100755 index 0000000000000..96cd73ed8c304 --- /dev/null +++ b/third-party/update_boost_math.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e # stop at the first error + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) +VERSION="1.89.0" + +echo "This script deletes ${SCRIPT_DIR}/boost-math and re-downloads it from the standalone Boost.Math release version ${VERSION}." +echo "It then subsets it so it only contains the parts that are used in libc++." +echo +read -p "Press a key to continue, or Ctrl+C to cancel" + +echo "****************************************" +echo "Downloading Boost.Math ${VERSION}" +echo "****************************************" +BOOST_URL="https://github.com/boostorg/math/archive/refs/tags/boost-${VERSION}.tar.gz" +function cleanup_tarball() { + rm ${SCRIPT_DIR}/boost-math-${VERSION}.tar.gz +} +trap cleanup_tarball EXIT +wget "${BOOST_URL}" -O ${SCRIPT_DIR}/boost-math-${VERSION}.tar.gz +rm -rf ${SCRIPT_DIR}/boost-math +mkdir ${SCRIPT_DIR}/boost-math +tar -x --file ${SCRIPT_DIR}/boost-math-${VERSION}.tar.gz -C ${SCRIPT_DIR}/boost-math --strip-components=1 + +echo "****************************************" +echo "Subsetting Boost.Math ${VERSION}" +echo "****************************************" +rm -rf ${SCRIPT_DIR}/boost-math/{.circleci,.drone,.github,build,config,doc,example,meta,reporting,src,test,tools} From 60ab8c89673a84a34e4245c5a590c45e22852f13 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Mon, 27 Oct 2025 14:48:04 -0700 Subject: [PATCH 13/33] [lld][macho] Use reloc length correctly in hash computation (#165287) `Reloc::length` actually encodes the log2 of the length. Thanks @int3 for pointing this out in https://github.com/llvm/llvm-project/issues/160894#issuecomment-3416250179. This code computes hashes of relocations. With the correct length, the hashes should more accurately represent the relocation. In my testing of some large binaries, the compressed size change is negligable. --- lld/MachO/BPSectionOrderer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lld/MachO/BPSectionOrderer.cpp b/lld/MachO/BPSectionOrderer.cpp index 1f07ea9caf5df..d50abc22fc6c1 100644 --- a/lld/MachO/BPSectionOrderer.cpp +++ b/lld/MachO/BPSectionOrderer.cpp @@ -61,12 +61,13 @@ struct BPOrdererMachO : lld::BPOrderer { // Calculate relocation hashes for (const auto &r : sec.relocs) { - if (r.length == 0 || r.referent.isNull() || r.offset >= data.size()) + uint32_t relocLength = 1 << r.length; + if (r.referent.isNull() || r.offset + relocLength > data.size()) continue; uint64_t relocHash = getRelocHash(r, sectionToIdx); uint32_t start = (r.offset < windowSize) ? 0 : r.offset - windowSize + 1; - for (uint32_t i = start; i < r.offset + r.length; i++) { + for (uint32_t i = start; i < r.offset + relocLength; i++) { auto window = data.drop_front(i).take_front(windowSize); hashes.push_back(xxh3_64bits(window) ^ relocHash); } From a06550574981d78f4e2ff5978391c4ed621e6b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20V=20Arrechea?= Date: Mon, 27 Oct 2025 16:05:48 -0600 Subject: [PATCH 14/33] Begin -print-on-crash output with semicolon (#164903) So it's treated as a comment and doesn't need to be manually removed from the output when used as IR. --- llvm/lib/Passes/StandardInstrumentations.cpp | 2 +- llvm/test/Other/print-on-crash.ll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp index de293308ae69e..7290a86503120 100644 --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -2499,7 +2499,7 @@ void PrintCrashIRInstrumentation::registerCallbacks( [&PIC, this](StringRef PassID, Any IR) { SavedIR.clear(); raw_string_ostream OS(SavedIR); - OS << formatv("*** Dump of {0}IR Before Last Pass {1}", + OS << formatv("; *** Dump of {0}IR Before Last Pass {1}", llvm::forcePrintModuleIR() ? "Module " : "", PassID); if (!isInteresting(IR, PassID, PIC.getPassNameForClassName(PassID))) { OS << " Filtered Out ***\n"; diff --git a/llvm/test/Other/print-on-crash.ll b/llvm/test/Other/print-on-crash.ll index 565da0c389c16..f1e3414fb6352 100644 --- a/llvm/test/Other/print-on-crash.ll +++ b/llvm/test/Other/print-on-crash.ll @@ -17,7 +17,7 @@ ; RUN: not --crash opt -print-on-crash -print-module-scope -passes=trigger-crash-module -filter-passes=blah < %s 2>&1 | FileCheck %s --check-prefix=CHECK_FILTERED -; CHECK_SIMPLE: *** Dump of IR Before Last Pass {{.*}} Started *** +; CHECK_SIMPLE: ; *** Dump of IR Before Last Pass {{.*}} Started *** ; CHECK_SIMPLE: @main ; CHECK_SIMPLE: entry: ; CHECK_NO_CRASH-NOT: *** Dump of IR From 9702ec056b5509238353bff71c8f8bb664d95e4c Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 27 Oct 2025 18:26:08 -0400 Subject: [PATCH 15/33] [flang] Fixed regression with CDEFINED linkage (#164616) https://github.com/llvm/llvm-project/pull/162722 introduced a regression that started creating initializers for CDEFINED variables. CDEFINED variables cannot have initializers, because their storage is expected come from elsewhere, likely outside of Fortran. Fixed the regression and improved the regression test to catch the incorrect initialization case. Also, based on the code review feedback, made CDEFINED variable initialization a hard error and updated tests accordingly. --- flang/include/flang/Support/Fortran-features.h | 2 +- flang/lib/Semantics/resolve-names.cpp | 8 ++++---- flang/test/Lower/cdefined.f90 | 7 ++++--- flang/test/Semantics/cdefined.f90 | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h index 51364d552be64..c7d0b7fca1d59 100644 --- a/flang/include/flang/Support/Fortran-features.h +++ b/flang/include/flang/Support/Fortran-features.h @@ -73,7 +73,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, ZeroDoStep, UnusedForallIndex, OpenMPUsage, DataLength, IgnoredDirective, HomonymousSpecific, HomonymousResult, IgnoredIntrinsicFunctionType, PreviousScalarUse, RedeclaredInaccessibleComponent, ImplicitShared, - IndexVarRedefinition, IncompatibleImplicitInterfaces, CdefinedInit, + IndexVarRedefinition, IncompatibleImplicitInterfaces, VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg, MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation, CompatibleDeclarationsFromDistinctModules, ConstantIsContiguous, diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 4af6cf6a91239..561ebd2a982c3 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -9194,11 +9194,11 @@ bool DeclarationVisitor::CheckNonPointerInitialization( "'%s' has already been initialized"_err_en_US); } else if (IsAllocatable(ultimate)) { Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US); + } else if (details->isCDefined()) { + // CDEFINED variables cannot have initializer, because their storage + // may come outside of Fortran. + Say(name, "CDEFINED variable cannot be initialized"_err_en_US); } else { - if (details->isCDefined()) { - context().Warn(common::UsageWarning::CdefinedInit, name.source, - "CDEFINED variable should not have an initializer"_warn_en_US); - } return true; } } else { diff --git a/flang/test/Lower/cdefined.f90 b/flang/test/Lower/cdefined.f90 index 89599442589eb..748f8f701e58b 100644 --- a/flang/test/Lower/cdefined.f90 +++ b/flang/test/Lower/cdefined.f90 @@ -1,9 +1,10 @@ ! RUN: bbc -emit-hlfir -o - %s | FileCheck %s ! Ensure that CDEFINED variable has external (default) linkage and that -! it doesn't have an initializer +! it doesn't have either zero or constant initializer. module m use iso_c_binding - integer(c_int), bind(C, name='c_global', CDEFINED) :: c = 42 + integer(c_int), bind(C, name='c_global', CDEFINED) :: c ! CHECK: fir.global @c_global : i32 - ! CHECK-NOT: fir.zero_bits + ! CHECK-NOT: fir.zero_bits + ! CHECK-NOT: arith.constant end diff --git a/flang/test/Semantics/cdefined.f90 b/flang/test/Semantics/cdefined.f90 index 84103ce661d0b..ef59e43c6b37e 100644 --- a/flang/test/Semantics/cdefined.f90 +++ b/flang/test/Semantics/cdefined.f90 @@ -1,6 +1,6 @@ -! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror +! RUN: %python %S/test_errors.py %s %flang_fc1 module m use iso_c_binding - !WARNING: CDEFINED variable should not have an initializer [-Wcdefined-init] + !ERROR: CDEFINED variable cannot be initialized integer(c_int), bind(C, name='c_global', CDEFINED) :: c = 42 end From 676d3b881b0b5b39ce74f83e9a924ab05384035c Mon Sep 17 00:00:00 2001 From: Baranov Victor Date: Tue, 28 Oct 2025 01:32:58 +0300 Subject: [PATCH 16/33] [clang-tidy][NFC] Fix various clang-tidy warning on headers 1/N (#165175) Started running `clang-tidy` on our clang-tidy headers. This part covers what `clang-tidy` could fix automatically (with `--fix` option). The main goal is to enable `HeaderFilterRegex: 'clang-tools-extra/clang-tidy/.*'` eventually in config. --- clang-tools-extra/clang-tidy/ClangTidyModule.h | 2 +- clang-tools-extra/clang-tidy/ClangTidyOptions.h | 2 +- .../clang-tidy/ExpandModularHeadersPPCallbacks.h | 2 +- .../clang-tidy/abseil/DurationAdditionCheck.cpp | 2 +- .../clang-tidy/abseil/DurationComparisonCheck.cpp | 2 +- .../abseil/DurationConversionCastCheck.cpp | 2 +- .../abseil/DurationFactoryFloatCheck.cpp | 2 +- .../abseil/DurationFactoryScaleCheck.cpp | 2 +- .../clang-tidy/abseil/DurationRewriter.h | 10 +++++----- .../clang-tidy/abseil/DurationSubtractionCheck.cpp | 2 +- .../clang-tidy/abseil/TimeComparisonCheck.cpp | 2 +- .../abseil/UpgradeDurationConversionsCheck.cpp | 2 +- .../clang-tidy/android/CloexecCheck.h | 2 +- .../bugprone/NarrowingConversionsCheck.h | 2 +- .../bugprone/NotNullTerminatedResultCheck.cpp | 8 ++++---- .../bugprone/NotNullTerminatedResultCheck.h | 8 ++++---- .../SpecialMemberFunctionsCheck.h | 4 ++-- .../clang-tidy/google/TodoCommentCheck.h | 2 +- .../clang-tidy/misc/ConfusableIdentifierCheck.h | 2 +- .../clang-tidy/misc/MisleadingBidirectional.h | 2 +- .../clang-tidy/misc/MisleadingIdentifier.h | 2 +- .../clang-tidy/misc/UnusedParametersCheck.h | 2 +- .../clang-tidy/modernize/LoopConvertUtils.cpp | 6 +++--- .../clang-tidy/modernize/LoopConvertUtils.h | 2 +- .../performance/NoexceptDestructorCheck.h | 5 ++--- .../performance/NoexceptFunctionBaseCheck.h | 3 +-- .../performance/NoexceptMoveConstructorCheck.h | 5 ++--- .../clang-tidy/performance/NoexceptSwapCheck.h | 5 ++--- .../readability/AvoidReturnWithVoidValueCheck.h | 1 - .../clang-tidy/readability/IdentifierNamingCheck.h | 2 +- .../clang-tidy/utils/BracesAroundStatement.h | 2 +- .../clang-tidy/utils/IncludeSorter.cpp | 5 ++--- clang-tools-extra/clang-tidy/utils/IncludeSorter.h | 4 ++-- clang-tools-extra/clang-tidy/utils/Matchers.h | 2 +- .../clang-tidy/utils/RenamerClangTidyCheck.h | 2 +- .../include/clang-include-cleaner/Types.h | 14 ++++++-------- 36 files changed, 58 insertions(+), 66 deletions(-) diff --git a/clang-tools-extra/clang-tidy/ClangTidyModule.h b/clang-tools-extra/clang-tidy/ClangTidyModule.h index 8d697c6261286..53ef3f153dd15 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyModule.h +++ b/clang-tools-extra/clang-tidy/ClangTidyModule.h @@ -85,7 +85,7 @@ class ClangTidyCheckFactories { /// them a prefixed name. class ClangTidyModule { public: - virtual ~ClangTidyModule() {} + virtual ~ClangTidyModule() = default; /// Implement this function in order to register all \c CheckFactories /// belonging to this module. diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h index 2aae92f1d9eb3..4c97c5ba801f0 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -171,7 +171,7 @@ class ClangTidyOptionsProvider { static const char OptionsSourceTypeCheckCommandLineOption[]; static const char OptionsSourceTypeConfigCommandLineOption[]; - virtual ~ClangTidyOptionsProvider() {} + virtual ~ClangTidyOptionsProvider() = default; /// Returns global options, which are independent of the file. virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0; diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h index e599bda92c25c..aaa04107a11ec 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h @@ -44,7 +44,7 @@ class ExpandModularHeadersPPCallbacks : public PPCallbacks { ExpandModularHeadersPPCallbacks( CompilerInstance *CI, IntrusiveRefCntPtr OverlayFS); - ~ExpandModularHeadersPPCallbacks(); + ~ExpandModularHeadersPPCallbacks() override; /// Returns the preprocessor that provides callbacks for the whole /// translation unit, including the main file, textual headers, and modular diff --git a/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.cpp index 4e1bd3ae32ee5..03f78f1c96252 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.cpp @@ -21,7 +21,7 @@ void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( binaryOperator(hasOperatorName("+"), hasEitherOperand(expr(ignoringParenImpCasts( - callExpr(callee(functionDecl(TimeConversionFunction()) + callExpr(callee(functionDecl(timeConversionFunction()) .bind("function_decl"))) .bind("call"))))) .bind("binop"), diff --git a/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.cpp index cb8a478e288b6..16a244b7e9997 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -17,7 +17,7 @@ namespace clang::tidy::abseil { void DurationComparisonCheck::registerMatchers(MatchFinder *Finder) { auto Matcher = expr(comparisonOperatorWithCallee(functionDecl( - functionDecl(DurationConversionFunction()) + functionDecl(durationConversionFunction()) .bind("function_decl")))) .bind("binop"); diff --git a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp index cf591d9589057..11d6017c22e9d 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -19,7 +19,7 @@ namespace clang::tidy::abseil { void DurationConversionCastCheck::registerMatchers(MatchFinder *Finder) { auto CallMatcher = ignoringImpCasts(callExpr( - callee(functionDecl(DurationConversionFunction()).bind("func_decl")), + callee(functionDecl(durationConversionFunction()).bind("func_decl")), hasArgument(0, expr().bind("arg")))); Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index cccd7cf796150..83906fe05054f 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -28,7 +28,7 @@ static bool insideMacroDefinition(const MatchFinder::MatchResult &Result, void DurationFactoryFloatCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - callExpr(callee(functionDecl(DurationFactoryFunction())), + callExpr(callee(functionDecl(durationFactoryFunction())), hasArgument(0, anyOf(cxxStaticCastExpr(hasDestinationType( realFloatingPointType())), cStyleCastExpr(hasDestinationType( diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp index 1d6ff1ab17abd..334629767aff2 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp @@ -112,7 +112,7 @@ static std::optional getNewScale(DurationScale OldScale, void DurationFactoryScaleCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr( - callee(functionDecl(DurationFactoryFunction()).bind("call_decl")), + callee(functionDecl(durationFactoryFunction()).bind("call_decl")), hasArgument( 0, ignoringImpCasts(anyOf( diff --git a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.h b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.h index 27d6ca0616985..e3b1753e95a16 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.h @@ -96,7 +96,7 @@ bool isInMacro(const ast_matchers::MatchFinder::MatchResult &Result, const Expr *E); AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, - DurationConversionFunction) { + durationConversionFunction) { using namespace clang::ast_matchers; return functionDecl( hasAnyName("::absl::ToDoubleHours", "::absl::ToDoubleMinutes", @@ -108,7 +108,7 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, } AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, - DurationFactoryFunction) { + durationFactoryFunction) { using namespace clang::ast_matchers; return functionDecl(hasAnyName("::absl::Nanoseconds", "::absl::Microseconds", "::absl::Milliseconds", "::absl::Seconds", @@ -116,7 +116,7 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, } AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, - TimeConversionFunction) { + timeConversionFunction) { using namespace clang::ast_matchers; return functionDecl(hasAnyName( "::absl::ToUnixHours", "::absl::ToUnixMinutes", "::absl::ToUnixSeconds", @@ -125,12 +125,12 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, AST_MATCHER_FUNCTION_P(ast_matchers::internal::Matcher, comparisonOperatorWithCallee, - ast_matchers::internal::Matcher, funcDecl) { + ast_matchers::internal::Matcher, FuncDecl) { using namespace clang::ast_matchers; return binaryOperator( anyOf(hasOperatorName(">"), hasOperatorName(">="), hasOperatorName("=="), hasOperatorName("<="), hasOperatorName("<")), - hasEitherOperand(ignoringImpCasts(callExpr(callee(funcDecl))))); + hasEitherOperand(ignoringImpCasts(callExpr(callee(FuncDecl))))); } } // namespace clang::tidy::abseil diff --git a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp index fd5e2038f75d1..c5d93ad51ad17 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.cpp @@ -21,7 +21,7 @@ void DurationSubtractionCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( binaryOperator( hasOperatorName("-"), - hasLHS(callExpr(callee(functionDecl(DurationConversionFunction()) + hasLHS(callExpr(callee(functionDecl(durationConversionFunction()) .bind("function_decl")), hasArgument(0, expr().bind("lhs_arg"))))) .bind("binop"), diff --git a/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.cpp b/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.cpp index 52121a57de0d1..7a97a1895ad02 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.cpp @@ -18,7 +18,7 @@ namespace clang::tidy::abseil { void TimeComparisonCheck::registerMatchers(MatchFinder *Finder) { auto Matcher = expr(comparisonOperatorWithCallee(functionDecl( - functionDecl(TimeConversionFunction()).bind("function_decl")))) + functionDecl(timeConversionFunction()).bind("function_decl")))) .bind("binop"); Finder->addMatcher(Matcher, this); diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index f7905e081170e..8b197e5b939e7 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -104,7 +104,7 @@ void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { hasCastKind(CK_UserDefinedConversion)))), hasParent(callExpr( callee(functionDecl( - DurationFactoryFunction(), + durationFactoryFunction(), unless(hasParent(functionTemplateDecl())))), hasArgument(0, expr().bind("arg"))))) .bind("OuterExpr")), diff --git a/clang-tools-extra/clang-tidy/android/CloexecCheck.h b/clang-tools-extra/clang-tidy/android/CloexecCheck.h index b2b59f5be1b9a..858d96ab45b61 100644 --- a/clang-tools-extra/clang-tidy/android/CloexecCheck.h +++ b/clang-tools-extra/clang-tidy/android/CloexecCheck.h @@ -82,7 +82,7 @@ class CloexecCheck : public ClangTidyCheck { /// \param Mode The required mode char. /// \param ArgPos The 0-based position of the flag argument. void insertStringFlag(const ast_matchers::MatchFinder::MatchResult &Result, - const char Mode, const int ArgPos); + char Mode, int ArgPos); /// Helper function to get the spelling of a particular argument. StringRef getSpellingArg(const ast_matchers::MatchFinder::MatchResult &Result, diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h index 9c05827556e67..9631c71dee64e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.h @@ -41,7 +41,7 @@ class NarrowingConversionsCheck : public ClangTidyCheck { void diagNarrowIntegerConstantToSignedInt(SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs, const llvm::APSInt &Value, - const uint64_t HexBits); + uint64_t HexBits); void diagNarrowConstant(SourceLocation SourceLoc, const Expr &Lhs, const Expr &Rhs); diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp index ca85168ffce0b..08fae7b59bae5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp @@ -823,7 +823,7 @@ void NotNullTerminatedResultCheck::check( if (Name.starts_with("mem") || Name.starts_with("wmem")) memoryHandlerFunctionFix(Name, Result); else if (Name == "strerror_s") - strerror_sFix(Result); + strerrorSFix(Result); else if (Name.ends_with("ncmp")) ncmpFix(Name, Result); else if (Name.ends_with("xfrm")) @@ -852,7 +852,7 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix( if (Name.ends_with("cpy")) { memcpyFix(Name, Result, Diag); } else if (Name.ends_with("cpy_s")) { - memcpy_sFix(Name, Result, Diag); + memcpySFix(Name, Result, Diag); } else if (Name.ends_with("move")) { memmoveFix(Name, Result, Diag); } else if (Name.ends_with("move_s")) { @@ -889,7 +889,7 @@ void NotNullTerminatedResultCheck::memcpyFix( insertNullTerminatorExpr(Name, Result, Diag); } -void NotNullTerminatedResultCheck::memcpy_sFix( +void NotNullTerminatedResultCheck::memcpySFix( StringRef Name, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { bool IsOverflows = isDestCapacityFix(Result, Diag); @@ -950,7 +950,7 @@ void NotNullTerminatedResultCheck::memmoveFix( lengthArgHandle(LengthHandleKind::Increase, Result, Diag); } -void NotNullTerminatedResultCheck::strerror_sFix( +void NotNullTerminatedResultCheck::strerrorSFix( const MatchFinder::MatchResult &Result) { auto Diag = diag(Result.Nodes.getNodeAs(FunctionExprName)->getBeginLoc(), diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h index ca3fbf0febf7a..a8f4ca32a0b5b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h @@ -43,15 +43,15 @@ class NotNullTerminatedResultCheck : public ClangTidyCheck { void memcpyFix(StringRef Name, const ast_matchers::MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag); - void memcpy_sFix(StringRef Name, - const ast_matchers::MatchFinder::MatchResult &Result, - DiagnosticBuilder &Diag); + void memcpySFix(StringRef Name, + const ast_matchers::MatchFinder::MatchResult &Result, + DiagnosticBuilder &Diag); void memchrFix(StringRef Name, const ast_matchers::MatchFinder::MatchResult &Result); void memmoveFix(StringRef Name, const ast_matchers::MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) const; - void strerror_sFix(const ast_matchers::MatchFinder::MatchResult &Result); + void strerrorSFix(const ast_matchers::MatchFinder::MatchResult &Result); void ncmpFix(StringRef Name, const ast_matchers::MatchFinder::MatchResult &Result); void xfrmFix(StringRef Name, diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index 8cdaf315eac52..507aaa1cb9d79 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -84,11 +84,11 @@ struct DenseMapInfo< using ClassDefId = clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId; - static inline ClassDefId getEmptyKey() { + static ClassDefId getEmptyKey() { return {DenseMapInfo::getEmptyKey(), "EMPTY"}; } - static inline ClassDefId getTombstoneKey() { + static ClassDefId getTombstoneKey() { return {DenseMapInfo::getTombstoneKey(), "TOMBSTONE"}; } diff --git a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h index 05f9cc6618eb1..08cea131ec44d 100644 --- a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h +++ b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h @@ -22,7 +22,7 @@ namespace clang::tidy::google::readability { class TodoCommentCheck : public ClangTidyCheck { public: TodoCommentCheck(StringRef Name, ClangTidyContext *Context); - ~TodoCommentCheck(); + ~TodoCommentCheck() override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.h b/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.h index 37337954822b7..b341d03083c92 100644 --- a/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.h @@ -21,7 +21,7 @@ namespace clang::tidy::misc { class ConfusableIdentifierCheck : public ClangTidyCheck { public: ConfusableIdentifierCheck(StringRef Name, ClangTidyContext *Context); - ~ConfusableIdentifierCheck(); + ~ConfusableIdentifierCheck() override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h index aa7e0432b9ceb..ba895b95b9a25 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h +++ b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h @@ -16,7 +16,7 @@ namespace clang::tidy::misc { class MisleadingBidirectionalCheck : public ClangTidyCheck { public: MisleadingBidirectionalCheck(StringRef Name, ClangTidyContext *Context); - ~MisleadingBidirectionalCheck(); + ~MisleadingBidirectionalCheck() override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h index 5e1a56ddc479a..06b83d567a9d2 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h +++ b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h @@ -16,7 +16,7 @@ namespace clang::tidy::misc { class MisleadingIdentifierCheck : public ClangTidyCheck { public: MisleadingIdentifierCheck(StringRef Name, ClangTidyContext *Context); - ~MisleadingIdentifierCheck(); + ~MisleadingIdentifierCheck() override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h index 6e09086d667f9..877fc4d6503d6 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.h @@ -18,7 +18,7 @@ namespace clang::tidy::misc { class UnusedParametersCheck : public ClangTidyCheck { public: UnusedParametersCheck(StringRef Name, ClangTidyContext *Context); - ~UnusedParametersCheck(); + ~UnusedParametersCheck() override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index 586deea46e86f..6fb780844f2b6 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -785,7 +785,7 @@ bool ForLoopIndexUseVisitor::TraverseLambdaCapture(LambdaExpr *LE, C->getLocation())); } if (VDecl->isInitCapture()) - TraverseStmtImpl(cast(VDecl)->getInit()); + traverseStmtImpl(cast(VDecl)->getInit()); } return VisitorBase::TraverseLambdaCapture(LE, C, Init); } @@ -815,7 +815,7 @@ bool ForLoopIndexUseVisitor::VisitDeclStmt(DeclStmt *S) { return true; } -bool ForLoopIndexUseVisitor::TraverseStmtImpl(Stmt *S) { +bool ForLoopIndexUseVisitor::traverseStmtImpl(Stmt *S) { // All this pointer swapping is a mechanism for tracking immediate parentage // of Stmts. const Stmt *OldNextParent = NextStmtParent; @@ -838,7 +838,7 @@ bool ForLoopIndexUseVisitor::TraverseStmt(Stmt *S) { return true; } } - return TraverseStmtImpl(S); + return traverseStmtImpl(S); } std::string VariableNamer::createIndexName() { diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h index 306eca7140d1a..0a0db5e6c633f 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h @@ -354,7 +354,7 @@ class ForLoopIndexUseVisitor bool VisitDeclStmt(DeclStmt *S); bool TraverseStmt(Stmt *S); - bool TraverseStmtImpl(Stmt *S); + bool traverseStmtImpl(Stmt *S); /// Add an expression to the list of expressions on which the container /// expression depends. diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptDestructorCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptDestructorCheck.h index ce2b1c9c17a19..12e6839220f29 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptDestructorCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoexceptDestructorCheck.h @@ -27,10 +27,9 @@ class NoexceptDestructorCheck : public NoexceptFunctionBaseCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; private: - DiagnosticBuilder - reportMissingNoexcept(const FunctionDecl *FuncDecl) final override; + DiagnosticBuilder reportMissingNoexcept(const FunctionDecl *FuncDecl) final; void reportNoexceptEvaluatedToFalse(const FunctionDecl *FuncDecl, - const Expr *NoexceptExpr) final override; + const Expr *NoexceptExpr) final; }; } // namespace clang::tidy::performance diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h index 075b4fe964d89..56a1e4af010a2 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h @@ -27,8 +27,7 @@ class NoexceptFunctionBaseCheck : public ClangTidyCheck { bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus11 && LangOpts.CXXExceptions; } - void - check(const ast_matchers::MatchFinder::MatchResult &Result) final override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) final; std::optional getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h index 11a8068aebbc4..db95ebc87b1cb 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h @@ -31,10 +31,9 @@ class NoexceptMoveConstructorCheck : public NoexceptFunctionBaseCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; private: - DiagnosticBuilder - reportMissingNoexcept(const FunctionDecl *FuncDecl) final override; + DiagnosticBuilder reportMissingNoexcept(const FunctionDecl *FuncDecl) final; void reportNoexceptEvaluatedToFalse(const FunctionDecl *FuncDecl, - const Expr *NoexceptExpr) final override; + const Expr *NoexceptExpr) final; }; } // namespace clang::tidy::performance diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.h index 9466b3a127302..7c5572ee56ee0 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.h @@ -27,10 +27,9 @@ class NoexceptSwapCheck : public NoexceptFunctionBaseCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; private: - DiagnosticBuilder - reportMissingNoexcept(const FunctionDecl *FuncDecl) final override; + DiagnosticBuilder reportMissingNoexcept(const FunctionDecl *FuncDecl) final; void reportNoexceptEvaluatedToFalse(const FunctionDecl *FuncDecl, - const Expr *NoexceptExpr) final override; + const Expr *NoexceptExpr) final; }; } // namespace clang::tidy::performance diff --git a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.h b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.h index 1533b9acf2c02..97b522af1b589 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.h +++ b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.h @@ -34,7 +34,6 @@ class AvoidReturnWithVoidValueCheck : public ClangTidyCheck { } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; -private: bool IgnoreMacros; bool StrictMode; }; diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h index 3db9d23150af3..0b17af88810c2 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -33,7 +33,7 @@ enum StyleKind : int; class IdentifierNamingCheck final : public RenamerClangTidyCheck { public: IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context); - ~IdentifierNamingCheck(); + ~IdentifierNamingCheck() override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h index 699d75435db7b..53ce2e0ea859c 100644 --- a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h +++ b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h @@ -68,7 +68,7 @@ struct BraceInsertionHints { /// The algorithm computing them respects comment before and after the statement /// and adds line breaks before the braces accordingly. BraceInsertionHints -getBraceInsertionsHints(const Stmt *const S, const LangOptions &LangOpts, +getBraceInsertionsHints(const Stmt *S, const LangOptions &LangOpts, const SourceManager &SM, SourceLocation StartLoc, SourceLocation EndLocHint = SourceLocation()); diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp index 58e33567f07e9..7e2aad9a97c8e 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp @@ -118,9 +118,8 @@ static int compareHeaders(StringRef LHS, StringRef RHS, return LHS.compare(RHS); } -IncludeSorter::IncludeSorter(const SourceManager *SourceMgr, - const FileID FileID, StringRef FileName, - IncludeStyle Style) +IncludeSorter::IncludeSorter(const SourceManager *SourceMgr, FileID FileID, + StringRef FileName, IncludeStyle Style) : SourceMgr(SourceMgr), Style(Style), CurrentFileID(FileID), CanonicalFile(makeCanonicalName(FileName, Style)) {} diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.h b/clang-tools-extra/clang-tidy/utils/IncludeSorter.h index ce752c45f2a77..66830ee7f1ef3 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.h +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.h @@ -23,7 +23,7 @@ namespace utils { class IncludeSorter { public: /// Supported include styles. - enum IncludeStyle { IS_LLVM = 0, IS_Google = 1, IS_Google_ObjC }; + enum IncludeStyle { IS_LLVM = 0, IS_Google = 1, IS_Google_ObjC = 2 }; /// The classifications of inclusions, in the order they should be sorted. enum IncludeKinds { @@ -37,7 +37,7 @@ class IncludeSorter { /// ``IncludeSorter`` constructor; takes the FileID and name of the file to be /// processed by the sorter. - IncludeSorter(const SourceManager *SourceMgr, const FileID FileID, + IncludeSorter(const SourceManager *SourceMgr, FileID FileID, StringRef FileName, IncludeStyle Style); /// Adds the given include directive to the sorter. diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h b/clang-tools-extra/clang-tidy/utils/Matchers.h index 6caa35de3c98f..4eac0655e3922 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.h +++ b/clang-tools-extra/clang-tidy/utils/Matchers.h @@ -51,7 +51,7 @@ AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) { // Returns QualType matcher for target char type only. AST_MATCHER(QualType, isSimpleChar) { - const auto ActualType = Node.getTypePtr(); + const auto *ActualType = Node.getTypePtr(); return ActualType && (ActualType->isSpecificBuiltinType(BuiltinType::Char_S) || ActualType->isSpecificBuiltinType(BuiltinType::Char_U)); diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h index 68b3040895417..b38bc082644cb 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h @@ -28,7 +28,7 @@ namespace tidy { class RenamerClangTidyCheck : public ClangTidyCheck { public: RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context); - ~RenamerClangTidyCheck(); + ~RenamerClangTidyCheck() override; /// Derived classes should not implement any matching logic themselves; this /// class will do the matching and call the derived class' diff --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h index 057b92c147047..660d8eb227cca 100644 --- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h +++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h @@ -219,10 +219,10 @@ template <> struct DenseMapInfo { using Outer = clang::include_cleaner::Symbol; using Base = DenseMapInfo; - static inline Outer getEmptyKey() { + static Outer getEmptyKey() { return {Outer::SentinelTag{}, Base::getEmptyKey()}; } - static inline Outer getTombstoneKey() { + static Outer getTombstoneKey() { return {Outer::SentinelTag{}, Base::getTombstoneKey()}; } static unsigned getHashValue(const Outer &Val) { @@ -236,10 +236,8 @@ template <> struct DenseMapInfo { using Outer = clang::include_cleaner::Macro; using Base = DenseMapInfo; - static inline Outer getEmptyKey() { return {nullptr, Base::getEmptyKey()}; } - static inline Outer getTombstoneKey() { - return {nullptr, Base::getTombstoneKey()}; - } + static Outer getEmptyKey() { return {nullptr, Base::getEmptyKey()}; } + static Outer getTombstoneKey() { return {nullptr, Base::getTombstoneKey()}; } static unsigned getHashValue(const Outer &Val) { return Base::getHashValue(Val.Definition); } @@ -251,10 +249,10 @@ template <> struct DenseMapInfo { using Outer = clang::include_cleaner::Header; using Base = DenseMapInfo; - static inline Outer getEmptyKey() { + static Outer getEmptyKey() { return {Outer::SentinelTag{}, Base::getEmptyKey()}; } - static inline Outer getTombstoneKey() { + static Outer getTombstoneKey() { return {Outer::SentinelTag{}, Base::getTombstoneKey()}; } static unsigned getHashValue(const Outer &Val) { From 7a7237b3541a6dc49d3a151770b6962424f904a2 Mon Sep 17 00:00:00 2001 From: jimingham Date: Mon, 27 Oct 2025 15:43:42 -0700 Subject: [PATCH 17/33] The test added for PR#164905 doesn't run on Windows. (#165318) --- .../API/driver/stdio_closed/TestDriverWithClosedSTDIO.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/driver/stdio_closed/TestDriverWithClosedSTDIO.py b/lldb/test/API/driver/stdio_closed/TestDriverWithClosedSTDIO.py index cff97b822db81..751926b116002 100644 --- a/lldb/test/API/driver/stdio_closed/TestDriverWithClosedSTDIO.py +++ b/lldb/test/API/driver/stdio_closed/TestDriverWithClosedSTDIO.py @@ -12,7 +12,7 @@ import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test.lldbtest import * - +from lldbsuite.test.decorators import * class TestDriverWithClosedSTDIO(TestBase): # If your test case doesn't stress debug info, then @@ -20,6 +20,9 @@ class TestDriverWithClosedSTDIO(TestBase): # each debug info format. NO_DEBUG_INFO_TESTCASE = True + # Windows doesn't have the fcntl module, so we can't run this + # test there. + @skipIf(oslist=["windows"]) def test_run_lldb_and_wait(self): """This test forks, closes the stdio channels and exec's lldb. Then it waits for it to exit and asserts it did that successfully""" From f8243ce9c73bda19648a7b3b3bfcb584783469da Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 27 Oct 2025 15:48:23 -0700 Subject: [PATCH 18/33] [LLDB] Remove signature from python copy when injecting ASAN runtime --- lldb/test/API/lit.cfg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index dcff8687fb4ca..f2a14d1475385 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -90,6 +90,8 @@ def find_python_interpreter(): ) shutil.copy(real_python, copied_python) + # macOS 15+ restricts injecting the ASAN runtime to only user-compiled code. + subprocess.check_call(["/usr/bin/codesign", "--remove-signature", copied_python]) # Now make sure the copied Python works. The Python in Xcode has a relative # RPATH and cannot be copied. From 23cc43d955c3a524eda8a077ec9d8b0d2a24ef61 Mon Sep 17 00:00:00 2001 From: Odric Roux-Paris Date: Mon, 27 Oct 2025 23:51:28 +0100 Subject: [PATCH 19/33] [lldb] print errors when the debug server is not found (#165157) --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b4422a7d58077..3c4d9a1f1ad37 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -3672,6 +3672,12 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( } } #endif + + if (!FileSystem::Instance().Exists(debugserver_path)) + return Status::FromErrorString("could not find '" DEBUGSERVER_BASENAME + "'. Please ensure it is properly installed " + "and available in your PATH"); + debugserver_launch_info.SetExecutableFile(debugserver_path, /*add_exe_file_as_first_arg=*/true); From f05bd9c2e019aa6e83e0ab63f5ea7bc4d217a76c Mon Sep 17 00:00:00 2001 From: joaosaffran Date: Mon, 27 Oct 2025 15:59:03 -0700 Subject: [PATCH 20/33] [HLSL] Adding DXIL Storage type into `TypedInfo` (#164887) In DXIL, some 64bit types are actually represented with their 32bit counterpart. This was already being address in the codegen, however the metadata generation was lacking this information. This PR is fixing this issue. Closes: [#146735](https://github.com/llvm/llvm-project/issues/146735) --- llvm/include/llvm/Analysis/DXILResource.h | 1 + llvm/lib/Analysis/DXILResource.cpp | 19 ++++++++++++++++--- llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 2 +- .../DXILResource/buffer-frombinding.ll | 19 +++++++++++++++++++ .../CodeGen/DirectX/Metadata/srv_metadata.ll | 19 +++++++++---------- .../CodeGen/DirectX/Metadata/uav_metadata.ll | 17 ++++++++--------- 6 files changed, 54 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index c7aff167324e6..2b0dcb966578e 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -293,6 +293,7 @@ class ResourceTypeInfo { struct TypedInfo { dxil::ElementType ElementTy; + dxil::ElementType DXILStorageTy; uint32_t ElementCount; bool operator==(const TypedInfo &RHS) const { diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 6f19a68dcd194..27114e0705a1d 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -206,6 +206,14 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) { return ElementType::Invalid; } +static dxil::ElementType toDXILStorageType(dxil::ElementType ET) { + if (ET == dxil::ElementType::U64 || ET == dxil::ElementType::F64 || + ET == dxil::ElementType::I64 || ET == dxil::ElementType::SNormF64 || + ET == dxil::ElementType::UNormF64) + return dxil::ElementType::U32; + return ET; +} + ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC_, const dxil::ResourceKind Kind_) @@ -569,10 +577,11 @@ ResourceTypeInfo::TypedInfo ResourceTypeInfo::getTyped() const { auto [ElTy, IsSigned] = getTypedElementType(Kind, HandleTy); dxil::ElementType ET = toDXILElementType(ElTy, IsSigned); + dxil::ElementType DXILStorageTy = toDXILStorageType(ET); uint32_t Count = 1; if (auto *VTy = dyn_cast(ElTy)) Count = VTy->getNumElements(); - return {ET, Count}; + return {ET, DXILStorageTy, Count}; } dxil::SamplerFeedbackType ResourceTypeInfo::getFeedbackType() const { @@ -636,7 +645,10 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const { OS << " Alignment: " << Struct.AlignLog2 << "\n"; } else if (isTyped()) { TypedInfo Typed = getTyped(); - OS << " Element Type: " << getElementTypeName(Typed.ElementTy) << "\n" + OS << " Element Type: " << getElementTypeName(Typed.ElementTy); + if (Typed.ElementTy != Typed.DXILStorageTy) + OS << " (stored as " << getElementTypeName(Typed.DXILStorageTy) << ")"; + OS << "\n" << " Element Count: " << Typed.ElementCount << "\n"; } else if (isFeedback()) OS << " Feedback Type: " << getSamplerFeedbackTypeName(getFeedbackType()) @@ -714,7 +726,8 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M, Tags.push_back(getIntMD(RTI.getStruct(DL).Stride)); } else if (RTI.isTyped()) { Tags.push_back(getIntMD(llvm::to_underlying(ExtPropTags::ElementType))); - Tags.push_back(getIntMD(llvm::to_underlying(RTI.getTyped().ElementTy))); + Tags.push_back( + getIntMD(llvm::to_underlying(RTI.getTyped().DXILStorageTy))); } else if (RTI.isFeedback()) { Tags.push_back( getIntMD(llvm::to_underlying(ExtPropTags::SamplerFeedbackKind))); diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp index dc84ae49abbe3..9da3bdb8d59b2 100644 --- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp +++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp @@ -49,7 +49,7 @@ static StringRef getRCPrefix(dxil::ResourceClass RC) { static StringRef getFormatName(const dxil::ResourceTypeInfo &RI) { if (RI.isTyped()) { - switch (RI.getTyped().ElementTy) { + switch (RI.getTyped().DXILStorageTy) { case dxil::ElementType::I1: return "i1"; case dxil::ElementType::I16: diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll index ab1945d2921cc..d92010ed41d4c 100644 --- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll +++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll @@ -9,6 +9,7 @@ @Four.str = private unnamed_addr constant [5 x i8] c"Four\00", align 1 @Array.str = private unnamed_addr constant [6 x i8] c"Array\00", align 1 @Five.str = private unnamed_addr constant [5 x i8] c"Five\00", align 1 +@Six.str = private unnamed_addr constant [4 x i8] c"Six\00", align 1 @CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1 @Constants.str = private unnamed_addr constant [10 x i8] c"Constants\00", align 1 @@ -137,6 +138,23 @@ define void @test_typedbuffer() { ; CHECK: Element Type: f32 ; CHECK: Element Count: 4 + %uav4 = call target("dx.TypedBuffer", double, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 5, i32 0, i32 1, i32 0, ptr @Six.str) + ; CHECK: Resource [[UAV4:[0-9]+]]: + ; CHECK: Name: Six + ; CHECK: Binding: + ; CHECK: Record ID: 4 + ; CHECK: Space: 5 + ; CHECK: Lower Bound: 0 + ; CHECK: Size: 1 + ; CHECK: Globally Coherent: 0 + ; CHECK: Counter Direction: Unknown + ; CHECK: Class: UAV + ; CHECK: Kind: Buffer + ; CHECK: IsROV: 0 + ; CHECK: Element Type: f64 (stored as u32) + ; CHECK: Element Count: 1 + %cb0 = call target("dx.CBuffer", {float}) @llvm.dx.resource.handlefrombinding(i32 1, i32 0, i32 1, i32 0, ptr @CB.str) ; CHECK: Resource [[CB0:[0-9]+]]: @@ -175,6 +193,7 @@ define void @test_typedbuffer() { ; CHECK-DAG: Call bound to [[UAV1]]: %uav1 = ; CHECK-DAG: Call bound to [[UAV2]]: %uav2_1 = ; CHECK-DAG: Call bound to [[UAV2]]: %uav2_2 = +; CHECK-DAG: Call bound to [[UAV4]]: %uav4 = ; CHECK-DAG: Call bound to [[CB0]]: %cb0 = ; CHECK-DAG: Call bound to [[CB1]]: %cb1 = diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll index a2059beeb0acb..0062f90326490 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll @@ -22,14 +22,14 @@ target triple = "dxil-pc-shadermodel6.6-compute" ; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- --------- ; PRINT-NEXT:; Zero texture f16 buf T0 t0 1 ; PRINT-NEXT:; One texture f32 buf T1 t1 1 -; PRINT-NEXT:; Two texture f64 buf T2 t2 1 +; PRINT-NEXT:; Two texture u32 buf T2 t2 1 ; PRINT-NEXT:; Three texture i32 buf T3 t3 1 ; PRINT-NEXT:; Four texture byte r/o T4 t5 1 ; PRINT-NEXT:; Five texture struct r/o T5 t6 1 -; PRINT-NEXT:; Six texture u64 buf T6 t10,space2 1 +; PRINT-NEXT:; Six texture u32 buf T6 t10,space2 1 ; PRINT-NEXT:; Array texture f32 buf T7 t4,space3 100 -; PRINT-NEXT:; Array2 texture f64 buf T8 t2,space4 unbounded -; PRINT-NEXT:; Seven texture u64 buf T9 t20,space5 1 +; PRINT-NEXT:; Array2 texture u32 buf T8 t2,space4 unbounded +; PRINT-NEXT:; Seven texture u32 buf T9 t20,space5 1 ; define void @test() #0 { @@ -120,15 +120,14 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: ![[Half]] = !{i32 0, i32 8} ; CHECK: ![[One]] = !{i32 1, ptr @One, !"One", i32 0, i32 1, i32 1, i32 10, i32 0, ![[Float:[0-9]+]]} ; CHECK: ![[Float]] = !{i32 0, i32 9} -; CHECK: ![[Two]] = !{i32 2, ptr @Two, !"Two", i32 0, i32 2, i32 1, i32 10, i32 0, ![[Double:[0-9]+]]} -; CHECK: ![[Double]] = !{i32 0, i32 10} +; CHECK: ![[Two]] = !{i32 2, ptr @Two, !"Two", i32 0, i32 2, i32 1, i32 10, i32 0, ![[U32:[0-9]+]]} +; CHECK: ![[U32]] = !{i32 0, i32 5} ; CHECK: ![[Three]] = !{i32 3, ptr @Three, !"Three", i32 0, i32 3, i32 1, i32 10, i32 0, ![[I32:[0-9]+]]} ; CHECK: ![[I32]] = !{i32 0, i32 4} ; CHECK: ![[Four]] = !{i32 4, ptr @Four, !"Four", i32 0, i32 5, i32 1, i32 11, i32 0, null} ; CHECK: ![[Five]] = !{i32 5, ptr @Five, !"Five", i32 0, i32 6, i32 1, i32 12, i32 0, ![[FiveStride:[0-9]+]]} ; CHECK: ![[FiveStride]] = !{i32 1, i32 2} -; CHECK: ![[Six]] = !{i32 6, ptr @Six, !"Six", i32 2, i32 10, i32 1, i32 10, i32 0, ![[U64:[0-9]+]]} -; CHECK: ![[U64]] = !{i32 0, i32 7} +; CHECK: ![[Six]] = !{i32 6, ptr @Six, !"Six", i32 2, i32 10, i32 1, i32 10, i32 0, ![[U32:[0-9]+]]} ; CHECK: ![[Array]] = !{i32 7, ptr @Array, !"Array", i32 3, i32 4, i32 100, i32 10, i32 0, ![[Float]]} -; CHECK: ![[Array2]] = !{i32 8, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i32 0, ![[Double]]} -; CHECK: ![[Seven]] = !{i32 9, ptr @Seven, !"Seven", i32 5, i32 20, i32 1, i32 10, i32 0, ![[U64]]} +; CHECK: ![[Array2]] = !{i32 8, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i32 0, ![[U32]]} +; CHECK: ![[Seven]] = !{i32 9, ptr @Seven, !"Seven", i32 5, i32 20, i32 1, i32 10, i32 0, ![[U32]]} diff --git a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll index 5b2b3ef280626..d377a528abca1 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll @@ -25,17 +25,17 @@ target triple = "dxil-pc-shadermodel6.6-compute" ; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- --------- ; PRINT-NEXT:; Zero UAV f16 buf U0 u0 1 ; PRINT-NEXT:; One UAV f32 buf U1 u1 1 -; PRINT-NEXT:; Two UAV f64 buf U2 u2 1 +; PRINT-NEXT:; Two UAV u32 buf U2 u2 1 ; PRINT-NEXT:; Three UAV i32 buf U3 u3 1 ; PRINT-NEXT:; Four UAV byte r/w U4 u5 1 ; PRINT-NEXT:; Five UAV struct r/w U5 u6 1 ; PRINT-NEXT:; Six UAV i32 buf U6 u7 1 ; PRINT-NEXT:; Seven UAV struct r/w U7 u8 1 ; PRINT-NEXT:; Eight UAV byte r/w U8 u9 1 -; PRINT-NEXT:; Nine UAV u64 buf U9 u10,space2 1 +; PRINT-NEXT:; Nine UAV u32 buf U9 u10,space2 1 ; PRINT-NEXT:; Array UAV f32 buf U10 u4,space3 100 -; PRINT-NEXT:; Array2 UAV f64 buf U11 u2,space4 unbounded -; PRINT-NEXT:; Ten UAV u64 buf U12 u22,space5 1 +; PRINT-NEXT:; Array2 UAV u32 buf U11 u2,space4 unbounded +; PRINT-NEXT:; Ten UAV u32 buf U12 u22,space5 1 define void @test() #0 { ; RWBuffer Zero : register(u0) @@ -144,8 +144,8 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: ![[Half]] = !{i32 0, i32 8} ; CHECK: ![[One]] = !{i32 1, ptr @One, !"One", i32 0, i32 1, i32 1, i32 10, i1 false, i1 false, i1 false, ![[Float:[0-9]+]]} ; CHECK: ![[Float]] = !{i32 0, i32 9} -; CHECK: ![[Two]] = !{i32 2, ptr @Two, !"Two", i32 0, i32 2, i32 1, i32 10, i1 false, i1 false, i1 false, ![[Double:[0-9]+]]} -; CHECK: ![[Double]] = !{i32 0, i32 10} +; CHECK: ![[Two]] = !{i32 2, ptr @Two, !"Two", i32 0, i32 2, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U32:[0-9]+]]} +; CHECK: ![[U32]] = !{i32 0, i32 5} ; CHECK: ![[Three]] = !{i32 3, ptr @Three, !"Three", i32 0, i32 3, i32 1, i32 10, i1 false, i1 false, i1 false, ![[I32:[0-9]+]]} ; CHECK: ![[I32]] = !{i32 0, i32 4} ; CHECK: ![[Four]] = !{i32 4, ptr @Four, !"Four", i32 0, i32 5, i32 1, i32 11, i1 false, i1 false, i1 false, null} @@ -155,8 +155,7 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: ![[Seven]] = !{i32 7, ptr @Seven, !"Seven", i32 0, i32 8, i32 1, i32 12, i1 false, i1 false, i1 true, ![[SevenStride:[0-9]+]]} ; CHECK: ![[SevenStride]] = !{i32 1, i32 16} ; CHECK: ![[Eight]] = !{i32 8, ptr @Eight, !"Eight", i32 0, i32 9, i32 1, i32 11, i1 false, i1 false, i1 true, null} -; CHECK: ![[Nine]] = !{i32 9, ptr @Nine, !"Nine", i32 2, i32 10, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U64:[0-9]+]]} -; CHECK: ![[U64]] = !{i32 0, i32 7} +; CHECK: ![[Nine]] = !{i32 9, ptr @Nine, !"Nine", i32 2, i32 10, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U32]]} ; CHECK: ![[Array]] = !{i32 10, ptr @Array, !"Array", i32 3, i32 4, i32 100, i32 10, i1 false, i1 false, i1 false, ![[Float]]} -; CHECK: ![[Array2]] = !{i32 11, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i1 false, i1 false, i1 false, ![[Double]]} +; CHECK: ![[Array2]] = !{i32 11, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i1 false, i1 false, i1 false, ![[U32]]} ; CHECK: ![[Ten]] = !{i32 12, ptr @Ten, !"Ten", i32 5, i32 22, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U64:[0-9]+]]} From 31417ba0decbc0472a7581b66df4b4b4a8853c78 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Mon, 27 Oct 2025 23:19:29 +0000 Subject: [PATCH 21/33] [lld-macho] Link against libatomic when necessary (#144259) In `Driver.cpp` `std::atomic` is used which may need libatomic. Build failure (if that is of interest): ``` [127/135] Linking CXX shared library lib/liblldMachO.so.20.1 ninja: job failed: : && /usr/lib/ccache/bin/clang++-20 -fPIC -Os -fstack-clash-protection -Wformat -Werror=format-security -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1 -g -O2 -DNDEBUG -g1 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wl,--as-needed,-O1,--sort-common -Wl,-z,defs -Wl,-z,nodelete -Wl,-rpath-link,/home/user/aports/main/lld20/src/lld-20.1.5.src/build/./lib -Wl,--gc-sections -shared -Wl,-soname,liblldMachO.so.20.1 -o lib/liblldMachO.so.20.1 MachO/CMakeFiles/lldMachO.dir/Arch/ARM64.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/ARM64Common.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/ARM64_32.cpp.o MachO/CMakeFiles/lldMachO.dir/Arch/X86_64.cpp.o MachO/CMakeFiles/lldMachO.dir/ConcatOutputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o MachO/CMakeFiles/lldMachO.dir/DriverUtils.cpp.o MachO/CMakeFiles/lldMachO.dir/Dwarf.cpp.o MachO/CMakeFiles/lldMachO.dir/EhFrame.cpp.o MachO/CMakeFiles/lldMachO.dir/ExportTrie.cpp.o MachO/CMakeFiles/lldMachO.dir/ICF.cpp.o MachO/CMakeFiles/lldMachO.dir/InputFiles.cpp.o MachO/CMakeFiles/lldMachO.dir/InputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/LTO.cpp.o MachO/CMakeFiles/lldMachO.dir/MapFile.cpp.o MachO/CMakeFiles/lldMachO.dir/MarkLive.cpp.o MachO/CMakeFiles/lldMachO.dir/ObjC.cpp.o MachO/CMakeFiles/lldMachO.dir/OutputSection.cpp.o MachO/CMakeFiles/lldMachO.dir/OutputSegment.cpp.o MachO/CMakeFiles/lldMachO.dir/Relocations.cpp.o MachO/CMakeFiles/lldMachO.dir/BPSectionOrderer.cpp.o MachO/CMakeFiles/lldMachO.dir/SectionPriorities.cpp.o MachO/CMakeFiles/lldMachO.dir/Sections.cpp.o MachO/CMakeFiles/lldMachO.dir/SymbolTable.cpp.o MachO/CMakeFiles/lldMachO.dir/Symbols.cpp.o MachO/CMakeFiles/lldMachO.dir/SyntheticSections.cpp.o MachO/CMakeFiles/lldMachO.dir/Target.cpp.o MachO/CMakeFiles/lldMachO.dir/UnwindInfoSection.cpp.o MachO/CMakeFiles/lldMachO.dir/Writer.cpp.o -L/usr/lib/llvm20/lib -Wl,-rpath,"\$ORIGIN/../lib:/usr/lib/llvm20/lib:/home/user/aports/main/lld20/src/lld-20.1.5.src/build/lib:" lib/liblldCommon.so.20.1 /usr/lib/llvm20/lib/libLLVM.so.20.1 && : /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o: in function `handleExplicitExports()': /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:501:(.text._ZL21handleExplicitExportsv+0xb8): undefined reference to `__atomic_load_8' /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:501:(.text._ZL21handleExplicitExportsv+0x180): undefined reference to `__atomic_load_8' /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../powerpc-alpine-linux-musl/bin/ld: MachO/CMakeFiles/lldMachO.dir/Driver.cpp.o: in function `void llvm::function_ref::callback_fn(lld::macho::Symbol* const*, lld::macho::Symbol* const*, handleExplicitExports()::$_0)::{lambda(unsigned int)#1}>(int, unsigned int)': /usr/lib/gcc/powerpc-alpine-linux-musl/14.3.0/../../../../include/c++/14.3.0/bits/atomic_base.h:631:(.text._ZN4llvm12function_refIFvjEE11callback_fnIZNS_15parallelForEachIPKPN3lld5macho6SymbolEZL21handleExplicitExportsvE3$_0EEvT_SC_T0_EUljE_EEvij+0xd4): undefined reference to `__atomic_fetch_add_8' clang++-20: error: linker command failed with exit code 1 (use -v to see invocation) ``` CC @int3 @gkmhub @smeenai Similar to https://github.com/llvm/llvm-project/commit/f0b451c77f14947e3e7d314f048679fa2f5c6298 --- lld/MachO/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt index 3cd94ced75cc0..72631f11511bf 100644 --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -59,6 +59,7 @@ add_lld_library(lldMachO LINK_LIBS lldCommon ${LLVM_PTHREAD_LIB} + ${LLVM_ATOMIC_LIB} DEPENDS MachOOptionsTableGen From 66acd04a78c0a9c66fd761c3f09883b6e875b600 Mon Sep 17 00:00:00 2001 From: Jorn Tuyls Date: Tue, 28 Oct 2025 00:42:29 +0100 Subject: [PATCH 22/33] [MemRef] Fix value bounds interface for ExpandShapeOp (#165333) We shouldn't just consider the dynamic dimensions, but all output dimensions for the value bounds constraints. The previous test just worked because the dynamic dimension was on the first position. --- mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp | 2 +- .../Dialect/MemRef/value-bounds-op-interface-impl.mlir | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp index a15bf891dd596..6fa8ce4efff3b 100644 --- a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp +++ b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp @@ -66,7 +66,7 @@ struct ExpandShapeOpInterface ValueBoundsConstraintSet &cstr) const { auto expandOp = cast(op); assert(value == expandOp.getResult() && "invalid value"); - cstr.bound(value)[dim] == expandOp.getOutputShape()[dim]; + cstr.bound(value)[dim] == expandOp.getMixedOutputShape()[dim]; } }; diff --git a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir index ac1f22b68b1e1..f9b81dfc7d468 100644 --- a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir +++ b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir @@ -67,11 +67,11 @@ func.func @memref_dim_all_positive(%m: memref, %x: index) { // CHECK-SAME: %[[m:[a-zA-Z0-9]+]]: memref // CHECK-SAME: %[[sz:[a-zA-Z0-9]+]]: index // CHECK: %[[c4:.*]] = arith.constant 4 : index -// CHECK: return %[[sz]], %[[c4]] +// CHECK: return %[[c4]], %[[sz]] func.func @memref_expand(%m: memref, %sz: index) -> (index, index) { - %0 = memref.expand_shape %m [[0, 1]] output_shape [%sz, 4]: memref into memref - %1 = "test.reify_bound"(%0) {dim = 0} : (memref) -> (index) - %2 = "test.reify_bound"(%0) {dim = 1} : (memref) -> (index) + %0 = memref.expand_shape %m [[0, 1]] output_shape [4, %sz]: memref into memref<4x?xf32> + %1 = "test.reify_bound"(%0) {dim = 0} : (memref<4x?xf32>) -> (index) + %2 = "test.reify_bound"(%0) {dim = 1} : (memref<4x?xf32>) -> (index) return %1, %2 : index, index } From 1fb2ab37af4065a8bc9288e43456a87724110786 Mon Sep 17 00:00:00 2001 From: Changpeng Fang Date: Mon, 27 Oct 2025 17:00:42 -0700 Subject: [PATCH 23/33] [InstCombine] Add the missing insertion point before IRBuilder instruction creation (#165315) Should set the insertion point appropriately before we create an instruction with IRBuilder. Fixes: SWDEV-562571 --- .../InstCombineSimplifyDemanded.cpp | 2 ++ .../InstCombine/fold-selective-shift.ll | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 651e305f57dfc..550dfc57a348b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -105,6 +105,8 @@ static Value *simplifyShiftSelectingPackedElement(Instruction *I, if (~KnownShrBits.Zero != ShlAmt) return nullptr; + IRBuilderBase::InsertPointGuard Guard(IC.Builder); + IC.Builder.SetInsertPoint(I); Value *ShrAmtZ = IC.Builder.CreateICmpEQ(ShrAmt, Constant::getNullValue(ShrAmt->getType()), ShrAmt->getName() + ".z"); diff --git a/llvm/test/Transforms/InstCombine/fold-selective-shift.ll b/llvm/test/Transforms/InstCombine/fold-selective-shift.ll index 2b2296541f14a..dcfd93328e087 100644 --- a/llvm/test/Transforms/InstCombine/fold-selective-shift.ll +++ b/llvm/test/Transforms/InstCombine/fold-selective-shift.ll @@ -21,6 +21,28 @@ define i16 @selective_shift_16(i32 %mask, i16 %upper, i16 %lower) { ret i16 %trunc } +; Will assert if InsertPoint is not set before creating an instruction +; with IRBuilder +define i16 @selective_shift_16_insertpt(i32 %mask, i16 %upper, i16 %lower) { +; CHECK-LABEL: define i16 @selective_shift_16_insertpt( +; CHECK-SAME: i32 [[MASK:%.*]], i16 [[UPPER:%.*]], i16 [[LOWER:%.*]]) { +; CHECK-NEXT: [[MASK_BIT:%.*]] = and i32 [[MASK]], 16 +; CHECK-NEXT: [[MASK_BIT_Z:%.*]] = icmp eq i32 [[MASK_BIT]], 0 +; CHECK-NEXT: [[SEL_V:%.*]] = select i1 [[MASK_BIT_Z]], i16 [[LOWER]], i16 [[UPPER]] +; CHECK-NEXT: [[ADD_ONE:%.*]] = add i16 [[SEL_V]], 1 +; CHECK-NEXT: ret i16 [[ADD_ONE]] +; + %mask.bit = and i32 %mask, 16 + %upper.zext = zext i16 %upper to i32 + %upper.shl = shl nuw i32 %upper.zext, 16 + %lower.zext = zext i16 %lower to i32 + %pack = or disjoint i32 %upper.shl, %lower.zext + %sel = lshr i32 %pack, %mask.bit + %add.one = add i32 %sel, 1 + %trunc = trunc i32 %add.one to i16 + ret i16 %trunc +} + define i16 @selective_shift_16.commute(i32 %mask, i16 %upper, i16 %lower) { ; CHECK-LABEL: define i16 @selective_shift_16.commute( ; CHECK-SAME: i32 [[MASK:%.*]], i16 [[UPPER:%.*]], i16 [[LOWER:%.*]]) { From 3f26d567535b0b06824a2470ae3b4e02288615e6 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 21 Aug 2025 06:14:55 -0700 Subject: [PATCH 24/33] [MLIR] Apply clang-tidy fixes for llvm-else-after-return in SuperVectorize.cpp (NFC) --- mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp index 50a0f3dc74781..e08cc6f645d71 100644 --- a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp +++ b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp @@ -978,12 +978,11 @@ static Operation *vectorizeAffineApplyOp(AffineApplyOp applyOp, LLVM_DEBUG( dbgs() << "\n[early-vect]+++++ affine.apply on vector operand\n"); return nullptr; - } else { - Value updatedOperand = state.valueScalarReplacement.lookupOrNull(operand); - if (!updatedOperand) - updatedOperand = operand; - updatedOperands.push_back(updatedOperand); } + Value updatedOperand = state.valueScalarReplacement.lookupOrNull(operand); + if (!updatedOperand) + updatedOperand = operand; + updatedOperands.push_back(updatedOperand); } auto newApplyOp = AffineApplyOp::create( From aed12c33ade9ea48f1a596cd98fde958803a17a7 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 21 Aug 2025 10:38:07 -0700 Subject: [PATCH 25/33] [MLIR] Apply clang-tidy fixes for llvm-qualified-auto in MLIRContext.cpp (NFC) --- mlir/lib/IR/MLIRContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp index 5f63fe6d81662..73219c6917061 100644 --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -709,7 +709,7 @@ ArrayRef MLIRContext::getRegisteredOperations() { /// Return information for registered operations by dialect. ArrayRef MLIRContext::getRegisteredOperationsByDialect(StringRef dialectName) { - auto lowerBound = llvm::lower_bound( + auto *lowerBound = llvm::lower_bound( impl->sortedRegisteredOperations, dialectName, [](auto &lhs, auto &rhs) { return lhs.getDialect().getNamespace().compare(rhs); }); @@ -718,7 +718,7 @@ MLIRContext::getRegisteredOperationsByDialect(StringRef dialectName) { lowerBound->getDialect().getNamespace() != dialectName) return ArrayRef(); - auto upperBound = + auto *upperBound = std::upper_bound(lowerBound, impl->sortedRegisteredOperations.end(), dialectName, [](auto &lhs, auto &rhs) { return lhs.compare(rhs.getDialect().getNamespace()); From bc2f746e789e00de3f38c091308f14dc0a121838 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 21 Aug 2025 10:17:17 -0700 Subject: [PATCH 26/33] [MLIR] Apply clang-tidy fixes for llvm-qualified-auto in XeGPUUtils.cpp (NFC) --- mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp index b4605cd7e94d6..a38993e0c55b1 100644 --- a/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp +++ b/mlir/lib/Dialect/XeGPU/Utils/XeGPUUtils.cpp @@ -147,7 +147,7 @@ xegpu::DistributeLayoutAttr xegpu::getDistributeLayoutAttr(const Value value) { } if (auto arg = dyn_cast(value)) { - auto parentOp = arg.getOwner()->getParentOp(); + auto *parentOp = arg.getOwner()->getParentOp(); if (auto loop = dyn_cast(parentOp)) { OpOperand *tiedInit = loop.getTiedLoopInit(arg); if (tiedInit) From c7f3c0b08f457c245071f8fedfc85a1423f86ab2 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 21 Aug 2025 09:24:06 -0700 Subject: [PATCH 27/33] [MLIR] Apply clang-tidy fixes for misc-use-internal-linkage in TosaCanonicalizations.cpp (NFC) --- mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp index a85ff10aa0d73..293c6af6202f4 100644 --- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp +++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp @@ -38,7 +38,7 @@ using namespace mlir::tosa; //===----------------------------------------------------------------------===// // Check that the zero point of the tensor and padding operations are aligned. -bool checkMatchingPadConstAndZp(Value padConst, Value zp) { +static bool checkMatchingPadConstAndZp(Value padConst, Value zp) { // Check that padConst is a constant value and a scalar tensor DenseElementsAttr padConstAttr; if (!matchPattern(padConst, m_Constant(&padConstAttr)) || @@ -889,8 +889,9 @@ void SliceOp::getCanonicalizationPatterns(RewritePatternSet &results, //===----------------------------------------------------------------------===// template -DenseElementsAttr binaryFolder(DenseElementsAttr lhs, DenseElementsAttr rhs, - RankedTensorType returnTy) { +static DenseElementsAttr binaryFolder(DenseElementsAttr lhs, + DenseElementsAttr rhs, + RankedTensorType returnTy) { if (rhs && lhs && rhs.isSplat() && lhs.isSplat()) { auto lETy = llvm::cast(lhs.getType()).getElementType(); auto rETy = llvm::cast(rhs.getType()).getElementType(); From 61e3c84f6c526ecadaceef3a40f8f5d1910544d4 Mon Sep 17 00:00:00 2001 From: Zhaoxin Yang Date: Tue, 28 Oct 2025 08:43:16 +0800 Subject: [PATCH 28/33] [LoongArch][NFC] Pre-commit tests for flog2 (#162976) --- .../CodeGen/LoongArch/ir-instruction/flog2.ll | 32 +++ .../LoongArch/lasx/ir-instruction/flog2.ll | 264 ++++++++++++++++++ .../LoongArch/lsx/ir-instruction/flog2.ll | 162 +++++++++++ 3 files changed, 458 insertions(+) create mode 100644 llvm/test/CodeGen/LoongArch/ir-instruction/flog2.ll create mode 100644 llvm/test/CodeGen/LoongArch/lasx/ir-instruction/flog2.ll create mode 100644 llvm/test/CodeGen/LoongArch/lsx/ir-instruction/flog2.ll diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/flog2.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/flog2.ll new file mode 100644 index 0000000000000..93fcd421e4bd7 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/flog2.ll @@ -0,0 +1,32 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32 +; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64 + +declare float @llvm.log2.f32(float) +declare double @llvm.log2.f64(double) + +define float @flog2_s(float %x) nounwind { +; LA32-LABEL: flog2_s: +; LA32: # %bb.0: +; LA32-NEXT: b log2f +; +; LA64-LABEL: flog2_s: +; LA64: # %bb.0: +; LA64-NEXT: pcaddu18i $t8, %call36(log2f) +; LA64-NEXT: jr $t8 + %y = call float @llvm.log2.f32(float %x) + ret float %y +} + +define double @flog2_d(double %x) nounwind { +; LA32-LABEL: flog2_d: +; LA32: # %bb.0: +; LA32-NEXT: b log2 +; +; LA64-LABEL: flog2_d: +; LA64: # %bb.0: +; LA64-NEXT: pcaddu18i $t8, %call36(log2) +; LA64-NEXT: jr $t8 + %y = call double @llvm.log2.f64(double %x) + ret double %y +} diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/flog2.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/flog2.ll new file mode 100644 index 0000000000000..68f2e3ab488e1 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/flog2.ll @@ -0,0 +1,264 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s --check-prefix=LA32 +; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s --check-prefix=LA64 + +declare <8 x float> @llvm.log2.v8f32(<8 x float>) +declare <4 x double> @llvm.log2.v4f64(<4 x double>) + +define void @flog2_v8f32(ptr %res, ptr %a) nounwind { +; LA32-LABEL: flog2_v8f32: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -128 +; LA32-NEXT: st.w $ra, $sp, 124 # 4-byte Folded Spill +; LA32-NEXT: st.w $fp, $sp, 120 # 4-byte Folded Spill +; LA32-NEXT: xvld $xr0, $a1, 0 +; LA32-NEXT: xvst $xr0, $sp, 80 # 32-byte Folded Spill +; LA32-NEXT: move $fp, $a0 +; LA32-NEXT: xvpickve.w $xr0, $xr0, 5 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 48 # 16-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 4 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $xr0 +; LA32-NEXT: vld $vr1, $sp, 48 # 16-byte Folded Reload +; LA32-NEXT: vextrins.w $vr0, $vr1, 16 +; LA32-NEXT: xvst $xr0, $sp, 48 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 6 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: xvld $xr1, $sp, 48 # 32-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 32 +; LA32-NEXT: xvst $xr1, $sp, 48 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 7 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: xvld $xr1, $sp, 48 # 32-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 48 +; LA32-NEXT: xvst $xr1, $sp, 48 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 1 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 0 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $xr0 +; LA32-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vextrins.w $vr0, $vr1, 16 +; LA32-NEXT: xvst $xr0, $sp, 16 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 2 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: xvld $xr1, $sp, 16 # 32-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 32 +; LA32-NEXT: xvst $xr1, $sp, 16 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.w $xr0, $xr0, 3 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: xvld $xr1, $sp, 16 # 32-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 48 +; LA32-NEXT: xvld $xr0, $sp, 48 # 32-byte Folded Reload +; LA32-NEXT: xvpermi.q $xr1, $xr0, 2 +; LA32-NEXT: xvst $xr1, $fp, 0 +; LA32-NEXT: ld.w $fp, $sp, 120 # 4-byte Folded Reload +; LA32-NEXT: ld.w $ra, $sp, 124 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 128 +; LA32-NEXT: ret +; +; LA64-LABEL: flog2_v8f32: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -128 +; LA64-NEXT: st.d $ra, $sp, 120 # 8-byte Folded Spill +; LA64-NEXT: st.d $fp, $sp, 112 # 8-byte Folded Spill +; LA64-NEXT: xvld $xr0, $a1, 0 +; LA64-NEXT: xvst $xr0, $sp, 80 # 32-byte Folded Spill +; LA64-NEXT: move $fp, $a0 +; LA64-NEXT: xvpickve.w $xr0, $xr0, 5 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 48 # 16-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 4 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $xr0 +; LA64-NEXT: vld $vr1, $sp, 48 # 16-byte Folded Reload +; LA64-NEXT: vextrins.w $vr0, $vr1, 16 +; LA64-NEXT: xvst $xr0, $sp, 48 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 6 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: xvld $xr1, $sp, 48 # 32-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 32 +; LA64-NEXT: xvst $xr1, $sp, 48 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 7 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: xvld $xr1, $sp, 48 # 32-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 48 +; LA64-NEXT: xvst $xr1, $sp, 48 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 1 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $xr0 +; LA64-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vextrins.w $vr0, $vr1, 16 +; LA64-NEXT: xvst $xr0, $sp, 16 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 2 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: xvld $xr1, $sp, 16 # 32-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 32 +; LA64-NEXT: xvst $xr1, $sp, 16 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 80 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.w $xr0, $xr0, 3 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: xvld $xr1, $sp, 16 # 32-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 48 +; LA64-NEXT: xvld $xr0, $sp, 48 # 32-byte Folded Reload +; LA64-NEXT: xvpermi.q $xr1, $xr0, 2 +; LA64-NEXT: xvst $xr1, $fp, 0 +; LA64-NEXT: ld.d $fp, $sp, 112 # 8-byte Folded Reload +; LA64-NEXT: ld.d $ra, $sp, 120 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 128 +; LA64-NEXT: ret +entry: + %v = load <8 x float>, ptr %a + %r = call <8 x float> @llvm.log2.v8f32(<8 x float> %v) + store <8 x float> %r, ptr %res + ret void +} + +define void @flog2_v4f64(ptr %res, ptr %a) nounwind { +; LA32-LABEL: flog2_v4f64: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -112 +; LA32-NEXT: st.w $ra, $sp, 108 # 4-byte Folded Spill +; LA32-NEXT: st.w $fp, $sp, 104 # 4-byte Folded Spill +; LA32-NEXT: xvld $xr0, $a1, 0 +; LA32-NEXT: xvst $xr0, $sp, 64 # 32-byte Folded Spill +; LA32-NEXT: move $fp, $a0 +; LA32-NEXT: xvpickve.d $xr0, $xr0, 3 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 32 # 16-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.d $xr0, $xr0, 2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0 +; LA32-NEXT: vld $vr1, $sp, 32 # 16-byte Folded Reload +; LA32-NEXT: vextrins.d $vr0, $vr1, 16 +; LA32-NEXT: xvst $xr0, $sp, 32 # 32-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.d $xr0, $xr0, 1 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA32-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA32-NEXT: xvpickve.d $xr0, $xr0, 0 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0 +; LA32-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vextrins.d $vr0, $vr1, 16 +; LA32-NEXT: xvld $xr1, $sp, 32 # 32-byte Folded Reload +; LA32-NEXT: xvpermi.q $xr0, $xr1, 2 +; LA32-NEXT: xvst $xr0, $fp, 0 +; LA32-NEXT: ld.w $fp, $sp, 104 # 4-byte Folded Reload +; LA32-NEXT: ld.w $ra, $sp, 108 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 112 +; LA32-NEXT: ret +; +; LA64-LABEL: flog2_v4f64: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -112 +; LA64-NEXT: st.d $ra, $sp, 104 # 8-byte Folded Spill +; LA64-NEXT: st.d $fp, $sp, 96 # 8-byte Folded Spill +; LA64-NEXT: xvld $xr0, $a1, 0 +; LA64-NEXT: xvst $xr0, $sp, 64 # 32-byte Folded Spill +; LA64-NEXT: move $fp, $a0 +; LA64-NEXT: xvpickve.d $xr0, $xr0, 3 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 32 # 16-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.d $xr0, $xr0, 2 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0 +; LA64-NEXT: vld $vr1, $sp, 32 # 16-byte Folded Reload +; LA64-NEXT: vextrins.d $vr0, $vr1, 16 +; LA64-NEXT: xvst $xr0, $sp, 32 # 32-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.d $xr0, $xr0, 1 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA64-NEXT: xvld $xr0, $sp, 64 # 32-byte Folded Reload +; LA64-NEXT: xvpickve.d $xr0, $xr0, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $xr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0 +; LA64-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vextrins.d $vr0, $vr1, 16 +; LA64-NEXT: xvld $xr1, $sp, 32 # 32-byte Folded Reload +; LA64-NEXT: xvpermi.q $xr0, $xr1, 2 +; LA64-NEXT: xvst $xr0, $fp, 0 +; LA64-NEXT: ld.d $fp, $sp, 96 # 8-byte Folded Reload +; LA64-NEXT: ld.d $ra, $sp, 104 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 112 +; LA64-NEXT: ret +entry: + %v = load <4 x double>, ptr %a + %r = call <4 x double> @llvm.log2.v4f64(<4 x double> %v) + store <4 x double> %r, ptr %res + ret void +} diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/flog2.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/flog2.ll new file mode 100644 index 0000000000000..e5e75ec617b51 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/flog2.ll @@ -0,0 +1,162 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lsx < %s | FileCheck %s --check-prefix=LA32 +; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s --check-prefix=LA64 + +declare <4 x float> @llvm.log2.v4f32(<4 x float>) +declare <2 x double> @llvm.log2.v2f64(<2 x double>) + +define void @flog2_v4f32(ptr %res, ptr %a) nounwind { +; LA32-LABEL: flog2_v4f32: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -48 +; LA32-NEXT: st.w $ra, $sp, 44 # 4-byte Folded Spill +; LA32-NEXT: st.w $fp, $sp, 40 # 4-byte Folded Spill +; LA32-NEXT: vld $vr0, $a1, 0 +; LA32-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA32-NEXT: move $fp, $a0 +; LA32-NEXT: vreplvei.w $vr0, $vr0, 1 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA32-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vreplvei.w $vr0, $vr0, 0 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA32-NEXT: vextrins.w $vr0, $vr1, 16 +; LA32-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA32-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vreplvei.w $vr0, $vr0, 2 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 32 +; LA32-NEXT: vst $vr1, $sp, 0 # 16-byte Folded Spill +; LA32-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vreplvei.w $vr0, $vr0, 3 +; LA32-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA32-NEXT: bl log2f +; LA32-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA32-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA32-NEXT: vextrins.w $vr1, $vr0, 48 +; LA32-NEXT: vst $vr1, $fp, 0 +; LA32-NEXT: ld.w $fp, $sp, 40 # 4-byte Folded Reload +; LA32-NEXT: ld.w $ra, $sp, 44 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 48 +; LA32-NEXT: ret +; +; LA64-LABEL: flog2_v4f32: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -48 +; LA64-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +; LA64-NEXT: st.d $fp, $sp, 32 # 8-byte Folded Spill +; LA64-NEXT: vld $vr0, $a1, 0 +; LA64-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA64-NEXT: move $fp, $a0 +; LA64-NEXT: vreplvei.w $vr0, $vr0, 1 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA64-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vreplvei.w $vr0, $vr0, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA64-NEXT: vextrins.w $vr0, $vr1, 16 +; LA64-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA64-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vreplvei.w $vr0, $vr0, 2 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 32 +; LA64-NEXT: vst $vr1, $sp, 0 # 16-byte Folded Spill +; LA64-NEXT: vld $vr0, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vreplvei.w $vr0, $vr0, 3 +; LA64-NEXT: # kill: def $f0 killed $f0 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2f) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0 killed $f0 def $vr0 +; LA64-NEXT: vld $vr1, $sp, 0 # 16-byte Folded Reload +; LA64-NEXT: vextrins.w $vr1, $vr0, 48 +; LA64-NEXT: vst $vr1, $fp, 0 +; LA64-NEXT: ld.d $fp, $sp, 32 # 8-byte Folded Reload +; LA64-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 48 +; LA64-NEXT: ret +entry: + %v = load <4 x float>, ptr %a + %r = call <4 x float> @llvm.log2.v4f32(<4 x float> %v) + store <4 x float> %r, ptr %res + ret void +} + +define void @flog2_v2f64(ptr %res, ptr %a) nounwind { +; LA32-LABEL: flog2_v2f64: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -48 +; LA32-NEXT: st.w $ra, $sp, 44 # 4-byte Folded Spill +; LA32-NEXT: st.w $fp, $sp, 40 # 4-byte Folded Spill +; LA32-NEXT: vld $vr0, $a1, 0 +; LA32-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA32-NEXT: move $fp, $a0 +; LA32-NEXT: vreplvei.d $vr0, $vr0, 1 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA32-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA32-NEXT: vld $vr0, $sp, 0 # 16-byte Folded Reload +; LA32-NEXT: vreplvei.d $vr0, $vr0, 0 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0 +; LA32-NEXT: bl log2 +; LA32-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA32-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA32-NEXT: vextrins.d $vr0, $vr1, 16 +; LA32-NEXT: vst $vr0, $fp, 0 +; LA32-NEXT: ld.w $fp, $sp, 40 # 4-byte Folded Reload +; LA32-NEXT: ld.w $ra, $sp, 44 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 48 +; LA32-NEXT: ret +; +; LA64-LABEL: flog2_v2f64: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -48 +; LA64-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill +; LA64-NEXT: st.d $fp, $sp, 32 # 8-byte Folded Spill +; LA64-NEXT: vld $vr0, $a1, 0 +; LA64-NEXT: vst $vr0, $sp, 0 # 16-byte Folded Spill +; LA64-NEXT: move $fp, $a0 +; LA64-NEXT: vreplvei.d $vr0, $vr0, 1 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA64-NEXT: vst $vr0, $sp, 16 # 16-byte Folded Spill +; LA64-NEXT: vld $vr0, $sp, 0 # 16-byte Folded Reload +; LA64-NEXT: vreplvei.d $vr0, $vr0, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 killed $vr0 +; LA64-NEXT: pcaddu18i $ra, %call36(log2) +; LA64-NEXT: jirl $ra, $ra, 0 +; LA64-NEXT: # kill: def $f0_64 killed $f0_64 def $vr0 +; LA64-NEXT: vld $vr1, $sp, 16 # 16-byte Folded Reload +; LA64-NEXT: vextrins.d $vr0, $vr1, 16 +; LA64-NEXT: vst $vr0, $fp, 0 +; LA64-NEXT: ld.d $fp, $sp, 32 # 8-byte Folded Reload +; LA64-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 48 +; LA64-NEXT: ret +entry: + %v = load <2 x double>, ptr %a + %r = call <2 x double> @llvm.log2.v2f64(<2 x double> %v) + store <2 x double> %r, ptr %res + ret void +} From 45b1bcfa26a40b189f34530eb3a2c8490c15965b Mon Sep 17 00:00:00 2001 From: Wenju He Date: Tue, 28 Oct 2025 09:01:50 +0800 Subject: [PATCH 29/33] [Instcombine] Avoid widening trunc+sext to trunc+shl+ashr when not profitable (#160483) Skip the transform that replaces: %a = trunc i64 %x to i16 %b = sext i16 %a to i32 with %a = trunc i64 %x to i32 %b = shl i32 %a, 16 %c = ashr exact i32 %b, 16 when (pre-trunc) source type is wider than the final destination type. Modern architectures typically have efficient sign-extend instruction. It is preferable to preserve the sext for this case. Resolves #116019 Also fold sext(trunc nsw) to trunc nsw when narrowing source. --- .../InstCombine/InstCombineCasts.cpp | 23 +++++++++++++++---- .../InstCombine/sext-of-trunc-nsw.ll | 11 +++++++++ .../test/Transforms/InstCombine/trunc-sext.ll | 16 +++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/trunc-sext.ll diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 9b9fe265c7bce..f939e7aa78c33 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1525,7 +1525,15 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) { } // Try to extend the entire expression tree to the wide destination type. - if (shouldChangeType(SrcTy, DestTy) && canEvaluateSExtd(Src, DestTy)) { + bool ShouldExtendExpression = true; + Value *TruncSrc = nullptr; + // It is not desirable to extend expression in the trunc + sext pattern when + // destination type is narrower than original (pre-trunc) type. + if (match(Src, m_Trunc(m_Value(TruncSrc)))) + if (TruncSrc->getType()->getScalarSizeInBits() > DestBitSize) + ShouldExtendExpression = false; + if (ShouldExtendExpression && shouldChangeType(SrcTy, DestTy) && + canEvaluateSExtd(Src, DestTy)) { // Okay, we can transform this! Insert the new expression now. LLVM_DEBUG( dbgs() << "ICE: EvaluateInDifferentType converting expression type" @@ -1545,13 +1553,18 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &Sext) { ShAmt); } - Value *X; - if (match(Src, m_Trunc(m_Value(X)))) { + Value *X = TruncSrc; + if (X) { // If the input has more sign bits than bits truncated, then convert // directly to final type. unsigned XBitSize = X->getType()->getScalarSizeInBits(); - if (ComputeNumSignBits(X, &Sext) > XBitSize - SrcBitSize) - return CastInst::CreateIntegerCast(X, DestTy, /* isSigned */ true); + bool HasNSW = cast(Src)->hasNoSignedWrap(); + if (HasNSW || (ComputeNumSignBits(X, &Sext) > XBitSize - SrcBitSize)) { + auto *Res = CastInst::CreateIntegerCast(X, DestTy, /* isSigned */ true); + if (auto *ResTrunc = dyn_cast(Res); ResTrunc && HasNSW) + ResTrunc->setHasNoSignedWrap(true); + return Res; + } // If input is a trunc from the destination type, then convert into shifts. if (Src->hasOneUse() && X->getType() == DestTy) { diff --git a/llvm/test/Transforms/InstCombine/sext-of-trunc-nsw.ll b/llvm/test/Transforms/InstCombine/sext-of-trunc-nsw.ll index 516f1a2bfd5c5..4128a15d8d7ce 100644 --- a/llvm/test/Transforms/InstCombine/sext-of-trunc-nsw.ll +++ b/llvm/test/Transforms/InstCombine/sext-of-trunc-nsw.ll @@ -144,6 +144,17 @@ define i24 @wide_source_matching_signbits(i32 %x) { ret i24 %c } +define i32 @wide_source_matching_signbits_has_nsw_flag(i64 %i) { +; CHECK-LABEL: define i32 @wide_source_matching_signbits_has_nsw_flag( +; CHECK-SAME: i64 [[I:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = trunc nsw i64 [[I]] to i32 +; CHECK-NEXT: ret i32 [[A]] +; + %a = trunc nsw i64 %i to i16 + %b = sext i16 %a to i32 + ret i32 %b +} + ; negative test - not enough sign-bits define i24 @wide_source_not_matching_signbits(i32 %x) { diff --git a/llvm/test/Transforms/InstCombine/trunc-sext.ll b/llvm/test/Transforms/InstCombine/trunc-sext.ll new file mode 100644 index 0000000000000..ac1438405e171 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/trunc-sext.ll @@ -0,0 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +target datalayout = "i16:16:16-i32:32:32-i64:64:64-n16:32:64" + +define i32 @test(i64 %i) { +; CHECK-LABEL: define i32 @test( +; CHECK-SAME: i64 [[I:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = trunc i64 [[I]] to i16 +; CHECK-NEXT: [[B:%.*]] = sext i16 [[A]] to i32 +; CHECK-NEXT: ret i32 [[B]] +; + %a = trunc i64 %i to i16 + %b = sext i16 %a to i32 + ret i32 %b +} From 0ece134031c5e442103db25985c4a36b338127bb Mon Sep 17 00:00:00 2001 From: jinge90 Date: Tue, 28 Oct 2025 09:10:28 +0800 Subject: [PATCH 30/33] [Clang][Driver] Enable offloadlib option for clang-cl (#162980) --[no-]offloadlib option is used by rocm and cuda toolchain to enable/disable device libraries in linking phase for device code. It makes sense to re-use this option in SYCL for similar purpose and since clang driver supports SYCL in CL compatibility mode, we also need to enable this option in CL compatibility mode. --------- Signed-off-by: jinge90 --- clang/include/clang/Driver/Options.td | 6 +++--- clang/test/Driver/sycl.c | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index bca8b26bc3d30..8784c9d7d206d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5980,10 +5980,10 @@ def : Flag<["-"], "nocudainc">, Alias; def no_offloadlib : Flag<["--"], "no-offloadlib">, MarshallingInfoFlag>, - Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, - HelpText<"Do not link device library for CUDA/HIP device compilation">; + Visibility<[ClangOption, CC1Option, CLOption, FlangOption, FC1Option]>, + HelpText<"Do not link device library for CUDA/HIP/SYCL device compilation">; def offloadlib : Flag<["--"], "offloadlib">, - Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, + Visibility<[ClangOption, CC1Option, CLOption, FlangOption, FC1Option]>, HelpText<"Link device libraries for GPU device compilation">; def : Flag<["-"], "nogpulib">, Alias, diff --git a/clang/test/Driver/sycl.c b/clang/test/Driver/sycl.c index 2a672ccf0692d..5c210c8c181da 100644 --- a/clang/test/Driver/sycl.c +++ b/clang/test/Driver/sycl.c @@ -25,3 +25,8 @@ // RUN: %clang_cl -### -fsycl -- %s 2>&1 | FileCheck %s --check-prefix=DEFAULT // DEFAULT: "-sycl-std=2020" + +// RUN: %clang -### -fsycl -sycl-std=2017 --no-offloadlib -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OFFLOADLIB +// RUN: %clangxx -### -fsycl -sycl-std=2017 --no-offloadlib -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OFFLOADLIB +// RUN: %clang_cl -### -fsycl -sycl-std=2017 --no-offloadlib -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OFFLOADLIB +// CHECK-NO-OFFLOADLIB-NOT: warning: unknown argument ignored in clang-cl: '--no-offloadlib' From 66b481556e01e6e2508d7c9146849167b9e0323f Mon Sep 17 00:00:00 2001 From: Jeffrey Byrnes Date: Mon, 27 Oct 2025 18:39:59 -0700 Subject: [PATCH 31/33] [AMDGPU][AsmParser]: Use dummy operand for parsing buffer_ SWZ operand. (#165305) `MCInstrDesc` counts the SWZ operand for `NumOperands` -- thus, since we do not parse this into the `MCInst` operands, there will be a mismatch between `MCInst.getNumOperands` and `MCInstrDesc.getNumOperands` . `llvm-mca` assumes that each operand counted by `MCInstrDesc.getNumOperands` will be present in `MCInst.operands` https://github.com/llvm/llvm-project/blob/263377a17570e1cbe6eeae9ffa5ce02f240839ef/llvm/lib/MCA/InstrBuilder.cpp#L324 This parses a dummy operand for the buffer_loads as a placeholder for the implicit SWZ operand. This is similar to the parsing of `tbuffer_` variants which automatically parse the dummy operand https://github.com/llvm/llvm-project/blob/263377a17570e1cbe6eeae9ffa5ce02f240839ef/llvm/utils/TableGen/AsmMatcherEmitter.cpp#L1853 --- .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 3 ++ llvm/test/MC/AMDGPU/buffer-op-swz-operand.s | 43 ++++++++++++++++++ .../llvm-mca/AMDGPU/buffer-op-swz-operand.s | 45 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 llvm/test/MC/AMDGPU/buffer-op-swz-operand.s create mode 100644 llvm/test/tools/llvm-mca/AMDGPU/buffer-op-swz-operand.s diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 5580e4c0746bd..09338c533fdf2 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -9028,6 +9028,9 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst, addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset); addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyCPol, 0); + // Parse a dummy operand as a placeholder for the SWZ operand. This enforces + // agreement between MCInstrDesc.getNumOperands and MCInst.getNumOperands. + Inst.addOperand(MCOperand::createImm(0)); } //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AMDGPU/buffer-op-swz-operand.s b/llvm/test/MC/AMDGPU/buffer-op-swz-operand.s new file mode 100644 index 0000000000000..8bd91484d149c --- /dev/null +++ b/llvm/test/MC/AMDGPU/buffer-op-swz-operand.s @@ -0,0 +1,43 @@ +// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx1100 --show-inst < %s | FileCheck %s + +// CHECK: .amdgcn_target "amdgcn-amd-amdhsa--gfx1100" +buffer_load_dwordx4 v[0:3], v0, s[0:3], 0, offen offset:4092 slc +// CHECK: buffer_load_b128 v[0:3], v0, s[0:3], 0 offen offset:4092 slc ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; > +buffer_store_dword v0, v1, s[0:3], 0 offen slc +// CHECK: buffer_store_b32 v0, v1, s[0:3], 0 offen slc ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; > + +; tbuffer ops use autogenerate asm parsers +tbuffer_load_format_xyzw v[0:3], v0, s[0:3], 0 format:[BUF_FMT_32_32_SINT] offen offset:4092 slc +// CHECK: tbuffer_load_format_xyzw v[0:3], v0, s[0:3], 0 format:[BUF_FMT_32_32_SINT] offen offset:4092 slc ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; > +tbuffer_store_d16_format_x v0, v1, s[0:3], 0 format:[BUF_FMT_10_10_10_2_SNORM] offen slc +// CHECK: tbuffer_store_d16_format_x v0, v1, s[0:3], 0 format:[BUF_FMT_10_10_10_2_SNORM] offen slc ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; +// CHECK-NEXT: ; > diff --git a/llvm/test/tools/llvm-mca/AMDGPU/buffer-op-swz-operand.s b/llvm/test/tools/llvm-mca/AMDGPU/buffer-op-swz-operand.s new file mode 100644 index 0000000000000..932d9d1cc48b5 --- /dev/null +++ b/llvm/test/tools/llvm-mca/AMDGPU/buffer-op-swz-operand.s @@ -0,0 +1,45 @@ +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 < %s | FileCheck %s + +buffer_load_dwordx4 v[30:33], v4, s[0:3], 0, offen offset:4092 +buffer_store_dword v0, v1, s[0:3], 0 offen + +# CHECK: Iterations: 100 +# CHECK-NEXT: Instructions: 200 +# CHECK-NEXT: Total Cycles: 280 +# CHECK-NEXT: Total uOps: 200 + +# CHECK: Dispatch Width: 1 +# CHECK-NEXT: uOps Per Cycle: 0.71 +# CHECK-NEXT: IPC: 0.71 +# CHECK-NEXT: Block RThroughput: 2.0 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 80 1.00 * U buffer_load_dwordx4 v[30:33], v4, s[0:3], 0 offen offset:4092 +# CHECK-NEXT: 1 80 1.00 * U buffer_store_dword v0, v1, s[0:3], 0 offen + +# CHECK: Resources: +# CHECK-NEXT: [0] - HWBranch +# CHECK-NEXT: [1] - HWExport +# CHECK-NEXT: [2] - HWLGKM +# CHECK-NEXT: [3] - HWSALU +# CHECK-NEXT: [4] - HWVALU +# CHECK-NEXT: [5] - HWVMEM +# CHECK-NEXT: [6] - HWXDL + +# CHECK: Resource pressure per iteration: +# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] +# CHECK-NEXT: - - - - - 2.00 - + +# CHECK: Resource pressure by instruction: +# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: - - - - - 1.00 - buffer_load_dwordx4 v[30:33], v4, s[0:3], 0 offen offset:4092 +# CHECK-NEXT: - - - - - 1.00 - buffer_store_dword v0, v1, s[0:3], 0 offen From d63983b2c47befd34121de19320a778b97e5c520 Mon Sep 17 00:00:00 2001 From: Alex White Date: Tue, 28 Oct 2025 04:54:34 +0200 Subject: [PATCH 32/33] [clang-tidy] Add more constexpr options to `readability-identifier-naming` (#162160) Add more constexpr options to `readability-identifier-naming` check such as: - `ClassConstexpr*` - `GlobalConstexprVariable*` - `LocalConstexprVariable*` - `StaticConstexprVariable*` closes #54110 --- .../readability/IdentifierNamingCheck.cpp | 22 +- clang-tools-extra/docs/ReleaseNotes.rst | 3 +- .../checks/readability/identifier-naming.rst | 194 ++++++++++++++++++ .../readability/identifier-naming.cpp | 19 +- 4 files changed, 232 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 5178bee5c3374..ef3eac80301d3 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -83,14 +83,18 @@ namespace readability { m(Member) \ m(ClassConstant) \ m(ClassMember) \ + m(ClassConstexpr) \ + m(GlobalConstexprVariable) \ m(GlobalConstant) \ m(GlobalConstantPointer) \ m(GlobalPointer) \ m(GlobalVariable) \ + m(LocalConstexprVariable) \ m(LocalConstant) \ m(LocalConstantPointer) \ m(LocalPointer) \ m(LocalVariable) \ + m(StaticConstexprVariable) \ m(StaticConstant) \ m(StaticVariable) \ m(Constant) \ @@ -1497,8 +1501,22 @@ StyleKind IdentifierNamingCheck::findStyleKindForField( StyleKind IdentifierNamingCheck::findStyleKindForVar( const VarDecl *Var, QualType Type, ArrayRef> NamingStyles) const { - if (Var->isConstexpr() && NamingStyles[SK_ConstexprVariable]) - return SK_ConstexprVariable; + if (Var->isConstexpr()) { + if (Var->isStaticDataMember() && NamingStyles[SK_ClassConstexpr]) + return SK_ClassConstexpr; + + if (Var->isFileVarDecl() && NamingStyles[SK_GlobalConstexprVariable]) + return SK_GlobalConstexprVariable; + + if (Var->isStaticLocal() && NamingStyles[SK_StaticConstexprVariable]) + return SK_StaticConstexprVariable; + + if (Var->isLocalVarDecl() && NamingStyles[SK_LocalConstexprVariable]) + return SK_LocalConstexprVariable; + + if (NamingStyles[SK_ConstexprVariable]) + return SK_ConstexprVariable; + } if (!Type.isNull() && Type.isConstQualified()) { if (Var->isStaticDataMember() && NamingStyles[SK_ClassConstant]) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 061fb114276dc..d3295045c2b78 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -416,7 +416,8 @@ Changes in existing checks - Improved :doc:`readability-identifier-naming ` check by ignoring declarations and macros in system headers. The documentation is also improved - to differentiate the general options from the specific ones. + to differentiate the general options from the specific ones. Options for + fine-grained control over ``constexpr`` variables were added. - Improved :doc:`readability-implicit-bool-conversion ` check by correctly diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst index 0e031a15dea90..6c4e0b7dec198 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/identifier-naming.rst @@ -59,6 +59,7 @@ The available options are summarized below: - :option:`AbstractClassCase`, :option:`AbstractClassPrefix`, :option:`AbstractClassSuffix`, :option:`AbstractClassIgnoredRegexp`, :option:`AbstractClassHungarianPrefix` - :option:`ClassCase`, :option:`ClassPrefix`, :option:`ClassSuffix`, :option:`ClassIgnoredRegexp`, :option:`ClassHungarianPrefix` + - :option:`ClassConstexprCase`, :option:`ClassConstexprPrefix`, :option:`ClassConstexprSuffix`, :option:`ClassConstexprIgnoredRegexp`, :option:`ClassConstexprHungarianPrefix` - :option:`ClassConstantCase`, :option:`ClassConstantPrefix`, :option:`ClassConstantSuffix`, :option:`ClassConstantIgnoredRegexp`, :option:`ClassConstantHungarianPrefix` - :option:`ClassMemberCase`, :option:`ClassMemberPrefix`, :option:`ClassMemberSuffix`, :option:`ClassMemberIgnoredRegexp`, :option:`ClassMemberHungarianPrefix` - :option:`ClassMethodCase`, :option:`ClassMethodPrefix`, :option:`ClassMethodSuffix`, :option:`ClassMethodIgnoredRegexp` @@ -73,12 +74,14 @@ The available options are summarized below: - :option:`EnumCase`, :option:`EnumPrefix`, :option:`EnumSuffix`, :option:`EnumIgnoredRegexp` - :option:`EnumConstantCase`, :option:`EnumConstantPrefix`, :option:`EnumConstantSuffix`, :option:`EnumConstantIgnoredRegexp`, :option:`EnumConstantHungarianPrefix` - :option:`FunctionCase`, :option:`FunctionPrefix`, :option:`FunctionSuffix`, :option:`FunctionIgnoredRegexp` + - :option:`GlobalConstexprVariableCase`, :option:`GlobalConstexprVariablePrefix`, :option:`GlobalConstexprVariableSuffix`, :option:`GlobalConstexprVariableIgnoredRegexp`, :option:`GlobalConstexprVariableHungarianPrefix` - :option:`GlobalConstantCase`, :option:`GlobalConstantPrefix`, :option:`GlobalConstantSuffix`, :option:`GlobalConstantIgnoredRegexp`, :option:`GlobalConstantHungarianPrefix` - :option:`GlobalConstantPointerCase`, :option:`GlobalConstantPointerPrefix`, :option:`GlobalConstantPointerSuffix`, :option:`GlobalConstantPointerIgnoredRegexp`, :option:`GlobalConstantPointerHungarianPrefix` - :option:`GlobalFunctionCase`, :option:`GlobalFunctionPrefix`, :option:`GlobalFunctionSuffix`, :option:`GlobalFunctionIgnoredRegexp` - :option:`GlobalPointerCase`, :option:`GlobalPointerPrefix`, :option:`GlobalPointerSuffix`, :option:`GlobalPointerIgnoredRegexp`, :option:`GlobalPointerHungarianPrefix` - :option:`GlobalVariableCase`, :option:`GlobalVariablePrefix`, :option:`GlobalVariableSuffix`, :option:`GlobalVariableIgnoredRegexp`, :option:`GlobalVariableHungarianPrefix` - :option:`InlineNamespaceCase`, :option:`InlineNamespacePrefix`, :option:`InlineNamespaceSuffix`, :option:`InlineNamespaceIgnoredRegexp` + - :option:`LocalConstexprVariableCase`, :option:`LocalConstexprVariablePrefix`, :option:`LocalConstexprVariableSuffix`, :option:`LocalConstexprVariableIgnoredRegexp`, :option:`LocalConstexprVariableHungarianPrefix` - :option:`LocalConstantCase`, :option:`LocalConstantPrefix`, :option:`LocalConstantSuffix`, :option:`LocalConstantIgnoredRegexp`, :option:`LocalConstantHungarianPrefix` - :option:`LocalConstantPointerCase`, :option:`LocalConstantPointerPrefix`, :option:`LocalConstantPointerSuffix`, :option:`LocalConstantPointerIgnoredRegexp`, :option:`LocalConstantPointerHungarianPrefix` - :option:`LocalPointerCase`, :option:`LocalPointerPrefix`, :option:`LocalPointerSuffix`, :option:`LocalPointerIgnoredRegexp`, :option:`LocalPointerHungarianPrefix` @@ -97,6 +100,7 @@ The available options are summarized below: - :option:`PublicMemberCase`, :option:`PublicMemberPrefix`, :option:`PublicMemberSuffix`, :option:`PublicMemberIgnoredRegexp`, :option:`PublicMemberHungarianPrefix` - :option:`PublicMethodCase`, :option:`PublicMethodPrefix`, :option:`PublicMethodSuffix`, :option:`PublicMethodIgnoredRegexp` - :option:`ScopedEnumConstantCase`, :option:`ScopedEnumConstantPrefix`, :option:`ScopedEnumConstantSuffix`, :option:`ScopedEnumConstantIgnoredRegexp` + - :option:`StaticConstexprVariableCase`, :option:`StaticConstexprVariablePrefix`, :option:`StaticConstexprVariableSuffix`, :option:`StaticConstexprVariableIgnoredRegexp`, :option:`StaticConstexprVariableHungarianPrefix` - :option:`StaticConstantCase`, :option:`StaticConstantPrefix`, :option:`StaticConstantSuffix`, :option:`StaticConstantIgnoredRegexp`, :option:`StaticConstantHungarianPrefix` - :option:`StaticVariableCase`, :option:`StaticVariablePrefix`, :option:`StaticVariableSuffix`, :option:`StaticVariableIgnoredRegexp`, :option:`StaticVariableHungarianPrefix` - :option:`StructCase`, :option:`StructPrefix`, :option:`StructSuffix`, :option:`StructIgnoredRegexp` @@ -307,6 +311,58 @@ After: ~pre_foo_post(); }; +.. option:: ClassConstexprCase + + When defined, the check will ensure class ``constexpr`` names conform to + the selected casing. + +.. option:: ClassConstexprPrefix + + When defined, the check will ensure class ``constexpr`` names will add the + prefixed with the given value (regardless of casing). + +.. option:: ClassConstexprIgnoredRegexp + + Identifier naming checks won't be enforced for class ``constexpr`` names + matching this regular expression. + +.. option:: ClassConstexprSuffix + + When defined, the check will ensure class ``constexpr`` names will add the + suffix with the given value (regardless of casing). + +.. option:: ClassConstexprHungarianPrefix + + When enabled, the check ensures that the declared identifier will have a + Hungarian notation prefix based on the declared type. + +For example using values of: + + - ClassConstexprCase of ``lower_case`` + - ClassConstexprPrefix of ``pre_`` + - ClassConstexprSuffix of ``_post`` + - ClassConstexprHungarianPrefix of ``On`` + +Identifies and/or transforms class ``constexpr`` variable names as follows: + +Before: + +.. code-block:: c++ + + class FOO { + public: + static constexpr int CLASS_CONSTEXPR; + }; + +After: + +.. code-block:: c++ + + class FOO { + public: + static const int pre_class_constexpr_post; + }; + .. option:: ClassConstantCase When defined, the check will ensure class constant names conform to the @@ -950,6 +1006,52 @@ After: different style. Default value is `true`. +.. option:: GlobalConstexprVariableCase + + When defined, the check will ensure global ``constexpr`` variable names + conform to the selected casing. + +.. option:: GlobalConstexprVariablePrefix + + When defined, the check will ensure global ``constexpr`` variable names + will add the prefixed with the given value (regardless of casing). + +.. option:: GlobalConstexprVariableIgnoredRegexp + + Identifier naming checks won't be enforced for global ``constexpr`` + variable names matching this regular expression. + +.. option:: GlobalConstexprVariableSuffix + + When defined, the check will ensure global ``constexpr`` variable names + will add the suffix with the given value (regardless of casing). + +.. option:: GlobalConstexprVariableHungarianPrefix + + When enabled, the check ensures that the declared identifier will have a + Hungarian notation prefix based on the declared type. + +For example using values of: + + - GlobalConstexprVariableCase of ``lower_case`` + - GlobalConstexprVariablePrefix of ``pre_`` + - GlobalConstexprVariableSuffix of ``_post`` + - GlobalConstexprVariableHungarianPrefix of ``On`` + +Identifies and/or transforms global ``constexpr`` variable names as follows: + +Before: + +.. code-block:: c++ + + constexpr unsigned ImportantValue = 69; + +After: + +.. code-block:: c++ + + constexpr unsigned pre_important_value_post = 69; + .. option:: GlobalConstantCase When defined, the check will ensure global constant names conform to the @@ -1228,6 +1330,52 @@ After: } } // namespace FOO_NS +.. option:: LocalConstexprVariableCase + + When defined, the check will ensure local ``constexpr`` variable names + conform to the selected casing. + +.. option:: LocalConstexprVariablePrefix + + When defined, the check will ensure local ``constexpr`` variable names will + add the prefixed with the given value (regardless of casing). + +.. option:: LocalConstexprVariableIgnoredRegexp + + Identifier naming checks won't be enforced for local ``constexpr`` variable + names matching this regular expression. + +.. option:: LocalConstexprVariableSuffix + + When defined, the check will ensure local ``constexpr`` variable names will + add the suffix with the given value (regardless of casing). + +.. option:: LocalConstexprVariableHungarianPrefix + + When enabled, the check ensures that the declared identifier will have a + Hungarian notation prefix based on the declared type. + +For example using values of: + + - LocalConstexprVariableCase of ``lower_case`` + - LocalConstexprVariablePrefix of ``pre_`` + - LocalConstexprVariableSuffix of ``_post`` + - LocalConstexprVariableHungarianPrefix of ``On`` + +Identifies and/or transforms local ``constexpr`` variable names as follows: + +Before: + +.. code-block:: c++ + + void foo() { int const local_Constexpr = 420; } + +After: + +.. code-block:: c++ + + void foo() { int const pre_local_constexpr_post = 420; } + .. option:: LocalConstantCase When defined, the check will ensure local constant names conform to the @@ -2077,6 +2225,52 @@ After: enum class FOO { pre_One_post, pre_Two_post, pre_Three_post }; +.. option:: StaticConstexprVariableCase + + When defined, the check will ensure static ``constexpr`` variable names + conform to the selected casing. + +.. option:: StaticConstexprVariablePrefix + + When defined, the check will ensure static ``constexpr`` variable names + will add the prefixed with the given value (regardless of casing). + +.. option:: StaticConstexprVariableIgnoredRegexp + + Identifier naming checks won't be enforced for static ``constexpr`` + variable names matching this regular expression. + +.. option:: StaticConstexprVariableSuffix + + When defined, the check will ensure static ``constexpr`` variable names + will add the suffix with the given value (regardless of casing). + +.. option:: StaticConstexprVariableHungarianPrefix + + When enabled, the check ensures that the declared identifier will have a + Hungarian notation prefix based on the declared type. + +For example using values of: + + - StaticConstexprVariableCase of ``lower_case`` + - StaticConstexprVariablePrefix of ``pre_`` + - StaticConstexprVariableSuffix of ``_post`` + - StaticConstexprVariableHungarianPrefix of ``On`` + +Identifies and/or transforms static ``constexpr`` variable names as follows: + +Before: + +.. code-block:: c++ + + static unsigned constexpr MyConstexprStatic_array[] = {1, 2, 3}; + +After: + +.. code-block:: c++ + + static unsigned constexpr pre_my_constexpr_static_array_post[] = {1, 2, 3}; + .. option:: StaticConstantCase When defined, the check will ensure static constant names conform to the diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp index 86502759c2bcd..91807337176d9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp @@ -10,6 +10,8 @@ // RUN: readability-identifier-naming.ClassConstantCase: CamelCase, \ // RUN: readability-identifier-naming.ClassConstantPrefix: 'k', \ // RUN: readability-identifier-naming.ClassMemberCase: CamelCase, \ +// RUN: readability-identifier-naming.ClassConstexprCase: CamelCase, \ +// RUN: readability-identifier-naming.GlobalConstexprVariableCase: UPPER_CASE, \ // RUN: readability-identifier-naming.ClassMethodCase: camelBack, \ // RUN: readability-identifier-naming.ConceptCase: CamelCase, \ // RUN: readability-identifier-naming.ConstantCase: UPPER_CASE, \ @@ -27,6 +29,7 @@ // RUN: readability-identifier-naming.GlobalVariableCase: lower_case, \ // RUN: readability-identifier-naming.GlobalVariablePrefix: 'g_', \ // RUN: readability-identifier-naming.InlineNamespaceCase: lower_case, \ +// RUN: readability-identifier-naming.LocalConstexprVariableCase: CamelCase, \ // RUN: readability-identifier-naming.LocalConstantCase: CamelCase, \ // RUN: readability-identifier-naming.LocalConstantPrefix: 'k', \ // RUN: readability-identifier-naming.LocalVariableCase: lower_case, \ @@ -47,6 +50,7 @@ // RUN: readability-identifier-naming.ParameterPackCase: camelBack, \ // RUN: readability-identifier-naming.PureFunctionCase: lower_case, \ // RUN: readability-identifier-naming.PureMethodCase: camelBack, \ +// RUN: readability-identifier-naming.StaticConstexprVariableCase: UPPER_CASE, \ // RUN: readability-identifier-naming.StaticConstantCase: UPPER_CASE, \ // RUN: readability-identifier-naming.StaticVariableCase: camelBack, \ // RUN: readability-identifier-naming.StaticVariablePrefix: 's_', \ @@ -186,8 +190,8 @@ enum class EMyEnumeration { }; constexpr int ConstExpr_variable = MyConstant; -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for constexpr variable 'ConstExpr_variable' -// CHECK-FIXES: constexpr int const_expr_variable = MY_CONSTANT; +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for global constexpr variable 'ConstExpr_variable' +// CHECK-FIXES: constexpr int CONST_EXPR_VARIABLE = MY_CONSTANT; class my_class { // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for class 'my_class' @@ -208,7 +212,7 @@ class my_class { private: const int MEMBER_one_1 = ConstExpr_variable; // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: invalid case style for constant member 'MEMBER_one_1' -// CHECK-FIXES: const int member_one_1 = const_expr_variable; +// CHECK-FIXES: const int member_one_1 = CONST_EXPR_VARIABLE; int member2 = 2; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member 'member2' // CHECK-FIXES: int __member2 = 2; @@ -276,6 +280,9 @@ class CMyWellNamedClass2 : public my_class { int my_Other_Bad_Member = 42; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for private member 'my_Other_Bad_Member' // CHECK-FIXES: int __my_Other_Bad_Member = 42; + static constexpr int my_Other_Other_Bad_Member = 69; + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: invalid case style for class constexpr 'my_Other_Other_Bad_Member' + // CHECK-FIXES: static constexpr int MyOtherOtherBadMember = 69; public: CMyWellNamedClass2() = default; CMyWellNamedClass2(CMyWellNamedClass2 const&) = default; @@ -447,12 +454,18 @@ void global_function(int PARAMETER_1, int const CONST_parameter) { static const int THIS_static_ConsTant = 4; // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for static constant 'THIS_static_ConsTant' // CHECK-FIXES: static const int THIS_STATIC_CONS_TANT = 4; + static constexpr int THIS_static_ConstExpr = 4; +// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for static constexpr variable 'THIS_static_ConstExpr' +// CHECK-FIXES: static constexpr int THIS_STATIC_CONST_EXPR = 4; static int THIS_static_variable; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: invalid case style for static variable 'THIS_static_variable' // CHECK-FIXES: static int s_thisStaticVariable; int const local_Constant = 3; // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: invalid case style for local constant 'local_Constant' // CHECK-FIXES: int const kLocalConstant = 3; + int constexpr local_Constexpr = 3; +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for local constexpr variable 'local_Constexpr' +// CHECK-FIXES: int constexpr LocalConstexpr = 3; int LOCAL_VARIABLE; // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for local variable 'LOCAL_VARIABLE' // CHECK-FIXES: int local_variable; From 7de1a17cc64bfcd1f0de055682d562dfb6476fb2 Mon Sep 17 00:00:00 2001 From: Victor Chernyakin Date: Mon, 27 Oct 2025 20:04:00 -0700 Subject: [PATCH 33/33] [clang-tidy] Fix `modernize-use-scoped-lock` crash on malformed code (#165127) This code: ```cpp void f() { std::lock_guard dont_crash {some_nonexistant_variable}; } ``` Generates an AST like this: ```txt TranslationUnitDecl `-FunctionDecl line:3:6 f 'void ()' `-CompoundStmt `-DeclStmt `-VarDecl col:31 dont_crash 'std::lock_guard' destroyed ``` Where the `VarDecl` has no initializer. The check doesn't expect this and crashes. --- .../clang-tidy/modernize/UseScopedLockCheck.cpp | 3 ++- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++ .../checkers/modernize/use-scoped-lock-no-crash.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-no-crash.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp index a004480cb1b92..9bf316939e2d0 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -217,7 +217,8 @@ void UseScopedLockCheck::diagOnSingleLock( // Create Fix-its only if we can find the constructor call to properly handle // 'std::lock_guard l(m, std::adopt_lock)' case. - const auto *CtorCall = dyn_cast(LockGuard->getInit()); + const auto *CtorCall = + dyn_cast_if_present(LockGuard->getInit()); if (!CtorCall) return; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index d3295045c2b78..47d2d7e16865a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -380,6 +380,11 @@ Changes in existing checks on Windows when the check was enabled with a 32-bit :program:`clang-tidy` binary. +- Improved :doc:`modernize-use-scoped-lock + ` check by fixing a crash + on malformed code (common when using :program:`clang-tidy` through + :program:`clangd`). + - Improved :doc:`modernize-use-std-format ` check to correctly match when the format string is converted to a different type by an implicit diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-no-crash.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-no-crash.cpp new file mode 100644 index 0000000000000..587dbe2707873 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-no-crash.cpp @@ -0,0 +1,9 @@ +// RUN: %check_clang_tidy -std=c++17-or-later -expect-clang-tidy-error %s modernize-use-scoped-lock %t -- -- -isystem %clang_tidy_headers + +#include + +void f() { + std::lock_guard dont_crash {some_nonexistant_variable}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard' [modernize-use-scoped-lock] + // CHECK-MESSAGES: :[[@LINE-2]]:43: error: use of undeclared identifier 'some_nonexistant_variable' [clang-diagnostic-error] +}